home *** CD-ROM | disk | FTP | other *** search
- /*
- ** UUXQT.C
- ** by William Loftus
- **
- ** Copyright 1988 by William Loftus, All Rights Reserved.
- ** Changes Copyright 1990 - 1991 by Matthew Dillon, All Rights Reserved.
- ** Changes Copyright 1993 - 1995 by Michael B. Smith, All Rights Reserved.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <log.h>
- #include <errno.h>
- #include "version.h"
- #include "protos.h"
- #include <owndevunit.h>
- #ifdef __SASC
- #include <dos.h>
- #endif
-
- IDENT (".22");
-
- /* #define PROCDEBUG */
- /* PROCDEBUG also affects the LogLevel assignment below */
-
- #ifdef PROCDEBUG
- #define D(x) printf x
- #else
- #define D(x)
- #endif
-
- static const char
- ProgName [] = "UUXQT",
- odu_name [] = { ODU_NAME };
- struct Library
- *OwnDevUnitBase;
- int
- UseSubDirs,
- numFiles,
- file_pointer,
- LoError,
- GloError;
- char
- *command,
- *config,
- *sys,
- *name,
- *uuspool,
- names [MAXFILES * 16],
- *pointers [MAXFILES],
- *xfile,
- dfile [128],
- cmd [2048 + 1024],
- ccmd [256],
- ccmd_args [2048],
- buf [2048];
-
- #define DELIM " \t\n\r"
-
- char *xstrtok (char *, const char *);
- void myexit (void);
-
- #ifdef __GNUC__
- #define __aligned
- #endif
-
- int
- brk (void)
- {
- return 0;
- }
-
- int
- bp_strcmp (const void *s1, const void *s2)
- {
- return strcmp (* ((char **) s1), * ((char **) s2));
- }
-
- int
- work_scan (const char *which)
- {
- int
- count;
-
- file_pointer = 0;
-
- /* we are already in the correct directory so don't change it */
- count = getfnl ("X.#?", names, sizeof (names), 0);
-
- if (count > 0)
- {
- printf ("New files have arrived (%s).\n", which);
-
- if (strbpl (pointers, MAXFILES, names) != count)
- {
- fprintf (stderr, "Too many execute files\n");
- return 0;
- }
- }
- else
- {
- if (numFiles == 0)
- printf ("No files to process (%s).\n", which);
- return 0;
- }
-
- qsort (pointers, count, sizeof (char *), bp_strcmp);
-
- return 1;
- }
-
- char *
- work_next (void)
- {
- char
- *ptr;
-
- if (ptr = pointers [file_pointer])
- ++file_pointer;
- return ptr;
- }
-
- int
- parse (char *x)
- {
- BPTR
- lock;
- FILE
- *fp;
- char
- *tmp;
-
- fp = fopen (x, "r");
- if (!fp)
- {
- ulog (-1, "Can't open %s", x);
- fprintf (stderr, "Can't open %s\n", x);
- return 0;
- }
-
- while (fgets (buf, sizeof (buf), fp))
- {
- if (buf [0] == 'F')
- {
- strcpy (dfile, xstrtok (&buf [1], DELIM));
- continue;
- }
-
- if (buf [0] == 'C')
- {
- strcpy (ccmd, xstrtok (&buf[1], DELIM));
- strcpy (ccmd_args, xstrtok (NULL, DELIM));
- while (tmp = strtok (NULL, DELIM))
- {
- strcat (ccmd_args, " ");
- strcat (ccmd_args, tmp);
- }
- continue;
- }
-
- if (buf [0] == '\n')
- continue;
-
- if (buf [0] == '#')
- {
- ulog (10, "Ignored: %s", buf);
- continue;
- }
-
- if (tmp = strchr (buf, '\n'))
- *tmp = '\0';
- ulog (5, "Ignored: %s", buf);
- }
-
- /*
- ** If unable to find file it could be munge-cased
- */
- if (lock = Lock (dfile, SHARED_LOCK))
- UnLock (lock);
- else
- mungecase_filename (dfile, dfile);
-
- ulog (5, "Command '%s', file '%s', args '%s'", ccmd, dfile, ccmd_args);
-
- if (command && strcmp (ccmd, command))
- {
- fclose (fp);
- D (("ignored '%s' while looking for '%s'\n", ccmd, command));
- return 0;
- }
- /*
- ** FIXME:
- ** Why do we ignore the arguments for everything except
- ** RMAIL and CUNBATCH?
- **
- ** Why do we even HAVE a cunbatch when such a thing doesn't
- ** exist?
- **
- ** Why don't we have a L.Cmds file approach?
- */
-
- if (strncmp (ccmd, "rmail", 5) == 0)
- {
- sprintf (cmd, "%s <%s %s", GetConfigProgram (RMAIL), dfile, ccmd_args);
- }
- else
- if (strncmp (ccmd, "cunbatch", 8) == 0)
- {
- sprintf (cmd, "%s <%s %s", GetConfigProgram (CUNBATCH), dfile, ccmd_args);
- }
- else
- if (strncmp (ccmd, "rnews", 5) == 0)
- {
- /* RNEWS likes it better when input isn't stdin */
- sprintf (cmd, "%s %s", GetConfigProgram (RNEWS), dfile);
- }
- else
- if (strncmp (ccmd, "rsmtp", 5) == 0)
- {
- sprintf (cmd, "%s <%s", GetConfigProgram (RSMTP), dfile);
- }
- else
- if (strncmp (ccmd, "rcsmtp", 5) == 0)
- {
- sprintf (cmd, "%s <%s", GetConfigProgram (RCSMTP), dfile);
- }
- else
- if (strncmp (ccmd, "rgsmtp", 5) == 0)
- {
- sprintf (cmd, "%s <%s", GetConfigProgram ("RGSMTP"), dfile);
- }
- else
- if (strnicmp (ccmd, "rlharc", 6) == 0)
- {
- sprintf (cmd, "%s %s", GetConfigProgram ("RLharc"), dfile);
- }
- else
- {
- fprintf (stderr, "Unknown command request %s - Operation Aborted -\n", ccmd);
- LoError = 1;
- fclose (fp);
- return 0;
- }
-
- fclose (fp);
- return 1;
- }
-
- int
- rename_xfile (void)
- {
- char
- *p = strdup (xfile);
- int
- i;
-
- if (!p)
- {
- ulog (-1, "Ran out of memory trying to rename %s", xfile);
- return 30;
- }
-
- for (i = strlen (p); i >= 0; --i)
- {
- if (p [i] == '/' || p [i] ==':')
- break;
- }
- ++i;
-
- if ((p [i] == 'X') || (p [i] == 'x'))
- {
- p [i] = 'E';
- if (rename (xfile, p) == 0)
- ulog (-1, "Renamed %s to %s", xfile, p);
- else
- ulog (-1, "Unable to rename %s to %s (Errno=%d, IoErr()=%ld)", xfile, p, errno, IoErr ());
- }
- else
- {
- ulog (-1, "Didn't try to rename '%s'", p);
- }
-
- free (p);
-
- return 0;
- }
-
- int
- process_cmd (const char *cmd)
- {
- int
- i,
- syserr;
-
- syserr = system (cmd);
-
- if (syserr == 0)
- {
- /* no problems */
- return 0;
- }
-
- ulog (-1, "Execute Error: rc=%d cmd=%s", syserr, cmd);
-
- LoError = 1;
-
- if (i = rename_xfile ())
- {
- return i;
- }
-
- return syserr;
- }
-
- void
- process_directory (const char *which)
- {
- if (UseSubDirs && strchr (which, ':') == 0 && strchr (which, '/') == 0)
- {
- static char
- path [256];
- int
- i;
-
- i = strlen (uuspool);
- if (uuspool [i - 1] == ':' || uuspool [i - 1] == '/')
- i = 1;
- else
- i = 0;
-
- sprintf (path, "%s%s%s", uuspool, i ? "" : "/", which);
- D (("dir (built) %s\n", path));
- safe_chdir (path);
- }
- else
- {
- D (("dir (arg) %s\n", which));
- safe_chdir (which);
- }
-
- while (work_scan (which))
- {
- while (xfile = work_next ())
- {
- LoError = 0;
- ++numFiles;
- LockFile (xfile);
- if (parse (xfile) && LoError == 0)
- {
- if (process_cmd (cmd) == 0)
- {
- remove (xfile);
- remove (dfile);
- }
- }
- else
- {
- rename_xfile ();
- }
- UnLockFile (xfile);
- if (LoError)
- GloError++;
- }
- }
-
- return;
- }
-
- void
- usage (void)
- {
- fprintf (stderr, "usage: %s [-c command] [-s system]\n", name);
- exit (30);
- }
-
- int
- main (int ac, char **av)
- {
- char
- *tmp;
-
- if (ac == 0)
- exit (10);
-
- LogProgram = ProgName;
- name = av [0];
-
- #ifdef PROCDEBUG
- /* normally zero */
- LogLevel = 99;
- #endif
-
- if (ac == 2 && *av [1] != '-')
- sys = av [1];
- else
- {
- int
- i;
- char
- *debug;
-
- for (i = 1; i < ac; i++)
- {
- tmp = av [i];
- if (*tmp != '-')
- usage ();
- tmp++;
-
- switch (*tmp)
- {
- case 'c':
- if (command)
- {
- fprintf (stderr, "You may only specify -c once\n");
- exit (20);
- }
-
- tmp++;
- if (*tmp)
- command = tmp;
- else
- command = av [++i];
- D (("set command '%s'\n", command));
- break;
-
- case 'I':
- if (config)
- {
- fprintf (stderr, "You may only specify -I once\n");
- exit (20);
- }
-
- tmp++;
- if (*tmp)
- config = tmp;
- else
- config = av [++i];
- D (("set config '%s'\b", config));
- /* FIXME: support alternate configuration files */
- fprintf (stderr, "Warning: The alternate configuration file you specified will be ignored\n");
- break;
-
- case 's':
- if (sys)
- {
- fprintf (stderr, "You may only specify -s once\n");
- exit (20);
- }
-
- tmp++;
- if (*tmp)
- sys = tmp;
- else
- sys = av [++i];
- D (("set sys '%s'\n", sys));
- break;
-
- case 'x':
- tmp++;
- if (*tmp)
- debug = tmp;
- else
- debug = av [++i];
- D (("ignored debug '%s'\n", debug));
- LogLevel = 5;
- /* FIXME: implement debug per Taylor? Maybe, but probably not. */
- fprintf (stderr, "Warning: your '-x %s' is being ignored\n", debug);
- break;
-
- default:
- usage ();
- }
- }
- }
-
- onbreak (brk);
- atexit (myexit);
-
- if ((OwnDevUnitBase = OpenLibrary (odu_name, 0)) == NULL)
- {
- fprintf (stderr, "Unable to open %s\n", odu_name);
- exit (20);
- }
-
- if (FileIsLocked (ProgName))
- {
- ulog (-1, "%s already running!", ProgName);
- exit (0);
- }
- LockFile (ProgName);
-
- tmp = GetConfig (USESUBDIRS, "0");
- if (*tmp == 'y' || *tmp == 'Y' || *tmp == '1')
- UseSubDirs = 1;
-
- uuspool = GetConfigDir (UUSPOOL);
-
- if (sys && UseSubDirs == 0)
- fprintf (stderr, "WARNING: system specification ignored\n");
-
- if (UseSubDirs == 0)
- {
- process_directory (uuspool);
- }
- else
- {
- if (sys)
- {
- process_directory (sys);
- }
- else
- {
- BPTR
- lock;
- __aligned struct FileInfoBlock
- fib;
-
- /* check normal UUSPOOL first, and get into */
- /* the correct directory for the Lock() below */
- process_directory (uuspool);
-
- /* process files in all subdirectories */
- lock = Lock ("", ACCESS_READ);
- if (lock && Examine (lock, &fib))
- {
- while (ExNext (lock, &fib))
- {
- if (fib.fib_DirEntryType < 0)
- continue;
- process_directory (fib.fib_FileName);
- }
- }
- if (lock)
- UnLock (lock);
- }
- }
-
- UnLockFile (ProgName);
-
- if (sys)
- ulog (-1, "Processed %d files for %s", numFiles, sys);
- else
- ulog (-1, "Processed %d files", numFiles);
- if (GloError)
- ulog (-1, "%d files had errors", GloError);
-
- exit (0);
- }
-
- char *
- xstrtok (char *s, const char *toks)
- {
- char
- *r;
-
- if (r = strtok (s, toks))
- return r;
-
- return "";
- }
-
- void
- myexit (void)
- {
- UnLockFiles ();
-
- if (OwnDevUnitBase)
- {
- CloseLibrary (OwnDevUnitBase);
- OwnDevUnitBase = NULL;
- }
-
- return;
- }
-