home *** CD-ROM | disk | FTP | other *** search
- /* uuxqt.c
- Run uux commands.
-
- Copyright (C) 1991, 1992, 1993, 1994, 1995 Ian Lance Taylor
-
- This file is part of the Taylor UUCP package.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The author of the program may be contacted at ian@airs.com or
- c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
- */
-
- #include "uucp.h"
-
- #if USE_RCS_ID
- const char uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.82 1995/07/19 04:22:26 ian Rel $";
- #endif
-
- #include <errno.h>
- #include <ctype.h>
-
- #include "getopt.h"
-
- #include "uudefs.h"
- #include "uuconf.h"
- #include "system.h"
-
- /* Static variables used to unlock things if we get a fatal error. */
- static int iQlock_seq = -1;
- static const char *zQunlock_cmd;
- static const char *zQunlock_file;
- static boolean fQunlock_directory;
- int cQmaxuuxqts;
-
- /* Static variables to free in uqcleanup. */
- static char *zQoutput;
- static char *zQmail;
-
- /* Local functions. */
- static void uqusage P((void));
- static void uqhelp P((void));
- static void uqabort P((void));
- static void uqdo_xqt_file P((pointer puuconf, const char *zfile,
- const char *zbase,
- const struct uuconf_system *qsys,
- const char *zlocalname,
- const char *zcmd, boolean *pfprocessed));
- static void uqcleanup P((const char *zfile, int iflags));
- static int isave_files P((const struct uuconf_system *, const char *zmail,
- const char *zfile, int iclean));
- static boolean fqforward P((const char *zfile, char **pzallowed,
- const char *zlog, const char *zmail));
-
- /* Long getopt options. */
- static const struct option asQlongopts[] =
- {
- { "command", required_argument, 0, 'c' },
- { "system", required_argument, 0, 's' },
- { "config", required_argument, NULL, 'I' },
- { "debug", required_argument, NULL, 'x' },
- { "version", no_argument, NULL, 'v' },
- { "help", no_argument, NULL, 1 },
- { NULL, 0, NULL, 0 }
- };
-
- int
- main (argc, argv)
- int argc;
- char **argv;
- {
- /* The type of command to execute (NULL for any type). */
- const char *zcmd = NULL;
- /* The configuration file name. */
- const char *zconfig = NULL;
- /* The system to execute commands for. */
- const char *zdosys = NULL;
- int iopt;
- pointer puuconf;
- int iuuconf;
- const char *zlocalname;
- boolean fany;
- char *z, *zgetsys;
- boolean ferr;
- boolean fsys;
- struct uuconf_system ssys;
-
- zProgram = argv[0];
-
- while ((iopt = getopt_long (argc, argv, "c:I:s:vx:", asQlongopts,
- (int *) NULL)) != EOF)
- {
- switch (iopt)
- {
- case 'c':
- /* Set the type of command to execute. */
- zcmd = optarg;
- break;
-
- case 'I':
- /* Set the configuration file name. */
- if (fsysdep_other_config (optarg))
- zconfig = optarg;
- break;
-
- case 's':
- zdosys = optarg;
- break;
-
- case 'x':
- #if DEBUG > 1
- /* Set the debugging level. */
- iDebug |= idebug_parse (optarg);
- #endif
- break;
-
- case 'v':
- /* Print version and exit. */
- printf ("%s: Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995 Ian Lance Taylor\n",
- zProgram, VERSION);
- exit (EXIT_SUCCESS);
- /*NOTREACHED*/
-
- case 1:
- /* --help. */
- uqhelp ();
- exit (EXIT_SUCCESS);
- /*NOTREACHED*/
-
- case 0:
- /* Long option found and flag set. */
- break;
-
- default:
- uqusage ();
- break;
- }
- }
-
- if (optind != argc)
- uqusage ();
-
- iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
- if (iuuconf != UUCONF_SUCCESS)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
-
- #if DEBUG > 1
- {
- const char *zdebug;
-
- iuuconf = uuconf_debuglevel (puuconf, &zdebug);
- if (iuuconf != UUCONF_SUCCESS)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
- if (zdebug != NULL)
- iDebug |= idebug_parse (zdebug);
- }
- #endif
-
- iuuconf = uuconf_maxuuxqts (puuconf, &cQmaxuuxqts);
- if (iuuconf != UUCONF_SUCCESS)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
-
- #ifdef SIGINT
- usysdep_signal (SIGINT);
- #endif
- #ifdef SIGHUP
- usysdep_signal (SIGHUP);
- #endif
- #ifdef SIGQUIT
- usysdep_signal (SIGQUIT);
- #endif
- #ifdef SIGTERM
- usysdep_signal (SIGTERM);
- #endif
- #ifdef SIGPIPE
- usysdep_signal (SIGPIPE);
- #endif
-
- usysdep_initialize (puuconf, INIT_SUID);
-
- ulog_to_file (puuconf, TRUE);
- ulog_fatal_fn (uqabort);
-
- iuuconf = uuconf_localname (puuconf, &zlocalname);
- if (iuuconf == UUCONF_NOT_FOUND)
- {
- zlocalname = zsysdep_localname ();
- if (zlocalname == NULL)
- exit (EXIT_FAILURE);
- }
- else if (iuuconf != UUCONF_SUCCESS)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
-
- fsys = FALSE;
-
- /* If we were given a system name, canonicalize it. */
- if (zdosys != NULL)
- {
- iuuconf = uuconf_system_info (puuconf, zdosys, &ssys);
- if (iuuconf != UUCONF_SUCCESS)
- {
- if (iuuconf != UUCONF_NOT_FOUND)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
-
- if (strcmp (zdosys, zlocalname) == 0)
- {
- iuuconf = uuconf_system_local (puuconf, &ssys);
- if (iuuconf != UUCONF_SUCCESS)
- ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
- ssys.uuconf_zname = (char *) zlocalname;
- }
- else
- {
- if (! funknown_system (puuconf, zdosys, &ssys))
- ulog (LOG_FATAL, "%s: system not found", zdosys);
- }
- }
-
- zdosys = zbufcpy (ssys.uuconf_zname);
- fsys = TRUE;
- }
-
- /* Limit the number of uuxqt processes, and make sure we're the only
- uuxqt daemon running for this command. */
- iQlock_seq = ixsysdep_lock_uuxqt (zcmd, cQmaxuuxqts);
- if (iQlock_seq < 0)
- {
- ulog_close ();
- usysdep_exit (TRUE);
- }
- zQunlock_cmd = zcmd;
-
- /* Keep scanning the execute files until we don't process any of
- them. */
- do
- {
- fany = FALSE;
-
- /* Look for each execute file, and run it. */
-
- if (! fsysdep_get_xqt_init (zdosys))
- {
- ulog_close ();
- usysdep_exit (FALSE);
- }
-
- while ((z = zsysdep_get_xqt (zdosys, &zgetsys, &ferr)) != NULL)
- {
- const char *zloc;
- boolean fprocessed;
- char *zbase;
-
- /* Get the system information for the system returned by
- zsysdep_get_xqt. */
- if (! fsys || strcmp (ssys.uuconf_zname, zgetsys) != 0)
- {
- if (fsys)
- (void) uuconf_system_free (puuconf, &ssys);
-
- iuuconf = uuconf_system_info (puuconf, zgetsys,
- &ssys);
- if (iuuconf != UUCONF_SUCCESS)
- {
- if (iuuconf != UUCONF_NOT_FOUND)
- {
- ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
- ubuffree (z);
- ubuffree (zgetsys);
- continue;
- }
- else if (strcmp (zgetsys, zlocalname) == 0)
- {
- iuuconf = uuconf_system_local (puuconf, &ssys);
- if (iuuconf != UUCONF_SUCCESS)
- {
- ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
- ubuffree (z);
- ubuffree (zgetsys);
- continue;
- }
- ssys.uuconf_zname = (char *) zlocalname;
- }
- else
- {
- if (! funknown_system (puuconf, zgetsys, &ssys))
- {
- ulog (LOG_ERROR,
- "%s: Execute file for unknown system %s",
- z, zgetsys);
- (void) remove (z);
- ubuffree (z);
- ubuffree (zgetsys);
- continue;
- }
- }
- }
-
- fsys = TRUE;
- }
-
- /* If we've received a signal, get out of the loop. */
- if (FGOT_SIGNAL ())
- {
- ubuffree (z);
- ubuffree (zgetsys);
- break;
- }
-
- /* Make sure we are supposed to be executing jobs for this
- system. */
- if (zdosys != NULL && strcmp (zdosys, ssys.uuconf_zname) != 0)
- {
- ubuffree (z);
- ubuffree (zgetsys);
- continue;
- }
-
- zloc = ssys.uuconf_zlocalname;
- if (zloc == NULL)
- zloc = zlocalname;
-
- ulog_system (ssys.uuconf_zname);
- zbase = zsysdep_base_name (z);
- uqdo_xqt_file (puuconf, z, zbase, &ssys, zloc, zcmd, &fprocessed);
- ubuffree (zbase);
- ulog_system ((const char *) NULL);
- ulog_user ((const char *) NULL);
-
- if (fprocessed)
- fany = TRUE;
- ubuffree (z);
- ubuffree (zgetsys);
- }
-
- usysdep_get_xqt_free (zdosys);
- }
- while (fany && ! FGOT_SIGNAL ());
-
- (void) fsysdep_unlock_uuxqt (iQlock_seq, zcmd, cQmaxuuxqts);
- iQlock_seq = -1;
-
- ulog_close ();
-
- if (FGOT_SIGNAL ())
- ferr = TRUE;
-
- usysdep_exit (! ferr);
-
- /* Avoid errors about not returning a value. */
- return 0;
- }
-
- static void
- uqhelp ()
- {
- printf ("Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995 Ian Lance Taylor\n",
- VERSION);
- printf ("Usage: %s [-c,--command cmd] [-s,--system system]\n", zProgram);
- printf (" -c,--command cmd: Set type of command to execute\n");
- printf (" -s,--system system: Execute commands only for named system\n");
- printf (" -x,--debug debug: Set debugging level\n");
- #if HAVE_TAYLOR_CONFIG
- printf (" -I,--config file: Set configuration file to use\n");
- #endif /* HAVE_TAYLOR_CONFIG */
- printf (" -v,--version: Print version and exit\n");
- printf (" --help: Print help and exit\n");
- }
-
- static void
- uqusage ()
- {
- fprintf (stderr,
- "Usage: %s [-c,--command cmd] [-s,--system system]\n", zProgram);
- fprintf (stderr, "Use %s --help for help\n", zProgram);
- exit (EXIT_FAILURE);
- }
-
- /* This is the abort function called when we get a fatal error. */
-
- static void
- uqabort ()
- {
- #if ! HAVE_HDB_LOGGING
- /* When using HDB logging, it's a pain to have no system name. */
- ulog_system ((const char *) NULL);
- #endif
-
- ulog_user ((const char *) NULL);
-
- if (fQunlock_directory)
- (void) fsysdep_unlock_uuxqt_dir (iQlock_seq);
-
- if (zQunlock_file != NULL)
- (void) fsysdep_unlock_uuxqt_file (zQunlock_file);
-
- if (iQlock_seq >= 0)
- (void) fsysdep_unlock_uuxqt (iQlock_seq, zQunlock_cmd, cQmaxuuxqts);
-
- ulog_close ();
-
- usysdep_exit (FALSE);
- }
-
- /* An execute file is a series of lines. The first character of each
- line is a command. The following commands are defined:
-
- C command-line
- I standard-input
- O standard-output [ system ]
- F required-file filename-to-use
- R requestor-address
- U user system
- Z (acknowledge if command failed; default)
- N (no acknowledgement on failure)
- n (acknowledge if command succeeded)
- B (return command input on error)
- e (process with sh)
- E (process with exec)
- M status-file
- # comment
-
- Unrecognized commands are ignored. We actually do not recognize
- the Z command, since it requests default behaviour. We always send
- mail on failure, unless the N command appears. We never send mail
- on success, unless the n command appears.
-
- This code does not currently support the B or M commands. */
-
- /* Command arguments. */
- static char **azQargs;
- /* Command as a complete string. */
- static char *zQcmd;
- /* Standard input file name. */
- static char *zQinput;
- /* Standard output file name. */
- static char *zQoutfile;
- /* Standard output system. */
- static char *zQoutsys;
- /* Number of required files. */
- static int cQfiles;
- /* Names of required files. */
- static char **azQfiles;
- /* Names required files should be renamed to (NULL if original is OK). */
- static char **azQfiles_to;
- /* Requestor address (this is where mail should be sent). */
- static char *zQrequestor;
- /* User name. */
- static const char *zQuser;
- /* System name. */
- static const char *zQsystem;
- /* This is set by the N flag, meaning that no acknowledgement should
- be mailed on failure. */
- static boolean fQno_ack;
- /* This is set by the n flag, meaning that acknowledgement should be
- mailed if the command succeeded. */
- static boolean fQsuccess_ack;
- /* This is set by the B flag, meaning that command input should be
- mailed to the requestor if an error occurred. */
- static boolean fQsend_input;
- /* This is set by the E flag, meaning that exec should be used to
- execute the command. */
- static boolean fQuse_exec;
- /* The status should be copied to this file on the requesting host. */
- static const char *zQstatus_file;
- #if ALLOW_SH_EXECUTION
- /* This is set by the e flag, meaning that sh should be used to
- execute the command. */
- static boolean fQuse_sh;
- #endif /* ALLOW_SH_EXECUTION */
-
- static int iqcmd P((pointer puuconf, int argc, char **argv, pointer pvar,
- pointer pinfo));
- static int iqout P((pointer puuconf, int argc, char **argv, pointer pvar,
- pointer pinfo));
- static int iqfile P((pointer puuconf, int argc, char **argv, pointer pvar,
- pointer pinfo));
- static int iqrequestor P((pointer puuconf, int argc, char **argv,
- pointer pvar, pointer pinfo));
- static int iquser P((pointer puuconf, int argc, char **argv, pointer pvar,
- pointer pinfo));
- static int iqset P((pointer puuconf, int argc, char **argv, pointer pvar,
- pointer pinfo));
-
- /* We are lax about the number of arguments the functions accept,
- because there is a lot of variation in what other (buggy) UUCP
- packages generate. Unused arguments are ignored. */
-
- static const struct uuconf_cmdtab asQcmds[] =
- {
- { "C", UUCONF_CMDTABTYPE_FN | 0, NULL, iqcmd },
- { "I", UUCONF_CMDTABTYPE_STRING, (pointer) &zQinput, NULL },
- { "O", UUCONF_CMDTABTYPE_FN | 0, NULL, iqout },
- { "F", UUCONF_CMDTABTYPE_FN | 0, NULL, iqfile },
- { "R", UUCONF_CMDTABTYPE_FN | 0, NULL, iqrequestor },
- { "U", UUCONF_CMDTABTYPE_FN | 0, NULL, iquser },
- { "N", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQno_ack, iqset },
- { "n", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQsuccess_ack, iqset },
- { "B", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQsend_input, iqset },
- #if ALLOW_SH_EXECUTION
- { "e", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQuse_sh, iqset },
- #endif
- { "E", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQuse_exec, iqset },
- { "M", UUCONF_CMDTABTYPE_STRING, (pointer) &zQstatus_file, NULL },
- { NULL, 0, NULL, NULL }
- };
-
- /* Handle the C command: store off the arguments. */
-
- /*ARGSUSED*/
- static int
- iqcmd (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- int i;
- size_t clen;
-
- if (argc <= 1)
- return UUCONF_CMDTABRET_CONTINUE;
-
- azQargs = (char **) xmalloc (argc * sizeof (char *));
- clen = 0;
- for (i = 1; i < argc; i++)
- {
- azQargs[i - 1] = zbufcpy (argv[i]);
- clen += strlen (argv[i]) + 1;
- }
- azQargs[i - 1] = NULL;
-
- zQcmd = (char *) xmalloc (clen);
- zQcmd[0] = '\0';
- for (i = 1; i < argc - 1; i++)
- {
- strcat (zQcmd, argv[i]);
- strcat (zQcmd, " ");
- }
- strcat (zQcmd, argv[i]);
-
- return UUCONF_CMDTABRET_CONTINUE;
- }
-
- /* Handle the O command, which may have one or two arguments. */
-
- /*ARGSUSED*/
- static int
- iqout (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- if (argc > 1)
- zQoutfile = zbufcpy (argv[1]);
- if (argc > 2)
- zQoutsys = zbufcpy (argv[2]);
-
- return UUCONF_CMDTABRET_CONTINUE;
- }
-
- /* Handle the F command, which may have one or two arguments. */
-
- /*ARGSUSED*/
- static int
- iqfile (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- if (argc < 2)
- return UUCONF_CMDTABRET_CONTINUE;
-
- /* If this file is not in the spool directory, just ignore it. */
- if (! fspool_file (argv[1]))
- return UUCONF_CMDTABRET_CONTINUE;
-
- ++cQfiles;
- azQfiles = (char **) xrealloc ((pointer) azQfiles,
- cQfiles * sizeof (char *));
- azQfiles_to = (char **) xrealloc ((pointer) azQfiles_to,
- cQfiles * sizeof (char *));
-
- azQfiles[cQfiles - 1] = zbufcpy (argv[1]);
- if (argc > 2)
- azQfiles_to[cQfiles - 1] = zbufcpy (argv[2]);
- else
- azQfiles_to[cQfiles - 1] = NULL;
-
- return UUCONF_CMDTABRET_CONTINUE;
- }
-
- /* Handle the R command, which may have one or two arguments. */
-
- /*ARGSUSED*/
- static int
- iqrequestor (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- /* We normally have a single argument, which is the ``requestor''
- address, to which we should send any success or error messages.
- Apparently the DOS program UUPC sends two arguments, which are
- the username and the host. */
- if (argc == 2)
- zQrequestor = zbufcpy (argv[1]);
- else if (argc > 2)
- {
- zQrequestor = zbufalc (strlen (argv[1]) + strlen (argv[2])
- + sizeof "!");
- sprintf (zQrequestor, "%s!%s", argv[2], argv[1]);
- }
-
- return UUCONF_CMDTABRET_CONTINUE;
- }
-
- /* Handle the U command, which takes two arguments. */
-
- /*ARGSUSED*/
- static int
- iquser (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- if (argc > 1)
- zQuser = argv[1];
- if (argc > 2)
- zQsystem = argv[2];
- return UUCONF_CMDTABRET_KEEP;
- }
-
- /* Handle various commands which just set boolean variables. */
-
- /*ARGSUSED*/
- static int
- iqset (puuconf, argc, argv, pvar, pinfo)
- pointer puuconf;
- int argc;
- char **argv;
- pointer pvar;
- pointer pinfo;
- {
- boolean *pf = (boolean *) pvar;
-
- *pf = TRUE;
- return UUCONF_CMDTABRET_CONTINUE;
- }
-
- /* The execution processing does a lot of things that have to be
- cleaned up. Rather than try to add the appropriate statements
- to each return point, we keep a set of flags indicating what
- has to be cleaned up. The actual clean up is done by the
- function uqcleanup. */
- #define REMOVE_FILE (01)
- #define REMOVE_NEEDED (02)
- #define FREE_QINPUT (04)
- #define REMOVE_QINPUT (010)
- #define FREE_OUTPUT (020)
- #define FREE_MAIL (040)
-
- /* Process an execute file. The zfile argument is the name of the
- execute file. The zbase argument is the base name of zfile. The
- qsys argument describes the system it came from. The zcmd argument
- is the name of the command we are executing (from the -c option) or
- NULL if any command is OK. This sets *pfprocessed to TRUE if the
- file is ready to be executed. */
-
- static void
- uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed)
- pointer puuconf;
- const char *zfile;
- const char *zbase;
- const struct uuconf_system *qsys;
- const char *zlocalname;
- const char *zcmd;
- boolean *pfprocessed;
- {
- char *zabsolute;
- boolean ferr;
- FILE *e;
- int iuuconf;
- int i;
- int iclean;
- const char *zmail;
- char *zoutput;
- char *zinput;
- boolean fbadname;
- char abtemp[CFILE_NAME_LEN];
- char abdata[CFILE_NAME_LEN];
- char *zerror;
- struct uuconf_system soutsys;
- const struct uuconf_system *qoutsys;
- boolean fshell;
- size_t clen;
- char *zfullcmd;
- boolean ftemp;
-
- *pfprocessed = FALSE;
-
- e = fopen (zfile, "r");
- if (e == NULL)
- return;
-
- azQargs = NULL;
- zQcmd = NULL;
- zQinput = NULL;
- zQoutfile = NULL;
- zQoutsys = NULL;
- cQfiles = 0;
- azQfiles = NULL;
- azQfiles_to = NULL;
- zQrequestor = NULL;
- zQuser = NULL;
- zQsystem = NULL;
- fQno_ack = FALSE;
- fQsuccess_ack = FALSE;
- fQsend_input = FALSE;
- fQuse_exec = FALSE;
- zQstatus_file = NULL;
- #if ALLOW_SH_EXECUTION
- fQuse_sh = FALSE;
- #endif
-
- iuuconf = uuconf_cmd_file (puuconf, e, asQcmds, (pointer) zbase,
- (uuconf_cmdtabfn) NULL,
- (UUCONF_CMDTABFLAG_CASE
- | UUCONF_CMDTABFLAG_NOCOMMENTS),
- (pointer) NULL);
- (void) fclose (e);
-
- if (iuuconf != UUCONF_SUCCESS)
- {
- ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
-
- /* If we got a non-transient error, we notify the administrator.
- We can't bounce it back to the original requestor, because we
- don't know how to read the file to figure out who it is (it
- would probably be possible to read the file and work it out,
- but it doesn't seem worth it for such an unlikely error). */
- if (UUCONF_ERROR_VALUE (iuuconf) == UUCONF_SYNTAX_ERROR
- || UUCONF_ERROR_VALUE (iuuconf) == UUCONF_UNKNOWN_COMMAND)
- {
- const char *az[20];
- char *znew;
-
- i = 0;
- az[i++] = "The execution file\n\t";
- az[i++] = zfile;
- az[i++] = "\nfor system\n\t";
- az[i++] = qsys->uuconf_zname;
- az[i++] = "\nwas corrupt. ";
- znew = zsysdep_save_corrupt_file (zfile);
- if (znew == NULL)
- {
- az[i++] = "The file could not be preserved.\n";
- (void) remove (zfile);
- }
- else
- {
- az[i++] = "It has been moved to\n\t";
- az[i++] = znew;
- az[i++] = "\n";
- }
- (void) fsysdep_mail (OWNER, "Corrupt execution file", i, az);
- ubuffree (znew);
- }
-
- return;
- }
-
- iclean = 0;
-
- if (azQargs == NULL)
- {
- ulog (LOG_ERROR, "%s: No command given", zbase);
- uqcleanup (zfile, iclean | REMOVE_FILE);
- return;
- }
-
- if (zcmd != NULL)
- {
- if (strcmp (zcmd, azQargs[0]) != 0)
- {
- uqcleanup (zfile, iclean);
- return;
- }
- }
- else
- {
- /* If there is a lock file for this particular command already,
- it means that some other uuxqt is supposed to handle it. */
- if (fsysdep_uuxqt_locked (azQargs[0]))
- {
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- /* Lock this particular file. */
- if (! fsysdep_lock_uuxqt_file (zfile))
- {
- uqcleanup (zfile, iclean);
- return;
- }
-
- zQunlock_file = zfile;
-
- /* Now that we have the file locked, make sure it still exists.
- Otherwise another uuxqt could have just finished processing it
- and removed the lock file. */
- if (! fsysdep_file_exists (zfile))
- {
- uqcleanup (zfile, iclean);
- return;
- }
-
- if (zQuser != NULL)
- ulog_user (zQuser);
- else if (zQrequestor != NULL)
- ulog_user (zQrequestor);
- else
- ulog_user ("unknown");
-
- /* zQsystem, if it is set, comes from the execution file, which
- means that we do not trust it. We only retain it if
- qsys->uuconf_zname is a prefix of it, since that can happen with
- a job from an anonymous system on certain spool directory types,
- and is unlikely to cause any trouble anyhow. */
- if (zQsystem == NULL
- || strncmp (zQsystem, qsys->uuconf_zname,
- strlen (qsys->uuconf_zname)) != 0)
- zQsystem = qsys->uuconf_zname;
-
- /* Make sure that all the required files exist, and get their
- full names in the spool directory. */
- for (i = 0; i < cQfiles; i++)
- {
- char *zreal;
-
- zreal = zsysdep_spool_file_name (qsys, azQfiles[i], (pointer) NULL);
- if (zreal == NULL)
- {
- uqcleanup (zfile, iclean);
- return;
- }
- if (! fsysdep_file_exists (zreal))
- {
- uqcleanup (zfile, iclean);
- return;
- }
- ubuffree (azQfiles[i]);
- azQfiles[i] = zbufcpy (zreal);
- ubuffree (zreal);
- }
-
- /* Lock the execution directory. */
- if (! fsysdep_lock_uuxqt_dir (iQlock_seq))
- {
- ulog (LOG_ERROR, "Could not lock execute directory");
- uqcleanup (zfile, iclean);
- return;
- }
- fQunlock_directory = TRUE;
-
- iclean |= REMOVE_FILE | REMOVE_NEEDED;
- *pfprocessed = TRUE;
-
- /* Get the address to mail results to. Prepend the system from
- which the execute file originated, since mail addresses are
- relative to it. */
- zmail = NULL;
- if (zQrequestor != NULL)
- zmail = zQrequestor;
- else if (zQuser != NULL)
- zmail = zQuser;
- if (zmail != NULL
- #if HAVE_INTERNET_MAIL
- && strchr (zmail, '@') == NULL
- #endif
- && strcmp (zQsystem, zlocalname) != 0)
- {
- char *zset;
-
- zset = zbufalc (strlen (zQsystem) + strlen (zmail) + 2);
- sprintf (zset, "%s!%s", zQsystem, zmail);
- zmail = zset;
- zQmail = zset;
- iclean |= FREE_MAIL;
- }
-
- /* The command "uucp" is handled specially. We make sure that the
- appropriate forwarding is permitted, and we add a -u argument to
- specify the user. */
- if (strcmp (azQargs[0], "uucp") == 0)
- {
- char *zfrom, *zto;
- boolean fmany;
- char **azargs;
- const char *zuser;
-
- zfrom = NULL;
- zto = NULL;
- fmany = FALSE;
-
- /* Skip all the options, and get the from and to specs. We
- don't permit multiple arguments. */
- for (i = 1; azQargs[i] != NULL; i++)
- {
- if (azQargs[i][0] == '-')
- {
- char *zopts;
-
- for (zopts = azQargs[i] + 1; *zopts != '\0'; zopts++)
- {
- /* The -g, -n, and -s options take an argument. */
- if (*zopts == 'g' || *zopts == 'n' || *zopts == 's')
- {
- if (zopts[1] == '\0')
- ++i;
- break;
- }
- /* The -I, -u and -x options are not permitted. */
- if (*zopts == 'I' || *zopts == 'u' || *zopts == 'x')
- {
- *zopts = 'r';
- if (zopts[1] != '\0')
- zopts[1] = '\0';
- else
- {
- ++i;
- azQargs[i] = zbufcpy ("-r");
- }
- break;
- }
- }
- }
- else if (zfrom == NULL)
- zfrom = azQargs[i];
- else if (zto == NULL)
- zto = azQargs[i];
- else
- {
- fmany = TRUE;
- break;
- }
- }
-
- /* Add the -u argument. This is required to let uucp do the
- correct permissions checking on the file transfer. */
- for (i = 0; azQargs[i] != NULL; i++)
- ;
- azargs = (char **) xmalloc ((i + 2) * sizeof (char *));
- azargs[0] = azQargs[0];
- zuser = zQuser;
- if (zuser == NULL)
- zuser = "uucp";
- azargs[1] = zbufalc (strlen (zQsystem) + strlen (zuser)
- + sizeof "-u!");
- sprintf (azargs[1], "-u%s!%s", zQsystem, zuser);
- memcpy (azargs + 2, azQargs + 1, i * sizeof (char *));
- xfree ((pointer) azQargs);
- azQargs = azargs;
-
- /* Find the uucp binary. */
- zabsolute = zsysdep_find_command ("uucp", qsys->uuconf_pzcmds,
- qsys->uuconf_pzpath, &ferr);
- if (zabsolute == NULL && ! ferr)
- {
- const char *azcmds[2];
-
- /* If "uucp" is not a permitted command, then the forwarding
- entries must be set. */
- if (! fqforward (zfrom, qsys->uuconf_pzforward_from, "from", zmail)
- || ! fqforward (zto, qsys->uuconf_pzforward_to, "to", zmail))
- {
- uqcleanup (zfile, iclean);
- return;
- }
-
- /* If "uucp" is not a permitted command, then only uucp
- requests with a single source are permitted, since that
- is all that will be generated by uucp or uux. */
- if (fmany)
- {
- ulog (LOG_ERROR, "Bad uucp request %s", zQcmd);
-
- if (zmail != NULL && ! fQno_ack)
- {
- const char *az[20];
-
- i = 0;
- az[i++] = "Your execution request failed because it was an";
- az[i++] = " unsupported uucp request.\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
-
- uqcleanup (zfile, iclean);
- return;
- }
-
- azcmds[0] = "uucp";
- azcmds[1] = NULL;
- zabsolute = zsysdep_find_command ("uucp", (char **) azcmds,
- qsys->uuconf_pzpath, &ferr);
- }
- if (zabsolute == NULL)
- {
- if (! ferr)
- ulog (LOG_ERROR, "Can't find uucp executable");
-
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
- }
- else
- {
- /* Get the pathname to execute. */
- zabsolute = zsysdep_find_command (azQargs[0], qsys->uuconf_pzcmds,
- qsys->uuconf_pzpath,
- &ferr);
- if (zabsolute == NULL)
- {
- if (ferr)
- {
- /* If we get an error, try again later. */
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
-
- /* Not permitted. Send mail to requestor. */
- ulog (LOG_ERROR, "Not permitted to execute %s",
- azQargs[0]);
-
- if (zmail != NULL && ! fQno_ack)
- {
- const char *az[20];
-
- i = 0;
- az[i++] = "Your execution request failed because you are not";
- az[i++] = " permitted to execute\n\t";
- az[i++] = azQargs[0];
- az[i++] = "\non this system.\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
-
- iclean = isave_files (qsys, zmail, zfile, iclean);
-
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- ubuffree (azQargs[0]);
- azQargs[0] = zabsolute;
-
- for (i = 1; azQargs[i] != NULL; i++)
- {
- char *zlocal;
-
- zlocal = zsysdep_xqt_local_file (qsys, azQargs[i]);
- if (zlocal != NULL)
- {
- ubuffree (azQargs[i]);
- azQargs[i] = zlocal;
- }
- }
-
- #if ! ALLOW_FILENAME_ARGUMENTS
-
- /* Check all the arguments to make sure they don't try to specify
- files they are not permitted to access. */
- for (i = 1; azQargs[i] != NULL; i++)
- {
- if (! fsysdep_xqt_check_file (qsys, azQargs[i]))
- {
- if (zmail != NULL && ! fQno_ack)
- {
- const char *az[20];
- const char *zfailed;
-
- zfailed = azQargs[i];
- i = 0;
- az[i++] = "Your execution request failed because you are not";
- az[i++] = " permitted to refer to file\n\t";
- az[i++] = zfailed;
- az[i++] = "\non this system.\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
-
- iclean = isave_files (qsys, zmail, zfile, iclean);
-
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- #endif /* ! ALLOW_FILENAME_ARGUMENTS */
-
- ulog (LOG_NORMAL, "Executing %s (%s)", zbase, zQcmd);
-
- if (zQinput != NULL)
- {
- boolean fspool;
- char *zreal;
-
- fspool = fspool_file (zQinput);
- if (! fspool)
- zreal = zsysdep_local_file (zQinput, qsys->uuconf_zpubdir, &fbadname);
- else
- {
- zreal = zsysdep_spool_file_name (qsys, zQinput, (pointer) NULL);
- fbadname = FALSE;
- }
- if (zreal == NULL && ! fbadname)
- {
- /* If we get an error, try again later. */
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
-
- if (zreal != NULL)
- {
- zQinput = zreal;
- iclean |= FREE_QINPUT;
- if (fspool)
- iclean |= REMOVE_QINPUT;
- }
-
- if (zreal == NULL
- || (! fspool
- && ! fin_directory_list (zQinput, qsys->uuconf_pzremote_send,
- qsys->uuconf_zpubdir, TRUE, TRUE,
- (const char *) NULL)))
- {
- ulog (LOG_ERROR, "Not permitted to read %s", zQinput);
-
- if (zmail != NULL && ! fQno_ack)
- {
- const char *az[20];
-
- i = 0;
- az[i++] = "Your execution request failed because you are";
- az[i++] = " not permitted to read\n\t";
- az[i++] = zQinput;
- az[i++] = "\non this system.\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
-
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- zoutput = NULL;
- if (zQoutfile == NULL)
- qoutsys = NULL;
- else if (zQoutsys != NULL
- && strcmp (zQoutsys, zlocalname) != 0)
- {
- char *zdata;
-
- /* The output file is destined for some other system, so we must
- use a temporary file to catch standard output. */
- if (strcmp (zQoutsys, qsys->uuconf_zname) == 0)
- qoutsys = qsys;
- else
- {
- iuuconf = uuconf_system_info (puuconf, zQoutsys, &soutsys);
- if (iuuconf != UUCONF_SUCCESS)
- {
- if (iuuconf != UUCONF_NOT_FOUND)
- {
- ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
-
- if (! funknown_system (puuconf, zQoutsys, &soutsys))
- {
- ulog (LOG_ERROR,
- "Can't send standard output to unknown system %s",
- zQoutsys);
- /* We don't send mail to unknown systems, either.
- Maybe we should. */
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- qoutsys = &soutsys;
- }
-
- zdata = zsysdep_data_file_name (qoutsys, zlocalname,
- BDEFAULT_UUX_GRADE, FALSE, abtemp,
- abdata, (char *) NULL);
- if (zdata == NULL)
- {
- /* If we get an error, try again later. */
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
- zoutput = zdata;
- zQoutput = zoutput;
- iclean |= FREE_OUTPUT;
- }
- else
- {
- boolean fok;
-
- qoutsys = NULL;
-
- /* If we permitted the standard output to be redirected into
- the spool directory, people could set up phony commands. */
- if (fspool_file (zQoutfile))
- fok = FALSE;
- else
- {
- zoutput = zsysdep_local_file (zQoutfile, qsys->uuconf_zpubdir,
- &fbadname);
- if (zoutput == NULL)
- {
- if (! fbadname)
- {
- /* If we get an error, try again later. */
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
- fok = FALSE;
- }
- else
- {
- ubuffree (zQoutfile);
- zQoutfile = zoutput;
-
- /* Make sure it's OK to receive this file. */
- fok = fin_directory_list (zQoutfile,
- qsys->uuconf_pzremote_receive,
- qsys->uuconf_zpubdir, TRUE, FALSE,
- (const char *) NULL);
- }
- }
-
- if (! fok)
- {
- ulog (LOG_ERROR, "Not permitted to write to %s", zQoutfile);
-
- if (zmail != NULL && ! fQno_ack)
- {
- const char *az[20];
-
- i = 0;
- az[i++] = "Your execution request failed because you are";
- az[i++] = " not permitted to write to\n\t";
- az[i++] = zQoutfile;
- az[i++] = "\non this system.\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
-
- uqcleanup (zfile, iclean);
- return;
- }
- }
-
- /* Move the required files to the execution directory if necessary. */
- zinput = zQinput;
- if (! fsysdep_move_uuxqt_files (cQfiles, (const char **) azQfiles,
- (const char **) azQfiles_to,
- TRUE, iQlock_seq, &zinput))
- {
- /* If we get an error, try again later. */
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
- if (zQinput != NULL && strcmp (zQinput, zinput) != 0)
- {
- if ((iclean & FREE_QINPUT) != 0)
- ubuffree (zQinput);
- zQinput = zinput;
- iclean |= FREE_QINPUT;
- }
-
- #if ALLOW_SH_EXECUTION
- fshell = fQuse_sh;
- #else
- fshell = FALSE;
- #endif
-
- /* Get a shell command which uses the full path of the command to
- execute. */
- clen = 0;
- for (i = 0; azQargs[i] != NULL; i++)
- clen += strlen (azQargs[i]) + 1;
- zfullcmd = zbufalc (clen);
- strcpy (zfullcmd, azQargs[0]);
- for (i = 1; azQargs[i] != NULL; i++)
- {
- strcat (zfullcmd, " ");
- strcat (zfullcmd, azQargs[i]);
- }
-
- if (! fsysdep_execute (qsys,
- zQuser == NULL ? (const char *) "uucp" : zQuser,
- (const char **) azQargs, zfullcmd, zQinput,
- zoutput, fshell, iQlock_seq, &zerror, &ftemp))
- {
- ubuffree (zfullcmd);
-
- (void) fsysdep_move_uuxqt_files (cQfiles, (const char **) azQfiles,
- (const char **) azQfiles_to,
- FALSE, iQlock_seq,
- (char **) NULL);
-
- if (ftemp)
- {
- ulog (LOG_NORMAL, "Will retry later (%s)", zbase);
- if (zoutput != NULL)
- (void) remove (zoutput);
- if (zerror != NULL)
- {
- (void) remove (zerror);
- ubuffree (zerror);
- }
- uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED));
- *pfprocessed = FALSE;
- return;
- }
-
- ulog (LOG_NORMAL, "Execution failed (%s)", zbase);
-
- if (zmail != NULL && ! fQno_ack)
- {
- const char **pz;
- int cgot;
- FILE *eerr;
- int istart;
-
- cgot = 20;
- pz = (const char **) xmalloc (cgot * sizeof (const char *));
- i = 0;
- pz[i++] = "Execution request failed:\n\t";
- pz[i++] = zQcmd;
- pz[i++] = "\n";
-
- if (zerror == NULL)
- eerr = NULL;
- else
- eerr = fopen (zerror, "r");
- if (eerr == NULL)
- {
- pz[i++] = "There was no output on standard error\n";
- istart = i;
- }
- else
- {
- char *zline;
- size_t cline;
-
- pz[i++] = "Standard error output was:\n";
- istart = i;
-
- zline = NULL;
- cline = 0;
- while (getline (&zline, &cline, eerr) > 0)
- {
- if (i >= cgot)
- {
- cgot += 20;
- pz = ((const char **)
- xrealloc ((pointer) pz,
- cgot * sizeof (const char *)));
- }
- pz[i++] = zbufcpy (zline);
- }
-
- (void) fclose (eerr);
- xfree ((pointer) zline);
- }
-
- (void) fsysdep_mail (zmail, "Execution failed", i, pz);
-
- for (; istart < i; istart++)
- ubuffree ((char *) pz[istart]);
- xfree ((pointer) pz);
- }
-
- if (qoutsys != NULL)
- (void) remove (zoutput);
-
- iclean = isave_files (qsys, zmail, zfile, iclean);
- }
- else
- {
- ubuffree (zfullcmd);
-
- if (zmail != NULL && fQsuccess_ack)
- {
- const char *az[20];
-
- i = 0;
- az[i++] = "\nExecution request succeeded:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution succeded", i, az);
- }
-
- /* Now we may have to uucp the output to some other machine. */
-
- if (qoutsys != NULL)
- {
- struct scmd s;
-
- /* Fill in the command structure. */
-
- s.bcmd = 'S';
- s.bgrade = BDEFAULT_UUX_GRADE;
- s.pseq = NULL;
- s.zfrom = abtemp;
- s.zto = zQoutfile;
- if (zQuser != NULL)
- s.zuser = zQuser;
- else
- s.zuser = "uucp";
- if (zmail != NULL && fQsuccess_ack)
- s.zoptions = "Cn";
- else
- s.zoptions = "C";
- s.ztemp = abtemp;
- s.imode = 0666;
- if (zmail != NULL && fQsuccess_ack)
- s.znotify = zmail;
- else
- s.znotify = "";
- s.cbytes = -1;
- s.zcmd = NULL;
- s.ipos = 0;
-
- ubuffree (zsysdep_spool_commands (qoutsys, BDEFAULT_UUX_GRADE,
- 1, &s));
- }
- }
-
- if (zerror != NULL)
- {
- (void) remove (zerror);
- ubuffree (zerror);
- }
-
- uqcleanup (zfile, iclean);
- }
-
- /* If we have enough disk space, save the data files so that the UUCP
- administrator can examine them. Send a mail message listing the
- saved files. */
-
- static int
- isave_files (qsys, zmail, zfile, iclean)
- const struct uuconf_system *qsys;
- const char *zmail;
- const char *zfile;
- int iclean;
- {
- long cspace;
- char *zsavecmd;
- char **pzsave;
- int c;
- int ifile;
- char *zsaveinput;
- const char **pz;
- int i;
-
- /* Save the files if there is 1.5 times the amount of required free
- space. */
- cspace = csysdep_bytes_free (zfile);
- if (cspace == -1)
- cspace = FREE_SPACE_DELTA;
- cspace -= qsys->uuconf_cfree_space + qsys->uuconf_cfree_space / 2;
- if (cspace < 0)
- return iclean;
-
- zsavecmd = zsysdep_save_failed_file (zfile);
- if (zsavecmd == NULL)
- return iclean;
-
- c = 1;
-
- pzsave = (char **) xmalloc (cQfiles * sizeof (char *));
- for (ifile = 0; ifile < cQfiles; ifile++)
- {
- if (azQfiles[ifile] != NULL)
- {
- ++c;
- pzsave[ifile] = zsysdep_save_failed_file (azQfiles[ifile]);
- if (pzsave[ifile] == NULL)
- {
- ubuffree (zsavecmd);
- for (i = 0; i < ifile; i++)
- if (azQfiles[i] != NULL)
- ubuffree (pzsave[i]);
- xfree ((pointer) pzsave);
- return iclean;
- }
- }
- }
-
- zsaveinput = NULL;
- if ((iclean & REMOVE_QINPUT) != 0
- && fsysdep_file_exists (zQinput))
- {
- zsaveinput = zsysdep_save_failed_file (zQinput);
- if (zsaveinput == NULL)
- {
- ubuffree (zsavecmd);
- for (i = 0; i < cQfiles; i++)
- if (azQfiles[i] != NULL)
- ubuffree (pzsave[i]);
- xfree ((pointer) pzsave);
- return iclean;
- }
- }
-
- pz = (const char **) xmalloc ((20 + 2 * cQfiles) * sizeof (char *));
- i = 0;
-
- pz[i++] = "A UUCP execution request failed:\n\t";
- pz[i++] = zQcmd;
- if (zmail != NULL)
- {
- pz[i++] = "\nThe request was made by\n\t";
- pz[i++] = zmail;
- }
- else
- {
- pz[i++] = "\nThe request came from system\n\t";
- pz[i++] = qsys->uuconf_zname;
- }
- if (c == 1 && zsaveinput == NULL)
- pz[i++] = "\nThe following file has been saved:\n\t";
- else
- pz[i++] = "\nThe following files have been saved:\n\t";
- pz[i++] = zsavecmd;
- for (ifile = 0; ifile < cQfiles; ifile++)
- {
- if (azQfiles[ifile] != NULL)
- {
- pz[i++] = "\n\t";
- pz[i++] = pzsave[ifile];
- }
- }
- if (zsaveinput != NULL)
- {
- pz[i++] = "\n\t";
- pz[i++] = zsaveinput;
- }
- pz[i++] = "\n";
-
- (void) fsysdep_mail (OWNER,
- "UUCP execution files saved after failure",
- i, pz);
-
- xfree ((pointer) pz);
-
- ubuffree (zsavecmd);
- for (ifile = 0; ifile < cQfiles; ifile++)
- if (azQfiles[ifile] != NULL)
- ubuffree (pzsave[ifile]);
- xfree ((pointer) pzsave);
- ubuffree (zsaveinput);
-
- return iclean &~ (REMOVE_FILE | REMOVE_NEEDED);
- }
-
- /* Clean up the results of uqdo_xqt_file. */
-
- static void
- uqcleanup (zfile, iflags)
- const char *zfile;
- int iflags;
- {
- int i;
-
- DEBUG_MESSAGE2 (DEBUG_SPOOLDIR,
- "uqcleanup: %s, %d", zfile, iflags);
-
- if (zQunlock_file != NULL)
- {
- (void) fsysdep_unlock_uuxqt_file (zQunlock_file);
- zQunlock_file = NULL;
- }
-
- if ((iflags & REMOVE_FILE) != 0)
- (void) remove (zfile);
-
- if ((iflags & REMOVE_NEEDED) != 0)
- {
- for (i = 0; i < cQfiles; i++)
- {
- if (azQfiles[i] != NULL)
- (void) remove (azQfiles[i]);
- }
- if ((iflags & REMOVE_QINPUT) != 0)
- (void) remove (zQinput);
- }
-
- if ((iflags & FREE_QINPUT) != 0)
- ubuffree (zQinput);
-
- if ((iflags & FREE_OUTPUT) != 0)
- ubuffree (zQoutput);
- if ((iflags & FREE_MAIL) != 0)
- ubuffree (zQmail);
-
- if (fQunlock_directory)
- {
- (void) fsysdep_unlock_uuxqt_dir (iQlock_seq);
- fQunlock_directory = FALSE;
- }
-
- for (i = 0; i < cQfiles; i++)
- {
- ubuffree (azQfiles[i]);
- ubuffree (azQfiles_to[i]);
- }
-
- ubuffree (zQoutfile);
- ubuffree (zQoutsys);
- ubuffree (zQrequestor);
-
- if (azQargs != NULL)
- {
- for (i = 0; azQargs[i] != NULL; i++)
- ubuffree (azQargs[i]);
- xfree ((pointer) azQargs);
- azQargs = NULL;
- }
-
- xfree ((pointer) zQcmd);
- zQcmd = NULL;
-
- xfree ((pointer) azQfiles);
- azQfiles = NULL;
-
- xfree ((pointer) azQfiles_to);
- azQfiles_to = NULL;
- }
-
- /* Check whether forwarding is permitted. */
-
- static boolean
- fqforward (zfile, pzallowed, zlog, zmail)
- const char *zfile;
- char **pzallowed;
- const char *zlog;
- const char *zmail;
- {
- const char *zexclam;
-
- zexclam = strchr (zfile, '!');
- if (zexclam != NULL)
- {
- size_t clen;
- char *zsys;
- boolean fret;
-
- clen = zexclam - zfile;
- zsys = zbufalc (clen + 1);
- memcpy (zsys, zfile, clen);
- zsys[clen] = '\0';
-
- fret = FALSE;
- if (pzallowed != NULL)
- {
- char **pz;
-
- for (pz = pzallowed; *pz != NULL; pz++)
- {
- if (strcmp (*pz, "ANY") == 0
- || strcmp (*pz, zsys) == 0)
- {
- fret = TRUE;
- break;
- }
- }
- }
-
- if (! fret)
- {
- ulog (LOG_ERROR, "Not permitted to forward %s %s (%s)",
- zlog, zsys, zQcmd);
-
- if (zmail != NULL && ! fQno_ack)
- {
- int i;
- const char *az[20];
-
- i = 0;
- az[i++] = "Your execution request failed because you are";
- az[i++] = " not permitted to forward files\n";
- az[i++] = zlog;
- az[i++] = " the system\n\t";
- az[i++] = zsys;
- az[i++] = "\n";
- az[i++] = "Execution requested was:\n\t";
- az[i++] = zQcmd;
- az[i++] = "\n";
-
- (void) fsysdep_mail (zmail, "Execution failed", i, az);
- }
- }
-
- ubuffree (zsys);
-
- return fret;
- }
-
- return TRUE;
- }
-