home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / cnews.tar / batch / batcher.c < prev    next >
C/C++ Source or Header  |  1994-11-27  |  3KB  |  147 lines

  1. /*
  2.  * batcher - send a bunch of news articles as an unbatch script
  3.  *
  4.  * Usage: batcher listfile
  5.  *
  6.  *    where listfile is a file containing a list, one per line, of
  7.  *    names of files containing articles.  Only the first
  8.  *    field of each line is looked at, so there can be more if needed
  9.  *    for other things.  Non-absolute pathnames are understood to lie
  10.  *    under the current directory; chdiring to the right place is the
  11.  *    parent's problem.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <signal.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include "fgetfln.h"
  20.  
  21. #ifndef READSIZE
  22. #define READSIZE 8192    /* allows for even 4.2 worst case file systems */
  23. #endif
  24. char buffer[READSIZE];
  25.  
  26. char *progname;
  27.  
  28. int debug = 0;            /* Debugging? */
  29.  
  30. char filler[] = "--- Filler to cover I/O error ---\n";
  31. #define    NFILL    (sizeof(filler)-1)
  32.  
  33. main(argc, argv)
  34. int argc;
  35. char *argv[];
  36. {
  37.     int c;
  38.     int errflg = 0;
  39.     extern int optind;
  40.     extern char *optarg;
  41.     register FILE *list;
  42.  
  43.     progname = argv[0];
  44.     while ((c = getopt(argc, argv, "x")) != EOF)
  45.         switch (c) {
  46.         case 'x':    /* Debugging. */
  47.             debug++;
  48.             break;
  49.         case '?':
  50.         default:
  51.             errflg++;
  52.             break;
  53.         }
  54.     if (errflg || optind < argc-1) {
  55.         (void) fprintf(stderr,
  56.             "Usage: batcher [listfile]\n");
  57.         exit(2);
  58.     }
  59.  
  60.     if (optind == argc-1) {
  61.         list = fopen(argv[optind], "r");
  62.         if (list == NULL)
  63.             error("unable to open `%s'", argv[optind]);
  64.         procfile(list, argv[optind]);
  65.     } else
  66.         procfile(stdin, "<standard input>");
  67.  
  68.     exit(0);
  69. }
  70.  
  71. /*
  72.  - procfile - process a file of article names
  73.  */
  74. procfile(list, filename)
  75. FILE *list;
  76. char *filename;
  77. {
  78.     char *article;
  79.  
  80.     if (debug)
  81.         fprintf(stderr, "procfile(%s)\n", filename);
  82.     while ((article = fgetline(list, (size_t *)NULL)) != NULL)
  83.         procart(article);
  84.  
  85.     if (!feof(list))
  86.         error("fgetline failure in `%s'", filename);
  87. }
  88.  
  89. /*
  90.  - procart - process an article
  91.  */
  92. procart(article)
  93. register char *article;
  94. {
  95.     register int artfile;
  96.     register int count;
  97.     struct stat sbuf;
  98.     register char *endp;
  99.  
  100.     if (debug)
  101.         fprintf(stderr, "procart(%s)\n", article);
  102.     endp = strchr(article, '\t');
  103.     if (endp == NULL)
  104.         endp = strchr(article, ' ');
  105.     if (endp != NULL)
  106.         *endp = '\0';
  107.     if (debug)
  108.         fprintf(stderr, "article is %s\n", article);
  109.  
  110.     artfile = open(article, 0);
  111.     if (artfile < 0) {
  112.         /*
  113.          * Can't read the article.  This isn't necessarily a
  114.          * disaster, since things like cancellations will do
  115.          * this.  Mumble and carry on.
  116.          */
  117.         if (debug)
  118.             warning("can't find `%s'", article);
  119.         return;
  120.     }
  121.  
  122.     if (fstat(artfile, &sbuf) < 0)
  123.         error("internal disaster, can't fstat", "");
  124.  
  125.     printf("#! rnews %ld\n", (long)sbuf.st_size);
  126.     while ((count = read(artfile, buffer, sizeof buffer)) > 0) {
  127.         if (fwrite(buffer, sizeof(char), count, stdout) != count)
  128.             error("write failure in `%s'", article);
  129.         sbuf.st_size -= count;
  130.     }
  131.     if (count < 0) {
  132.         /* tricky -- should avoid infinite loops on disk errors */
  133.         warning("read failure in `%s'", article);
  134.         while (sbuf.st_size >= NFILL) {
  135.             if (fwrite(filler, sizeof(char), NFILL, stdout) != NFILL)
  136.                 error("write failure in `%s'", article);
  137.             sbuf.st_size -= NFILL;
  138.         }
  139.         while (sbuf.st_size > 0) {
  140.             putc('\n', stdout);
  141.             sbuf.st_size--;
  142.         }
  143.     }
  144.  
  145.     (void) close(artfile);
  146. }
  147.