Annotation of coherent/g/usr/lib/uucp/tay104/uustat.c, revision 1.1.1.1

1.1       root        1: /* uustat.c
                      2:    UUCP status program
                      3: 
                      4:    Copyright (C) 1991, 1992 Ian Lance Taylor
                      5: 
                      6:    This file is part of the Taylor UUCP package.
                      7: 
                      8:    This program is free software; you can redistribute it and/or
                      9:    modify it under the terms of the GNU General Public License as
                     10:    published by the Free Software Foundation; either version 2 of the
                     11:    License, or (at your option) any later version.
                     12: 
                     13:    This program is distributed in the hope that it will be useful, but
                     14:    WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     16:    General Public License for more details.
                     17: 
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with this program; if not, write to the Free Software
                     20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     21: 
                     22:    The author of the program may be contacted at [email protected] or
                     23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
                     24:    */
                     25: 
                     26: #include "uucp.h"
                     27: 
                     28: #if USE_RCS_ID
                     29: const char uustat_rcsid[] = "$Id: uustat.c,v 1.1 93/07/30 07:59:49 bin Exp Locker: bin $";
                     30: #endif
                     31: 
                     32: #include <ctype.h>
                     33: #include <errno.h>
                     34: 
                     35: #if HAVE_TIME_H
                     36: #include <time.h>
                     37: #endif
                     38: 
                     39: #include "getopt.h"
                     40: 
                     41: #include "uudefs.h"
                     42: #include "uuconf.h"
                     43: #include "system.h"
                     44: 
                     45: /* The uustat program permits various listings and manipulations of
                     46:    files in the spool directory.  This implementation supports the
                     47:    following switches:
                     48: 
                     49:    -a list all jobs
                     50:    -Blines number of lines of standard input to mail
                     51:    -ccommand list only executions of specified command
                     52:    -Ccommand list only jobs other than executions of specified command
                     53:    -e list execute jobs rather than command requests
                     54:    -i ask user whether to kill each listed job
                     55:    -Ifile set configuration file name
                     56:    -kjobid kill job with specified ID
                     57:    -K kill each listed job
                     58:    -m report status for all remote machines
                     59:    -M mail uucp about each job killed with -K
                     60:    -N mail requestor about each job killed with -K
                     61:    -ohour report jobs older than specified number of hours
                     62:    -p do "ps -flp" on all processes holding lock files (Unix specific)
                     63:    -q list number of jobs for all systems
                     64:    -Q don't list jobs, just do -K processing
                     65:    -rjobid rejuvenate job with specified ID
                     66:    -ssystem report on all jobs for specified system
                     67:    -Ssystem report on all jobs other than for specified system
                     68:    -uuser report on all jobs for specified user
                     69:    -Uuser report on all jobs other than for specified user
                     70:    -Wcomment comment to include in mail messages
                     71:    -xdebug set debugging level
                     72:    -yhour report jobs younger than specified number of hours  */
                     73: 
                     74: /* The program name.  */
                     75: char abProgram[] = "uustat";
                     76: 
                     77: /* What to do with a job that matches the selection criteria; these
                     78:    values may be or'red together.  */
                     79: #define JOB_SHOW (01)
                     80: #define JOB_INQUIRE (02)
                     81: #define JOB_KILL (04)
                     82: #define JOB_MAIL (010)
                     83: #define JOB_NOTIFY (020)
                     84: 
                     85: /* This structure is used to accumulate all the lines in a single
                     86:    command file, so that they can all be displayed at once and so that
                     87:    executions can be displayed reasonably.  */
                     88: 
                     89: struct scmdlist
                     90: {
                     91:   struct scmdlist *qnext;
                     92:   struct scmd s;
                     93:   long itime;
                     94: };
                     95: 
                     96: /* Local functions.  */
                     97: 
                     98: static void ususage P((void));
                     99: static boolean fsxqt_file_read P((pointer puuconf, const char *zfile));
                    100: static void usxqt_file_free P((void));
                    101: static int isxqt_cmd P((pointer puuconf, int argc, char **argv, pointer pvar,
                    102:                        pointer pinfo));
                    103: static int isxqt_file P((pointer puuconf, int argc, char **argv, pointer pvar,
                    104:                         pointer pinfo));
                    105: static int isxqt_user P((pointer puuconf, int argc, char **argv, pointer pvar,
                    106:                         pointer pinfo));
                    107: static boolean fsworkfiles P((pointer puuconf, int icmd, int csystems,
                    108:                              char **pazsystems, boolean fnotsystems,
                    109:                              int cusers, char **pazusers,
                    110:                              boolean fnotusers, long iold, long iyoung,
                    111:                              int ccommands, char **pazcommands,
                    112:                              boolean fnotcommands, const char *zcomment,
                    113:                              int cstdin));
                    114: static boolean fsworkfiles_system P((pointer puuconf,int icmd,
                    115:                                     const struct uuconf_system *qsys,
                    116:                                     int cusers,  char **pazusers,
                    117:                                     boolean fnotusers, long iold,
                    118:                                     long iyoung, int ccommands,
                    119:                                     char **pazcommands,
                    120:                                     boolean fnotcommands,
                    121:                                     const char *zcomment, int cstdin));
                    122: static boolean fsworkfile_show P((pointer puuconf, int icmd,
                    123:                                  const struct uuconf_system *qsys,
                    124:                                  const struct scmd *qcmd,
                    125:                                  long itime, int ccommands,
                    126:                                  char **pazcommands, boolean fnotcommands,
                    127:                                  const char *zcomment, int cstdin));
                    128: static void usworkfile_header P((const struct uuconf_system *qsys,
                    129:                                 const struct scmd *qcmd,
                    130:                                 const char *zjobid,
                    131:                                 long itime, boolean ffirst));
                    132: static boolean fsexecutions P((pointer puuconf, int icmd, int csystems,
                    133:                               char **pazsystems, boolean fnotsystems,
                    134:                               int cusers, char **pazusers,
                    135:                               boolean fnotusers, long iold, long iyoung,
                    136:                               int ccommands, char **pazcommands,
                    137:                               boolean fnotcommands, const char *zcomment,
                    138:                               int cstdin));
                    139: static boolean fsnotify P((pointer puuconf, int icmd, const char *zcomment,
                    140:                           int cstdin, boolean fkilled, const char *zcmd,
                    141:                           struct scmdlist *qcmd, const char *zid,
                    142:                           const char *zuser,
                    143:                           const struct uuconf_system *qsys,
                    144:                           const char *zstdin, pointer pstdinseq,
                    145:                           const char *zrequestor));
                    146: static boolean fsquery P((pointer puuconf));
                    147: static int csunits_show P((long idiff));
                    148: static boolean fsmachines P((void));
                    149: 
                    150: /* Long getopt options.  */
                    151: static const struct option asSlongopts[] = { { NULL, 0, NULL, 0 } };
                    152: 
                    153: int
                    154: main (argc, argv)
                    155:      int argc;
                    156:      char **argv;
                    157: {
                    158:   /* -a: list all jobs.  */
                    159:   boolean fall = FALSE;
                    160:   /* -B lines: number of lines of standard input to mail.  */
                    161:   int cstdin = 100;
                    162:   /* -c,-C command: list only specified command.  */
                    163:   int ccommands = 0;
                    164:   char **pazcommands = NULL;
                    165:   boolean fnotcommands = FALSE;
                    166:   /* -e: list execute jobs.  */
                    167:   boolean fexecute = FALSE;
                    168:   /* -k jobid: kill specified job.  */
                    169:   int ckills = 0;
                    170:   char **pazkills = NULL;
                    171:   /* -m: report machine status.  */
                    172:   boolean fmachine = FALSE;
                    173:   /* -o hour: report jobs older than given number of hours.  */
                    174:   int ioldhours = -1;
                    175:   /* -p: report status of jobs holding lock files.  */
                    176:   boolean fps = FALSE;
                    177:   /* -q: list number of jobs for each system.  */
                    178:   boolean fquery = FALSE;
                    179:   /* -r jobid: rejuvenate specified job.  */
                    180:   int crejuvs = 0;
                    181:   char **pazrejuvs = NULL;
                    182:   /* -s,-S system: list all jobs for specified system.  */
                    183:   int csystems = 0;
                    184:   char **pazsystems = NULL;
                    185:   boolean fnotsystems = FALSE;
                    186:   /* -u,-U user: list all jobs for specified user.  */
                    187:   int cusers = 0;
                    188:   char **pazusers = NULL;
                    189:   boolean fnotusers = FALSE;
                    190:   /* -W comment: comment to include in mail messages.  */
                    191:   const char *zcomment = NULL;
                    192:   /* -y hour: report jobs younger than given number of hours.  */
                    193:   int iyounghours = -1;
                    194:   /* -I file: set configuration file.  */
                    195:   const char *zconfig = NULL;
                    196:   /* -Q, -i, -K, -M, -N: what to do with each job.  */
                    197:   int icmd = JOB_SHOW;
                    198:   int ccmds;
                    199:   int iopt;
                    200:   pointer puuconf;
                    201:   int iuuconf;
                    202:   long iold;
                    203:   long iyoung;
                    204:   const char *azoneuser[1];
                    205:   boolean fret;
                    206: 
                    207:   while ((iopt = getopt_long (argc, argv,
                    208:                              "aB:c:C:eiI:k:KmMNo:pqQr:s:S:u:U:W:x:y:",
                    209:                              asSlongopts, (int *) NULL)) != EOF)
                    210:     {
                    211:       switch (iopt)
                    212:        {
                    213:        case 'a':
                    214:          /* List all jobs.  */
                    215:          fall = TRUE;
                    216:          break;
                    217: 
                    218:        case 'B':
                    219:          /* Number of lines of standard input to mail.  */
                    220:          cstdin = (int) strtol (optarg, (char **) NULL, 10);
                    221:          break;
                    222: 
                    223:        case 'C':
                    224:          /* List jobs for other than specified command.  */
                    225:          fnotcommands = TRUE;
                    226:          /* Fall through.  */
                    227:        case 'c':
                    228:          /* List specified command.  */
                    229:          ++ccommands;
                    230:          pazcommands = (char **) xrealloc ((pointer) pazcommands,
                    231:                                            ccommands * sizeof (char *));
                    232:          pazcommands[ccommands - 1] = optarg;
                    233:          break;
                    234: 
                    235:        case 'e':
                    236:          /* List execute jobs.  */
                    237:          fexecute = TRUE;
                    238:          break;
                    239: 
                    240:        case 'i':
                    241:          /* Prompt the user whether to kill each job.  */
                    242:          icmd |= JOB_INQUIRE;
                    243:          break;
                    244: 
                    245:        case 'I':
                    246:          /* Set configuration file name.  */
                    247:          if (fsysdep_other_config (optarg))
                    248:            zconfig = optarg;
                    249:          break;
                    250: 
                    251:        case 'k':
                    252:          /* Kill specified job.  */
                    253:          ++ckills;
                    254:          pazkills = (char **) xrealloc ((pointer) pazkills,
                    255:                                         ckills * sizeof (char *));
                    256:          pazkills[ckills - 1] = optarg;
                    257:          break;
                    258: 
                    259:        case 'K':
                    260:          /* Kill each listed job.  */
                    261:          icmd |= JOB_KILL;
                    262:          break;
                    263: 
                    264:        case 'm':
                    265:          /* Report machine status.  */
                    266:          fmachine = TRUE;
                    267:          break;
                    268: 
                    269:        case 'M':
                    270:          /* Mail to uucp action taken on each job.  */
                    271:          icmd |= JOB_MAIL;
                    272:          break;
                    273: 
                    274:        case 'N':
                    275:          /*  Mail to requestor action taken on each job.  */
                    276:          icmd |= JOB_NOTIFY;
                    277:          break;
                    278: 
                    279:        case 'o':
                    280:          /* Report old jobs.  */
                    281:          ioldhours = (int) strtol (optarg, (char **) NULL, 10);
                    282:          break;
                    283: 
                    284:        case 'p':
                    285:          /* Get status of processes holding locks.  */
                    286:          fps = TRUE;
                    287:          break;
                    288: 
                    289:        case 'q':
                    290:          /* List number of jobs for each system.  */
                    291:          fquery = TRUE;
                    292:          break;
                    293: 
                    294:        case 'Q':
                    295:          /* Don't list jobs, just do -K processing.  */
                    296:          icmd &=~ JOB_SHOW;
                    297:          break;
                    298: 
                    299:        case 'r':
                    300:          /* Rejuvenate specified job.  */
                    301:          ++crejuvs;
                    302:          pazrejuvs = (char **) xrealloc ((pointer) pazrejuvs,
                    303:                                          crejuvs * sizeof (char *));
                    304:          pazrejuvs[crejuvs - 1] = optarg;
                    305:          break;
                    306: 
                    307:        case 'S':
                    308:          /* List jobs for other than specified system.  */
                    309:          fnotsystems = TRUE;
                    310:          /* Fall through.  */
                    311:        case 's':
                    312:          /* List jobs for specified system.  */
                    313:          ++csystems;
                    314:          pazsystems = (char **) xrealloc ((pointer) pazsystems,
                    315:                                           csystems * sizeof (char *));
                    316:          pazsystems[csystems - 1] = optarg;
                    317:          break;
                    318: 
                    319:        case 'U':
                    320:          /* List jobs for other than specified user.  */
                    321:          fnotusers = TRUE;
                    322:          /* Fall through.  */
                    323:        case 'u':
                    324:          /* List jobs for specified user.  */
                    325:          ++cusers;
                    326:          pazusers = (char **) xrealloc ((pointer) pazusers,
                    327:                                         cusers * sizeof (char *));
                    328:          pazusers[cusers - 1] = optarg;
                    329:          break;
                    330: 
                    331:        case 'W':
                    332:          /* Comment to include in mail messages.  */
                    333:          zcomment = optarg;
                    334:          break;
                    335: 
                    336:        case 'x':
                    337: #if DEBUG > 1
                    338:          /* Set debugging level.  */
                    339:          iDebug |= idebug_parse (optarg);
                    340: #endif
                    341:          break;
                    342: 
                    343:        case 'y':
                    344:          /* List jobs younger than given number of hours.  */
                    345:          iyounghours = (int) strtol (optarg, (char **) NULL, 10);
                    346:          break;
                    347: 
                    348:        case 0:
                    349:          /* Long option found and flag set.  */
                    350:          break;
                    351: 
                    352:        default:
                    353:          ususage ();
                    354:          break;
                    355:        }
                    356:     }
                    357: 
                    358:   if (optind != argc)
                    359:     ususage ();
                    360: 
                    361:   /* To avoid confusion, most options are only permitted by
                    362:      themselves.  This restriction might be removed later, but it is
                    363:      imposed by most implementations.  We do permit any combination of
                    364:      -c, -s, -u, -o and -y, and any combination of -k and -r.  */
                    365:   ccmds = 0;
                    366:   if (fall)
                    367:     ++ccmds;
                    368:   if (ckills > 0 || crejuvs > 0)
                    369:     ++ccmds;
                    370:   if (fmachine)
                    371:     ++ccmds;
                    372:   if (fps)
                    373:     ++ccmds;
                    374:   if (fquery)
                    375:     ++ccmds;
                    376:   if (fexecute || csystems > 0 || cusers > 0 || ioldhours != -1
                    377:       || iyounghours != -1 || ccommands > 0)
                    378:     ++ccmds;
                    379: 
                    380:   if (ccmds > 1)
                    381:     {
                    382:       ulog (LOG_ERROR, "Too many options");
                    383:       ususage ();
                    384:     }
                    385: 
                    386:   iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
                    387:   if (iuuconf != UUCONF_SUCCESS)
                    388:     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    389: 
                    390: #if DEBUG > 1
                    391:   {
                    392:     const char *zdebug;
                    393: 
                    394:     iuuconf = uuconf_debuglevel (puuconf, &zdebug);
                    395:     if (iuuconf != UUCONF_SUCCESS)
                    396:       ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    397:     if (zdebug != NULL)
                    398:       iDebug |= idebug_parse (zdebug);
                    399:   }
                    400: #endif
                    401: 
                    402:   usysdep_initialize (puuconf, INIT_SUID);
                    403: 
                    404:   /* If no commands were specified, we list all commands for the given
                    405:      user.  */
                    406:   if (ccmds == 0)
                    407:     {
                    408:       cusers = 1;
                    409:       azoneuser[0] = zsysdep_login_name ();
                    410:       pazusers = (char **) azoneuser;
                    411:     }
                    412: 
                    413:   /* Canonicalize the system names.  */
                    414:   if (csystems > 0)
                    415:     {
                    416:       int i;
                    417: 
                    418:       for (i = 0; i < csystems; i++)
                    419:        {
                    420:          struct uuconf_system ssys;
                    421: 
                    422:          iuuconf = uuconf_system_info (puuconf, pazsystems[i], &ssys);
                    423:          if (iuuconf != UUCONF_SUCCESS)
                    424:            {
                    425:              if (iuuconf == UUCONF_NOT_FOUND)
                    426:                ulog (LOG_FATAL, "%s: System not found", pazsystems[i]);
                    427:              else
                    428:                ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    429:            }
                    430:          if (strcmp (pazsystems[i], ssys.uuconf_zname) != 0)
                    431:            pazsystems[i] = zbufcpy (ssys.uuconf_zname);
                    432:          (void) uuconf_system_free (puuconf, &ssys);
                    433:        }
                    434:     }
                    435: 
                    436:   if (ioldhours == -1)
                    437:     iold = (long) -1;
                    438:   else
                    439:     {
                    440:       iold = (ixsysdep_time ((long *) NULL)
                    441:              - (long) ioldhours * (long) 60 * (long) 60);
                    442:       if (iold < 0L)
                    443:        iold = 0L;
                    444:     }
                    445:   if (iyounghours == -1)
                    446:     iyoung = (long) -1;
                    447:   else
                    448:     {
                    449:       iyoung = (ixsysdep_time ((long *) NULL)
                    450:                - (long) iyounghours * (long) 60 * (long) 60);
                    451:       if (iyoung < 0L)
                    452:        iyoung = 0L;
                    453:     }
                    454: 
                    455:   if (! fexecute
                    456:       && (fall
                    457:          || csystems > 0
                    458:          || cusers > 0
                    459:          || ioldhours != -1
                    460:          || iyounghours != -1
                    461:          || ccommands > 0))
                    462:     fret = fsworkfiles (puuconf, icmd, csystems, pazsystems, fnotsystems,
                    463:                        cusers, pazusers, fnotusers, iold,  iyoung,
                    464:                        ccommands, pazcommands, fnotcommands, zcomment,
                    465:                        cstdin);
                    466:   else if (fexecute)
                    467:     fret = fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems,
                    468:                         cusers, pazusers, fnotusers, iold, iyoung,
                    469:                         ccommands, pazcommands, fnotcommands, zcomment,
                    470:                         cstdin);
                    471:   else if (icmd != JOB_SHOW)
                    472:     {
                    473:       ulog (LOG_ERROR,
                    474:            "-i, -K, -M, -N, -Q not supported with -k, -m, -p, -q, -r");
                    475:       ususage ();
                    476:       fret = FALSE;
                    477:     }
                    478:   else if (fquery)
                    479:     fret = fsquery (puuconf);
                    480:   else if (fmachine)
                    481:     fret = fsmachines ();
                    482:   else if (ckills > 0 || crejuvs > 0)
                    483:     {
                    484:       int i;
                    485: 
                    486:       fret = TRUE;
                    487:       for (i = 0; i < ckills; i++)
                    488:        if (! fsysdep_kill_job (puuconf, pazkills[i]))
                    489:          fret = FALSE;
                    490: 
                    491:       for (i = 0; i < crejuvs; i++)
                    492:        if (! fsysdep_rejuvenate_job (puuconf, pazrejuvs[i]))
                    493:          fret = FALSE;
                    494:     }
                    495:   else if (fps)
                    496:     fret = fsysdep_lock_status ();
                    497:   else
                    498:     {
                    499: #if DEBUG > 0
                    500:       ulog (LOG_FATAL, "Can't happen");
                    501: #endif
                    502:       fret = FALSE;
                    503:     }
                    504: 
                    505:   ulog_close ();
                    506: 
                    507:   usysdep_exit (fret);
                    508: 
                    509:   /* Avoid errors about not returning a value.  */
                    510:   return 0;
                    511: }
                    512: 
                    513: /* Print a usage message and die.  */
                    514: 
                    515: static void
                    516: ususage ()
                    517: {
                    518:   fprintf (stderr,
                    519:           "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n",
                    520:           VERSION);
                    521:   fprintf (stderr,
                    522:           "Usage: uustat [options]\n");
                    523:   fprintf (stderr,
                    524:           " -a: list all UUCP jobs\n");
                    525:   fprintf (stderr, 
                    526:           " -B num: number of lines to return in -M or -N mail message\n");
                    527:   fprintf (stderr,
                    528:           " -c command: list requests for named command\n");
                    529:   fprintf (stderr,
                    530:           " -C command: list requests for other than named command\n");
                    531:   fprintf (stderr,
                    532:           " -e: list queued executions rather than job requests\n");
                    533:   fprintf (stderr,
                    534:           " -i: prompt for whether to kill each listed job\n");
                    535:   fprintf (stderr,
                    536:           " -k job: kill specified UUCP job\n");
                    537:   fprintf (stderr,
                    538:           " -K: kill each listed job\n");
                    539:   fprintf (stderr,
                    540:           " -m: report status for all remote machines\n");
                    541:   fprintf (stderr,
                    542:           " -M: mail report on each listed job to UUCP administrator\n");
                    543:   fprintf (stderr,
                    544:           " -N: mail report on each listed job to requestor\n");
                    545:   fprintf (stderr,
                    546:           " -o hours: list all jobs older than given number of hours\n");
                    547:   fprintf (stderr,
                    548:           " -p: show status of all processes holding UUCP locks\n");
                    549:   fprintf (stderr,
                    550:           " -q: list number of jobs for each system\n");
                    551:   fprintf (stderr,
                    552:           " -Q: don't list jobs, just take actions (-i, -K, -M, -N)\n");
                    553:   fprintf (stderr,
                    554:           " -r job: rejuvenate specified UUCP job\n");
                    555:   fprintf (stderr,
                    556:           " -s system: list all jobs for specified system\n");
                    557:   fprintf (stderr,
                    558:           " -S system: list all jobs for other than specified system\n");
                    559:   fprintf (stderr,
                    560:           " -u user: list all jobs for specified user\n");
                    561:   fprintf (stderr,
                    562:           " -U user: list all jobs for other than specified user\n");
                    563:   fprintf (stderr,
                    564:           " -W comment: comment to include in mail messages\n");
                    565:   fprintf (stderr,
                    566:           " -y hours: list all jobs younger than given number of hours\n");
                    567:   fprintf (stderr,
                    568:           " -x debug: Set debugging level (0 for none, 9 is max)\n");
                    569: #if HAVE_TAYLOR_CONFIG
                    570:   fprintf (stderr,
                    571:           " -I file: Set configuration file to use\n");
                    572: #endif /* HAVE_TAYLOR_CONFIG */
                    573:   exit (EXIT_FAILURE);
                    574: }
                    575: 
                    576: /* We need to be able to read information from an execution file.  */
                    577: 
                    578: /* The user name extracted from an execution file.  */
                    579: static char *zSxqt_user;
                    580: 
                    581: /* The system name from an execution file.  */
                    582: static char *zSxqt_system;
                    583: 
                    584: /* Address of requesting user (who to send mail to).  */
                    585: static const char *zSxqt_requestor;
                    586: 
                    587: /* The command (no arguments) from an execution file.  */
                    588: static char *zSxqt_prog;
                    589: 
                    590: /* The full command line from an execution file.  */
                    591: static char *zSxqt_cmd;
                    592: 
                    593: /* Number of files associated with an execution file.  */
                    594: static int cSxqt_files;
                    595: 
                    596: /* Names of files associated with execution file.  */
                    597: static char **pazSxqt_files;
                    598: 
                    599: /* Standard input file name.  */
                    600: static const char *zSxqt_stdin;
                    601: 
                    602: /* A command table used to dispatch an execution file.  */
                    603: static const struct uuconf_cmdtab asSxqt_cmds[] =
                    604: {
                    605:   { "C", UUCONF_CMDTABTYPE_FN | 0, NULL, isxqt_cmd },
                    606:   { "I", UUCONF_CMDTABTYPE_STRING, (pointer) &zSxqt_stdin, NULL },
                    607:   { "F", UUCONF_CMDTABTYPE_FN | 0, NULL, isxqt_file },
                    608:   { "R", UUCONF_CMDTABTYPE_STRING, (pointer) &zSxqt_requestor, NULL },
                    609:   { "U", UUCONF_CMDTABTYPE_FN | 3, NULL, isxqt_user },
                    610:   { NULL, 0, NULL, NULL }
                    611: };
                    612: 
                    613: /* Read an execution file, setting the above variables.  */
                    614: 
                    615: static boolean
                    616: fsxqt_file_read (puuconf, zfile)
                    617:      pointer puuconf;
                    618:      const char *zfile;
                    619: {
                    620:   FILE *e;
                    621:   int iuuconf;
                    622:   boolean fret;
                    623: 
                    624:   e = fopen (zfile, "r");
                    625:   if (e == NULL)
                    626:     {
                    627:       ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
                    628:       return FALSE;
                    629:     }
                    630: 
                    631:   zSxqt_user = NULL;
                    632:   zSxqt_system = NULL;
                    633:   zSxqt_stdin = NULL;
                    634:   zSxqt_requestor = NULL;
                    635:   zSxqt_prog = NULL;
                    636:   zSxqt_cmd = NULL;
                    637:   cSxqt_files = 0;
                    638:   pazSxqt_files = NULL;
                    639: 
                    640:   iuuconf = uuconf_cmd_file (puuconf, e, asSxqt_cmds, (pointer) NULL,
                    641:                             (uuconf_cmdtabfn) NULL,
                    642:                             UUCONF_CMDTABFLAG_CASE, (pointer) NULL);
                    643:   (void) fclose (e);
                    644:   if (iuuconf == UUCONF_SUCCESS)
                    645:     fret = TRUE;
                    646:   else
                    647:     {
                    648:       ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                    649:       fret = FALSE;
                    650:     }
                    651: 
                    652:   if (zSxqt_user == NULL)
                    653:     zSxqt_user = zbufcpy ("*unknown*");
                    654:   if (zSxqt_system == NULL)
                    655:     zSxqt_system = zbufcpy ("*unknown*");
                    656:   if (zSxqt_prog == NULL)
                    657:     {
                    658:       zSxqt_prog = zbufcpy ("*none*");
                    659:       zSxqt_cmd = zbufcpy ("*none*");
                    660:     }
                    661: 
                    662:   return fret;
                    663: }
                    664: 
                    665: /* Free up the information read from an execution file.  */
                    666: 
                    667: static void
                    668: usxqt_file_free ()
                    669: {
                    670:   int i;
                    671: 
                    672:   ubuffree (zSxqt_user);
                    673:   zSxqt_user = NULL;
                    674:   ubuffree (zSxqt_system);
                    675:   zSxqt_system = NULL;
                    676:   ubuffree (zSxqt_prog);
                    677:   zSxqt_prog = NULL;
                    678:   ubuffree (zSxqt_cmd);
                    679:   zSxqt_cmd = NULL;
                    680:   for (i = 0; i < cSxqt_files; i++)
                    681:     ubuffree (pazSxqt_files[i]);
                    682:   cSxqt_files = 0;
                    683:   xfree ((pointer) pazSxqt_files);
                    684:   pazSxqt_files = NULL;
                    685:   zSxqt_stdin = NULL;
                    686:   zSxqt_requestor = NULL;
                    687: }
                    688: 
                    689: /* Get the command from an execution file.  */
                    690: 
                    691: /*ARGSUSED*/
                    692: static int
                    693: isxqt_cmd (puuconf, argc, argv, pvar, pinfo)
                    694:      pointer puuconf;
                    695:      int argc;
                    696:      char **argv;
                    697:      pointer pvar;
                    698:      pointer pinfo;
                    699: {
                    700:   size_t clen;
                    701:   int i;
                    702: 
                    703:   if (argc <= 1)
                    704:     return UUCONF_CMDTABRET_CONTINUE;
                    705: 
                    706:   zSxqt_prog = zbufcpy (argv[1]);
                    707: 
                    708:   clen = 0;
                    709:   for (i = 1; i < argc; i++)
                    710:     clen += strlen (argv[i]) + 1;
                    711: 
                    712:   zSxqt_cmd = zbufalc (clen);
                    713:   zSxqt_cmd[0] = '\0';
                    714:   for (i = 1; i < argc - 1; i++)
                    715:     {
                    716:       strcat (zSxqt_cmd, argv[i]);
                    717:       strcat (zSxqt_cmd, " ");
                    718:     }
                    719:   strcat (zSxqt_cmd, argv[i]);
                    720: 
                    721:   return UUCONF_CMDTABRET_CONTINUE;
                    722: }
                    723: 
                    724: /* Get the associated files from an execution file.  */
                    725: 
                    726: /*ARGSUSED*/
                    727: static int
                    728: isxqt_file (puuconf, argc, argv, pvar, pinfo)
                    729:      pointer puuconf;
                    730:      int argc;
                    731:      char **argv;
                    732:      pointer pvar;
                    733:      pointer pinfo;
                    734: {
                    735:   if (argc != 2 && argc != 3)
                    736:     return UUCONF_CMDTABRET_CONTINUE;
                    737: 
                    738:   /* If this file is not in the spool directory, just ignore it.  */
                    739:   if (! fspool_file (argv[1]))
                    740:     return UUCONF_CMDTABRET_CONTINUE;
                    741: 
                    742:   ++cSxqt_files;
                    743:   pazSxqt_files = (char **) xrealloc ((pointer) pazSxqt_files,
                    744:                                      cSxqt_files * sizeof (char *));
                    745: 
                    746:   pazSxqt_files[cSxqt_files - 1] = zbufcpy (argv[1]);
                    747: 
                    748:   return UUCONF_CMDTABRET_CONTINUE;
                    749: }
                    750: 
                    751: /* Get the requesting user and system from an execution file.  */
                    752: 
                    753: /*ARGSUSED*/
                    754: static int
                    755: isxqt_user (puuconf, argc, argv, pvar, pinfo)
                    756:      pointer puuconf;
                    757:      int argc;
                    758:      char **argv;
                    759:      pointer pvar;
                    760:      pointer pinfo;
                    761: {
                    762:   zSxqt_user = zbufcpy (argv[1]);
                    763:   zSxqt_system = zbufcpy (argv[2]);
                    764:   return UUCONF_CMDTABRET_CONTINUE;
                    765: }
                    766: 
                    767: /* Handle various possible requests to look at work files.  */
                    768: 
                    769: static boolean
                    770: fsworkfiles (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers,
                    771:             pazusers, fnotusers, iold, iyoung, ccommands, pazcommands,
                    772:             fnotcommands, zcomment, cstdin)
                    773:      pointer puuconf;
                    774:      int icmd;
                    775:      int csystems;
                    776:      char **pazsystems;
                    777:      boolean fnotsystems;
                    778:      int cusers;
                    779:      char **pazusers;
                    780:      boolean fnotusers;
                    781:      long iold;
                    782:      long iyoung;
                    783:      int ccommands;
                    784:      char **pazcommands;
                    785:      boolean fnotcommands;
                    786:      const char *zcomment;
                    787:      int cstdin;
                    788: {
                    789:   boolean fret;
                    790:   int i;
                    791:   int iuuconf;
                    792:   struct uuconf_system ssys;
                    793: 
                    794:   fret = TRUE;
                    795: 
                    796:   if (csystems > 0 && ! fnotsystems)
                    797:     {
                    798:       for (i = 0; i < csystems; i++)
                    799:        {
                    800:          iuuconf = uuconf_system_info (puuconf, pazsystems[i], &ssys);
                    801:          if (iuuconf != UUCONF_SUCCESS)
                    802:            {
                    803:              if (iuuconf == UUCONF_NOT_FOUND)
                    804:                ulog (LOG_ERROR, "%s: System not found", pazsystems[i]);
                    805:              else
                    806:                ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                    807:              fret = FALSE;
                    808:              continue;
                    809:            }
                    810: 
                    811:          if (! fsworkfiles_system (puuconf, icmd, &ssys, cusers, pazusers,
                    812:                                    fnotusers, iold, iyoung, ccommands,
                    813:                                    pazcommands, fnotcommands, zcomment,
                    814:                                    cstdin))
                    815:            fret = FALSE;
                    816: 
                    817:          (void) uuconf_system_free (puuconf, &ssys);
                    818:        }
                    819:     }
                    820:   else
                    821:     {
                    822:       char **pznames, **pz;
                    823: 
                    824:       iuuconf = uuconf_system_names (puuconf, &pznames, 0);
                    825:       if (iuuconf != UUCONF_SUCCESS)
                    826:        {
                    827:          ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                    828:          return FALSE;
                    829:        }
                    830:       
                    831:       for (pz = pznames; *pz != NULL; pz++)
                    832:        {
                    833:          if (csystems > 0)
                    834:            {
                    835:              for (i = 0; i < csystems; i++)
                    836:                if (strcmp (*pz, pazsystems[i]) == 0)
                    837:                  break;
                    838:              if (i < csystems)
                    839:                continue;
                    840:            }
                    841: 
                    842:          iuuconf = uuconf_system_info (puuconf, *pz, &ssys);
                    843:          if (iuuconf != UUCONF_SUCCESS)
                    844:            {
                    845:              ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                    846:              fret = FALSE;
                    847:              continue;
                    848:            }
                    849: 
                    850:          if (! fsworkfiles_system (puuconf, icmd, &ssys, cusers, pazusers,
                    851:                                    fnotusers, iold, iyoung, ccommands,
                    852:                                    pazcommands, fnotcommands, zcomment,
                    853:                                    cstdin))
                    854:            fret = FALSE;
                    855: 
                    856:          (void) uuconf_system_free (puuconf, &ssys);
                    857:          xfree ((pointer) *pz);
                    858:        }
                    859:       xfree ((pointer) pznames);
                    860:     }
                    861: 
                    862:   return fret;
                    863: }
                    864: 
                    865: /* Look at the work files for a particular system.  */
                    866: 
                    867: static boolean
                    868: fsworkfiles_system (puuconf, icmd, qsys, cusers, pazusers, fnotusers, iold,
                    869:                    iyoung, ccommands, pazcommands, fnotcommands, zcomment,
                    870:                    cstdin)
                    871:      pointer puuconf;
                    872:      int icmd;
                    873:      const struct uuconf_system *qsys;
                    874:      int cusers;
                    875:      char **pazusers;
                    876:      boolean fnotusers;
                    877:      long iold;
                    878:      long iyoung;
                    879:      int ccommands;
                    880:      char **pazcommands;
                    881:      boolean fnotcommands;
                    882:      const char *zcomment;
                    883:      int cstdin;
                    884: {
                    885:   boolean fret;
                    886: 
                    887:   if (! fsysdep_get_work_init (qsys, UUCONF_GRADE_LOW))
                    888:     return FALSE;
                    889: 
                    890:   while (TRUE)
                    891:     {
                    892:       struct scmd s;
                    893:       long itime;
                    894: 
                    895:       if (! fsysdep_get_work (qsys, UUCONF_GRADE_LOW, &s))
                    896:        {
                    897:          usysdep_get_work_free (qsys);
                    898:          return FALSE;
                    899:        }
                    900:       if (s.bcmd == 'H')
                    901:        break;
                    902: 
                    903:       if (cusers > 0)
                    904:        {
                    905:          boolean fmatch;
                    906:          int i;
                    907: 
                    908:          fmatch = fnotusers;
                    909:          for (i = 0; i < cusers; i++)
                    910:            {
                    911:              if (s.zuser != NULL
                    912:                  && strcmp (pazusers[i], s.zuser) == 0)
                    913:                {
                    914:                  fmatch = ! fmatch;
                    915:                  break;
                    916:                }
                    917:            }
                    918:          if (! fmatch)
                    919:            continue;
                    920:        }
                    921: 
                    922:       itime = ixsysdep_work_time (qsys, s.pseq);
                    923: 
                    924:       if (iold != (long) -1 && itime > iold)
                    925:        continue;
                    926: 
                    927:       if (iyoung != (long) -1 && itime < iyoung)
                    928:        continue;
                    929: 
                    930:       if (! fsworkfile_show (puuconf, icmd, qsys, &s, itime, ccommands,
                    931:                             pazcommands, fnotcommands, zcomment, cstdin))
                    932:        {
                    933:          usysdep_get_work_free (qsys);
                    934:          return FALSE;
                    935:        }
                    936:     }
                    937: 
                    938:   fret = fsworkfile_show (puuconf, icmd, qsys, (const struct scmd *) NULL,
                    939:                          0L, ccommands, pazcommands, fnotcommands, zcomment,
                    940:                          cstdin);
                    941: 
                    942:   usysdep_get_work_free (qsys);
                    943: 
                    944:   return fret;
                    945: }
                    946: 
                    947: /* Show a single workfile.  This is actually called once for each line
                    948:    in the workfile, so we accumulate the lines and show them all at
                    949:    once.  This lets us show an execution in a useful fashion.  */
                    950: 
                    951: static boolean
                    952: fsworkfile_show (puuconf, icmd, qsys, qcmd, itime, ccommands, pazcommands,
                    953:                 fnotcommands, zcomment, cstdin)
                    954:      pointer puuconf;
                    955:      int icmd;
                    956:      const struct uuconf_system *qsys;
                    957:      const struct scmd *qcmd;
                    958:      long itime;
                    959:      int ccommands;
                    960:      char **pazcommands;
                    961:      boolean fnotcommands;
                    962:      const char *zcomment;
                    963:      int cstdin;
                    964: {
                    965:   static struct scmdlist *qlist;
                    966:   static char *zlistid;
                    967:   char *zid;
                    968: 
                    969:   if (qcmd == NULL)
                    970:     zid = NULL;
                    971:   else
                    972:     {
                    973:       zid = zsysdep_jobid (qsys, qcmd->pseq);
                    974:       if (zid == NULL)
                    975:        return FALSE;
                    976:     }
                    977: 
                    978:   /* If this is the same jobid as the list, put it on the end.  */
                    979: 
                    980:   if (qcmd != NULL
                    981:       && qlist != NULL
                    982:       && strcmp (zlistid, zid) == 0)
                    983:     {
                    984:       struct scmdlist *qnew, **pq;
                    985: 
                    986:       ubuffree (zid);
                    987:       qnew = (struct scmdlist *) xmalloc (sizeof (struct scmdlist));
                    988:       qnew->qnext = NULL;
                    989:       qnew->s = *qcmd;
                    990:       qnew->itime = itime;
                    991:       for (pq = &qlist; *pq != NULL; pq = &(*pq)->qnext)
                    992:        ;
                    993:       *pq = qnew;
                    994:       return TRUE;
                    995:     }
                    996: 
                    997:   /* Here we have found a different job ID, so we print the scmd
                    998:      structures that we have accumulated.  We look for the special
                    999:      case of an execution (an E command, or one of the destination
                   1000:      files begins with X.).  We could be more clever about other
                   1001:      situations as well.  */
                   1002:   if (qlist != NULL)
                   1003:     {
                   1004:       boolean fmatch;
                   1005:       const char *zprog, *zcmd, *zrequestor, *zstdin;
                   1006:       char *zfree;
                   1007:       struct scmdlist *qxqt;
                   1008:       struct scmdlist *qfree;
                   1009: 
                   1010:       fmatch = FALSE;
                   1011:       zprog = zcmd = zrequestor = zstdin = NULL;
                   1012:       zfree = NULL;
                   1013: 
                   1014:       for (qxqt = qlist; qxqt != NULL; qxqt = qxqt->qnext)
                   1015:        if (qxqt->s.bcmd == 'E'
                   1016:            || (qxqt->s.bcmd == 'S'
                   1017:                && qxqt->s.zto[0] == 'X'
                   1018:                && qxqt->s.zto[1] == '.'
                   1019:                && fspool_file (qxqt->s.zfrom)))
                   1020:          break;
                   1021: 
                   1022:       if (qxqt == NULL)
                   1023:        {
                   1024:          if (ccommands == 0
                   1025:              || (fnotcommands
                   1026:                  && strcmp (pazcommands[0], "ALL") == 0))
                   1027:            {
                   1028:              /* Show all the lines in a regular work file.  */
                   1029:              fmatch = TRUE;
                   1030: 
                   1031:              if ((icmd & JOB_SHOW) != 0)
                   1032:                {
                   1033:                  struct scmdlist *qshow;
                   1034: 
                   1035:                  for (qshow = qlist; qshow != NULL; qshow = qshow->qnext)
                   1036:                    {
                   1037:                      char *zfile;
                   1038:                      long cbytes;
                   1039: 
                   1040:                      usworkfile_header (qsys, &qshow->s, zlistid,
                   1041:                                         qshow->itime, qshow == qlist);
                   1042: 
                   1043:                      switch (qshow->s.bcmd)
                   1044:                        {
                   1045:                        case 'S':
                   1046:                          if (strchr (qshow->s.zoptions, 'C') != NULL
                   1047:                              || fspool_file (qshow->s.zfrom))
                   1048:                            zfile = zsysdep_spool_file_name (qsys,
                   1049:                                                             qshow->s.ztemp,
                   1050:                                                             qshow->s.pseq);
                   1051:                          else
                   1052:                            zfile = zbufcpy (qshow->s.zfrom);
                   1053:                          if (zfile == NULL)
                   1054:                            cbytes = 0;
                   1055:                          else
                   1056:                            {
                   1057:                              cbytes = csysdep_size (zfile);
                   1058:                              if (cbytes < 0)
                   1059:                                cbytes = 0;
                   1060:                            }
                   1061:                          printf ("Sending %s (%ld bytes) to %s",
                   1062:                                  qshow->s.zfrom, cbytes, qshow->s.zto);
                   1063:                          ubuffree (zfile);
                   1064:                          break;
                   1065:                        case 'R':
                   1066:                          printf ("Requesting %s to %s", qshow->s.zfrom,
                   1067:                                  qshow->s.zto);
                   1068:                          break;
                   1069:                        case 'X':
                   1070:                          printf ("Requesting %s to %s", qshow->s.zfrom,
                   1071:                                  qshow->s.zto);
                   1072:                          break;
                   1073:                        case 'P':
                   1074:                          printf ("(poll file)");
                   1075:                          break;
                   1076: #if DEBUG > 0
                   1077:                        default:
                   1078:                          printf ("Bad line %d", qshow->s.bcmd);
                   1079:                          break;
                   1080: #endif
                   1081:                        }
                   1082: 
                   1083:                      printf ("\n");
                   1084:                    }
                   1085:                }
                   1086:            }
                   1087:        }
                   1088:       else
                   1089:        {
                   1090:          long csize;
                   1091:          struct scmdlist *qsize;
                   1092: 
                   1093:          /* Show the command for an execution file.  */
                   1094:          if (qxqt->s.bcmd == 'E')
                   1095:            {
                   1096:              zfree = zbufcpy (qxqt->s.zcmd);
                   1097:              zfree[strcspn (zfree, " \t")] = '\0';
                   1098:              zprog = zfree;
                   1099:              zcmd = qxqt->s.zcmd;
                   1100:              if (strchr (qxqt->s.zoptions, 'R') != NULL)
                   1101:                zrequestor = qxqt->s.znotify;
                   1102:            }
                   1103:          else
                   1104:            {
                   1105:              char *zxqt;
                   1106: 
                   1107:              zxqt = zsysdep_spool_file_name (qsys, qxqt->s.zfrom,
                   1108:                                              qxqt->s.pseq);
                   1109:              if (zxqt == NULL)
                   1110:                return FALSE;
                   1111: 
                   1112:              if (! fsxqt_file_read (puuconf, zxqt))
                   1113:                {
                   1114:                  ubuffree (zxqt);
                   1115:                  return FALSE;
                   1116:                }
                   1117: 
                   1118:              ubuffree (zxqt);
                   1119: 
                   1120:              zprog = zSxqt_prog;
                   1121:              zcmd = zSxqt_cmd;
                   1122:              zrequestor = zSxqt_requestor;
                   1123:            }
                   1124: 
                   1125:          csize = 0L;
                   1126:          for (qsize = qlist; qsize != NULL; qsize = qsize->qnext)
                   1127:            {
                   1128:              if (qsize->s.bcmd == 'S' || qsize->s.bcmd == 'E')
                   1129:                {
                   1130:                  char *zfile;
                   1131: 
                   1132:                  if (strchr (qsize->s.zoptions, 'C') != NULL
                   1133:                      || fspool_file (qsize->s.zfrom))
                   1134:                    zfile = zsysdep_spool_file_name (qsys, qsize->s.ztemp,
                   1135:                                                     qsize->s.pseq);
                   1136:                  else
                   1137:                    zfile = zbufcpy (qsize->s.zfrom);
                   1138:                  if (zfile != NULL)
                   1139:                    {
                   1140:                      long cbytes;
                   1141: 
                   1142:                      cbytes = csysdep_size (zfile);
                   1143:                      if (cbytes > 0)
                   1144:                        csize += cbytes;
                   1145:                      ubuffree (zfile);
                   1146:                    }
                   1147:                }
                   1148:            }
                   1149: 
                   1150:          if (ccommands == 0)
                   1151:            fmatch = TRUE;
                   1152:          else
                   1153:            {
                   1154:              int i;
                   1155: 
                   1156:              fmatch = fnotcommands;
                   1157:              for (i = 0; i < ccommands; i++)
                   1158:                {
                   1159:                  if (strcmp (pazcommands[i], "ALL") == 0
                   1160:                      || strcmp (pazcommands[i], zprog) == 0)
                   1161:                    {
                   1162:                      fmatch = ! fmatch;
                   1163:                      break;
                   1164:                    }
                   1165:                }
                   1166:            }
                   1167: 
                   1168:          /* To get the name of the standard input file on this system
                   1169:             we have to look through the list of file transfers to
                   1170:             find the right one on the remote system.  */
                   1171:          if (fmatch)
                   1172:            {
                   1173:              struct scmdlist *qstdin;
                   1174: 
                   1175:              if (qxqt->s.bcmd == 'E')
                   1176:                qstdin = qxqt;
                   1177:              else if (zSxqt_stdin != NULL)
                   1178:                {
                   1179:                  for (qstdin = qlist;
                   1180:                       qstdin != NULL;
                   1181:                       qstdin = qstdin->qnext)
                   1182:                    if (qstdin->s.bcmd == 'S'
                   1183:                        && strcmp (qstdin->s.zto, zSxqt_stdin) == 0)
                   1184:                      break;
                   1185:                }
                   1186:              else
                   1187:                qstdin = NULL;
                   1188: 
                   1189:              if (qstdin != NULL)
                   1190:                {
                   1191:                  if (strchr (qstdin->s.zoptions, 'C') != NULL
                   1192:                      || fspool_file (qstdin->s.zfrom))
                   1193:                    zstdin = qstdin->s.ztemp;
                   1194:                  else
                   1195:                    zstdin = qstdin->s.zfrom;
                   1196:                }
                   1197:            }
                   1198: 
                   1199:          if (fmatch && (icmd & JOB_SHOW) != 0)
                   1200:            {
                   1201:              usworkfile_header (qsys, &qxqt->s, zlistid, qxqt->itime,
                   1202:                                 TRUE);
                   1203:              printf ("Executing %s (sending %ld bytes)\n", zcmd, csize);
                   1204:            }
                   1205:        }
                   1206: 
                   1207:       if (fmatch)
                   1208:        {
                   1209:          boolean fkill;
                   1210: 
                   1211:          fkill = FALSE;
                   1212:          if ((icmd & JOB_INQUIRE) != 0)
                   1213:            {
                   1214:              int b;
                   1215: 
                   1216:              /* Ask stdin whether this job should be killed.  */
                   1217:              fprintf (stderr, "%s: Kill %s? ", abProgram, zlistid);
                   1218:              (void) fflush (stderr);
                   1219:              b = getchar ();
                   1220:              fkill = b == 'y' || b == 'Y';
                   1221:              while (b != EOF && b != '\n')
                   1222:                b = getchar ();
                   1223:            }
                   1224:          else if ((icmd & JOB_KILL) != 0)
                   1225:            fkill = TRUE;
                   1226:              
                   1227:          if (fkill
                   1228:              && (qlist->s.zuser == NULL
                   1229:                  || strcmp (zsysdep_login_name (), qlist->s.zuser) != 0)
                   1230:              && ! fsysdep_privileged ())
                   1231:            ulog (LOG_ERROR, "%s: Not submitted by you", zlistid);
                   1232:          else
                   1233:            {
                   1234:              if ((icmd & (JOB_MAIL | JOB_NOTIFY)) != 0)
                   1235:                {
                   1236:                  if (! fsnotify (puuconf, icmd, zcomment, cstdin, fkill,
                   1237:                                  zcmd, qlist, zlistid, qlist->s.zuser,
                   1238:                                  qsys, zstdin, qlist->s.pseq, zrequestor))
                   1239:                    return FALSE;
                   1240:                }
                   1241: 
                   1242:              if (fkill)
                   1243:                {
                   1244:                  if (! fsysdep_kill_job (puuconf, zlistid))
                   1245:                    return FALSE;
                   1246:                }
                   1247:            }
                   1248:        }
                   1249: 
                   1250:       if (qxqt != NULL)
                   1251:        {
                   1252:          if (qxqt->s.bcmd == 'E')
                   1253:            ubuffree (zfree);
                   1254:          else
                   1255:            usxqt_file_free ();
                   1256:        }
                   1257: 
                   1258:       /* Free up the list of entries.  */
                   1259:       qfree = qlist;
                   1260:       while (qfree != NULL)
                   1261:        {
                   1262:          struct scmdlist *qnext;
                   1263: 
                   1264:          qnext = qfree->qnext;
                   1265:          xfree ((pointer) qfree);
                   1266:          qfree = qnext;
                   1267:        }
                   1268: 
                   1269:       ubuffree (zlistid);
                   1270: 
                   1271:       qlist = NULL;
                   1272:       zlistid = NULL;
                   1273:     }
                   1274: 
                   1275:   /* Start a new list with the entry we just got.  */
                   1276:   if (qcmd != NULL)
                   1277:     {
                   1278:       qlist = (struct scmdlist *) xmalloc (sizeof (struct scmdlist));
                   1279:       qlist->qnext = NULL;
                   1280:       qlist->s = *qcmd;
                   1281:       qlist->itime = itime;
                   1282:       zlistid = zid;
                   1283:     }
                   1284: 
                   1285:   return TRUE;
                   1286: }
                   1287: 
                   1288: /* Show the header of the line describing a workfile.  */
                   1289: 
                   1290: static void
                   1291: usworkfile_header (qsys, qcmd, zjobid, itime, ffirst)
                   1292:      const struct uuconf_system *qsys;
                   1293:      const struct scmd *qcmd;
                   1294:      const char *zjobid;
                   1295:      long itime;
                   1296:      boolean ffirst;
                   1297: {
                   1298:   const char *zshowid;
                   1299:   struct tm stime;
                   1300: 
                   1301:   if (ffirst)
                   1302:     zshowid = zjobid;
                   1303:   else
                   1304:     zshowid = "-";
                   1305: 
                   1306:   printf ("%s %s %s ", zshowid, qsys->uuconf_zname,
                   1307:          qcmd->zuser != NULL ? qcmd->zuser : OWNER);
                   1308: 
                   1309:   usysdep_localtime (itime, &stime);
                   1310:   printf ("%02d-%02d %02d:%02d ",
                   1311:          stime.tm_mon + 1, stime.tm_mday, stime.tm_hour, stime.tm_min);
                   1312: }
                   1313: 
                   1314: /* List queued executions that have not been processed by uuxqt for
                   1315:    one reason or another.  */
                   1316: 
                   1317: static boolean
                   1318: fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers,
                   1319:              pazusers, fnotusers, iold, iyoung, ccommands, pazcommands,
                   1320:              fnotcommands, zcomment, cstdin)
                   1321:      pointer puuconf;
                   1322:      int icmd;
                   1323:      int csystems;
                   1324:      char **pazsystems;
                   1325:      boolean fnotsystems;
                   1326:      int cusers;
                   1327:      char **pazusers;
                   1328:      boolean fnotusers;
                   1329:      long iold;
                   1330:      long iyoung;
                   1331:      int ccommands;
                   1332:      char **pazcommands;
                   1333:      boolean fnotcommands;
                   1334:      const char *zcomment;
                   1335:      int cstdin;
                   1336: {
                   1337:   const char *zlocalname;
                   1338:   int iuuconf;
                   1339:   char *zfile;
                   1340:   char *zsystem;
                   1341:   boolean ferr;
                   1342: 
                   1343:   iuuconf = uuconf_localname (puuconf, &zlocalname);
                   1344:   if (iuuconf == UUCONF_NOT_FOUND)
                   1345:     {
                   1346:       zlocalname = zsysdep_localname ();
                   1347:       if (zlocalname == NULL)
                   1348:        return FALSE;
                   1349:     }
                   1350:   else if (iuuconf != UUCONF_SUCCESS)
                   1351:     {
                   1352:       ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1353:       return FALSE;
                   1354:     }
                   1355: 
                   1356:   if (! fsysdep_get_xqt_init ())
                   1357:     return FALSE;
                   1358: 
                   1359:   while ((zfile = zsysdep_get_xqt (&zsystem, &ferr)) != NULL)
                   1360:     {
                   1361:       boolean fmatch;
                   1362:       int i;
                   1363:       long itime;
                   1364: 
                   1365:       if (csystems > 0)
                   1366:        {
                   1367:          fmatch = fnotsystems;
                   1368:          for (i = 0; i < csystems; i++)
                   1369:            {
                   1370:              if (strcmp (pazsystems[i], zsystem) == 0)
                   1371:                {
                   1372:                  fmatch = ! fmatch;
                   1373:                  break;
                   1374:                }
                   1375:            }
                   1376:          if (! fmatch)
                   1377:            {
                   1378:              ubuffree (zfile);
                   1379:              ubuffree (zsystem);
                   1380:              continue;
                   1381:            }
                   1382:        }
                   1383: 
                   1384:       itime = ixsysdep_file_time (zfile);
                   1385: 
                   1386:       if ((iold != (long) -1 && itime > iold)
                   1387:          || (iyoung != (long) -1 && itime < iyoung))
                   1388:        {
                   1389:          ubuffree (zfile);
                   1390:          ubuffree (zsystem);
                   1391:          continue;
                   1392:        }
                   1393: 
                   1394:       /* We need to read the execution file before we can check the
                   1395:         user name.  */
                   1396:       if (! fsxqt_file_read (puuconf, zfile))
                   1397:        {
                   1398:          ubuffree (zfile);
                   1399:          ubuffree (zsystem);
                   1400:          continue;      
                   1401:        }
                   1402: 
                   1403:       if (cusers == 0)
                   1404:        fmatch = TRUE;
                   1405:       else
                   1406:        {
                   1407:          fmatch = fnotusers;
                   1408:          for (i = 0; i < cusers; i++)
                   1409:            {
                   1410:              if (strcmp (zSxqt_user, pazusers[i]) == 0
                   1411:                  || (zSxqt_requestor != NULL
                   1412:                      && strcmp (zSxqt_requestor, pazusers[i]) == 0))
                   1413:                {
                   1414:                  fmatch = ! fmatch;
                   1415:                  break;
                   1416:                }
                   1417:            }
                   1418:        }
                   1419: 
                   1420:       if (fmatch && ccommands > 0)
                   1421:        {
                   1422:          fmatch = fnotcommands;
                   1423:          for (i = 0; i < ccommands; i++)
                   1424:            {
                   1425:              if (strcmp (pazcommands[i], "ALL") == 0
                   1426:                  || strcmp (pazcommands[i], zSxqt_prog) == 0)
                   1427:                {
                   1428:                  fmatch = ! fmatch;
                   1429:                  break;
                   1430:                }
                   1431:            }
                   1432:        }
                   1433: 
                   1434:       if (fmatch)
                   1435:        {
                   1436:          boolean fbad, fkill;
                   1437:          struct uuconf_system ssys;
                   1438: 
                   1439:          fbad = FALSE;
                   1440: 
                   1441:          if ((icmd & JOB_SHOW) != 0)
                   1442:            {
                   1443:              struct tm stime;
                   1444: 
                   1445:              printf ("%s %s!", zsystem, zSxqt_system);
                   1446:              if (zSxqt_requestor != NULL)
                   1447:                printf ("%s", zSxqt_requestor);
                   1448:              else
                   1449:                printf ("%s", zSxqt_user);
                   1450: 
                   1451:              usysdep_localtime (itime, &stime);
                   1452:              printf (" %02d-%02d %02d:%02d ",
                   1453:                      stime.tm_mon + 1, stime.tm_mday, stime.tm_hour,
                   1454:                      stime.tm_min);
                   1455: 
                   1456:              printf ("%s\n", zSxqt_cmd);
                   1457:            }
                   1458: 
                   1459:          fkill = FALSE;
                   1460:          if ((icmd & JOB_INQUIRE) != 0)
                   1461:            {
                   1462:              int b;
                   1463: 
                   1464:              /* Ask stdin whether this job should be killed.  */
                   1465:              fprintf (stderr, "%s: Kill %s? ", abProgram, zSxqt_cmd);
                   1466:              (void) fflush (stderr);
                   1467:              b = getchar ();
                   1468:              fkill = b == 'y' || b == 'Y';
                   1469:              while (b != EOF && b != '\n')
                   1470:                b = getchar ();
                   1471:            }
                   1472:          else if ((icmd & JOB_KILL) != 0)
                   1473:            fkill = TRUE;
                   1474: 
                   1475:          if (fkill)
                   1476:            {
                   1477:              if ((strcmp (zSxqt_user, zsysdep_login_name ()) != 0
                   1478:                   || strcmp (zsystem, zlocalname) != 0)
                   1479:                  && ! fsysdep_privileged ())
                   1480:                {
                   1481:                  ulog (LOG_ERROR, "Job not submitted by you\n");
                   1482:                  fbad = TRUE;
                   1483:                }
                   1484:            }
                   1485: 
                   1486:          if (! fbad)
                   1487:            {
                   1488:              iuuconf = uuconf_system_info (puuconf, zsystem, &ssys);
                   1489:              if (iuuconf != UUCONF_SUCCESS)
                   1490:                {
                   1491:                  if (iuuconf != UUCONF_NOT_FOUND)
                   1492:                    {
                   1493:                      ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1494:                      fbad = TRUE;
                   1495:                    }
                   1496:                  else if (strcmp (zsystem, zlocalname) == 0)
                   1497:                    {
                   1498:                      iuuconf = uuconf_system_local (puuconf, &ssys);
                   1499:                      if (iuuconf != UUCONF_SUCCESS)
                   1500:                        {
                   1501:                          ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1502:                          fbad = TRUE;
                   1503:                        }
                   1504:                    }
                   1505:                  else if (! funknown_system (puuconf, zsystem, &ssys))
                   1506:                    {
                   1507:                      ulog (LOG_ERROR, "Job for unknown system %s",
                   1508:                            zsystem);
                   1509:                      fbad = TRUE;
                   1510:                    }
                   1511:                }
                   1512:            }
                   1513: 
                   1514:          if (! fbad && (icmd & (JOB_MAIL | JOB_NOTIFY)) != 0)
                   1515:            {
                   1516:              if (! fsnotify (puuconf, icmd, zcomment, cstdin, fkill,
                   1517:                              zSxqt_cmd, (struct scmdlist *) NULL,
                   1518:                              (const char *) NULL, zSxqt_user, &ssys,
                   1519:                              zSxqt_stdin, (pointer) NULL, zSxqt_requestor))
                   1520:                {
                   1521:                  ferr = TRUE;
                   1522:                  usxqt_file_free ();
                   1523:                  ubuffree (zfile);
                   1524:                  ubuffree (zsystem);
                   1525:                  break;
                   1526:                }
                   1527:            }
                   1528: 
                   1529:          if (! fbad && fkill)
                   1530:            {
                   1531:              for (i = 0; i < cSxqt_files; i++)
                   1532:                {
                   1533:                  char *z;
                   1534: 
                   1535:                  z = zsysdep_spool_file_name (&ssys, pazSxqt_files[i],
                   1536:                                               (pointer) NULL);
                   1537:                  if (z != NULL)
                   1538:                    {
                   1539:                      (void) remove (z);
                   1540:                      ubuffree (z);
                   1541:                    }
                   1542:                }
                   1543:              if (remove (zfile) != 0)
                   1544:                ulog (LOG_ERROR, "remove (%s): %s", zfile,
                   1545:                      strerror (errno));
                   1546:            }
                   1547: 
                   1548:          if (! fbad)
                   1549:            (void) uuconf_system_free (puuconf, &ssys);
                   1550:        }
                   1551: 
                   1552:       usxqt_file_free ();
                   1553:       ubuffree (zfile);
                   1554:       ubuffree (zsystem);
                   1555:     }
                   1556: 
                   1557:   usysdep_get_xqt_free ();
                   1558: 
                   1559:   return ferr;
                   1560: }
                   1561: 
                   1562: /* When a job is killed, send mail to the appropriate people.  */
                   1563: 
                   1564: static boolean
                   1565: fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser,
                   1566:          qsys, zstdin, pstdinseq, zrequestor)
                   1567:      pointer puuconf;
                   1568:      int icmd;
                   1569:      const char *zcomment;
                   1570:      int cstdin;
                   1571:      boolean fkilled;
                   1572:      const char *zcmd;
                   1573:      struct scmdlist *qcmd;
                   1574:      const char *zid;
                   1575:      const char *zuser;
                   1576:      const struct uuconf_system *qsys;
                   1577:      const char *zstdin;
                   1578:      pointer pstdinseq;
                   1579:      const char *zrequestor;
                   1580: {
                   1581:   const char **pz;
                   1582:   int cgot;
                   1583:   int i, istdin;
                   1584:   const char *zsubject;
                   1585:   boolean fret;
                   1586: 
                   1587:   pz = (const char **) xmalloc (20 * sizeof (const char *));
                   1588:   cgot = 20;
                   1589: 
                   1590:   i = 0;
                   1591:   if (zid == NULL)
                   1592:     pz[i++] = "A UUCP execution request";
                   1593:   else
                   1594:     {
                   1595:       pz[i++] = "UUCP job\n\t";
                   1596:       pz[i++] = zid;
                   1597:       pz[i++] = "\nfor system\n\t";
                   1598:       pz[i++] = qsys->uuconf_zname;
                   1599:     }
                   1600:   pz[i++] = "\nrequested by\n\t";
                   1601:   pz[i++] = zuser != NULL ? zuser : OWNER;
                   1602:   if (zid == NULL)
                   1603:     {
                   1604:       pz[i++] = "\non system\n\t";
                   1605:       pz[i++] = qsys->uuconf_zname;
                   1606:     }
                   1607:   pz[i++] = "\n";
                   1608: 
                   1609:   if (fkilled)
                   1610:     pz[i++] = "has been killed.\n";
                   1611: 
                   1612:   if (zcomment != NULL)
                   1613:     {
                   1614:       pz[i++] = zcomment;
                   1615:       pz[i++] = "\n";
                   1616:     }
                   1617: 
                   1618:   pz[i++] = "The job ";
                   1619:   if (fkilled)
                   1620:     pz[i++] = "was\n";
                   1621:   else
                   1622:     pz[i++] = "is\n";
                   1623: 
                   1624:   if (zcmd != NULL)
                   1625:     {
                   1626:       pz[i++] = "\t";
                   1627:       pz[i++] = zcmd;
                   1628:     }
                   1629:   else
                   1630:     {
                   1631:       struct scmdlist *qshow;
                   1632: 
                   1633:       for (qshow = qcmd; qshow != NULL; qshow = qshow->qnext)
                   1634:        {
                   1635:          if (i + 10 > cgot)
                   1636:            {
                   1637:              cgot += 20;
                   1638:              pz = (const char **) xrealloc ((pointer) pz,
                   1639:                                             cgot * sizeof (const char *));
                   1640:            }
                   1641: 
                   1642:          switch (qshow->s.bcmd)
                   1643:            {
                   1644:            case 'S':
                   1645:              pz[i++] = "\tsend ";
                   1646:              break;
                   1647:            default:
                   1648:            case 'R':
                   1649:            case 'X':
                   1650:              pz[i++] = "\trequest ";
                   1651:              break;
                   1652:            case 'P':
                   1653:              pz[i++] = "\tpoll ";
                   1654: #if DEBUG > 0
                   1655:            case 'E':
                   1656:              ulog (LOG_FATAL, "fsnotify: Can't happen");
                   1657:              break;
                   1658: #endif
                   1659:            }
                   1660:          if (qshow->s.zfrom != NULL && qshow->s.zto != NULL)
                   1661:            {
                   1662:              pz[i++] = qshow->s.zfrom;
                   1663:              pz[i++] = " to ";
                   1664:              pz[i++] = qshow->s.zto;
                   1665:            }
                   1666:        }
                   1667:     }
                   1668: 
                   1669:   istdin = i;
                   1670:   if (cstdin > 0 && zstdin != NULL)
                   1671:     {
                   1672:       boolean fspool;
                   1673:       char *zfile;
                   1674:       FILE *e;
                   1675: 
                   1676:       fspool = fspool_file (zstdin);
                   1677:       if (fspool)
                   1678:        zfile = zsysdep_spool_file_name (qsys, zstdin, pstdinseq);
                   1679:       else
                   1680:        zfile = zsysdep_local_file (zstdin, qsys->uuconf_zpubdir);
                   1681: 
                   1682:       if (zfile != NULL
                   1683:          && (fspool
                   1684:              || fin_directory_list (zfile, qsys->uuconf_pzremote_send,
                   1685:                                     qsys->uuconf_zpubdir, TRUE, TRUE,
                   1686:                                     (const char *) NULL)))
                   1687:        {
                   1688:          e = fopen (zfile, "r");
                   1689:          if (e != NULL)
                   1690:            {
                   1691:              int clines, clen;
                   1692:              char *zline;
                   1693:              size_t cline;
                   1694: 
                   1695:              pz[i++] = "\n";
                   1696:              istdin = i;
                   1697: 
                   1698:              clines = 0;
                   1699: 
                   1700:              zline = NULL;
                   1701:              cline = 0;
                   1702:              while ((clen = getline (&zline, &cline, e)) > 0)
                   1703:                {
                   1704:                  if (memchr (zline, '\0', (size_t) clen) != NULL)
                   1705:                    {
                   1706:                      int ifree;
                   1707: 
                   1708:                      /* A null character means this is probably a
                   1709:                         binary file.  */
                   1710:                      for (ifree = istdin; ifree < i; ifree++)
                   1711:                        ubuffree ((char *) pz[ifree]);
                   1712:                      i = istdin - 1;
                   1713:                      break;
                   1714:                    }
                   1715:                  ++clines;
                   1716:                  if (clines > cstdin)
                   1717:                    break;
                   1718:                  if (i >= cgot)
                   1719:                    {
                   1720:                      cgot += 20;
                   1721:                      pz = (const char **) xrealloc ((pointer) pz,
                   1722:                                                     (cgot
                   1723:                                                      * sizeof (char *)));
                   1724:                    }
                   1725:                  pz[i++] = zbufcpy (zline);
                   1726:                }
                   1727:              xfree ((pointer) zline);
                   1728:              (void) fclose (e);
                   1729:            }
                   1730:        }
                   1731: 
                   1732:       ubuffree (zfile);
                   1733:     }
                   1734: 
                   1735:   if (fkilled)
                   1736:     zsubject = "UUCP job killed";
                   1737:   else
                   1738:     zsubject = "UUCP notification";
                   1739: 
                   1740:   fret = TRUE;
                   1741: 
                   1742:   if ((icmd & JOB_MAIL) != 0)
                   1743:     {
                   1744:       if (! fsysdep_mail (OWNER, zsubject, i, pz))
                   1745:        fret = FALSE;
                   1746:     }
                   1747: 
                   1748:   if ((icmd & JOB_NOTIFY) != 0
                   1749:       && (zrequestor != NULL || zuser != NULL))
                   1750:     {
                   1751:       const char *zmail;
                   1752:       char *zfree;
                   1753: 
                   1754:       if (zrequestor != NULL)
                   1755:        zmail = zrequestor;
                   1756:       else
                   1757:        zmail = zuser;
                   1758: 
                   1759:       zfree = NULL;
                   1760: 
                   1761:       if (zid == NULL)
                   1762:        {
                   1763:          int iuuconf;
                   1764:          const char *zloc;
                   1765: 
                   1766:          /* This is an execution request, which may be from another
                   1767:             system.  If it is, we must prepend that system name to
                   1768:             the user name extracted from the X. file.  */
                   1769:          iuuconf = uuconf_localname (puuconf, &zloc);
                   1770:          if (iuuconf == UUCONF_NOT_FOUND)
                   1771:            {
                   1772:              zloc = zsysdep_localname ();
                   1773:              if (zloc == NULL)
                   1774:                return FALSE;
                   1775:            }
                   1776:          else if (iuuconf != UUCONF_SUCCESS)
                   1777:            ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                   1778: 
                   1779:          if (strcmp (qsys->uuconf_zname, zloc) != 0
                   1780: #if HAVE_INTERNET_MAIL
                   1781:              && strchr (zmail, '@') == NULL
                   1782: #endif
                   1783:              )
                   1784:            {
                   1785:              zfree = zbufalc (strlen (qsys->uuconf_zname)
                   1786:                               + strlen (zmail)
                   1787:                               + sizeof "!");
                   1788:              sprintf (zfree, "%s!%s", qsys->uuconf_zname, zmail);
                   1789:              zmail = zfree;
                   1790:            }
                   1791:        }
                   1792: 
                   1793:       if (! fsysdep_mail (zmail, zsubject, i, pz))
                   1794:        fret = FALSE;
                   1795: 
                   1796:       ubuffree (zfree);
                   1797:     }
                   1798: 
                   1799:   while (istdin < i)
                   1800:     {
                   1801:       ubuffree ((char *) pz[istdin]);
                   1802:       istdin++;
                   1803:     }
                   1804: 
                   1805:   xfree ((pointer) pz);
                   1806: 
                   1807:   return fret;
                   1808: }
                   1809: 
                   1810: /* Handle the -q option.  For each remote system this lists the number
                   1811:    of jobs queued, the number of executions queued, and the current
                   1812:    call status.  We get the executions all at once, because they are
                   1813:    not accessed by system.  They could be, but it is possible to have
                   1814:    executions pending for an unknown system, so special handling would
                   1815:    still be required.  */
                   1816: 
                   1817: struct sxqtlist
                   1818: {
                   1819:   struct sxqtlist *qnext;
                   1820:   char *zsystem;
                   1821:   int cxqts;
                   1822:   long ifirst;
                   1823: };
                   1824: 
                   1825: /* These local functions need the definition of sxqtlist for the
                   1826:    prototype.  */
                   1827: 
                   1828: static boolean fsquery_system P((const struct uuconf_system *qsys,
                   1829:                                 struct sxqtlist **pq,
                   1830:                                 long inow, const char *zlocalname));
                   1831: static boolean fsquery_show P((const struct uuconf_system *qsys, int cwork,
                   1832:                               long ifirstwork,
                   1833:                               struct sxqtlist *qxqt,
                   1834:                               long inow, const char *zlocalname));
                   1835: 
                   1836: static boolean
                   1837: fsquery (puuconf)
                   1838:      pointer puuconf;
                   1839: {
                   1840:   int iuuconf;
                   1841:   const char *zlocalname;
                   1842:   struct sxqtlist *qlist;
                   1843:   char *zfile, *zsystem;
                   1844:   boolean ferr;
                   1845:   long inow;
                   1846:   char **pznames, **pz;
                   1847:   boolean fret;
                   1848: 
                   1849:   iuuconf = uuconf_localname (puuconf, &zlocalname);
                   1850:   if (iuuconf == UUCONF_NOT_FOUND)
                   1851:     {
                   1852:       zlocalname = zsysdep_localname ();
                   1853:       if (zlocalname == NULL)
                   1854:        return FALSE;
                   1855:     }
                   1856:   else if (iuuconf != UUCONF_SUCCESS)
                   1857:     {
                   1858:       ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1859:       return FALSE;
                   1860:     }
                   1861: 
                   1862:   /* Get a count of all the execution files.  */
                   1863:   if (! fsysdep_get_xqt_init ())
                   1864:     return FALSE;
                   1865: 
                   1866:   qlist = NULL;
                   1867:   while ((zfile = zsysdep_get_xqt (&zsystem, &ferr)) != NULL)
                   1868:     {
                   1869:       struct sxqtlist *qlook;
                   1870: 
                   1871:       for (qlook = qlist; qlook != NULL; qlook = qlook->qnext)
                   1872:        if (strcmp (zsystem, qlook->zsystem) == 0)
                   1873:          break;
                   1874: 
                   1875:       if (qlook != NULL)
                   1876:        {
                   1877:          long itime;
                   1878: 
                   1879:          ubuffree (zsystem);
                   1880:          ++qlook->cxqts;
                   1881:          itime = ixsysdep_file_time (zfile);
                   1882:          if (itime < qlook->ifirst)
                   1883:            qlook->ifirst = itime;
                   1884:        }
                   1885:       else
                   1886:        {
                   1887:          struct sxqtlist *qnew;
                   1888: 
                   1889:          qnew = (struct sxqtlist *) xmalloc (sizeof (struct sxqtlist));
                   1890:          qnew->qnext = qlist;
                   1891:          qnew->zsystem = zsystem;
                   1892:          qnew->cxqts = 1;
                   1893:          qnew->ifirst = ixsysdep_file_time (zfile);
                   1894:          qlist = qnew;
                   1895:        }
                   1896: 
                   1897:       ubuffree (zfile);
                   1898:     }
                   1899: 
                   1900:   usysdep_get_xqt_free ();
                   1901: 
                   1902:   if (ferr)
                   1903:     return FALSE;
                   1904: 
                   1905:   inow = ixsysdep_time ((long *) NULL);
                   1906: 
                   1907:   /* Show the information for each system.  */
                   1908:   iuuconf = uuconf_system_names (puuconf, &pznames, 0);
                   1909:   if (iuuconf != UUCONF_SUCCESS)
                   1910:     {
                   1911:       ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1912:       return FALSE;
                   1913:     }
                   1914: 
                   1915:   fret = TRUE;
                   1916: 
                   1917:   for (pz = pznames; *pz != NULL; pz++)
                   1918:     {
                   1919:       struct uuconf_system ssys;
                   1920: 
                   1921:       iuuconf = uuconf_system_info (puuconf, *pz, &ssys);
                   1922:       if (iuuconf != UUCONF_SUCCESS)
                   1923:        {
                   1924:          ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1925:          fret = FALSE;
                   1926:          continue;
                   1927:        }
                   1928: 
                   1929:       if (! fsquery_system (&ssys, &qlist, inow, zlocalname))
                   1930:        fret = FALSE;
                   1931: 
                   1932:       (void) uuconf_system_free (puuconf, &ssys);
                   1933:       xfree ((pointer) *pz);
                   1934:     }
                   1935: 
                   1936:   /* Check for the local system in the list of execution files.  */
                   1937:   if (qlist != NULL)
                   1938:     {
                   1939:       struct sxqtlist **pq;
                   1940: 
                   1941:       for (pq = &qlist; *pq != NULL; pq = &(*pq)->qnext)
                   1942:        {
                   1943:          if (strcmp ((*pq)->zsystem, zlocalname) == 0)
                   1944:            {
                   1945:              struct uuconf_system ssys;
                   1946:              struct sxqtlist *qfree;
                   1947: 
                   1948:              iuuconf = uuconf_system_info (puuconf, zlocalname, &ssys);
                   1949:              if (iuuconf != UUCONF_SUCCESS)
                   1950:                {
                   1951:                  if (iuuconf != UUCONF_NOT_FOUND)
                   1952:                    {
                   1953:                      ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1954:                      fret = FALSE;
                   1955:                      break;
                   1956:                    }
                   1957: 
                   1958:                  iuuconf = uuconf_system_local (puuconf, &ssys);
                   1959:                  if (iuuconf != UUCONF_SUCCESS)
                   1960:                    {
                   1961:                      ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
                   1962:                      fret = FALSE;
                   1963:                      break;
                   1964:                    }
                   1965:                  ssys.uuconf_zname = (char *) zlocalname;
                   1966:                }
                   1967: 
                   1968:              if (! fsquery_show (&ssys, 0, 0L, *pq, inow, zlocalname))
                   1969:                fret = FALSE;
                   1970:              (void) uuconf_system_free (puuconf, &ssys);
                   1971:              qfree = *pq;
                   1972:              *pq = qfree->qnext;
                   1973:              ubuffree (qfree->zsystem);
                   1974:              xfree ((pointer) qfree);
                   1975:              break;
                   1976:            }
                   1977:        }
                   1978:     }
                   1979: 
                   1980:   /* Print out information for any unknown systems for which we have
                   1981:      execution files.  */
                   1982:   while (qlist != NULL)
                   1983:     {
                   1984:       struct uuconf_system ssys;
                   1985:       struct sxqtlist *qnext;
                   1986: 
                   1987:       if (! funknown_system (puuconf, qlist->zsystem, &ssys))
                   1988:        {
                   1989:          ulog (LOG_ERROR, "Executions queued up for unknown systems");
                   1990:          fret = FALSE;
                   1991:          break;
                   1992:        }
                   1993: 
                   1994:       if (! fsquery_show (&ssys, 0, 0L, qlist, inow, zlocalname))
                   1995:        fret = FALSE;
                   1996:       (void) uuconf_system_free (puuconf, &ssys);
                   1997:       qnext = qlist->qnext;
                   1998:       ubuffree (qlist->zsystem);
                   1999:       xfree ((pointer) qlist);
                   2000:       qlist = qnext;
                   2001:     }
                   2002: 
                   2003:   return fret;
                   2004: }
                   2005: 
                   2006: /* Query a single known system.  */
                   2007: 
                   2008: static boolean
                   2009: fsquery_system (qsys, pq, inow, zlocalname)
                   2010:      const struct uuconf_system *qsys;
                   2011:      struct sxqtlist **pq;
                   2012:      long inow;
                   2013:      const char *zlocalname;
                   2014: {
                   2015:   int cwork;
                   2016:   long ifirstwork;
                   2017:   char *zid;
                   2018:   boolean fret;
                   2019: 
                   2020:   if (! fsysdep_get_work_init (qsys, UUCONF_GRADE_LOW))
                   2021:     return FALSE;
                   2022: 
                   2023:   cwork = 0;
                   2024:   ifirstwork = 0L;
                   2025:   zid = NULL;
                   2026:   while (TRUE)
                   2027:     {
                   2028:       struct scmd s;
                   2029:       long itime;
                   2030:       char *zthisid;
                   2031: 
                   2032:       if (! fsysdep_get_work (qsys, UUCONF_GRADE_LOW, &s))
                   2033:        return FALSE;
                   2034:       if (s.bcmd == 'H')
                   2035:        break;
                   2036: 
                   2037:       zthisid = zsysdep_jobid (qsys, s.pseq);
                   2038:       if (zid != NULL && strcmp (zid, zthisid) == 0)
                   2039:        ubuffree (zthisid);
                   2040:       else
                   2041:        {
                   2042:          ++cwork;
                   2043:          ubuffree (zid);
                   2044:          zid = zthisid;
                   2045:        }
                   2046: 
                   2047:       itime = ixsysdep_work_time (qsys, s.pseq);
                   2048:       if (ifirstwork == 0L || ifirstwork > itime)
                   2049:        ifirstwork = itime;
                   2050:     }
                   2051: 
                   2052:   usysdep_get_work_free (qsys);
                   2053:   ubuffree (zid);
                   2054: 
                   2055:   /* Find the execution information, if any.  */
                   2056:   while (*pq != NULL)
                   2057:     {
                   2058:       if (strcmp ((*pq)->zsystem, qsys->uuconf_zname) == 0)
                   2059:        break;
                   2060:       pq = &(*pq)->qnext;
                   2061:     }
                   2062: 
                   2063:   /* If there are no commands and no executions, don't print any
                   2064:      information for this system.  */
                   2065:   if (cwork == 0 && *pq == NULL)
                   2066:     return TRUE;
                   2067: 
                   2068:   fret = fsquery_show (qsys, cwork, ifirstwork, *pq, inow, zlocalname);
                   2069: 
                   2070:   if (*pq != NULL)
                   2071:     {
                   2072:       struct sxqtlist *qfree;
                   2073: 
                   2074:       qfree = *pq;
                   2075:       *pq = qfree->qnext;
                   2076:       ubuffree (qfree->zsystem);
                   2077:       xfree ((pointer) qfree);
                   2078:     }
                   2079: 
                   2080:   return fret;
                   2081: }
                   2082: 
                   2083: /* Print out the query information for a single system.  We handle the
                   2084:    local system specially.  */
                   2085: 
                   2086: static boolean
                   2087: fsquery_show (qsys, cwork, ifirstwork, qxqt, inow, zlocalname)
                   2088:      const struct uuconf_system *qsys;
                   2089:      int cwork;
                   2090:      long ifirstwork;
                   2091:      struct sxqtlist *qxqt;
                   2092:      long inow;
                   2093:      const char *zlocalname;
                   2094: {
                   2095:   boolean flocal;
                   2096:   struct sstatus sstat;
                   2097:   boolean fnostatus;
                   2098:   struct tm stime;
                   2099:   int cpad;
                   2100: 
                   2101:   flocal = strcmp (qsys->uuconf_zname, zlocalname) == 0;
                   2102: 
                   2103:   if (! flocal)
                   2104:     {
                   2105:       if (! fsysdep_get_status (qsys, &sstat, &fnostatus))
                   2106:        return FALSE;
                   2107:     }
                   2108: 
                   2109:   printf ("%-10s %3dC (", qsys->uuconf_zname, cwork);
                   2110: 
                   2111:   if (cwork == 0)
                   2112:     {
                   2113:       printf ("0 secs");
                   2114:       cpad = 3;
                   2115:     }
                   2116:   else
                   2117:     cpad = csunits_show (inow - ifirstwork);
                   2118: 
                   2119:   printf (") ");
                   2120:   while (cpad-- != 0)
                   2121:     printf (" ");
                   2122: 
                   2123:   if (qxqt == NULL)
                   2124:     printf ("  0X (0 secs)  ");
                   2125:   else
                   2126:     {
                   2127:       printf ("%3dX (", qxqt->cxqts);
                   2128:       cpad = csunits_show (inow - qxqt->ifirst);
                   2129:       printf (")");
                   2130:       while (cpad-- != 0)
                   2131:        printf (" ");
                   2132:     }
                   2133: 
                   2134:   if (flocal || fnostatus)
                   2135:     {
                   2136:       printf ("\n");
                   2137:       return TRUE;
                   2138:     }
                   2139: 
                   2140:   usysdep_localtime (sstat.ilast, &stime);
                   2141: 
                   2142:   printf (" %02d-%02d %02d:%02d ", 
                   2143:          stime.tm_mon + 1,stime.tm_mday, stime.tm_hour, stime.tm_min);
                   2144: 
                   2145:   printf ("%s\n", azStatus[(int) sstat.ttype]);
                   2146: 
                   2147:   return TRUE;
                   2148: }
                   2149: 
                   2150: /* Print a time difference in the largest applicable units.  */
                   2151: 
                   2152: static int
                   2153: csunits_show (idiff)
                   2154:      long idiff;
                   2155: {
                   2156:   const char *zunit;
                   2157:   long iunits;
                   2158:   int cpad;
                   2159: 
                   2160:   if (idiff > (long) 24 * (long) 60 * (long) 60)
                   2161:     {
                   2162:       iunits = idiff / ((long) 24 * (long) 60 * (long) 60);
                   2163:       zunit = "day";
                   2164:       cpad = 4;
                   2165:     }
                   2166:   else if (idiff > (long) 60 * 60)
                   2167:     {
                   2168:       iunits = idiff / (long) (60 * 60);
                   2169:       zunit = "hour";
                   2170:       cpad = 3;
                   2171:     }
                   2172:   else if (idiff > (long) 60)
                   2173:     {
                   2174:       iunits = idiff / (long) 60;
                   2175:       zunit = "min";
                   2176:       cpad = 4;
                   2177:     }
                   2178:   else
                   2179:     {
                   2180:       iunits = idiff;
                   2181:       zunit = "sec";
                   2182:       cpad = 4;
                   2183:     }
                   2184: 
                   2185:   printf ("%ld %s%s", iunits, zunit, iunits == 1 ? "" : "s");
                   2186: 
                   2187:   if (iunits != 1)
                   2188:     --cpad;
                   2189:   if (iunits > 99)
                   2190:     --cpad;
                   2191:   if (iunits > 9)
                   2192:     --cpad;
                   2193:   return cpad;
                   2194: }
                   2195: 
                   2196: /* Give a list of all status entries for all machines that we have
                   2197:    status entries for.  We need to get a list of status entries in a
                   2198:    system dependent fashion, since we may have status for unknown
                   2199:    systems.  */
                   2200: 
                   2201: static boolean
                   2202: fsmachines ()
                   2203: {
                   2204:   pointer phold;
                   2205:   char *zsystem;
                   2206:   boolean ferr;
                   2207:   struct sstatus sstat;
                   2208: 
                   2209:   if (! fsysdep_all_status_init (&phold))
                   2210:     return FALSE;
                   2211: 
                   2212:   while ((zsystem = zsysdep_all_status (phold, &ferr, &sstat)) != NULL)
                   2213:     {
                   2214:       struct tm stime;
                   2215: 
                   2216:       usysdep_localtime (sstat.ilast, &stime);
                   2217:       printf ("%-14s %02d-%02d %02d:%02d %s", zsystem,
                   2218:              stime.tm_mon + 1, stime.tm_mday, stime.tm_hour,
                   2219:              stime.tm_min, azStatus[(int) sstat.ttype]);
                   2220:       ubuffree (zsystem);
                   2221:       if (sstat.ttype != STATUS_TALKING
                   2222:          && sstat.cwait > 0)
                   2223:        {
                   2224:          printf (" (%d %s", sstat.cretries,
                   2225:                  sstat.cretries == 1 ? "try" : "tries");
                   2226:          if (sstat.ilast + sstat.cwait > ixsysdep_time ((long *) NULL))
                   2227:            {
                   2228:              usysdep_localtime (sstat.ilast + sstat.cwait, &stime);
                   2229:              printf (", next after %02d-%02d %02d:%02d",
                   2230:                      stime.tm_mon + 1, stime.tm_mday, stime.tm_hour,
                   2231:                      stime.tm_min);
                   2232:            }
                   2233:          printf (")");
                   2234:        }
                   2235:       printf ("\n");
                   2236:     }
                   2237: 
                   2238:   usysdep_all_status_free (phold);
                   2239: 
                   2240:   return ! ferr;
                   2241: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.