home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / snews-20.zip / UNBATCH.C < prev    next >
C/C++ Source or Header  |  1992-08-02  |  10KB  |  396 lines

  1. /*
  2.     SNEWS 2.0
  3.  
  4.     unbatch - quick and dirty news toss, no feeding of other sites
  5.  
  6.  
  7.     Copyright (C) 1991  John McCombs, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.                         PO Box 2708, Christchurch, NEW ZEALAND
  10.  
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License, version 1, as
  13.     published by the Free Software Foundation.
  14.  
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19.  
  20.     See the file COPYING, which contains a copy of the GNU General
  21.     Public License.
  22.  
  23.  
  24.  
  25.     USAGE: unbatch
  26.             -n  means decompress the first batch, then stop before tossing
  27.             -v  means verbose, tell what we are doing
  28.  
  29.  */
  30.  
  31.  
  32. #include "defs.h"
  33. #include "unbatch.h"
  34.  
  35. unsigned _stklen = 16384;
  36.  
  37. INFO my_stuff;
  38. char iobuf[IOBUFSIZE];
  39.  
  40. #ifdef system
  41. #undef system
  42. #endif
  43.  
  44.  
  45. /*------------------------------- main --------------------------------*/
  46. void main(int argc, char *argv[])
  47. {
  48.     FILE   *tmp_file;
  49.     static char name[256], in_name[256];
  50.     int    done, no_toss;
  51.     int    drive;
  52.     long   required_disk, disk_free;
  53.     struct stat st;
  54.     struct dfree df;
  55.     struct ffblk ffblk;
  56.  
  57.     fprintf(stderr, "UNBATCH: (%s)\n", VERSION);
  58.  
  59.     /* if TRUE, then just uncompress, don't unbatch */
  60.     no_toss = (argc == 2) && (strncmp("-n", argv[1], 2) == 0);
  61.  
  62.     if (!load_stuff()) {
  63.         fprintf(stderr, "Couldn't read rc info\n");
  64.         exit(1);
  65.     }
  66.  
  67.     load_active_file();
  68.     free_ng();
  69.  
  70.     sprintf(in_name, "%s*.*", my_stuff.incoming_dir);
  71.     done = findfirst(in_name, &ffblk, 0);
  72.     while (!done) {
  73.  
  74.         sprintf(name, "%s%s", my_stuff.incoming_dir, ffblk.ff_name);
  75.         printf("unbatch: processing %s\n", name);
  76.  
  77.         /*
  78.          Check for enough room. First, the batch in copied without
  79.          the header. Thus, the same space is needed again. Then,
  80.          the copied batch is uncompressed and read in over a pipe
  81.          which doesn't need extra space. Only space for the
  82.          articles is needed, slightly more than the uncompressed
  83.          size of the batch, say 3 times as much. We need a total
  84.          space of about four times the size of the original batch.
  85.      And this is only if no different device is used for the 
  86.      temp files.
  87.          */
  88.  
  89.         stat(name, &st);
  90.  
  91.         required_disk = st.st_size * 4L;
  92.  
  93.         drive = getdisk();
  94.         getdfree(drive+1, &df);
  95.         disk_free = (long)df.df_avail * (long)df.df_bsec * (long)df.df_sclus;
  96.  
  97.         if (disk_free < required_disk){
  98.             fprintf(stderr, "unbatch: %ld bytes of disk req'd to unpack batch\n");
  99.             exit(1);
  100.         }
  101.  
  102.         /* uncompress the news batch and return a pointer to the pipe */
  103.         if ((tmp_file = decode_batch(name, in_name, no_toss)) != NULL) {
  104.  
  105.             open_hist_file();
  106.             toss(tmp_file);
  107.             close_hist_file();
  108.  
  109.             if (in_name[0]) {
  110.           pclose(tmp_file);
  111.               unlink(in_name);
  112.         } 
  113.         else 
  114.               fclose(tmp_file);
  115.  
  116.             unlink(name);
  117.  
  118.         } else if (!no_toss) {
  119.             printf("could not unpack compressed news batch %s\n", name);
  120.             exit(1);
  121.         }
  122.  
  123.         done = findnext(&ffblk);
  124.  
  125.     }
  126.  
  127.     close_active_file();
  128. }
  129.  
  130.  
  131. /*--------------------------- unpack the batch ------------------------*/
  132. void save_message(LINE *spool, char *newsgroups, 
  133.           char *subject, char *msg_id)
  134. {
  135.     /*
  136.      *  For each newsgroup
  137.      *    - open the text file
  138.      *    - save the file pointer
  139.      *    - append the message to it
  140.      *    - close the file
  141.      *    - open the index file
  142.      *    - save the file pointer and the subject line
  143.      */
  144.     char buf[512], nglist[256], *group, *p;
  145.     FILE *out_file = NULL;
  146.     LINE *help;
  147.     ACTIVE *gp;
  148.     long where;
  149.     time_t t;
  150.     int saved = FALSE;
  151.  
  152.     time(&t);
  153.     nglist[0] = 0;
  154.  
  155.     p = strtok(newsgroups, " \r\n,:");
  156.     p = strtok(NULL, " \r\n,:");
  157.  
  158.     while (p != NULL) {
  159.  
  160.     group = p;
  161.     p = strtok(NULL, " \r\n,:");
  162.  
  163.     gp = find_news_group(group);
  164.     if (stricmp(gp->group, "junk") == 0 && (p != NULL || saved))
  165.       continue;
  166.  
  167.     out_file = open_out_file(group);
  168.     where = ftell(out_file);
  169.     help = spool;
  170.  
  171.     setvbuf(out_file, iobuf, _IOFBF, IOBUFSIZE);
  172.  
  173.     for (help = spool; help != NULL; help = help->next)
  174.         fputs(help->data, out_file);
  175.  
  176.     fprintf(out_file, "\n@@@@END\n");
  177.     fclose(out_file);
  178.   
  179.     out_file = open_index_file(group);
  180.     fprintf(out_file,"%08ld %08ld %09ld %s", where,
  181.         gp->hi_num, t, subject);
  182.     fclose(out_file);
  183.  
  184.     saved = TRUE;
  185.         if ( nglist[0] )
  186.           strcat(nglist, ",");
  187.         strcat(nglist, group);
  188.     }
  189.  
  190.     while (spool) {
  191.         help = spool;
  192.     spool = spool->next;
  193.     free(help->data);
  194.     free(help);
  195.     }
  196.  
  197.     add_hist_record(msg_id, nglist);
  198. }
  199.  
  200. void toss(FILE *tmp_file)
  201. {
  202.     /*
  203.      *  Toss it into the appropriate files.
  204.      */
  205.     LINE *spool = NULL, *help;
  206.     char buf[512], buf2[512], *p;
  207.     char newsgroups[256], subject[256], msg_id[256];
  208.     int  in_header, control;
  209.  
  210.     strcpy(msg_id, "");
  211.     strcpy(subject, "-- no subject --\n");
  212.     strcpy(newsgroups, "");
  213.  
  214.     rewind(tmp_file);
  215.     in_header = TRUE;
  216.     control = FALSE;
  217.  
  218.     /* read the file */
  219.     while (fgets(buf, 511, tmp_file) != NULL) {
  220.  
  221.         if (strstr(buf, "#! rnews") != NULL) {
  222.  
  223.             if (control)
  224.                 strcpy(newsgroups, "Newsgroups: control"); /* kludge */
  225.  
  226.         if (spool != NULL)
  227.             save_message(spool, newsgroups, subject, msg_id);
  228.  
  229.             strcpy(subject, "-- no subject --\n");
  230.             in_header = TRUE;
  231.             control = FALSE;
  232.         spool = NULL;
  233.  
  234.         } else {
  235.             /* flag the end of the header */
  236.             if (strcmp(buf, "\n") == 0)
  237.                 in_header = FALSE;
  238.  
  239.             /* save the newsgroups line */
  240.             if (in_header) {
  241.                 if (strnicmp(buf,"Message-ID:",11) == 0) {
  242.                     strcpy(buf2, buf);
  243.                     p = strtok(buf2, " \t\r\n");  p = strtok(NULL, " \t\r\n");
  244.                     strcpy(msg_id, p);
  245.                 }
  246.                 if (strnicmp(buf,"Newsgroups:",11) == 0)
  247.                     strcpy(newsgroups,buf);
  248.                 if (strnicmp(buf,"Subject:",8) == 0)
  249.                     strcpy(subject, buf+8);
  250.                 if (strnicmp(buf,"Control:",8) == 0)
  251.                     control = TRUE;
  252.                 /* add our system name to the path list */
  253.                 if (strnicmp(buf, "Path:", 5) == 0) {
  254.                     p = strtok(buf, " \t");
  255.                     p = strtok(NULL, " \t");
  256.             strcpy(buf2, p);
  257.                     sprintf(buf, "Path: %s!%s", my_stuff.my_site, buf2);
  258.                 }
  259.             }
  260.  
  261.         if (spool == NULL)
  262.         spool = help = (LINE *) xmalloc(sizeof(LINE));
  263.         else {
  264.             help->next = (LINE *) xmalloc(sizeof(LINE));
  265.         help = help->next;
  266.         }
  267.         help->next = NULL;
  268.         help->data = (char *) xmalloc(strlen(buf) + 1);
  269.         strcpy(help->data, buf);
  270.         }
  271.  
  272.     }
  273.  
  274.     /* process the last one */
  275.  
  276.     if (control)
  277.         strcpy(newsgroups, "Newsgroups: control"); /* kludge */
  278.  
  279.     if (spool != NULL)
  280.     save_message(spool, newsgroups, subject, msg_id);
  281. }
  282.  
  283.  
  284.  
  285.  
  286.  
  287. /*--------------------------- unpack the batch ------------------------*/
  288. FILE *decode_batch(char *fn, char *tn, int no_toss)
  289. {
  290.     /*
  291.      *  take the batch, strip off the !cunbatch, and feed the file to
  292.      *  uncompress, the opened uncompressed file is returned
  293.      */
  294.  
  295.     FILE *in_file, *out_file;
  296.     int res, buf_cnt, header;
  297.     char buf[1025], out[256];
  298.     char compr[16];
  299.     long pos;
  300.     short magic;
  301.  
  302.     buf_cnt = 0;
  303.     header = FALSE;
  304.     *tn = 0;
  305.  
  306.     /* open the batch file */
  307.     if ((in_file = fopen(fn, "rb")) == NULL) {
  308.         printf("batchfile %s could not be opened\n", fn);
  309.         return(NULL);
  310.     }
  311.  
  312.     if (fread(buf, 1, 12, in_file) == 0) {
  313.         printf("batch %s is inexplicably too small\n", fn);
  314.         return(NULL);
  315.     }
  316.  
  317.     if (memcmp(buf, "#! rnews ", 9) == 0) {
  318.         rewind(in_file);
  319.     return(in_file);
  320.     }
  321.  
  322.     if (memcmp(buf, "#! cunbatch\n", 12) == 0)
  323.         header = TRUE;
  324.     else if (memcmp(buf, "#! funbatch\n", 12) == 0)
  325.         header = TRUE;
  326.     else
  327.         rewind(in_file);
  328.  
  329.     pos = ftell(in_file);
  330.     fread(&magic, 1, sizeof(short), in_file);
  331.     fseek(in_file, pos, SEEK_SET);
  332.  
  333.     if (magic == COMPRESS)
  334.         strcpy(compr, "compress");
  335.     else if (magic == FREEZE)
  336.         strcpy(compr, "freeze");
  337.     else {
  338.         printf("batch %s has unknown compression type\n", fn);
  339.     return(NULL);
  340.     }
  341.  
  342.     if (header) {
  343.     /* open the compressed */
  344.     sprintf(tn, "%s\\unbatch.tmp", my_stuff.temp_name);
  345.     if ((out_file = fopen(tn, "wb")) == NULL) {
  346.         printf("cannot open output file %s\n", buf);
  347.         return(NULL);
  348.     }
  349.  
  350.     while ((res = fread(buf, 1, 1024, in_file)) > 0) {
  351.         fwrite(buf, 1, res, out_file);
  352.         buf_cnt++;
  353.     }
  354.  
  355.     fclose(in_file);
  356.     fclose(out_file);
  357.  
  358.     if (no_toss) {
  359.         sprintf(out, "%s\\n_XXXXXX", my_stuff.temp_name);
  360.         mktemp(out);
  361.         sprintf(buf, "%s -d <%s >%s", compr, tn, out);
  362.         system(buf);
  363.         unlink(tn);
  364.         return(NULL);
  365.     }
  366.  
  367.     /* open the uncompressed */
  368.     sprintf(buf, "%s -d <%s", compr, tn);
  369.     if ((out_file = popen(buf, "rb")) == NULL) {
  370.         printf("cannot open pipe to \"%s\"\n", buf);
  371.         return(NULL);
  372.     }
  373.     }
  374.     else {
  375.         fclose(in_file);
  376.     *tn = 0;
  377.       
  378.     if (no_toss) {
  379.         sprintf(out, "%s\\n_XXXXXX", my_stuff.temp_name);
  380.         mktemp(out);
  381.         sprintf(buf, "%s -d <%s >%s", compr, fn, out);
  382.         system(buf);
  383.         return(NULL);
  384.     }
  385.  
  386.     /* open the uncompressed */
  387.     sprintf(buf, "%s -d <%s", compr, fn);
  388.     if ((out_file = popen(buf, "rb")) == NULL) {
  389.         printf("cannot open pipe to \"%s\"\n", buf);
  390.         return(NULL);
  391.     }
  392.     }
  393.  
  394.     return(out_file);
  395. }
  396.