|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.