home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / uucico / uuxqt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-17  |  8.9 KB  |  509 lines

  1. /*
  2. **  UUXQT.C
  3. **    by William Loftus
  4. **
  5. **    Copyright 1988 by William Loftus, All Rights Reserved.
  6. **    Changes Copyright 1990, 1991 by Matthew Dillon, All Rights Reserved.
  7. **    Changes Copyright 1993, 1994 by Michael B. Smith, All Rights Reserved.
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <log.h>
  14. #include <errno.h>
  15. #include "version.h"
  16. #include "protos.h"
  17. #include <owndevunit.h>
  18.  
  19. IDENT (".21");
  20.  
  21. /* #define PROCDEBUG */
  22. /* PROCDEBUG also affects the LogLevel assignment below */
  23.  
  24. #ifdef PROCDEBUG
  25. #define D(x)        printf x
  26. #else
  27. #define D(x)
  28. #endif
  29.  
  30. static const char
  31.     ProgName [] = "UUXQT",
  32.     odu_name [] = { ODU_NAME };
  33. struct Library
  34.     *OwnDevUnitBase = NULL;
  35. int
  36.     UseSubDirs = 0,
  37.     numFiles = 0,
  38.     file_pointer,
  39.     LoError,
  40.     GloError = 0;
  41. char
  42.     *command = NULL,
  43.     *config  = NULL,
  44.     *sys     = NULL,
  45.     *name     = NULL,
  46.     *uuspool = NULL,
  47.     names [MAXFILES * 16],
  48.     *pointers [MAXFILES],
  49.     *xfile,
  50.     dfile [128],
  51.     cmd [2048 + 1024],
  52.     ccmd [256],
  53.     ccmd_args [2048],
  54.     buf [2048];
  55.  
  56. #define DELIM " \t\n\r"
  57.  
  58. char *xstrtok (char *, const char *);
  59. void myexit (void);
  60.  
  61. #ifdef __GNUC__
  62. #define __aligned
  63. #endif
  64.  
  65. int
  66. brk (void)
  67. {
  68.     return 0;
  69. }
  70.  
  71. int
  72. bp_strcmp (const void *s1, const void *s2)
  73. {
  74.     return strcmp (* ((char **) s1), * ((char **) s2));
  75. }
  76.  
  77. int
  78. work_scan (const char *which)
  79. {
  80.     int
  81.         count;
  82.  
  83.     file_pointer = 0;
  84.  
  85.     /* we are already in the correct directory so don't change it */
  86.     count = getfnl ("X.#?", names, sizeof (names), 0);
  87.  
  88.     if (count > 0) {
  89.         printf ("New files have arrived (%s).\n", which);
  90.  
  91.         if (strbpl (pointers, MAXFILES, names) != count) {
  92.             fprintf (stderr, "Too many execute files\n");
  93.             return 0;
  94.         }
  95.     }
  96.     else {
  97.         if (numFiles == 0)
  98.             printf ("No files to process (%s).\n", which);
  99.         return 0;
  100.     }
  101.  
  102.     qsort (pointers, count, sizeof (char *), bp_strcmp);
  103.  
  104.     return 1;
  105. }
  106.  
  107. char *
  108. work_next (void)
  109. {
  110.     char
  111.         *ptr;
  112.  
  113.     if (ptr = pointers [file_pointer])
  114.         ++file_pointer;
  115.     return ptr;
  116. }
  117.  
  118. int
  119. parse (char *x)
  120. {
  121.     BPTR
  122.         lock;
  123.     FILE
  124.         *fp;
  125.     char
  126.         *tmp;
  127.  
  128.     fp = fopen (x, "r");
  129.     if (!fp) {
  130.         ulog (-1, "Can't open %s", x);
  131.         fprintf (stderr, "Can't open %s\n", x);
  132.         return 0;
  133.     }
  134.  
  135.     while (fgets (buf, sizeof (buf), fp)) {
  136.         if (buf [0] == 'F') {
  137.             strcpy (dfile, xstrtok (&buf [1], DELIM));
  138.             continue;
  139.         }
  140.  
  141.         if (buf [0] == 'C') {
  142.             strcpy (ccmd, xstrtok (&buf[1], DELIM));
  143.             strcpy (ccmd_args, xstrtok (NULL, DELIM));
  144.             while (tmp = strtok (NULL, DELIM)) {
  145.                 strcat (ccmd_args, " ");
  146.                 strcat (ccmd_args, tmp);
  147.             }
  148.             continue;
  149.         }
  150.  
  151.         if (buf [0] == '\n')
  152.             continue;
  153.  
  154.         if (buf [0] == '#') {
  155.             ulog (10, "Ignored: %s", buf);
  156.             continue;
  157.         }
  158.  
  159.         if (tmp = strchr (buf, '\n'))
  160.             *tmp = '\0';
  161.         ulog (5, "Ignored: %s", buf);
  162.     }
  163.  
  164.     /*
  165.     **  If unable to find file it could be munge-cased
  166.     */
  167.     if (lock = Lock (dfile, SHARED_LOCK))
  168.         UnLock (lock);
  169.     else
  170.         mungecase_filename (dfile, dfile);
  171.  
  172.     ulog (5, "Command '%s', file '%s', args '%s'", ccmd, dfile, ccmd_args);
  173.  
  174.     if (command && strcmp (ccmd, command)) {
  175.         fclose (fp);
  176.         D (("ignored '%s' while looking for '%s'\n", ccmd, command));
  177.         return 0;
  178.     }
  179.     /*
  180.     **  FIXME:
  181.     **    Why do we ignore the arguments for everything except
  182.     **    RMAIL and CUNBATCH?
  183.     **
  184.     **    Why do we even HAVE a cunbatch when such a thing doesn't
  185.     **    exist?
  186.     **
  187.     **    Why don't we have a L.Cmds file approach?
  188.     */
  189.  
  190.     if (strncmp (ccmd, "rmail", 5) == 0) {
  191.         sprintf (cmd, "%s <%s %s", GetConfigProgram (RMAIL), dfile, ccmd_args);
  192.     }
  193.     else
  194.     if (strncmp (ccmd, "cunbatch", 8) == 0) {
  195.         sprintf (cmd, "%s <%s %s", GetConfigProgram (CUNBATCH), dfile, ccmd_args);
  196.     }
  197.     else
  198.     if (strncmp (ccmd, "rnews", 5) == 0) {
  199.         /* RNEWS likes it better when input isn't stdin */
  200.         sprintf (cmd, "%s %s", GetConfigProgram (RNEWS), dfile);
  201.     }
  202.     else
  203.     if (strncmp (ccmd, "rsmtp", 5) == 0) {
  204.         sprintf (cmd, "%s <%s", GetConfigProgram (RSMTP), dfile);
  205.     }
  206.     else
  207.     if (strncmp (ccmd, "rcsmtp", 5) == 0) {
  208.         sprintf (cmd, "%s <%s", GetConfigProgram (RCSMTP), dfile);
  209.     }
  210.     else
  211.     if (strncmp (ccmd, "rgsmtp", 5) == 0) {
  212.         sprintf (cmd, "%s <%s", GetConfigProgram ("RGSMTP"), dfile);
  213.     }
  214.     else
  215.     if (strnicmp (ccmd, "rlharc", 6) == 0) {
  216.         sprintf (cmd, "%s %s", GetConfigProgram ("RLharc"), dfile);
  217.     }
  218.     else {
  219.         fprintf (stderr, "Unknown command request %s  - Operation Aborted -\n", ccmd);
  220.         LoError = 1;
  221.     }
  222.  
  223.     fclose (fp);
  224.     return 1;
  225. }
  226.  
  227. int
  228. process_cmd (const char *cmd)
  229. {
  230.     int
  231.         i,
  232.         syserr;
  233.     char
  234.         *p;
  235.  
  236.     syserr = system (cmd);
  237.  
  238.     if (syserr == 0)
  239.         /* no problems */
  240.         return 0;
  241.  
  242.     ulog (-1, "Execute Error: rc=%d cmd=%s", syserr, cmd);
  243.  
  244.     LoError = 1;
  245.     p = strdup (xfile);
  246.  
  247.     if (!p) {
  248.         ulog (-1, "Ran out of memory trying to rename %s", xfile);
  249.         return 30;
  250.     }
  251.  
  252.     for (i = strlen (p); i >= 0; --i) {
  253.         if (p [i] == '/' || p [i] ==':')
  254.             break;
  255.     }
  256.     ++i;
  257.  
  258.     if ((p [i] == 'X') || (p [i] == 'x')) {
  259.         p [i] = 'E';
  260.         if (rename (xfile, p) == 0)
  261.             ulog (-1, "Renamed %s to %s", xfile, p);
  262.         else
  263.             ulog (-1, "Unable to rename %s to %s (Errno=%d, IoErr()=%ld)", xfile, p, errno, IoErr ());
  264.     }
  265.     else {
  266.         ulog (-1, "Didn't try to rename '%s'", p);
  267.     }
  268.  
  269.     free (p);
  270.  
  271.     return syserr;
  272. }
  273.  
  274. void
  275. process_directory (const char *which)
  276. {
  277.     if (UseSubDirs && strchr (which, ':') == 0 && strchr (which, '/') == 0) {
  278.         static char
  279.             path [256];
  280.         int
  281.             i;
  282.  
  283.         i = strlen (uuspool);
  284.         if (uuspool [i - 1] == ':' || uuspool [i - 1] == '/')
  285.             i = 1;
  286.         else
  287.             i = 0;
  288.  
  289.         sprintf (path, "%s%s%s", uuspool, i ? "" : "/", which);
  290.         D (("dir (built) %s\n", path));
  291.         safe_chdir (path);
  292.     }
  293.     else {
  294.         D (("dir (arg) %s\n", which));
  295.         safe_chdir (which);
  296.     }
  297.  
  298.     while (work_scan (which)) {
  299.         while (xfile = work_next ()) {
  300.             LoError = 0;
  301.             ++numFiles;
  302.             LockFile (xfile);
  303.             if (parse (xfile) && LoError == 0) {
  304.                 if (process_cmd (cmd) == 0) {
  305.                     remove (xfile);
  306.                     remove (dfile);
  307.                 }
  308.             }
  309.             UnLockFile (xfile);
  310.             if (LoError)
  311.                 GloError++;
  312.         }
  313.     }
  314.  
  315.     return;
  316. }
  317.  
  318. void
  319. usage (void)
  320. {
  321.     fprintf (stderr, "usage: %s [-c command] [-s system]\n", name);
  322.     exit (30);
  323. }
  324.  
  325. int
  326. main (int ac, char **av)
  327. {
  328.     char
  329.         *tmp;
  330.  
  331.     if (ac == 0)
  332.         exit (10);
  333.  
  334.     LogProgram = ProgName;
  335.     name = av [0];
  336.  
  337. #ifdef PROCDEBUG
  338.     /* normally zero */
  339.     LogLevel = 99;
  340. #endif
  341.  
  342.     if (ac == 2 && *av [1] != '-')
  343.         sys = av [1];
  344.     else {
  345.         int
  346.             i;
  347.         char
  348.             *debug;
  349.  
  350.         for (i = 1; i < ac; i++) {
  351.             tmp = av [i];
  352.             if (*tmp != '-')
  353.                 usage ();
  354.             tmp++;
  355.  
  356.             switch (*tmp) {
  357.                 case 'c':
  358.                     if (command) {
  359.                         fprintf (stderr, "You may only specify -c once\n");
  360.                         exit (20);
  361.                     }
  362.  
  363.                     tmp++;
  364.                     if (*tmp)
  365.                         command = tmp;
  366.                     else
  367.                         command = av [++i];
  368.                     D (("set command '%s'\n", command));
  369.                     break;
  370.  
  371.                 case 'I':
  372.                     if (config) {
  373.                         fprintf (stderr, "You may only specify -I once\n");
  374.                         exit (20);
  375.                     }
  376.  
  377.                     tmp++;
  378.                     if (*tmp)
  379.                         config = tmp;
  380.                     else
  381.                         config = av [++i];
  382.                     D (("set config '%s'\b", config));
  383.                     /* FIXME: support alternate configuration files */
  384.                     fprintf (stderr, "Warning: The alternate configuration file you specified will be ignored\n");
  385.                     break;
  386.  
  387.                 case 's':
  388.                     if (sys) {
  389.                         fprintf (stderr, "You may only specify -s once\n");
  390.                         exit (20);
  391.                     }
  392.  
  393.                     tmp++;
  394.                     if (*tmp)
  395.                         sys = tmp;
  396.                     else
  397.                         sys = av [++i];
  398.                     D (("set sys '%s'\n", sys));
  399.                     break;
  400.  
  401.                 case 'x':
  402.                     tmp++;
  403.                     if (*tmp)
  404.                         debug = tmp;
  405.                     else
  406.                         debug = av [++i];
  407.                     D (("ignored debug '%s'\n", debug));
  408.                     LogLevel = 5;
  409.                     /* FIXME: implement debug per Taylor? Maybe, but probably not. */
  410.                     fprintf (stderr, "Warning: your '-x %s' is being ignored\n", debug);
  411.                     break;
  412.  
  413.                 default:
  414.                     usage ();
  415.             }
  416.         }
  417.     }
  418.  
  419.     onbreak (brk);
  420.     atexit (myexit);
  421.  
  422.     if ((OwnDevUnitBase = OpenLibrary (odu_name, 0)) == NULL) {
  423.         fprintf (stderr, "Unable to open %s\n", odu_name);
  424.         exit (20);
  425.     }
  426.  
  427.     if (FileIsLocked (ProgName)) {
  428.         ulog (-1, "%s already running!", ProgName);
  429.         exit (0);
  430.     }
  431.     LockFile (ProgName);
  432.  
  433.     tmp = GetConfig (USESUBDIRS, "0");
  434.     if (*tmp == 'y' || *tmp == 'Y' || *tmp == '1')
  435.         UseSubDirs = 1;
  436.  
  437.     uuspool = GetConfigDir (UUSPOOL);
  438.  
  439.     if (sys && UseSubDirs == 0)
  440.         fprintf (stderr, "WARNING: system specification ignored\n");
  441.  
  442.     if (UseSubDirs == 0) {
  443.         process_directory (uuspool);
  444.     }
  445.     else {
  446.         if (sys) {
  447.             process_directory (sys);
  448.         }
  449.         else {
  450.             BPTR
  451.                 lock;
  452.             __aligned struct FileInfoBlock
  453.                 fib;
  454.  
  455.             /* check normal UUSPOOL first, and get into   */
  456.             /* the correct directory for the Lock() below */
  457.             process_directory (uuspool);
  458.  
  459.             /* process files in all subdirectories */
  460.             lock = Lock ("", ACCESS_READ);
  461.             if (lock && Examine (lock, &fib)) {
  462.                 while (ExNext (lock, &fib)) {
  463.                     if (fib.fib_DirEntryType < 0)
  464.                         continue;
  465.                     process_directory (fib.fib_FileName);
  466.                 }
  467.             }
  468.             if (lock)
  469.                 UnLock (lock);
  470.         }
  471.     }
  472.  
  473.     UnLockFile (ProgName);
  474.  
  475.     if (sys)
  476.         ulog (-1, "Processed %d files for %s", numFiles, sys);
  477.     else
  478.         ulog (-1, "Processed %d files", numFiles);
  479.     if (GloError)
  480.         ulog (-1, "%d files had errors", GloError);
  481.  
  482.     exit (0);
  483. }
  484.  
  485. char *
  486. xstrtok (char *s, const char *toks)
  487. {
  488.     char
  489.         *r;
  490.  
  491.     if (r = strtok (s, toks))
  492.         return r;
  493.  
  494.     return "";
  495. }
  496.  
  497. void
  498. myexit (void)
  499. {
  500.     UnLockFiles ();
  501.  
  502.     if (OwnDevUnitBase) {
  503.         CloseLibrary (OwnDevUnitBase);
  504.         OwnDevUnitBase = NULL;
  505.     }
  506.  
  507.     return;
  508. }
  509.