|
|
1.1 ! root 1: /* uuxqt.c ! 2: Run uux commands. ! 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 uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.1 93/07/30 08:00:15 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <errno.h> ! 33: #include <ctype.h> ! 34: ! 35: #include "getopt.h" ! 36: ! 37: #include "uudefs.h" ! 38: #include "uuconf.h" ! 39: #include "system.h" ! 40: ! 41: /* The program name. */ ! 42: char abProgram[] = "uuxqt"; ! 43: ! 44: /* Static variables used to unlock things if we get a fatal error. */ ! 45: static int iQlock_seq = -1; ! 46: static const char *zQunlock_cmd; ! 47: static const char *zQunlock_file; ! 48: static boolean fQunlock_directory; ! 49: int cQmaxuuxqts; ! 50: ! 51: /* Static variables to free in uqcleanup. */ ! 52: static char *zQoutput; ! 53: static char *zQmail; ! 54: ! 55: /* Local functions. */ ! 56: static void uqusage P((void)); ! 57: static void uqabort P((void)); ! 58: static void uqdo_xqt_file P((pointer puuconf, const char *zfile, ! 59: const char *zbase, ! 60: const struct uuconf_system *qsys, ! 61: const char *zlocalname, ! 62: const char *zcmd, boolean *pfprocessed)); ! 63: static void uqcleanup P((const char *zfile, int iflags)); ! 64: static boolean fqforward P((const char *zfile, char **pzallowed, ! 65: const char *zlog, const char *zmail)); ! 66: ! 67: /* Long getopt options. */ ! 68: static const struct option asQlongopts[] = { { NULL, 0, NULL, 0 } }; ! 69: ! 70: int ! 71: main (argc, argv) ! 72: int argc; ! 73: char **argv; ! 74: { ! 75: /* The type of command to execute (NULL for any type). */ ! 76: const char *zcmd = NULL; ! 77: /* The configuration file name. */ ! 78: const char *zconfig = NULL; ! 79: /* The system to execute commands for. */ ! 80: const char *zdosys = NULL; ! 81: int iopt; ! 82: pointer puuconf; ! 83: int iuuconf; ! 84: const char *zlocalname; ! 85: boolean fany; ! 86: char *z, *zgetsys; ! 87: boolean ferr; ! 88: boolean fsys; ! 89: struct uuconf_system ssys; ! 90: ! 91: while ((iopt = getopt_long (argc, argv, "c:I:s:x:", asQlongopts, ! 92: (int *) NULL)) != EOF) ! 93: { ! 94: switch (iopt) ! 95: { ! 96: case 'c': ! 97: /* Set the type of command to execute. */ ! 98: zcmd = optarg; ! 99: break; ! 100: ! 101: case 'I': ! 102: /* Set the configuration file name. */ ! 103: if (fsysdep_other_config (optarg)) ! 104: zconfig = optarg; ! 105: break; ! 106: ! 107: case 's': ! 108: zdosys = optarg; ! 109: break; ! 110: ! 111: case 'x': ! 112: #if DEBUG > 1 ! 113: /* Set the debugging level. */ ! 114: iDebug |= idebug_parse (optarg); ! 115: #endif ! 116: break; ! 117: ! 118: case 0: ! 119: /* Long option found and flag set. */ ! 120: break; ! 121: ! 122: default: ! 123: uqusage (); ! 124: break; ! 125: } ! 126: } ! 127: ! 128: if (optind != argc) ! 129: uqusage (); ! 130: ! 131: iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig); ! 132: if (iuuconf != UUCONF_SUCCESS) ! 133: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 134: ! 135: #if DEBUG > 1 ! 136: { ! 137: const char *zdebug; ! 138: ! 139: iuuconf = uuconf_debuglevel (puuconf, &zdebug); ! 140: if (iuuconf != UUCONF_SUCCESS) ! 141: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 142: if (zdebug != NULL) ! 143: iDebug |= idebug_parse (zdebug); ! 144: } ! 145: #endif ! 146: ! 147: iuuconf = uuconf_maxuuxqts (puuconf, &cQmaxuuxqts); ! 148: if (iuuconf != UUCONF_SUCCESS) ! 149: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 150: ! 151: #ifdef SIGINT ! 152: usysdep_signal (SIGINT); ! 153: #endif ! 154: #ifdef SIGHUP ! 155: usysdep_signal (SIGHUP); ! 156: #endif ! 157: #ifdef SIGQUIT ! 158: usysdep_signal (SIGQUIT); ! 159: #endif ! 160: #ifdef SIGTERM ! 161: usysdep_signal (SIGTERM); ! 162: #endif ! 163: #ifdef SIGPIPE ! 164: usysdep_signal (SIGPIPE); ! 165: #endif ! 166: ! 167: usysdep_initialize (puuconf, INIT_SUID); ! 168: ! 169: ulog_to_file (puuconf, TRUE); ! 170: ulog_fatal_fn (uqabort); ! 171: ! 172: iuuconf = uuconf_localname (puuconf, &zlocalname); ! 173: if (iuuconf == UUCONF_NOT_FOUND) ! 174: { ! 175: zlocalname = zsysdep_localname (); ! 176: if (zlocalname == NULL) ! 177: exit (EXIT_FAILURE); ! 178: } ! 179: else if (iuuconf != UUCONF_SUCCESS) ! 180: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 181: ! 182: fsys = FALSE; ! 183: ! 184: /* If we were given a system name, canonicalize it, since the system ! 185: dependent layer will not be returning aliases. */ ! 186: if (zdosys != NULL) ! 187: { ! 188: iuuconf = uuconf_system_info (puuconf, zdosys, &ssys); ! 189: if (iuuconf == UUCONF_NOT_FOUND) ! 190: ulog (LOG_FATAL, "%s: System not found", zdosys); ! 191: else if (iuuconf != UUCONF_SUCCESS) ! 192: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 193: ! 194: zdosys = zbufcpy (ssys.uuconf_zname); ! 195: fsys = TRUE; ! 196: } ! 197: ! 198: /* Limit the number of uuxqt processes, and make sure we're the only ! 199: uuxqt daemon running for this command. */ ! 200: iQlock_seq = ixsysdep_lock_uuxqt (zcmd, cQmaxuuxqts); ! 201: if (iQlock_seq < 0) ! 202: { ! 203: ulog_close (); ! 204: usysdep_exit (TRUE); ! 205: } ! 206: zQunlock_cmd = zcmd; ! 207: ! 208: /* Keep scanning the execute files until we don't process any of ! 209: them. */ ! 210: do ! 211: { ! 212: fany = FALSE; ! 213: ! 214: /* Look for each execute file, and run it. */ ! 215: ! 216: if (! fsysdep_get_xqt_init ()) ! 217: { ! 218: ulog_close (); ! 219: usysdep_exit (FALSE); ! 220: } ! 221: ! 222: while ((z = zsysdep_get_xqt (&zgetsys, &ferr)) != NULL) ! 223: { ! 224: const char *zloc; ! 225: boolean fprocessed; ! 226: char *zbase; ! 227: ! 228: /* It would be more efficient to pass zdosys down to the ! 229: routines which retrieve execute files. */ ! 230: if (zdosys != NULL && strcmp (zdosys, zgetsys) != 0) ! 231: { ! 232: ubuffree (z); ! 233: ubuffree (zgetsys); ! 234: continue; ! 235: } ! 236: ! 237: if (! fsys || strcmp (ssys.uuconf_zname, zgetsys) != 0) ! 238: { ! 239: if (fsys) ! 240: (void) uuconf_system_free (puuconf, &ssys); ! 241: ! 242: iuuconf = uuconf_system_info (puuconf, zgetsys, ! 243: &ssys); ! 244: if (iuuconf != UUCONF_SUCCESS) ! 245: { ! 246: if (iuuconf != UUCONF_NOT_FOUND) ! 247: { ! 248: ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ! 249: ubuffree (z); ! 250: ubuffree (zgetsys); ! 251: continue; ! 252: } ! 253: else if (strcmp (zgetsys, zlocalname) == 0) ! 254: { ! 255: iuuconf = uuconf_system_local (puuconf, &ssys); ! 256: if (iuuconf != UUCONF_SUCCESS) ! 257: { ! 258: ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ! 259: ubuffree (z); ! 260: ubuffree (zgetsys); ! 261: continue; ! 262: } ! 263: } ! 264: else ! 265: { ! 266: if (! funknown_system (puuconf, zgetsys, &ssys)) ! 267: { ! 268: ulog (LOG_ERROR, ! 269: "%s: Execute file for unknown system %s", ! 270: z, zgetsys); ! 271: (void) remove (z); ! 272: ubuffree (z); ! 273: ubuffree (zgetsys); ! 274: continue; ! 275: } ! 276: } ! 277: } ! 278: ! 279: fsys = TRUE; ! 280: } ! 281: ! 282: /* If we've received a signal, get out of the loop. */ ! 283: if (FGOT_SIGNAL ()) ! 284: { ! 285: ubuffree (z); ! 286: ubuffree (zgetsys); ! 287: break; ! 288: } ! 289: ! 290: zloc = ssys.uuconf_zlocalname; ! 291: if (zloc == NULL) ! 292: zloc = zlocalname; ! 293: ! 294: ulog_system (ssys.uuconf_zname); ! 295: zbase = zsysdep_base_name (z); ! 296: uqdo_xqt_file (puuconf, z, zbase, &ssys, zloc, zcmd, &fprocessed); ! 297: ubuffree (zbase); ! 298: ulog_system ((const char *) NULL); ! 299: ulog_user ((const char *) NULL); ! 300: ! 301: if (fprocessed) ! 302: fany = TRUE; ! 303: ubuffree (z); ! 304: ubuffree (zgetsys); ! 305: } ! 306: ! 307: usysdep_get_xqt_free (); ! 308: } ! 309: while (fany && ! FGOT_SIGNAL ()); ! 310: ! 311: (void) fsysdep_unlock_uuxqt (iQlock_seq, zcmd, cQmaxuuxqts); ! 312: iQlock_seq = -1; ! 313: ! 314: ulog_close (); ! 315: ! 316: if (FGOT_SIGNAL ()) ! 317: ferr = TRUE; ! 318: ! 319: usysdep_exit (! ferr); ! 320: ! 321: /* Avoid errors about not returning a value. */ ! 322: return 0; ! 323: } ! 324: ! 325: static void ! 326: uqusage () ! 327: { ! 328: fprintf (stderr, ! 329: "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", ! 330: VERSION); ! 331: fprintf (stderr, ! 332: "Usage: uuxqt [-c cmd] [-I file] [-s system] [-x debug]\n"); ! 333: fprintf (stderr, ! 334: " -c cmd: Set type of command to execute\n"); ! 335: fprintf (stderr, ! 336: " -s system: Execute commands only for named system\n"); ! 337: fprintf (stderr, ! 338: " -x debug: Set debugging level (0 for none, 9 is max)\n"); ! 339: #if HAVE_TAYLOR_CONFIG ! 340: fprintf (stderr, ! 341: " -I file: Set configuration file to use\n"); ! 342: #endif /* HAVE_TAYLOR_CONFIG */ ! 343: exit (EXIT_FAILURE); ! 344: } ! 345: ! 346: /* This is the abort function called when we get a fatal error. */ ! 347: ! 348: static void ! 349: uqabort () ! 350: { ! 351: #if ! HAVE_HDB_LOGGING ! 352: /* When using HDB logging, it's a pain to have no system name. */ ! 353: ulog_system ((const char *) NULL); ! 354: #endif ! 355: ! 356: ulog_user ((const char *) NULL); ! 357: ! 358: if (fQunlock_directory) ! 359: (void) fsysdep_unlock_uuxqt_dir (iQlock_seq); ! 360: ! 361: if (zQunlock_file != NULL) ! 362: (void) fsysdep_unlock_uuxqt_file (zQunlock_file); ! 363: ! 364: if (iQlock_seq >= 0) ! 365: (void) fsysdep_unlock_uuxqt (iQlock_seq, zQunlock_cmd, cQmaxuuxqts); ! 366: ! 367: ulog_close (); ! 368: ! 369: usysdep_exit (FALSE); ! 370: } ! 371: ! 372: /* An execute file is a series of lines. The first character of each ! 373: line is a command. The following commands are defined: ! 374: ! 375: C command-line ! 376: I standard-input ! 377: O standard-output [ system ] ! 378: F required-file filename-to-use ! 379: R requestor-address ! 380: U user system ! 381: Z (acknowledge if command failed; default) ! 382: N (no acknowledgement on failure) ! 383: n (acknowledge if command succeeded) ! 384: B (return command input on error) ! 385: e (process with sh) ! 386: E (process with exec) ! 387: M status-file ! 388: # comment ! 389: ! 390: Unrecognized commands are ignored. We actually do not recognize ! 391: the Z command, since it requests default behaviour. We always send ! 392: mail on failure, unless the N command appears. We never send mail ! 393: on success, unless the n command appears. ! 394: ! 395: This code does not currently support the B or M commands. */ ! 396: ! 397: /* Command arguments. */ ! 398: static char **azQargs; ! 399: /* Command as a complete string. */ ! 400: static char *zQcmd; ! 401: /* Standard input file name. */ ! 402: static char *zQinput; ! 403: /* Standard output file name. */ ! 404: static char *zQoutfile; ! 405: /* Standard output system. */ ! 406: static char *zQoutsys; ! 407: /* Number of required files. */ ! 408: static int cQfiles; ! 409: /* Names of required files. */ ! 410: static char **azQfiles; ! 411: /* Names required files should be renamed to (NULL if original is OK). */ ! 412: static char **azQfiles_to; ! 413: /* Requestor address (this is where mail should be sent). */ ! 414: static char *zQrequestor; ! 415: /* User name. */ ! 416: static const char *zQuser; ! 417: /* System name. */ ! 418: static const char *zQsystem; ! 419: /* This is set by the N flag, meaning that no acknowledgement should ! 420: be mailed on failure. */ ! 421: static boolean fQno_ack; ! 422: /* This is set by the n flag, meaning that acknowledgement should be ! 423: mailed if the command succeeded. */ ! 424: static boolean fQsuccess_ack; ! 425: /* This is set by the B flag, meaning that command input should be ! 426: mailed to the requestor if an error occurred. */ ! 427: static boolean fQsend_input; ! 428: /* This is set by the E flag, meaning that exec should be used to ! 429: execute the command. */ ! 430: static boolean fQuse_exec; ! 431: /* The status should be copied to this file on the requesting host. */ ! 432: static const char *zQstatus_file; ! 433: #if ALLOW_SH_EXECUTION ! 434: /* This is set by the e flag, meaning that sh should be used to ! 435: execute the command. */ ! 436: static boolean fQuse_sh; ! 437: #endif /* ALLOW_SH_EXECUTION */ ! 438: ! 439: static int iqcmd P((pointer puuconf, int argc, char **argv, pointer pvar, ! 440: pointer pinfo)); ! 441: static int iqout P((pointer puuconf, int argc, char **argv, pointer pvar, ! 442: pointer pinfo)); ! 443: static int iqfile P((pointer puuconf, int argc, char **argv, pointer pvar, ! 444: pointer pinfo)); ! 445: static int iqrequestor P((pointer puuconf, int argc, char **argv, ! 446: pointer pvar, pointer pinfo)); ! 447: static int iquser P((pointer puuconf, int argc, char **argv, pointer pvar, ! 448: pointer pinfo)); ! 449: static int iqset P((pointer puuconf, int argc, char **argv, pointer pvar, ! 450: pointer pinfo)); ! 451: ! 452: static const struct uuconf_cmdtab asQcmds[] = ! 453: { ! 454: { "C", UUCONF_CMDTABTYPE_FN | 0, NULL, iqcmd }, ! 455: { "I", UUCONF_CMDTABTYPE_STRING, (pointer) &zQinput, NULL }, ! 456: { "O", UUCONF_CMDTABTYPE_FN | 0, NULL, iqout }, ! 457: { "F", UUCONF_CMDTABTYPE_FN | 0, NULL, iqfile }, ! 458: { "R", UUCONF_CMDTABTYPE_FN, NULL, iqrequestor }, ! 459: { "U", UUCONF_CMDTABTYPE_FN | 3, NULL, iquser }, ! 460: { "N", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQno_ack, iqset }, ! 461: { "n", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQsuccess_ack, iqset }, ! 462: /* Some systems create execution files in which B takes an argument; ! 463: I don't know what it means, so I just ignore it. */ ! 464: { "B", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQsend_input, iqset }, ! 465: #if ALLOW_SH_EXECUTION ! 466: { "e", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQuse_sh, iqset }, ! 467: #endif ! 468: { "E", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQuse_exec, iqset }, ! 469: { "M", UUCONF_CMDTABTYPE_STRING, (pointer) &zQstatus_file, NULL }, ! 470: { NULL, 0, NULL, NULL } ! 471: }; ! 472: ! 473: /* Handle the C command: store off the arguments. */ ! 474: ! 475: /*ARGSUSED*/ ! 476: static int ! 477: iqcmd (puuconf, argc, argv, pvar, pinfo) ! 478: pointer puuconf; ! 479: int argc; ! 480: char **argv; ! 481: pointer pvar; ! 482: pointer pinfo; ! 483: { ! 484: int i; ! 485: size_t clen; ! 486: ! 487: if (argc <= 1) ! 488: return UUCONF_CMDTABRET_CONTINUE; ! 489: ! 490: azQargs = (char **) xmalloc (argc * sizeof (char *)); ! 491: clen = 0; ! 492: for (i = 1; i < argc; i++) ! 493: { ! 494: azQargs[i - 1] = zbufcpy (argv[i]); ! 495: clen += strlen (argv[i]) + 1; ! 496: } ! 497: azQargs[i - 1] = NULL; ! 498: ! 499: zQcmd = (char *) xmalloc (clen); ! 500: zQcmd[0] = '\0'; ! 501: for (i = 1; i < argc - 1; i++) ! 502: { ! 503: strcat (zQcmd, argv[i]); ! 504: strcat (zQcmd, " "); ! 505: } ! 506: strcat (zQcmd, argv[i]); ! 507: ! 508: return UUCONF_CMDTABRET_CONTINUE; ! 509: } ! 510: ! 511: /* Handle the O command, which may have one or two arguments. */ ! 512: ! 513: /*ARGSUSED*/ ! 514: static int ! 515: iqout (puuconf, argc, argv, pvar, pinfo) ! 516: pointer puuconf; ! 517: int argc; ! 518: char **argv; ! 519: pointer pvar; ! 520: pointer pinfo; ! 521: { ! 522: const char *zbase = (const char *) pinfo; ! 523: ! 524: if (argc != 2 && argc != 3) ! 525: { ! 526: ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", ! 527: zbase, argv[0]); ! 528: return UUCONF_CMDTABRET_CONTINUE; ! 529: } ! 530: ! 531: zQoutfile = zbufcpy (argv[1]); ! 532: if (argc == 3) ! 533: zQoutsys = zbufcpy (argv[2]); ! 534: ! 535: return UUCONF_CMDTABRET_CONTINUE; ! 536: } ! 537: ! 538: /* Handle the F command, which may have one or two arguments. */ ! 539: ! 540: /*ARGSUSED*/ ! 541: static int ! 542: iqfile (puuconf, argc, argv, pvar, pinfo) ! 543: pointer puuconf; ! 544: int argc; ! 545: char **argv; ! 546: pointer pvar; ! 547: pointer pinfo; ! 548: { ! 549: const char *zbase = (const char *) pinfo; ! 550: ! 551: if (argc != 2 && argc != 3) ! 552: { ! 553: ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", ! 554: zbase, argv[0]); ! 555: return UUCONF_CMDTABRET_CONTINUE; ! 556: } ! 557: ! 558: /* If this file is not in the spool directory, just ignore it. */ ! 559: if (! fspool_file (argv[1])) ! 560: return UUCONF_CMDTABRET_CONTINUE; ! 561: ! 562: ++cQfiles; ! 563: azQfiles = (char **) xrealloc ((pointer) azQfiles, ! 564: cQfiles * sizeof (char *)); ! 565: azQfiles_to = (char **) xrealloc ((pointer) azQfiles_to, ! 566: cQfiles * sizeof (char *)); ! 567: ! 568: azQfiles[cQfiles - 1] = zbufcpy (argv[1]); ! 569: if (argc == 3) ! 570: azQfiles_to[cQfiles - 1] = zbufcpy (argv[2]); ! 571: else ! 572: azQfiles_to[cQfiles - 1] = NULL; ! 573: ! 574: return UUCONF_CMDTABRET_CONTINUE; ! 575: } ! 576: ! 577: /* Handle the R command, which may have one or two arguments. */ ! 578: ! 579: /*ARGSUSED*/ ! 580: static int ! 581: iqrequestor (puuconf, argc, argv, pvar, pinfo) ! 582: pointer puuconf; ! 583: int argc; ! 584: char **argv; ! 585: pointer pvar; ! 586: pointer pinfo; ! 587: { ! 588: const char *zbase = (const char *) pinfo; ! 589: ! 590: if (argc != 2 && argc != 3) ! 591: { ! 592: ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", ! 593: zbase, argv[0]); ! 594: return UUCONF_CMDTABRET_CONTINUE; ! 595: } ! 596: ! 597: /* We normally have a single argument, which is the ``requestor'' ! 598: address, to which we should send any success or error messages. ! 599: Apparently the DOS program UUPC sends two arguments, which are ! 600: the username and the host. */ ! 601: if (argc == 2) ! 602: zQrequestor = zbufcpy (argv[1]); ! 603: else ! 604: { ! 605: zQrequestor = zbufalc (strlen (argv[1]) + strlen (argv[2]) ! 606: + sizeof "!"); ! 607: sprintf (zQrequestor, "%s!%s", argv[2], argv[1]); ! 608: } ! 609: ! 610: return UUCONF_CMDTABRET_CONTINUE; ! 611: } ! 612: ! 613: /* Handle the U command, which takes two arguments. */ ! 614: ! 615: /*ARGSUSED*/ ! 616: static int ! 617: iquser (puuconf, argc, argv, pvar, pinfo) ! 618: pointer puuconf; ! 619: int argc; ! 620: char **argv; ! 621: pointer pvar; ! 622: pointer pinfo; ! 623: { ! 624: zQuser = argv[1]; ! 625: zQsystem = argv[2]; ! 626: return UUCONF_CMDTABRET_KEEP; ! 627: } ! 628: ! 629: /* Handle various commands which just set boolean variables. */ ! 630: ! 631: /*ARGSUSED*/ ! 632: static int ! 633: iqset (puuconf, argc, argv, pvar, pinfo) ! 634: pointer puuconf; ! 635: int argc; ! 636: char **argv; ! 637: pointer pvar; ! 638: pointer pinfo; ! 639: { ! 640: boolean *pf = (boolean *) pvar; ! 641: ! 642: *pf = TRUE; ! 643: return UUCONF_CMDTABRET_CONTINUE; ! 644: } ! 645: ! 646: /* The execution processing does a lot of things that have to be ! 647: cleaned up. Rather than try to add the appropriate statements ! 648: to each return point, we keep a set of flags indicating what ! 649: has to be cleaned up. The actual clean up is done by the ! 650: function uqcleanup. */ ! 651: #define REMOVE_FILE (01) ! 652: #define REMOVE_NEEDED (02) ! 653: #define FREE_QINPUT (04) ! 654: #define FREE_OUTPUT (010) ! 655: #define FREE_MAIL (020) ! 656: ! 657: /* Process an execute file. The zfile argument is the name of the ! 658: execute file. The zbase argument is the base name of zfile. The ! 659: qsys argument describes the system it came from. The zcmd argument ! 660: is the name of the command we are executing (from the -c option) or ! 661: NULL if any command is OK. This sets *pfprocessed to TRUE if the ! 662: file is ready to be executed. */ ! 663: ! 664: static void ! 665: uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) ! 666: pointer puuconf; ! 667: const char *zfile; ! 668: const char *zbase; ! 669: const struct uuconf_system *qsys; ! 670: const char *zlocalname; ! 671: const char *zcmd; ! 672: boolean *pfprocessed; ! 673: { ! 674: char *zabsolute; ! 675: boolean ferr; ! 676: FILE *e; ! 677: int iuuconf; ! 678: int i; ! 679: int iclean; ! 680: const char *zmail; ! 681: char *zoutput; ! 682: char *zinput; ! 683: char abtemp[CFILE_NAME_LEN]; ! 684: char abdata[CFILE_NAME_LEN]; ! 685: char *zerror; ! 686: struct uuconf_system soutsys; ! 687: const struct uuconf_system *qoutsys; ! 688: boolean fshell; ! 689: size_t clen; ! 690: char *zfullcmd; ! 691: boolean ftemp; ! 692: ! 693: *pfprocessed = FALSE; ! 694: ! 695: e = fopen (zfile, "r"); ! 696: if (e == NULL) ! 697: return; ! 698: ! 699: azQargs = NULL; ! 700: zQcmd = NULL; ! 701: zQinput = NULL; ! 702: zQoutfile = NULL; ! 703: zQoutsys = NULL; ! 704: cQfiles = 0; ! 705: azQfiles = NULL; ! 706: azQfiles_to = NULL; ! 707: zQrequestor = NULL; ! 708: zQuser = NULL; ! 709: zQsystem = NULL; ! 710: fQno_ack = FALSE; ! 711: fQsuccess_ack = FALSE; ! 712: fQsend_input = FALSE; ! 713: fQuse_exec = FALSE; ! 714: zQstatus_file = NULL; ! 715: #if ALLOW_SH_EXECUTION ! 716: fQuse_sh = FALSE; ! 717: #endif ! 718: ! 719: iuuconf = uuconf_cmd_file (puuconf, e, asQcmds, (pointer) zbase, ! 720: (uuconf_cmdtabfn) NULL, ! 721: UUCONF_CMDTABFLAG_CASE, (pointer) NULL); ! 722: (void) fclose (e); ! 723: ! 724: if (iuuconf != UUCONF_SUCCESS) ! 725: { ! 726: ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ! 727: return; ! 728: } ! 729: ! 730: iclean = 0; ! 731: ! 732: if (azQargs == NULL) ! 733: { ! 734: ulog (LOG_ERROR, "%s: No command given", zbase); ! 735: uqcleanup (zfile, iclean | REMOVE_FILE); ! 736: return; ! 737: } ! 738: ! 739: if (zcmd != NULL) ! 740: { ! 741: if (strcmp (zcmd, azQargs[0]) != 0) ! 742: { ! 743: uqcleanup (zfile, iclean); ! 744: return; ! 745: } ! 746: } ! 747: else ! 748: { ! 749: /* If there is a lock file for this particular command already, ! 750: it means that some other uuxqt is supposed to handle it. */ ! 751: if (fsysdep_uuxqt_locked (azQargs[0])) ! 752: { ! 753: uqcleanup (zfile, iclean); ! 754: return; ! 755: } ! 756: } ! 757: ! 758: /* Lock this particular file. */ ! 759: if (! fsysdep_lock_uuxqt_file (zfile)) ! 760: { ! 761: uqcleanup (zfile, iclean); ! 762: return; ! 763: } ! 764: ! 765: zQunlock_file = zfile; ! 766: ! 767: /* Now that we have the file locked, make sure it still exists. ! 768: Otherwise another uuxqt could have just finished processing it ! 769: and removed the lock file. */ ! 770: if (! fsysdep_file_exists (zfile)) ! 771: { ! 772: uqcleanup (zfile, iclean); ! 773: return; ! 774: } ! 775: ! 776: if (zQuser != NULL) ! 777: ulog_user (zQuser); ! 778: else if (zQrequestor != NULL) ! 779: ulog_user (zQrequestor); ! 780: else ! 781: ulog_user ("unknown"); ! 782: ! 783: /* Make sure that all the required files exist, and get their ! 784: full names in the spool directory. */ ! 785: for (i = 0; i < cQfiles; i++) ! 786: { ! 787: char *zreal; ! 788: ! 789: zreal = zsysdep_spool_file_name (qsys, azQfiles[i], (pointer) NULL); ! 790: if (zreal == NULL) ! 791: { ! 792: uqcleanup (zfile, iclean); ! 793: return; ! 794: } ! 795: if (! fsysdep_file_exists (zreal)) ! 796: { ! 797: uqcleanup (zfile, iclean); ! 798: return; ! 799: } ! 800: ubuffree (azQfiles[i]); ! 801: azQfiles[i] = zbufcpy (zreal); ! 802: ubuffree (zreal); ! 803: } ! 804: ! 805: /* Lock the execution directory. */ ! 806: if (! fsysdep_lock_uuxqt_dir (iQlock_seq)) ! 807: { ! 808: ulog (LOG_ERROR, "Could not lock execute directory"); ! 809: uqcleanup (zfile, iclean); ! 810: return; ! 811: } ! 812: fQunlock_directory = TRUE; ! 813: ! 814: iclean |= REMOVE_FILE | REMOVE_NEEDED; ! 815: *pfprocessed = TRUE; ! 816: ! 817: /* Get the address to mail results to. Prepend the system from ! 818: which the execute file originated, since mail addresses are ! 819: relative to it. */ ! 820: zmail = NULL; ! 821: if (zQrequestor != NULL) ! 822: zmail = zQrequestor; ! 823: else if (zQuser != NULL) ! 824: zmail = zQuser; ! 825: if (zmail != NULL ! 826: && zQsystem != NULL ! 827: #if HAVE_INTERNET_MAIL ! 828: && strchr (zmail, '@') == NULL ! 829: #endif ! 830: && strcmp (zQsystem, zlocalname) != 0) ! 831: { ! 832: char *zset; ! 833: ! 834: zset = zbufalc (strlen (zQsystem) + strlen (zmail) + 2); ! 835: sprintf (zset, "%s!%s", zQsystem, zmail); ! 836: zmail = zset; ! 837: zQmail = zset; ! 838: iclean |= FREE_MAIL; ! 839: } ! 840: ! 841: /* The command "uucp" is handled specially. We make sure that the ! 842: appropriate forwarding is permitted, and we add a -u argument to ! 843: specify the user. */ ! 844: if (strcmp (azQargs[0], "uucp") == 0) ! 845: { ! 846: char *zfrom, *zto; ! 847: boolean fmany; ! 848: char **azargs; ! 849: const char *zuser, *zsystem; ! 850: ! 851: zfrom = NULL; ! 852: zto = NULL; ! 853: fmany = FALSE; ! 854: ! 855: /* Skip all the options, and get the from and to specs. We ! 856: don't permit multiple arguments. */ ! 857: for (i = 1; azQargs[i] != NULL; i++) ! 858: { ! 859: if (azQargs[i][0] == '-') ! 860: { ! 861: char *zopts; ! 862: ! 863: for (zopts = azQargs[i] + 1; *zopts != '\0'; zopts++) ! 864: { ! 865: /* The -g, -n, and -s options take an argument. */ ! 866: if (*zopts == 'g' || *zopts == 'n' || *zopts == 's') ! 867: { ! 868: if (zopts[1] == '\0') ! 869: ++i; ! 870: break; ! 871: } ! 872: /* The -I, -u and -x options are not permitted. */ ! 873: if (*zopts == 'I' || *zopts == 'u' || *zopts == 'x') ! 874: { ! 875: *zopts = 'r'; ! 876: if (zopts[1] != '\0') ! 877: zopts[1] = '\0'; ! 878: else ! 879: { ! 880: ++i; ! 881: azQargs[i] = zbufcpy ("-r"); ! 882: } ! 883: break; ! 884: } ! 885: } ! 886: } ! 887: else if (zfrom == NULL) ! 888: zfrom = azQargs[i]; ! 889: else if (zto == NULL) ! 890: zto = azQargs[i]; ! 891: else ! 892: { ! 893: fmany = TRUE; ! 894: break; ! 895: } ! 896: } ! 897: ! 898: /* Add the -u argument. This is required to let uucp do the ! 899: correct permissions checking on the file transfer. */ ! 900: for (i = 0; azQargs[i] != NULL; i++) ! 901: ; ! 902: azargs = (char **) xmalloc ((i + 2) * sizeof (char *)); ! 903: azargs[0] = azQargs[0]; ! 904: zuser = zQuser; ! 905: if (zuser == NULL) ! 906: zuser = "uucp"; ! 907: zsystem = zQsystem; ! 908: if (zsystem == NULL) ! 909: zsystem = qsys->uuconf_zname; ! 910: azargs[1] = zbufalc (strlen (zsystem) + strlen (zuser) ! 911: + sizeof "-u!"); ! 912: sprintf (azargs[1], "-u%s!%s", zsystem, zuser); ! 913: memcpy (azargs + 2, azQargs + 1, i * sizeof (char *)); ! 914: xfree ((pointer) azQargs); ! 915: azQargs = azargs; ! 916: ! 917: /* Find the uucp binary. */ ! 918: zabsolute = zsysdep_find_command ("uucp", qsys->uuconf_pzcmds, ! 919: qsys->uuconf_pzpath, &ferr); ! 920: if (zabsolute == NULL && ! ferr) ! 921: { ! 922: const char *azcmds[2]; ! 923: ! 924: /* If "uucp" is not a permitted command, then the forwarding ! 925: entries must be set. */ ! 926: if (! fqforward (zfrom, qsys->uuconf_pzforward_from, "from", zmail) ! 927: || ! fqforward (zto, qsys->uuconf_pzforward_to, "to", zmail)) ! 928: { ! 929: uqcleanup (zfile, iclean); ! 930: return; ! 931: } ! 932: ! 933: /* If "uucp" is not a permitted command, then only uucp ! 934: requests with a single source are permitted, since that ! 935: is all that will be generated by uucp or uux. */ ! 936: if (fmany) ! 937: { ! 938: ulog (LOG_ERROR, "Bad uucp request %s", zQcmd); ! 939: ! 940: if (zmail != NULL && ! fQno_ack) ! 941: { ! 942: const char *az[20]; ! 943: ! 944: i = 0; ! 945: az[i++] = "Your execution request failed because it was an"; ! 946: az[i++] = " unsupported uucp request.\n"; ! 947: az[i++] = "Execution requested was:\n\t"; ! 948: az[i++] = zQcmd; ! 949: az[i++] = "\n"; ! 950: ! 951: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 952: } ! 953: ! 954: uqcleanup (zfile, iclean); ! 955: return; ! 956: } ! 957: ! 958: azcmds[0] = "uucp"; ! 959: azcmds[1] = NULL; ! 960: zabsolute = zsysdep_find_command ("uucp", (char **) azcmds, ! 961: qsys->uuconf_pzpath, &ferr); ! 962: } ! 963: if (zabsolute == NULL) ! 964: { ! 965: if (! ferr) ! 966: ulog (LOG_ERROR, "Can't find uucp executable"); ! 967: ! 968: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 969: *pfprocessed = FALSE; ! 970: return; ! 971: } ! 972: } ! 973: else ! 974: { ! 975: /* Get the pathname to execute. */ ! 976: zabsolute = zsysdep_find_command (azQargs[0], qsys->uuconf_pzcmds, ! 977: qsys->uuconf_pzpath, ! 978: &ferr); ! 979: if (zabsolute == NULL) ! 980: { ! 981: if (ferr) ! 982: { ! 983: /* If we get an error, try again later. */ ! 984: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 985: *pfprocessed = FALSE; ! 986: return; ! 987: } ! 988: ! 989: /* Not permitted. Send mail to requestor. */ ! 990: ulog (LOG_ERROR, "Not permitted to execute %s", ! 991: azQargs[0]); ! 992: ! 993: if (zmail != NULL && ! fQno_ack) ! 994: { ! 995: const char *az[20]; ! 996: ! 997: i = 0; ! 998: az[i++] = "Your execution request failed because you are not"; ! 999: az[i++] = " permitted to execute\n\t"; ! 1000: az[i++] = azQargs[0]; ! 1001: az[i++] = "\non this system.\n"; ! 1002: az[i++] = "Execution requested was:\n\t"; ! 1003: az[i++] = zQcmd; ! 1004: az[i++] = "\n"; ! 1005: ! 1006: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 1007: } ! 1008: ! 1009: uqcleanup (zfile, iclean); ! 1010: return; ! 1011: } ! 1012: } ! 1013: ! 1014: ubuffree (azQargs[0]); ! 1015: azQargs[0] = zabsolute; ! 1016: ! 1017: for (i = 1; azQargs[i] != NULL; i++) ! 1018: { ! 1019: char *zlocal; ! 1020: ! 1021: zlocal = zsysdep_xqt_local_file (qsys, azQargs[i]); ! 1022: if (zlocal != NULL) ! 1023: { ! 1024: ubuffree (azQargs[i]); ! 1025: azQargs[i] = zlocal; ! 1026: } ! 1027: } ! 1028: ! 1029: #if ! ALLOW_FILENAME_ARGUMENTS ! 1030: ! 1031: /* Check all the arguments to make sure they don't try to specify ! 1032: files they are not permitted to access. */ ! 1033: for (i = 1; azQargs[i] != NULL; i++) ! 1034: { ! 1035: if (! fsysdep_xqt_check_file (qsys, azQargs[i])) ! 1036: { ! 1037: if (zmail != NULL && ! fQno_ack) ! 1038: { ! 1039: const char *az[20]; ! 1040: const char *zfailed; ! 1041: ! 1042: zfailed = azQargs[i]; ! 1043: i = 0; ! 1044: az[i++] = "Your execution request failed because you are not"; ! 1045: az[i++] = " permitted to refer to file\n\t"; ! 1046: az[i++] = zfailed; ! 1047: az[i++] = "\non this system.\n"; ! 1048: az[i++] = "Execution requested was:\n\t"; ! 1049: az[i++] = zQcmd; ! 1050: az[i++] = "\n"; ! 1051: ! 1052: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 1053: } ! 1054: ! 1055: uqcleanup (zfile, iclean); ! 1056: return; ! 1057: } ! 1058: } ! 1059: ! 1060: #endif /* ! ALLOW_FILENAME_ARGUMENTS */ ! 1061: ! 1062: ulog (LOG_NORMAL, "Executing %s (%s)", zbase, zQcmd); ! 1063: ! 1064: if (zQinput != NULL) ! 1065: { ! 1066: boolean fspool; ! 1067: char *zreal; ! 1068: ! 1069: fspool = fspool_file (zQinput); ! 1070: if (fspool) ! 1071: zreal = zsysdep_spool_file_name (qsys, zQinput, (pointer) NULL); ! 1072: else ! 1073: zreal = zsysdep_local_file (zQinput, qsys->uuconf_zpubdir); ! 1074: if (zreal == NULL) ! 1075: { ! 1076: /* If we get an error, try again later. */ ! 1077: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1078: *pfprocessed = FALSE; ! 1079: return; ! 1080: } ! 1081: ! 1082: zQinput = zreal; ! 1083: iclean |= FREE_QINPUT; ! 1084: ! 1085: if (! fspool ! 1086: && ! fin_directory_list (zQinput, qsys->uuconf_pzremote_send, ! 1087: qsys->uuconf_zpubdir, TRUE, TRUE, ! 1088: (const char *) NULL)) ! 1089: { ! 1090: ulog (LOG_ERROR, "Not permitted to read %s", zQinput); ! 1091: ! 1092: if (zmail != NULL && ! fQno_ack) ! 1093: { ! 1094: const char *az[20]; ! 1095: ! 1096: i = 0; ! 1097: az[i++] = "Your execution request failed because you are"; ! 1098: az[i++] = " not permitted to read\n\t"; ! 1099: az[i++] = zQinput; ! 1100: az[i++] = "\non this system.\n"; ! 1101: az[i++] = "Execution requested was:\n\t"; ! 1102: az[i++] = zQcmd; ! 1103: az[i++] = "\n"; ! 1104: ! 1105: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 1106: } ! 1107: ! 1108: uqcleanup (zfile, iclean); ! 1109: return; ! 1110: } ! 1111: } ! 1112: ! 1113: zoutput = NULL; ! 1114: if (zQoutfile == NULL) ! 1115: qoutsys = NULL; ! 1116: else if (zQoutsys != NULL ! 1117: && strcmp (zQoutsys, zlocalname) != 0) ! 1118: { ! 1119: char *zdata; ! 1120: ! 1121: /* The output file is destined for some other system, so we must ! 1122: use a temporary file to catch standard output. */ ! 1123: if (strcmp (zQoutsys, qsys->uuconf_zname) == 0) ! 1124: qoutsys = qsys; ! 1125: else ! 1126: { ! 1127: iuuconf = uuconf_system_info (puuconf, zQoutsys, &soutsys); ! 1128: if (iuuconf != UUCONF_SUCCESS) ! 1129: { ! 1130: if (iuuconf != UUCONF_NOT_FOUND) ! 1131: { ! 1132: ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ! 1133: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1134: *pfprocessed = FALSE; ! 1135: return; ! 1136: } ! 1137: ! 1138: if (! funknown_system (puuconf, zQoutsys, &soutsys)) ! 1139: { ! 1140: ulog (LOG_ERROR, ! 1141: "Can't send standard output to unknown system %s", ! 1142: zQoutsys); ! 1143: /* We don't send mail to unknown systems, either. ! 1144: Maybe we should. */ ! 1145: uqcleanup (zfile, iclean); ! 1146: return; ! 1147: } ! 1148: } ! 1149: ! 1150: qoutsys = &soutsys; ! 1151: } ! 1152: ! 1153: zdata = zsysdep_data_file_name (qoutsys, zlocalname, ! 1154: BDEFAULT_UUX_GRADE, FALSE, abtemp, ! 1155: abdata, (char *) NULL); ! 1156: if (zdata == NULL) ! 1157: { ! 1158: /* If we get an error, try again later. */ ! 1159: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1160: *pfprocessed = FALSE; ! 1161: return; ! 1162: } ! 1163: zoutput = zdata; ! 1164: zQoutput = zoutput; ! 1165: iclean |= FREE_OUTPUT; ! 1166: } ! 1167: else ! 1168: { ! 1169: boolean fok; ! 1170: ! 1171: qoutsys = NULL; ! 1172: ! 1173: /* If we permitted the standard output to be redirected into ! 1174: the spool directory, people could set up phony commands. */ ! 1175: if (fspool_file (zQoutfile)) ! 1176: fok = FALSE; ! 1177: else ! 1178: { ! 1179: zoutput = zsysdep_local_file (zQoutfile, qsys->uuconf_zpubdir); ! 1180: if (zoutput == NULL) ! 1181: { ! 1182: /* If we get an error, try again later. */ ! 1183: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1184: *pfprocessed = FALSE; ! 1185: return; ! 1186: } ! 1187: ubuffree (zQoutfile); ! 1188: zQoutfile = zoutput; ! 1189: ! 1190: /* Make sure it's OK to receive this file. */ ! 1191: fok = fin_directory_list (zQoutfile, ! 1192: qsys->uuconf_pzremote_receive, ! 1193: qsys->uuconf_zpubdir, TRUE, FALSE, ! 1194: (const char *) NULL); ! 1195: } ! 1196: ! 1197: if (! fok) ! 1198: { ! 1199: ulog (LOG_ERROR, "Not permitted to write to %s", zQoutfile); ! 1200: ! 1201: if (zmail != NULL && ! fQno_ack) ! 1202: { ! 1203: const char *az[20]; ! 1204: ! 1205: i = 0; ! 1206: az[i++] = "Your execution request failed because you are"; ! 1207: az[i++] = " not permitted to write to\n\t"; ! 1208: az[i++] = zQoutfile; ! 1209: az[i++] = "\non this system.\n"; ! 1210: az[i++] = "Execution requested was:\n\t"; ! 1211: az[i++] = zQcmd; ! 1212: az[i++] = "\n"; ! 1213: ! 1214: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 1215: } ! 1216: ! 1217: uqcleanup (zfile, iclean); ! 1218: return; ! 1219: } ! 1220: } ! 1221: ! 1222: /* Move the required files to the execution directory if necessary. */ ! 1223: zinput = zQinput; ! 1224: if (! fsysdep_move_uuxqt_files (cQfiles, (const char **) azQfiles, ! 1225: (const char **) azQfiles_to, ! 1226: TRUE, iQlock_seq, &zinput)) ! 1227: { ! 1228: /* If we get an error, try again later. */ ! 1229: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1230: *pfprocessed = FALSE; ! 1231: return; ! 1232: } ! 1233: if (zQinput != NULL && strcmp (zQinput, zinput) != 0) ! 1234: { ! 1235: if ((iclean & FREE_QINPUT) != 0) ! 1236: ubuffree (zQinput); ! 1237: zQinput = zinput; ! 1238: iclean |= FREE_QINPUT; ! 1239: } ! 1240: ! 1241: #if ALLOW_SH_EXECUTION ! 1242: fshell = fQuse_sh; ! 1243: #else ! 1244: fshell = FALSE; ! 1245: #endif ! 1246: ! 1247: /* Get a shell command which uses the full path of the command to ! 1248: execute. */ ! 1249: clen = 0; ! 1250: for (i = 0; azQargs[i] != NULL; i++) ! 1251: clen += strlen (azQargs[i]) + 1; ! 1252: zfullcmd = zbufalc (clen); ! 1253: strcpy (zfullcmd, azQargs[0]); ! 1254: for (i = 1; azQargs[i] != NULL; i++) ! 1255: { ! 1256: strcat (zfullcmd, " "); ! 1257: strcat (zfullcmd, azQargs[i]); ! 1258: } ! 1259: ! 1260: if (! fsysdep_execute (qsys, ! 1261: zQuser == NULL ? (const char *) "uucp" : zQuser, ! 1262: (const char **) azQargs, zfullcmd, zQinput, ! 1263: zoutput, fshell, iQlock_seq, &zerror, &ftemp)) ! 1264: { ! 1265: ubuffree (zfullcmd); ! 1266: ! 1267: if (ftemp) ! 1268: { ! 1269: ulog (LOG_NORMAL, "Will retry later (%s)", zbase); ! 1270: if (zoutput != NULL) ! 1271: (void) remove (zoutput); ! 1272: if (zerror != NULL) ! 1273: { ! 1274: (void) remove (zerror); ! 1275: ubuffree (zerror); ! 1276: } ! 1277: (void) fsysdep_move_uuxqt_files (cQfiles, (const char **) azQfiles, ! 1278: (const char **) azQfiles_to, ! 1279: FALSE, iQlock_seq, ! 1280: (char **) NULL); ! 1281: uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); ! 1282: *pfprocessed = FALSE; ! 1283: return; ! 1284: } ! 1285: ! 1286: ulog (LOG_NORMAL, "Execution failed (%s)", zbase); ! 1287: ! 1288: if (zmail != NULL && ! fQno_ack) ! 1289: { ! 1290: const char **pz; ! 1291: int cgot; ! 1292: FILE *eerr; ! 1293: int istart; ! 1294: ! 1295: cgot = 20; ! 1296: pz = (const char **) xmalloc (cgot * sizeof (const char *)); ! 1297: i = 0; ! 1298: pz[i++] = "Execution request failed:\n\t"; ! 1299: pz[i++] = zQcmd; ! 1300: pz[i++] = "\n"; ! 1301: ! 1302: if (zerror == NULL) ! 1303: eerr = NULL; ! 1304: else ! 1305: eerr = fopen (zerror, "r"); ! 1306: if (eerr == NULL) ! 1307: { ! 1308: pz[i++] = "There was no output on standard error\n"; ! 1309: istart = i; ! 1310: } ! 1311: else ! 1312: { ! 1313: char *zline; ! 1314: size_t cline; ! 1315: ! 1316: pz[i++] = "Standard error output was:\n"; ! 1317: istart = i; ! 1318: ! 1319: zline = NULL; ! 1320: cline = 0; ! 1321: while (getline (&zline, &cline, eerr) > 0) ! 1322: { ! 1323: if (i >= cgot) ! 1324: { ! 1325: cgot += 20; ! 1326: pz = ((const char **) ! 1327: xrealloc ((pointer) pz, ! 1328: cgot * sizeof (const char *))); ! 1329: } ! 1330: pz[i++] = zbufcpy (zline); ! 1331: } ! 1332: ! 1333: (void) fclose (eerr); ! 1334: xfree ((pointer) zline); ! 1335: } ! 1336: ! 1337: (void) fsysdep_mail (zmail, "Execution failed", i, pz); ! 1338: ! 1339: for (; istart < i; istart++) ! 1340: ubuffree ((char *) pz[istart]); ! 1341: xfree ((pointer) pz); ! 1342: } ! 1343: ! 1344: if (qoutsys != NULL) ! 1345: (void) remove (zoutput); ! 1346: } ! 1347: else ! 1348: { ! 1349: ubuffree (zfullcmd); ! 1350: ! 1351: if (zmail != NULL && fQsuccess_ack) ! 1352: { ! 1353: const char *az[20]; ! 1354: ! 1355: i = 0; ! 1356: az[i++] = "\nExecution request succeeded:\n\t"; ! 1357: az[i++] = zQcmd; ! 1358: az[i++] = "\n"; ! 1359: ! 1360: (void) fsysdep_mail (zmail, "Execution succeded", i, az); ! 1361: } ! 1362: ! 1363: /* Now we may have to uucp the output to some other machine. */ ! 1364: ! 1365: if (qoutsys != NULL) ! 1366: { ! 1367: struct scmd s; ! 1368: ! 1369: /* Fill in the command structure. */ ! 1370: ! 1371: s.bcmd = 'S'; ! 1372: s.pseq = NULL; ! 1373: s.zfrom = abtemp; ! 1374: s.zto = zQoutfile; ! 1375: if (zQuser != NULL) ! 1376: s.zuser = zQuser; ! 1377: else ! 1378: s.zuser = "uucp"; ! 1379: if (zmail != NULL && fQsuccess_ack) ! 1380: s.zoptions = "Cn"; ! 1381: else ! 1382: s.zoptions = "C"; ! 1383: s.ztemp = abtemp; ! 1384: s.imode = 0666; ! 1385: if (zmail != NULL && fQsuccess_ack) ! 1386: s.znotify = zmail; ! 1387: else ! 1388: s.znotify = ""; ! 1389: s.cbytes = -1; ! 1390: s.zcmd = NULL; ! 1391: s.ipos = 0; ! 1392: ! 1393: ubuffree (zsysdep_spool_commands (qoutsys, BDEFAULT_UUX_GRADE, ! 1394: 1, &s)); ! 1395: } ! 1396: } ! 1397: ! 1398: if (zerror != NULL) ! 1399: { ! 1400: (void) remove (zerror); ! 1401: ubuffree (zerror); ! 1402: } ! 1403: ! 1404: uqcleanup (zfile, iclean); ! 1405: } ! 1406: ! 1407: /* Clean up the results of uqdo_xqt_file. */ ! 1408: ! 1409: static void ! 1410: uqcleanup (zfile, iflags) ! 1411: const char *zfile; ! 1412: int iflags; ! 1413: { ! 1414: int i; ! 1415: ! 1416: DEBUG_MESSAGE2 (DEBUG_SPOOLDIR, ! 1417: "uqcleanup: %s, %d", zfile, iflags); ! 1418: ! 1419: if (zQunlock_file != NULL) ! 1420: { ! 1421: (void) fsysdep_unlock_uuxqt_file (zQunlock_file); ! 1422: zQunlock_file = NULL; ! 1423: } ! 1424: ! 1425: if ((iflags & REMOVE_FILE) != 0) ! 1426: (void) remove (zfile); ! 1427: ! 1428: if ((iflags & REMOVE_NEEDED) != 0) ! 1429: { ! 1430: for (i = 0; i < cQfiles; i++) ! 1431: { ! 1432: if (azQfiles[i] != NULL) ! 1433: (void) remove (azQfiles[i]); ! 1434: } ! 1435: } ! 1436: ! 1437: if ((iflags & FREE_QINPUT) != 0) ! 1438: ubuffree (zQinput); ! 1439: ! 1440: if ((iflags & FREE_OUTPUT) != 0) ! 1441: ubuffree (zQoutput); ! 1442: if ((iflags & FREE_MAIL) != 0) ! 1443: ubuffree (zQmail); ! 1444: ! 1445: if (fQunlock_directory) ! 1446: { ! 1447: (void) fsysdep_unlock_uuxqt_dir (iQlock_seq); ! 1448: fQunlock_directory = FALSE; ! 1449: } ! 1450: ! 1451: for (i = 0; i < cQfiles; i++) ! 1452: { ! 1453: ubuffree (azQfiles[i]); ! 1454: ubuffree (azQfiles_to[i]); ! 1455: } ! 1456: ! 1457: ubuffree (zQoutfile); ! 1458: ubuffree (zQoutsys); ! 1459: ubuffree (zQrequestor); ! 1460: ! 1461: if (azQargs != NULL) ! 1462: { ! 1463: for (i = 0; azQargs[i] != NULL; i++) ! 1464: ubuffree (azQargs[i]); ! 1465: xfree ((pointer) azQargs); ! 1466: azQargs = NULL; ! 1467: } ! 1468: ! 1469: xfree ((pointer) zQcmd); ! 1470: zQcmd = NULL; ! 1471: ! 1472: xfree ((pointer) azQfiles); ! 1473: azQfiles = NULL; ! 1474: ! 1475: xfree ((pointer) azQfiles_to); ! 1476: azQfiles_to = NULL; ! 1477: } ! 1478: ! 1479: /* Check whether forwarding is permitted. */ ! 1480: ! 1481: static boolean ! 1482: fqforward (zfile, pzallowed, zlog, zmail) ! 1483: const char *zfile; ! 1484: char **pzallowed; ! 1485: const char *zlog; ! 1486: const char *zmail; ! 1487: { ! 1488: const char *zexclam; ! 1489: ! 1490: zexclam = strchr (zfile, '!'); ! 1491: if (zexclam != NULL) ! 1492: { ! 1493: size_t clen; ! 1494: char *zsys; ! 1495: boolean fret; ! 1496: ! 1497: clen = zexclam - zfile; ! 1498: zsys = zbufalc (clen + 1); ! 1499: memcpy (zsys, zfile, clen); ! 1500: zsys[clen] = '\0'; ! 1501: ! 1502: fret = FALSE; ! 1503: if (pzallowed != NULL) ! 1504: { ! 1505: char **pz; ! 1506: ! 1507: for (pz = pzallowed; *pz != NULL; pz++) ! 1508: { ! 1509: if (strcmp (*pz, "ANY") == 0 ! 1510: || strcmp (*pz, zsys) == 0) ! 1511: { ! 1512: fret = TRUE; ! 1513: break; ! 1514: } ! 1515: } ! 1516: } ! 1517: ! 1518: if (! fret) ! 1519: { ! 1520: ulog (LOG_ERROR, "Not permitted to forward %s %s (%s)", ! 1521: zlog, zsys, zQcmd); ! 1522: ! 1523: if (zmail != NULL && ! fQno_ack) ! 1524: { ! 1525: int i; ! 1526: const char *az[20]; ! 1527: ! 1528: i = 0; ! 1529: az[i++] = "Your execution request failed because you are"; ! 1530: az[i++] = " not permitted to forward files\n"; ! 1531: az[i++] = zlog; ! 1532: az[i++] = " the system\n\t"; ! 1533: az[i++] = zsys; ! 1534: az[i++] = "\n"; ! 1535: az[i++] = "Execution requested was:\n\t"; ! 1536: az[i++] = zQcmd; ! 1537: az[i++] = "\n"; ! 1538: ! 1539: (void) fsysdep_mail (zmail, "Execution failed", i, az); ! 1540: } ! 1541: } ! 1542: ! 1543: ubuffree (zsys); ! 1544: ! 1545: return fret; ! 1546: } ! 1547: ! 1548: return TRUE; ! 1549: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.