home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / LINEconsole / channels.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  20.9 KB  |  966 lines

  1. /* channels.c: channel routines */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/channels.c,v 6.0 1991/12/18 20:26:30 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/LINEconsole/RCS/channels.c,v 6.0 1991/12/18 20:26:30 jpo Rel $
  9.  *
  10.  * $Log: channels.c,v $
  11.  * Revision 6.0  1991/12/18  20:26:30  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16. #include    "console.h"
  17.  
  18. struct chan_struct    **globallist = NULL, **chan_matches = NULL, 
  19.             *currentchan = NULL;
  20. int            num_channels = 0, chan_num_matches = 0;
  21. char            *chan_match = NULL;
  22.  
  23. struct chan_struct    *find_channel();
  24.  
  25. extern char    *time_t2RFC(), *vol2str(), *cmd_argv[],
  26.     *time_t2str(), *mystrtotime(), *lowerfy();
  27. extern int    cmd_argc;
  28. extern Level    lev;
  29. extern time_t    boottime;
  30. static void create_channel_list(), update_channel_list();
  31. static struct chan_struct *create_channel();
  32. static void display_channel_list();
  33. static void free_channel_list();
  34.  
  35. extern int total_number_reports, total_number_messages, total_volume, compat;
  36. extern int connected;
  37. extern struct procStatus    *create_status();
  38. extern int info_shown;
  39.  
  40. int channel_all = FALSE;
  41.  
  42. #define    CHAN_READ_INTERVAL  60
  43.  
  44. /* ARGSUSED */
  45. int do_channelread (ad, ds, args, arg)
  46. int                ad;
  47. struct client_dispatch        *ds;
  48. char                **args;
  49. struct type_UNIV_UTCTime    **arg;
  50. {
  51.     char    *str;
  52.     UTC    utc;
  53.           
  54.     utc = (UTC) malloc (sizeof(struct UTCtime));
  55.     utc->ut_flags = UT_SEC;
  56.  
  57.     utc->ut_sec = CHAN_READ_INTERVAL;
  58.  
  59.     str = utct2str(utc);
  60.     *arg = str2qb (str, strlen(str), 1);
  61.     return OK;
  62. }
  63.  
  64. /* ARGSUSED */
  65. int channelread_result (ad, id, dummy, result, roi)
  66. int                            ad,
  67.                             id,
  68.                             dummy;
  69. register struct type_Qmgr_ChannelReadResult        *result;
  70. struct RoSAPindication                    *roi;
  71. {
  72.     if (compat) {
  73.         total_number_reports = 0;
  74.         total_number_messages = 0;
  75.         total_volume = 0;
  76.     }
  77.     if (globallist) 
  78.         update_channel_list(result->channels);
  79.     else
  80.         create_channel_list(result->channels);
  81.     order_channels(globallist, num_channels);
  82.     return OK;
  83. }
  84.  
  85. channel_list()
  86. {
  87.     if (connected == TRUE) {
  88.         if (cmd_argc > 1 && lexequ(cmd_argv[1], "all") == 0)
  89.             channel_all = TRUE;
  90.         else
  91.             channel_all = FALSE;
  92.         my_invoke(chanread, (char **) NULL);
  93.         if (globallist)
  94.             display_channel_list(globallist, num_channels);
  95.     }
  96.  
  97. }
  98.  
  99. channel_do_refresh ()
  100. {
  101.     if (connected == TRUE) {
  102.         my_invoke(chanread, (char **) NULL);
  103.         if (lev == channel) {
  104.             if (chan_num_matches > 0 && info_shown == TRUE)
  105.                 channel_info_regex();
  106.             else
  107.                 display_channel_list(globallist, num_channels);
  108.         }
  109.     }
  110. }
  111.  
  112. /*   */
  113.  
  114. extern FILE    *out;
  115.  
  116. static void display_channel_info(chan)
  117. struct chan_struct    *chan;
  118. {
  119.     char        *str,
  120.             *info_str;
  121.     int        info_strlen = BUFSIZ;
  122.     info_str = calloc(1, (unsigned) info_strlen);
  123.  
  124.     sprintf(info_str, ssformat, tab, 
  125.         chan->channelname, 
  126.         chan->channeldescrip);
  127.     if (chan->status->cachedUntil != 0)  {
  128.         str = time_t2RFC(chan->status->cachedUntil);
  129.         sprintf(info_str, plus_ssformat, info_str, tab,
  130.             "delayed until",
  131.             str);
  132.         free(str);
  133.     }
  134.     if (chan->oldestMessage != 0 && 
  135.         (chan->numberMessages != 0 || chan->numberReports != 0)) {
  136.         str = time_t2str(time((time_t *)0) - chan->oldestMessage);
  137.         sprintf(info_str, plus_ssformat, info_str, tab,
  138.             "oldest message",
  139.             str);
  140.         free(str);
  141.     }
  142.     if (chan->numberMessages != 0)
  143.         sprintf(info_str, plus_sdformat, info_str, tab,
  144.             "number of messages",
  145.             chan->numberMessages);
  146.     if (chan->numberReports != 0)
  147.         sprintf(info_str, plus_sdformat, info_str, tab,
  148.             "number of DRs",
  149.             chan->numberReports);
  150.  
  151.     if (chan->volumeMessages != 0) {
  152.         str = vol2str(chan->volumeMessages);
  153.         sprintf(info_str, plus_ssformat, info_str, tab,
  154.             "volume of messages",
  155.             str);
  156.         free(str);
  157.     }
  158.     if (chan->numberActiveProcesses != 0)
  159.         sprintf(info_str, plus_sdformat, info_str, tab,
  160.             "number of active processes",
  161.             chan->numberActiveProcesses);
  162.     sprintf(info_str, plus_ssformat, info_str, tab,
  163.         "status",
  164.         (chan->status->enabled == TRUE) ? "enabled" : "disabled");
  165.     if (chan->status->lastAttempt != 0) {
  166.         str = time_t2RFC(chan->status->lastAttempt);
  167.         sprintf(info_str, plus_ssformat, info_str, tab,
  168.             "last attempt",
  169.             str);
  170.         free(str);
  171.     }
  172.     if (chan->status->lastSuccess != 0) {
  173.         str = time_t2RFC(chan->status->lastSuccess);
  174.         sprintf(info_str, plus_ssformat, info_str, tab,
  175.             "last success",
  176.             str);
  177.         free(str);
  178.     }
  179.  
  180.     switch (chan->priority) {
  181.         case int_Qmgr_Priority_low:
  182.         sprintf(info_str, plus_ssformat, info_str, tab,
  183.             "priority",
  184.             "low");
  185.         break;
  186.         case int_Qmgr_Priority_normal:
  187.         sprintf(info_str, plus_ssformat, info_str, tab,
  188.             "priority",
  189.             "normal");
  190.         break;
  191.         case int_Qmgr_Priority_high:
  192.         sprintf(info_str, plus_ssformat, info_str, tab,
  193.             "priority",
  194.             "high");
  195.         break;
  196.         default:
  197.         break;
  198.     }
  199.     if (chan->maxprocs == 0)
  200.         sprintf(info_str, plus_ssformat, info_str, tab,
  201.             "maximum processes",
  202.             "unlimited");
  203.     else
  204.         sprintf(info_str, plus_sdformat, info_str, tab,
  205.             "maximum processes",
  206.             chan->maxprocs);
  207.  
  208.     fprintf(out, "%s\n", info_str);
  209.     free(info_str);
  210. }
  211.     
  212. static void display_channel(chan)
  213. struct chan_struct    *chan;
  214. {
  215.     /* one line per channel */
  216.     char    str[BUFSIZ];
  217.  
  218.     sprintf(str,"%s",chan->channelname);
  219.     if (chan -> numberActiveProcesses >= 1)
  220.         sprintf(str, "%s (ACTIVE %d process%s)",
  221.             str, chan->numberActiveProcesses,
  222.             (chan->numberActiveProcesses > 1) ? "s" : "");
  223.     sprintf(str,"%s: %d",
  224.         str,chan->numberMessages);
  225.     if (chan->numberReports != 0)
  226.       sprintf(str,"%s + %d", str, chan->numberReports);
  227.     if (chan->given_num_mtas != 0)
  228.         sprintf(str,"%s/%d",str, chan->given_num_mtas);
  229.     if (chan->status->enabled != TRUE)
  230.         sprintf(str, "%s (DISABLED)", str);
  231.     
  232.     fprintf(out, "%s\n", str);
  233. }
  234.  
  235. channel_info()
  236. {
  237.     if (chan_num_matches > 0) {
  238.         openpager();
  239.         display_channel_info(chan_matches[0]);
  240.         closepager();
  241.     }
  242. }
  243.  
  244. channel_info_regex()
  245. {
  246.     int    i;
  247.     if (chan_num_matches > 0) {
  248.         openpager();
  249.         if (chan_num_matches > 1)
  250.             fprintf(out, "%s: %d matches\n\n",
  251.                 chan_match, chan_num_matches);
  252.         for (i = 0; i < chan_num_matches; i++) {
  253.             display_channel_info(chan_matches[i]);
  254.             fprintf(out, "\n");
  255.         }
  256.         closepager();
  257.     }
  258. }
  259.  
  260. static void display_channel_list(list, num)
  261. struct chan_struct    **list;
  262. int            num;
  263. {
  264.     int    i;
  265.     int    badnessPast = FALSE;
  266.  
  267.     openpager();
  268.  
  269.     for (i = 0; i < num; i++) {
  270.         if (badnessPast == FALSE
  271.             && chanBadness(list[i]) == 0) {
  272.             if (channel_all == FALSE)
  273.                 i = num;
  274.             else if (badnessPast == FALSE) {
  275.                 fprintf(out, "==================================== Channels below have zero badness\n");
  276.                 badnessPast = TRUE;
  277.                 display_channel(list[i]);
  278.             }
  279.         } else
  280.             display_channel(list[i]);
  281.     }
  282.     closepager();
  283. }
  284.  
  285. /*   */
  286.  
  287. static void    create_channel_list(list)
  288. struct type_Qmgr_PrioritisedChannelList    *list;
  289. /* calloc and fillin in globallist */
  290. {
  291.     struct type_Qmgr_PrioritisedChannelList    *ix = list;
  292.     int    i,
  293.         num = 0;
  294.  
  295.     while (ix != NULL) {
  296.         num++;
  297.  
  298.         ix = ix->next;
  299.     }
  300.  
  301.     num_channels = num;
  302.     globallist = (struct chan_struct **) calloc((unsigned) num, 
  303.                              sizeof(struct chan_struct *));
  304.     chan_matches = (struct chan_struct **) calloc((unsigned) num, 
  305.                              sizeof(struct chan_struct *));
  306.     ix = list;
  307.     i = 0;
  308.     while ((ix != NULL) 
  309.            && (i < num)) {
  310.         globallist[i] = create_channel(ix);
  311.         i++;
  312.         ix = ix->next;
  313.     }
  314.     
  315. }
  316.  
  317. static void    update_channel(old, new)
  318. struct chan_struct            *old;
  319. struct type_Qmgr_PrioritisedChannelList    *new;
  320. {
  321.     struct type_Qmgr_ChannelInfo    *info;
  322.  
  323.     info = new->PrioritisedChannel->channel;
  324.     /* name and description don't change */
  325.     old->oldestMessage = convert_time(info->oldestMessage);
  326.     old->numberMessages = info->numberMessages;
  327.     old->numberReports = info->numberReports;
  328.     old->volumeMessages = info->volumeMessages;
  329.     old->given_num_mtas = info->numberMtas;
  330.     if (compat) {
  331.         total_volume += old->volumeMessages;
  332.         total_number_reports += old->numberReports;
  333.         total_number_messages += old->numberMessages;
  334.     }
  335.     old->numberActiveProcesses = info->numberActiveProcesses;
  336.     update_status(old->status,info->status);
  337.     old->priority = new->PrioritisedChannel->priority->parm;
  338.     old->maxprocs = info->maxprocs;
  339. }
  340.  
  341. static void    update_channel_list(new)
  342. struct type_Qmgr_PrioritisedChannelList    *new;
  343. {
  344.     struct type_Qmgr_PrioritisedChannelList *ix = new;
  345.     char                    *name = NULL;
  346.     struct chan_struct            *chan;
  347.  
  348.     while (ix != NULL) {
  349.         if (name != NULL) free(name);
  350.         name = qb2str(ix->PrioritisedChannel->channel->channel);
  351.  
  352.         chan = find_channel(name);
  353.         if (chan == NULL) {
  354.             PP_LOG(LLOG_EXCEPTIONS,
  355.                    ("console: can not find channel %s",name));
  356.             abort();
  357.         }
  358.         update_channel(chan,ix);
  359.         ix = ix->next;
  360.     }
  361. }
  362.  
  363. static struct chan_struct    *create_channel(chan)
  364. struct type_Qmgr_PrioritisedChannelList *chan;
  365. {
  366.     struct chan_struct        *temp;
  367.     struct type_Qmgr_ChannelInfo    *info;
  368.  
  369.     temp = (struct chan_struct *) calloc(1, sizeof(*temp));
  370.     info = chan->PrioritisedChannel->channel;
  371.     
  372.     temp->channelname = qb2str(info->channel);
  373.     temp->channeldescrip = qb2str(info->channelDescription);
  374.  
  375.     temp->oldestMessage = convert_time(info->oldestMessage); 
  376.     temp->numberMessages = info->numberMessages;
  377.     temp->numberReports = info->numberReports;
  378.     temp->volumeMessages = info->volumeMessages;
  379.     temp->given_num_mtas = info->numberMtas;
  380.     if (compat) {
  381.         total_volume += temp->volumeMessages;
  382.         total_number_reports += temp->numberReports;
  383.         total_number_messages += temp->numberMessages;
  384.     }
  385.     temp->numberActiveProcesses = info->numberActiveProcesses;
  386.     temp->status = create_status(info->status);
  387.     if (temp->status->lastSuccess == 0)
  388.         temp->status->lastSuccess = boottime;
  389.     temp->priority = chan->PrioritisedChannel->priority->parm;
  390.     temp->inbound = bit_test(info->direction, bit_Qmgr_direction_inbound);
  391.     temp->outbound = bit_test(info->direction, bit_Qmgr_direction_outbound);
  392.     temp->chantype = info->chantype;
  393.     temp->maxprocs = info->maxprocs;
  394.     add_tailor_to_chan(temp);
  395.     return temp;
  396. }
  397.  
  398. clear_channel_level()
  399. {
  400.     if (globallist) 
  401.         free_channel_list(globallist, num_channels);
  402.     globallist = NULL;
  403.     if (chan_matches) free(chan_matches);
  404.     chan_matches = NULL;
  405.     num_channels = 0;
  406. }
  407.  
  408. static void free_channel_list(list, num)
  409. struct chan_struct    **list;
  410. int            num;
  411. {
  412.     int    i =0;
  413.     if (list == NULL)
  414.         return;
  415.     while (i < num) {
  416.         free(list[i]->channelname);
  417.         free(list[i]->channeldescrip);
  418.         free ((char *)list[i]->status);
  419.         i++;
  420.     }
  421.     free((char *) list);
  422. }
  423.  
  424. /*   */
  425. struct chan_struct *find_channel(name)
  426. char            *name;
  427. {
  428.     int    i = 0;
  429.     while ((i < num_channels) && 
  430.            (lexequ(globallist[i]->channelname, name) != 0)) 
  431.         i++;
  432.  
  433.     if (i >= num_channels) 
  434.         return NULL;
  435.     else
  436.         return globallist[i];
  437. }
  438.  
  439. extern char    *re_comp();
  440. extern int    re_exec();
  441.  
  442. int    find_channel_regex(name)
  443. char    *name;
  444. {
  445.     int    i = 0;
  446.     char    *diag;
  447.  
  448.     if ((diag = re_comp(name)) != 0) {
  449.         fprintf(stderr,
  450.             "re_comp error for '%s' [%s]\n", name, diag);
  451.         return 0;
  452.     }
  453.     
  454.     for (i = 0, chan_num_matches = 0; i < num_channels; i++) 
  455.         if (re_exec(lowerfy(globallist[i]->channelname)) == 1) 
  456.             chan_matches[chan_num_matches++] = globallist[i];
  457.  
  458.     return chan_num_matches;
  459. }
  460.  
  461.  
  462. channel_set_current_regex()
  463. {
  464.     int    cont = TRUE, doquit = FALSE, first = TRUE;
  465.     char    buf[BUFSIZ];
  466.  
  467.     while (cont == TRUE) {
  468.         if (cmd_argc > 1 && first == TRUE) {
  469.             strcpy(buf, cmd_argv[1]);
  470.             first = FALSE;
  471.         } else {
  472.             fprintf(stdout, "match expression (%s) (q=quit) = ", 
  473.                 (chan_match == NULLCP) ? "" : chan_match);
  474.             fflush(stdout);
  475.  
  476.             if (gets(buf) == NULL)
  477.                 exit (OK);
  478.         }
  479.         (void) compress(buf, buf);
  480.         
  481.         if (emptyStr(buf) && (chan_match == NULLCP)) 
  482.             fprintf(stdout, "no match set\n");
  483.         else {
  484.             if (!emptyStr(buf)) {
  485.                 if (lexequ(buf, "q") != 0) {
  486.                     if (chan_match) free(chan_match);
  487.                     chan_match = strdup(buf);
  488.                 } else
  489.                     doquit = TRUE;
  490.             }
  491.             cont = FALSE;
  492.         }
  493.     }
  494.     if (doquit == TRUE)
  495.         return NOTOK;
  496.     if (find_channel_regex(chan_match) == 0) {
  497.         fprintf(stdout, "unable to find match for '%s'\n",
  498.             chan_match);
  499.         return NOTOK;
  500.     }
  501.     return OK;
  502. }
  503.         
  504. channel_set_current()
  505. {
  506.     int    cont = TRUE, i, doquit = FALSE, first = TRUE;
  507.     char    buf[BUFSIZ];
  508.     
  509.     while (cont == TRUE) {
  510.         if (cmd_argc > 1 && first == TRUE) {
  511.             strcpy(buf, cmd_argv[1]);
  512.             first = FALSE;
  513.         } else {
  514.             fprintf(stdout, "match expression (%s) (q=quit) = ", 
  515.                 (chan_match == NULLCP) ? "" : chan_match);
  516.             fflush(stdout);
  517.  
  518.  
  519.             if (gets(buf) == NULL)
  520.                 exit (OK);
  521.         }
  522.         compress(buf, buf);
  523.         if (emptyStr(buf) && (chan_match == NULLCP)) 
  524.                 fprintf(stdout, "no match set\n");
  525.         else if (!emptyStr(buf) && lexequ(buf, "q") == 0) {
  526.             doquit = TRUE;
  527.             cont = FALSE;
  528.         } else {
  529.             char    *expr = (emptyStr(buf)) ? chan_match : buf;
  530.             int num = find_channel_regex(expr);
  531.             switch (num) {
  532.                 case 0:
  533.                 fprintf(stdout, "unable to find match for '%s'\n", expr);
  534.                 break;
  535.                 case 1:
  536.                 cont = FALSE;
  537.                 if (expr != chan_match) {
  538.                     if (chan_match) free(chan_match);
  539.                     chan_match = strdup(expr);
  540.                 }
  541.                 currentchan = chan_matches[0];
  542.                 break;
  543.                 default:
  544.                 fprintf(stdout, "'%s' matches %d possible channels (", 
  545.                     expr, num);
  546.                 for (i = 0; i < num; i++)
  547.                     fprintf(stdout, "%s%s",
  548.                         chan_matches[i]->channelname,
  549.                         (i == num - 1) ? "" : ",");
  550.                 fprintf(stdout, ")\n\tneed unique channel\n");
  551.                 break;
  552.             }
  553.         }
  554.     }
  555.     if (doquit == TRUE)
  556.         return NOTOK;
  557.     return OK;
  558. }
  559.  
  560. int is_loc_chan(chan)
  561. struct chan_struct    *chan;
  562. {
  563.     if (chan->chantype == int_Qmgr_chantype_mts
  564.         && chan->outbound > 0)
  565.         return    TRUE;
  566.     else
  567.         return FALSE;
  568. }
  569.  
  570. /*   */
  571.  
  572. channel_next()
  573. {
  574.     if (globallist) {
  575.         int    i = 0;
  576.         if (chan_num_matches > 0) {
  577.             while ((i < num_channels) &&
  578.                    chan_matches[0] != globallist[i])
  579.                 i++;
  580.             if (i >= num_channels - 1)
  581.                 i = 0;
  582.             else
  583.                 i++;
  584.         } 
  585.         if (chan_match) free(chan_match);
  586.         chan_match = strdup(globallist[i]->channelname);
  587.         find_channel_regex(chan_match);
  588.     }
  589. }
  590.  
  591. channel_previous()
  592. {
  593.     if (globallist) {
  594.         int    i = num_channels -1;
  595.         if (chan_num_matches > 0) {
  596.             while ((i >= 0) &&
  597.                    chan_matches[0] != globallist[i])
  598.                 i--;
  599.             if (i <= 0)
  600.                 i = num_channels - 1;
  601.             else
  602.                 i--;
  603.         } 
  604.         if (chan_match) free(chan_match);
  605.         chan_match = strdup(globallist[i]->channelname);
  606.         find_channel_regex(chan_match);
  607.     }
  608. }
  609.         
  610. /*   */
  611.  
  612. channel_control(op, chan, mytime)
  613. Operations    op;
  614. char        *chan, *mytime;
  615. {
  616.     char    *args[3];
  617.     args[0] = chan;
  618.     args[1] = (char *) op;
  619.     args[2] = mytime;
  620.     my_invoke(op, args);
  621. }
  622.  
  623. channel_enable_regex()
  624. {
  625.     int    cont, i = 0;
  626.     char    buf[BUFSIZ];
  627.  
  628.     if (chan_num_matches > 0) {
  629.  
  630.         if (chan_num_matches > 1)
  631.             fprintf(stdout, "%s: %d matches\n\n",
  632.                 chan_match, chan_num_matches);
  633.  
  634.         for (i = 0; i < chan_num_matches; i++) {
  635.             cont = TRUE;
  636.             while (cont == TRUE) {
  637.                 if (chan_num_matches == 1) {
  638.                     fprintf(stdout, "enabling '%s'.\n",
  639.                         chan_matches[i]->channelname);
  640.                     buf[0] = 'y';
  641.                 } else {
  642.                     fprintf(stdout, "enable '%s' (y/n/q) ?",
  643.                         chan_matches[i]->channelname);
  644.                     fflush(stdout);
  645.                     if (gets(buf) == NULL)
  646.                         exit(OK);
  647.                     compress(buf, buf);
  648.                 }
  649.                 switch (buf[0]) {
  650.                     case 'y':
  651.                     case 'Y':
  652.                     channel_control(chanstart, 
  653.                             chan_matches[i]->channelname, 
  654.                             NULLCP);
  655.                     case 'n':
  656.                     case 'N':
  657.                     cont = FALSE;
  658.                     break;
  659.                     case 'q':
  660.                     case 'Q':
  661.                     cont = FALSE;
  662.                     i = chan_num_matches;
  663.                     default:
  664.                     break;
  665.                 }
  666.             }
  667.         }
  668.  
  669.     }
  670. }         
  671.  
  672. channel_disable_regex()
  673. {
  674.     int    cont, i;
  675.     char    buf[BUFSIZ];
  676.  
  677.     if (chan_num_matches > 0) {
  678.  
  679.         if (chan_num_matches > 1)
  680.             fprintf(stdout, "%s: %d matches\n\n",
  681.                 chan_match, chan_num_matches);
  682.  
  683.         for (i = 0; i < chan_num_matches; i++) {
  684.             cont = TRUE;
  685.             while (cont == TRUE) {
  686.                 if (chan_num_matches == 1)  {
  687.                     fprintf(stdout, "disabling '%s'.\n",
  688.                         chan_matches[i]->channelname);
  689.                     buf[0] = 'y';
  690.                 } else {
  691.                     fprintf(stdout, "disable '%s' (y/n/q) ?",
  692.                         chan_matches[i]->channelname);
  693.                     fflush(stdout);
  694.                     if (gets(buf) == NULL)
  695.                         exit(OK);
  696.                     compress(buf, buf);
  697.                 }
  698.                 switch (buf[0]) {
  699.                     case 'y':
  700.                     case 'Y':
  701.                     channel_control(chanstop, 
  702.                             chan_matches[i]->channelname, 
  703.                             NULLCP);
  704.                     case 'n':
  705.                     case 'N':
  706.                     cont = FALSE;
  707.                     break;
  708.                     case 'q':
  709.                     case 'Q':
  710.                     cont = FALSE;
  711.                     i = chan_num_matches;
  712.                     default:
  713.                     break;
  714.                 }
  715.             }
  716.         }
  717.  
  718.     }
  719. }         
  720.  
  721. channel_clear_regex()
  722. {
  723.     int    cont, i;
  724.     char    buf[BUFSIZ];
  725.  
  726.     if (chan_num_matches > 0) {
  727.  
  728.         if (chan_num_matches > 1)
  729.             fprintf(stdout, "%s: %d matches\n\n",
  730.                 chan_match, chan_num_matches);
  731.  
  732.         for (i = 0; i < chan_num_matches; i++) {
  733.             cont = TRUE;
  734.             while (cont == TRUE) {
  735.                 if (chan_num_matches == 1) {
  736.                     fprintf(stdout, "clearing '%s'.\n",
  737.                         chan_matches[i]->channelname);
  738.                     buf[0] = 'y';
  739.                 } else {
  740.                     fprintf(stdout, "clear '%s' (y/n/q) ?",
  741.                         chan_matches[i]->channelname);
  742.                     fflush(stdout);
  743.                     if (gets(buf) == NULL)
  744.                         exit(OK);
  745.                     compress(buf, buf);
  746.                 }
  747.                 switch (buf[0]) {
  748.                     case 'y':
  749.                     case 'Y':
  750.                     channel_control(chanclear, 
  751.                             chan_matches[i]->channelname, 
  752.                             NULLCP);
  753.                     case 'n':
  754.                     case 'N':
  755.                     cont = FALSE;
  756.                     break;
  757.                     case 'q':
  758.                     case 'Q':
  759.                     cont = FALSE;
  760.                     i = chan_num_matches;
  761.                     default:
  762.                     break;
  763.                 }
  764.             }
  765.         }
  766.  
  767.     }
  768. }         
  769.  
  770. channel_force(chan)
  771. struct chan_struct    *chan;
  772. {
  773.     
  774.     if (chan->status->enabled != TRUE)
  775.         channel_control(chanstart, chan->channelname, NULLCP);
  776.     if (chan->status->cachedUntil != 0)
  777.         channel_control(chanclear, chan->channelname, NULLCP);
  778. }
  779.  
  780. channel_below_clear_regex()
  781. {
  782.     int    cont, i;
  783.     char    buf[BUFSIZ];
  784.     
  785.     if (chan_num_matches > 0) {
  786.         if (chan_num_matches > 1)
  787.             fprintf(stdout, "%s: %d matches\n\n",
  788.                 chan_match, chan_num_matches);
  789.         for (i = 0; i < chan_num_matches; i++) {
  790.             cont = TRUE;
  791.             while (cont == TRUE) {
  792.                 if (chan_num_matches == 1) {
  793.                     fprintf(stdout, "clearing entities below '%s'.\n",
  794.                         chan_matches[i]->channelname);
  795.                     buf[0] = 'y';
  796.                 } else {
  797.                     fprintf(stdout, "clear entities below '%s' (y/n/q) ?",
  798.                         chan_matches[i]->channelname);
  799.                     fflush(stdout);
  800.                     if (gets(buf) == NULL)
  801.                         exit(OK);
  802.                     compress(buf, buf);
  803.                 }
  804.                 switch (buf[0]) {
  805.                     case 'y':
  806.                     case 'Y':
  807.                     currentchan = chan_matches[i];
  808.                     my_invoke(mtaread, 
  809.                           &(chan_matches[i]->channelname));
  810.                     mta_downforce_list(chan_matches[i]);
  811.                     channel_force(chan_matches[i]);
  812.                     currentchan = NULL;
  813.                     case 'n':
  814.                     case 'N':
  815.                     cont = FALSE;
  816.                     break;
  817.                     case 'q':
  818.                     case 'Q':
  819.                     cont = FALSE;
  820.                     i = chan_num_matches;
  821.                     default:
  822.                     break;
  823.                 }
  824.             }
  825.         }
  826.     }
  827. }
  828.  
  829. channel_delay_regex()
  830. {
  831.     int    cont, i, dcont;
  832.     char    buf[BUFSIZ];
  833.     char    delay[BUFSIZ];
  834.  
  835.     delay[0] = '\0';
  836.  
  837.     if (chan_num_matches > 0) {
  838.  
  839.         if (chan_num_matches > 1)
  840.             fprintf(stdout, "%s: %d matches\n\n",
  841.                 chan_match, chan_num_matches);
  842.  
  843.         for (i = 0; i < chan_num_matches; i++) {
  844.             cont = TRUE;
  845.             while (cont == TRUE) {
  846.                 if (chan_num_matches == 1) {
  847.                     fprintf(stdout, "delaying '%s'.\n",
  848.                         chan_matches[i]->channelname);
  849.                     buf[0] = 'y';
  850.                 } else {
  851.                     fprintf(stdout, "delay '%s' (y/n/q) ?",
  852.                         chan_matches[i]->channelname);
  853.                     fflush(stdout);
  854.                     if (gets(buf) == NULL)
  855.                         exit(OK);
  856.                     compress(buf, buf);
  857.                 }
  858.                 switch (buf[0]) {
  859.                     case 'y':
  860.                     case 'Y':
  861.                     dcont = TRUE;
  862.                     while (dcont == TRUE) {
  863.                         fprintf(stdout, "Delay (in s m h d and/or w) [%s] = ",
  864.                             (delay[0] != '\0') ? delay : "");
  865.                         fflush(stdout);
  866.         
  867.                         if (gets(buf) == NULL)
  868.                             exit(OK);
  869.                         compress(buf, buf);
  870.         
  871.                         if (emptyStr(buf)) {
  872.                             if (delay[0] != '\0')
  873.                                 /* happy with the one we got */
  874.                                 dcont = FALSE;
  875.                             else
  876.                                 fprintf(stdout, "no delay given\n");
  877.                         } else {
  878.                             dcont = FALSE;
  879.                             strcpy(delay, buf);
  880.                         }
  881.                     }
  882.                     
  883.                     channel_control(chancacheadd, 
  884.                             chan_matches[i]->channelname, 
  885.                             delay);
  886.                     case 'n':
  887.                     case 'N':
  888.                     cont = FALSE;
  889.                     break;
  890.                     case 'Q':
  891.                     case 'q':
  892.                     cont = FALSE;
  893.                     i = chan_num_matches;
  894.                     default:
  895.                     break;
  896.                 }
  897.             }
  898.         }
  899.  
  900.     }
  901. }         
  902.  
  903. /* ARGSUSED */
  904. int do_channelcontrol (ad, ds, args, arg)
  905. int                ad;
  906. struct client_dispatch        *ds;
  907. char                **args;
  908. struct type_Qmgr_ChannelControl    **arg;
  909. /* args[0] = channel */
  910. /* args[1] = stop,start,clear,cacheadd */
  911. /* args[2] = time */
  912. {
  913.     char    *timestr;
  914.     *arg = (struct type_Qmgr_ChannelControl *) malloc(sizeof(**arg));
  915.     (*arg)->control = (struct type_Qmgr_Control *)
  916.         malloc(sizeof(struct type_Qmgr_Control));
  917.  
  918.     (*arg)->channel = str2qb(args[0],
  919.                  strlen(args[0]),
  920.                  1);
  921.     switch ((Operations) args[1]) {
  922.         case chanstart:
  923.         (*arg)->control->offset = type_Qmgr_Control_start;
  924.         break;
  925.         case chanstop:
  926.         (*arg)->control->offset = type_Qmgr_Control_stop;
  927.         break;
  928.         case chanclear:
  929.         (*arg)->control->offset = type_Qmgr_Control_cacheClear;
  930.         break;
  931.         case chancacheadd:
  932.         (*arg)->control->offset = type_Qmgr_Control_cacheAdd;
  933.         timestr = mystrtotime(args[2]);
  934.         (*arg)->control->un.cacheAdd = str2qb(timestr,strlen(timestr),1);
  935.         free(timestr);
  936.         break;
  937.         default:
  938.         PP_LOG(LLOG_EXCEPTIONS,
  939.                ("console : '%s' unknown control param for channels",
  940.             args[1]));
  941.         return NOTOK;
  942.     }
  943.     return OK;
  944. }
  945.  
  946. /* ARGSUSED */
  947. int channelcontrol_result (ad, id, dummy, result, roi)
  948. int                            ad,
  949.                             id,
  950.                             dummy;
  951. register struct type_Qmgr_PrioritisedChannelList    *result;
  952. struct RoSAPindication                    *roi;
  953. {
  954.     if (compat) {
  955.         total_number_reports = 0;
  956.         total_number_messages = 0;
  957.         total_volume = 0;
  958.     }
  959.     if (globallist) 
  960.         update_channel_list(result);
  961.     else
  962.         create_channel_list(result);
  963.     return OK;
  964.  
  965. }
  966.