Annotation of coherent/g/usr/lib/uucp/tay104/uuxqt.c, revision 1.1

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: }

unix.superglobalmegacorp.com

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