home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / auucp+-1.02 / fuucp_plus_src.lzh / batch.c next >
Encoding:
C/C++ Source or Header  |  1990-11-21  |  7.6 KB  |  332 lines

  1. /*
  2.  * This software is Copyright 1985, 1989 by Rick Adams.
  3.  *
  4.  * Permission is hereby granted to copy, reproduce, redistribute or
  5.  * otherwise use this software as long as: there is no monetary
  6.  * profit gained specifically from the use or reproduction or this
  7.  * software, it is not sold, rented, traded or otherwise marketed, and
  8.  * this copyright notice is included prominently in any copy
  9.  * made.
  10.  *
  11.  * The author make no claims as to the fitness or correctness of
  12.  * this software for any use whatsoever, and it is provided as is. 
  13.  * Any use of this software is at the user's own risk.
  14.  *
  15.  * Batch: program to batch a list of news articles into an unbatch script.
  16.  * Usage: /usr/lib/news/batch listfile [bytecount]
  17.  *  where listfile is a file containing a list, one per line, of full
  18.  *  path names of files containing articles, e.g. as produced by the F
  19.  *  transmission option in the sys file.
  20.  *  bytecount is the maximum number of bytes to output before exiting
  21.  * Output is placed on standard output.
  22.  *
  23.  * Intended usage:
  24.  *
  25.  *    With the shellfile "sendbatch", with machine names as arguments:
  26.  *         e.g
  27.  *        sendbatch rlgvax seismo
  28.  *
  29.  * This would be invoked every hour or two from crontab.
  30.  *
  31.  * 10-Jul-90 Made somee changes to get it work with AmigaUUCP Plus
  32.  *           Ingo Feulner
  33.  */
  34.  
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include <errno.h>
  41. #include <fcntl.h>
  42. #include "uucp:src/include/config.h"
  43.  
  44. #include <exec/types.h>
  45. #include <libraries/dos.h>
  46. #include <proto/dos.h>
  47.  
  48. #define index strchr
  49. #define BUFLEN 256
  50. #define FIB      FileInfoBlock
  51.  
  52. /* version string for 2.0 */
  53. static char *version20 = "$VER: batch 1.00 (5 Aug 90)\n\r";
  54.  
  55. void logerror();
  56. int  stat();
  57.  
  58. struct stat sbuf;
  59.  
  60. extern int errno;
  61. extern char *sys_errlist[];
  62.  
  63. main(argc,argv)
  64. char **argv;
  65. {
  66.     FILE *fd, *nfd;
  67.         char *spooldir;   /* News Directory */
  68.     int c;
  69.     long n;
  70.     char path[256];
  71.     char *cp;
  72.     char *fdstatus;
  73.     long maxbytes, nbytes;
  74.     long atol();
  75.     int spooldirlen;
  76.     char fname[512];
  77.     char workfile[512];
  78.     char cbuf[BUFSIZ];
  79.     char *index(), *fgets();
  80.  
  81.     if (argc < 2)
  82.         {
  83.         fprintf(stderr, "AmigaUUCP Plus: batch 1.00 (5 Aug 90)\n");
  84.         fprintf(stderr, "Written by Ingo Feulner\n\n");
  85.         fprintf(stderr, "Usage: batch listfile [bytecount]\n");
  86.         exit(1);
  87.     }
  88.  
  89.     getcwd(path, 255); /* Get current directory */
  90.  
  91.         spooldir    = GetConfigDir(UUNEWS);
  92.         spooldirlen = strlen(spooldir);
  93.  
  94.     /*
  95.      * Rename real file to a work name to avoid race conditions.
  96.      * If workfile exists skip the rename in order
  97.      * to recover from a crash w/o losing anything.
  98.      */
  99.  
  100.     if (chdir(spooldir) < 0)
  101.         {
  102.         logerror("chdir(%s): %s", spooldir, sys_errlist[errno]);
  103.         exit(1);
  104.     }
  105.  
  106.     (void) strcpy(workfile, argv[1]);
  107.     (void) strcat(workfile, ".work");
  108.     if (access(workfile, 0) < 0)
  109.         {
  110.         if (access(argv[1], 0) < 0 && errno == ENOENT)
  111.             exit(0);    /* no news */
  112.         if (rename(argv[1], workfile) < 0)
  113.                 {
  114.             logerror("rename(%s,%s) %s", argv[1], workfile,
  115.                 sys_errlist[errno]);
  116.             exit(1);
  117.         }
  118.     }
  119.     fd = fopen(workfile, "r");
  120.     if (fd == NULL)
  121.         {
  122.         logerror("fopen(%s,r) %s", workfile, sys_errlist[errno]);
  123.         exit(1);
  124.     }
  125.  
  126.     if (argc > 2)
  127.         maxbytes = atol(argv[2]);
  128.     else
  129.         maxbytes = 100000000L; /* backwards compatible */
  130.     nbytes = 0;
  131.     while ((fdstatus = fgets(fname, sizeof fname, fd)) != NULL)
  132.         {
  133.         cp = index(fname, '\n');
  134.         if (cp)
  135.             *cp = '\0';
  136.         if (fname[0] == '\0')
  137.             continue;
  138.         /* this optimization speeds up batching significantly */
  139.         if (fname[0] == '/' && fname[spooldirlen-1] == '/')
  140.             nfd = fopen(&fname[spooldirlen], "r");
  141.         else
  142.             nfd = fopen(fname, "r");
  143.             
  144.         if (nfd == NULL)
  145.                 {
  146.             perror(fname);
  147.             continue;
  148.         }
  149.         (void) stat(fname, &sbuf);
  150.         if (cp)
  151.             *cp = '\n';
  152.         if (sbuf.st_size == 0)
  153.                 {
  154.             (void) fclose(nfd);
  155.             continue;
  156.         }
  157.         nbytes += sbuf.st_size;
  158.         if (nbytes > maxbytes && nbytes != sbuf.st_size)
  159.             break;
  160.         printf("#! rnews %ld\n", (long)sbuf.st_size);
  161.         /* guess length of #! rnews string */
  162.         nbytes += 13;
  163.         n = 0;
  164.         while (c = fread(cbuf, 1, sizeof cbuf, nfd))
  165.                 {
  166.             fwrite(cbuf, 1, c, stdout);
  167.             n += c;
  168.         }
  169.         (void) fclose(nfd);
  170.         if (ferror(stdout))
  171.                 {
  172.             logerror("stdout write %s", sys_errlist[errno]);
  173.             exit(1);
  174.         }
  175.         (void) fflush(stdout);
  176.         if (n != sbuf.st_size) { /* paranoia */
  177.             logerror("%s, expected %ld bytes, got %ld", fname,
  178.                 n, sbuf.st_size);
  179.             /* breaking out of this early will end up resyncing
  180.                the batch files (isn't serendipity wonderful?) */
  181.             break;
  182.         }
  183.     }
  184.  
  185.     if (fdstatus != NULL)        /* exceeded maxbytes */
  186.         {
  187.         char tmpfile[512];
  188.  
  189.         (void) strcpy(tmpfile, argv[1]);
  190.         (void) strcat(tmpfile, ".tmp");
  191.             nfd = fopen(tmpfile, "w");
  192.         if (nfd == NULL)
  193.                 {
  194.             logerror("fopen(%s,w) %s", tmpfile, sys_errlist[errno]);
  195.             exit(1);
  196.         }
  197.  
  198.         do
  199.                 {
  200.             fputs(fname, nfd);
  201.         } while (fgets(fname, sizeof fname, fd) != NULL);
  202.         if (ferror(nfd))
  203.                 {
  204.             logerror("write(%s) %s", tmpfile, sys_errlist[errno]);
  205.             exit(1);
  206.         }
  207.         (void) fclose(nfd);
  208.         (void) fclose(fd);
  209.         /* will pick it up next time thru */
  210.  
  211.                 (void)remove(workfile);
  212.         if (rename(tmpfile, workfile) < 0)
  213.                 {
  214.             logerror("rename(%s,%s) %s", tmpfile, workfile,
  215.                 sys_errlist[errno]);
  216.             exit(1);
  217.         }
  218.     }        
  219.     else
  220.         {
  221.                 fclose(fd);
  222.         (void) remove(workfile);
  223.         }
  224.  
  225.     chdir(path);
  226.     exit(0);
  227.     /*NOTREACHED*/
  228. }
  229.  
  230. /*
  231.  * Log the given message, with printf strings and parameters allowed,
  232.  * on the log file, if it can be written.
  233.  */
  234. /* VARARGS1 */
  235. void logerror(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  236. char *fmt;
  237. long a1, a2, a3, a4, a5, a6, a7, a8, a9;
  238. {
  239.     FILE *logfile;
  240.         char *libdir;
  241.  
  242.     char lfname[BUFLEN];        /* the log file */
  243.     char bfr[BUFLEN];
  244.     char *logtime, *ctime(); 
  245.     time_t t;
  246.  
  247.         libdir = GetConfigDir(UULIB);
  248.  
  249.     (void) time(&t);
  250.     logtime = ctime(&t);
  251.     logtime[16] = 0;
  252.     logtime += 4;
  253.  
  254.     (void) sprintf(lfname, "%s/batch.errlog", libdir);
  255.  
  256.     (void) sprintf(bfr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  257.     fprintf(stderr, bfr);
  258.     if (access(lfname, 0) == 0 && (logfile = fopen(lfname, "a")) != NULL)
  259.         {
  260.         (void) lseek(fileno(logfile), 0L, 2);
  261.         fprintf(logfile, "%s\tbatch\t%s\n", logtime, bfr);
  262.         (void) fclose(logfile);
  263.     }
  264. }
  265.  
  266.  
  267. stat(char *filename, struct stat *statbuf)
  268. {
  269.     BPTR alock, parent;
  270.     struct FIB *fib;
  271.     int modes;
  272.     extern long timezone;
  273.  
  274.     if ((!statbuf) || (!filename))
  275.     {
  276.     errno = EFAULT;
  277.     return (-1);
  278.     }
  279.     if (alock = Lock(filename, ACCESS_READ))
  280.     {
  281.     if((fib = (struct FileInfoBlock *)malloc(sizeof(struct FIB))) == NULL)
  282.     {
  283.         UnLock(alock);
  284.         errno = ENOMEM;
  285.         return (-1);    /* malloc failed */
  286.     }
  287.     Examine(alock, fib);
  288.     if (!(parent = ParentDir(alock)))
  289.     {
  290.         statbuf->st_mode = 0700;
  291.         statbuf->st_prot = ~0xf;
  292.     }
  293.     else
  294.     {
  295.         UnLock(parent);
  296.         modes = (~fib->fib_Protection >> 1) & 0x7;
  297.         statbuf->st_mode = (modes << 6);
  298.         statbuf->st_prot = fib->fib_Protection;
  299.     }
  300.     if (fib->fib_EntryType > 0)
  301.         statbuf->st_mode |= S_IFDIR;
  302.     else
  303.         statbuf->st_mode |= S_IFREG;
  304.     statbuf->st_dev = 0;
  305.     statbuf->st_ino = 0;
  306.     statbuf->st_size = fib->fib_Size;
  307.     statbuf->st_rdev = fib->fib_DiskKey;
  308.     statbuf->st_gid = 0;
  309.     statbuf->st_uid = 0;
  310.  
  311.     /*
  312.      * getft() doesn't compensate for time zones.
  313.      */
  314.     statbuf->st_mtime = getft(filename) + timezone;
  315.     statbuf->st_nlink = 1;
  316.  
  317.     /*
  318.      * These next fields really only exist for Amiga tar's benefit
  319.      */
  320.     strcpy(statbuf->st_comment, fib->fib_Comment);
  321.     memcpy((char *) &(statbuf->st_date), (char *) &(fib->fib_Date),
  322.            sizeof(statbuf->st_date));
  323.     free(fib);
  324.     UnLock(alock);
  325.     return (0);
  326.     } else
  327.     {
  328.     errno = ENOENT;
  329.     return (-1);        /* couldn't access file */
  330.     }
  331. }
  332.