home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 1.91
-
- unbatch - quick and dirty news toss, no feeding of other sites
-
-
- Copyright (C) 1991 John McCombs, Christchurch, NEW ZEALAND
- john@ahuriri.gen.nz
- PO Box 2708, Christchurch, NEW ZEALAND
-
- Modifications copyright (C) 1993 Daniel Fandrich
- <dan@fch.wimsey.bc.ca> or CompuServe 72365,306
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 1, as
- published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- See the file COPYING, which contains a copy of the GNU General
- Public License.
-
-
- Source is formatted with a tab size of 4.
-
-
- USAGE: unbatch
- -n means decompress the first batch, then stop before tossing
- -v means verbose, tell what we are doing NOT IMPLEMENTED
- -x n debug level -- higher numbers give more info
-
- */
-
-
- #include "defs.h"
- #include "unbatch.h"
- #include <process.h>
- #include <ctype.h>
-
- #define BUFFSIZE 16000
- #define BATCH_HEADER "#! cunbatch\n"
- #define NO_SUBJECT "-- no subject --\n" /*"<none>\n"*/
-
- unsigned _stklen = 16384;
- char *inbuf = NULL;
- char *outbuf = NULL;
- int debug = 0;
-
- INFO my_stuff;
-
-
- /*------------------------------- main --------------------------------*/
- int main(int argc, char *argv[])
- {
- FILE *tmp_file;
- static char name[256], in_name[256];
- int done, no_toss;
- /* int drive;
- long required_disk, disk_free;
- struct stat st;
- struct dfree df;
- */
- struct ffblk ffblk;
-
- signal(SIGINT, sig_break); /* turn control-break off */
-
- fprintf(stderr, "UNBATCH: (%s)\n\n", VERSION);
-
- /* if TRUE, then just uncompress, don't unbatch */
-
- /*
- inbuf = malloc(BUFFSIZE);
- outbuf = malloc(BUFFSIZE);
-
- if (!inbuf || !outbuf) {
- fprintf(stderr, "unbatch: not enough memory to set file buffers");
- exit(1);
- } */
-
- if ((argc > 1) && ((argv[1][0] == '-') || (argv[1][0] == '/')) &&
- ((argv[1][1] == '?') || (argv[1][1] == 'h'))) {
- printf("Usage: unbatch [-n] [-x debug]\n");
- exit(2);
- }
-
- no_toss = (argc >= 2) && (strncmp("-n", argv[1], 2) == 0);
- if ((argc >= 3+no_toss) && (strcmp("-x", argv[1+no_toss]) == 0))
- debug = atoi(argv[2+no_toss]); /* set debug level */
-
- if (debug >= 1)
- printf("loading config... ");
- if (!load_stuff()) {
- fprintf(stderr, "unbatch: can't read rc info\n");
- exit(1);
- }
- if (debug >= 1)
- printf("loading active... ");
- load_active_file();
- if (debug >= 1)
- printf("loading history... ");
- load_history_list();
- if (debug >= 1)
- printf("\n\n");
-
- sprintf(in_name, "%s*.*", my_stuff.incoming_dir);
- done = findfirst(in_name, &ffblk, 0);
- while (!done && !break_hit) {
-
- sprintf(name, "%s%s", my_stuff.incoming_dir, ffblk.ff_name);
- printf("unbatch: processing %s\n", name);
-
- /*
- * Check for enough room. We need:
- *
- * - more than twice the size of the batch for uncompressed
- * batch, say 2.8
- *
- * - space for the articles.
- *
- * For example a 100k batch may require 280kb for the uncompressed
- * batch, then another 280 kb for the articles.
- */
- /*
- stat(name, &st);
-
- required_disk = (st.st_size*2.8) * 2;
-
- drive = getdisk();
- getdfree(drive+1, &df);
- disk_free = (long)df.df_avail * (long)df.df_bsec * (long)df.df_sclus;
-
- if (disk_free < required_disk){
- fprintf(stderr, "unbatch: %ld bytes of disk req'd to unpack batch\n");
- exit(1);
- }
- */
-
- /* uncompress the news batch and return a pointer to the temp file */
- if ((tmp_file = decode_batches(name, no_toss)) != NULL) {
-
- open_hist_file();
- toss(tmp_file);
- close_hist_file();
- fclose(tmp_file);
-
- unlink(name); /* kill the batch */
- sprintf(name, "%s", my_stuff.temp_name);
- unlink(name);
-
- } else {
- fprintf(stderr, "unbatch: could not unpack compressed news batch %s\n", name);
- exit(1);
- }
-
- done = findnext(&ffblk);
-
- } /* while */
-
- close_active_file();
- if (break_hit) {
- fprintf(stderr, "unbatch: aborting due to ctrl-break\n");
- return 2;
- }
-
- return 0;
- }
-
-
-
-
-
-
-
- /*--------------------------- unpack the batch ------------------------*/
- void toss(FILE *tmp_file)
- {
- /*
- * Toss it into the appropriate files.
- *
- * TODO:
- * - badly structured, sort it out
- */
-
- /* make these static to avoid chewing up large amounts of stack */
- static char buf[1024], msg[256], subject[256], msg_id[256];
- static char newsgroups[1024], nglist[1024];
-
- FILE *out_file = NULL;
- FILE *spool_file = NULL;
- char *p;
- char junk_group[] = "junk";
- char tempname[81];
- long where;
- ACTIVE *gp;
- time_t t;
- int /*already_junked,*/ in_header, posted;
-
- strcpy(msg_id, "");
- strcpy(subject, NO_SUBJECT);
- strcpy(newsgroups, "");
-
- rewind(tmp_file);
- sprintf(tempname, "%sitem%04x.tmp", my_stuff.temp_str, getpid());
- time(&t);
- in_header = TRUE;
-
- /* read the file */
- while (fgets(buf, 511, tmp_file) != NULL) {
-
- if ((strncmp(buf, "#! rnews ", 9) == 0) && isdigit(buf[9])) {
-
- if (strlen(newsgroups) != 0) { /* we've read in an article */
- if (debug >= 2)
- printf("----- new article %s\n", msg_id);
-
- if (find_msg_id(msg_id) != NULL) {
- if (debug >= 1)
- printf("discarding duplicate article %s\n", msg_id);
- } else {
-
- posted = 0;
- strcpy(nglist, newsgroups+11);
- strtok(newsgroups, " \r\n,:");
- p = strtok(NULL, " \r\n,:");
-
- /*
- * For each newsgroup
- * - open the text file
- * - save the file pointer
- * - append the message to it
- * - close the file
- * - open the index file
- * - save the file pointer and the subject line
- */
-
- while (p != NULL) { /* post to each group in Newsgroups: */
-
- if (strcmp(find_news_group(p)->group, junk_group) != 0) {
- out_file = open_out_file(p);
- if (debug >= 2)
- printf("storing article in %s\n", p);
- posted = 1;
- where = ftell(out_file);
- rewind(spool_file);
- while (fgets(buf, 511, spool_file) != NULL)
- fputs(buf, out_file);
- fprintf(out_file, "\n@@@@END\n");
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write article file\n");
- exit(1);
- }
-
- out_file = open_index_file(p);
- gp = find_news_group(p);
- fprintf(out_file,"%08ld %08ld %09ld %s", where,
- gp->hi_num, t, subject);
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write index file\n");
- exit(1);
- }
- } else
- if (debug >= 2)
- printf("group %s doesn't exist\n", p);
- p = strtok(NULL, " \r\n,:");
- } /* while */
-
- if (!posted) {
- if (debug >= 1)
- printf("junking article %s\n", msg_id);
- out_file = open_out_file(junk_group);
- if (out_file) {
- where = ftell(out_file);
- rewind(spool_file);
- while (fgets(buf, 511, spool_file) != NULL)
- fputs(buf, out_file);
- fprintf(out_file, "\n@@@@END\n");
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write article file\n");
- exit(1);
- }
-
- out_file = open_index_file(junk_group);
- gp = find_news_group(junk_group);
- fprintf(out_file,"%08ld %08ld %09ld %s", where,
- gp->hi_num, t, subject);
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write index file\n");
- exit(1);
- }
- }
- else {
- /* will never get to this point because open_out_file() aborts if no junk */
- fprintf(stderr,"\nunbatch: junk group *must* exist!");
- exit(1);
- }
- } /* if */
- add_hist_record(msg_id, nglist);
-
- } /* if */
- if (fclose(spool_file)) {
- fprintf(stderr, "unbatch: can't write spool file\n");
- exit(1);
- }
- } /* if */
-
- strcpy(subject, NO_SUBJECT);
- in_header = TRUE;
-
- if ((spool_file = fopen(tempname, "w+b")) == NULL) {
- fprintf(stderr, "unbatch: can't open temp article file %s\n", tempname);
- exit(1);
- }
-
-
- } else { /* parse article text */
- /* flag the end of the header */
- if (strcmp(buf, "\n") == 0)
- in_header = FALSE;
-
- /* save the newsgroups line */
- if (in_header) {
- if (strnicmp(buf,"Message-ID:",11) == 0) {
- strncpy(msg, buf, sizeof(msg));
- msg[sizeof(msg)-1] = '\x0';
- strtok(msg, " \t\r\n");
- p = strtok(NULL, " \t\r\n");
- if (p) /* else we should really kill the article */
- strcpy(msg_id, p);
- }
- if (strnicmp(buf,"Newsgroups:",11) == 0)
- strcpy(newsgroups, buf);
- if (strnicmp(buf,"Subject:",8) == 0) {
- strncpy(subject, buf+8, sizeof(subject));
- subject[sizeof(subject)-1] = '\x0';
- }
-
- /* add our system name to the path list */
- if (strnicmp(buf, "Path:", 5) == 0) {
- strtok(buf, " \t");
- p = strtok(NULL, " \t");
- fprintf(spool_file, "Path: %s!%s", my_stuff.my_site, p);
- } else
- fprintf(spool_file, "%s", buf);
-
- } else { /* body of article */
- fprintf(spool_file, "%s", buf);
- } /* if */
- } /* if */
-
- } /* while */
-
-
-
-
-
- /* process the last one */
- if (strlen(newsgroups) != 0) {
- if (debug >= 2)
- printf("----- new article %s\n", msg_id);
-
- if (find_msg_id(msg_id) != NULL) {
- if (debug >= 1)
- printf("discarding duplicate article %s\n", msg_id);
- } else {
-
- posted = 0;
- strcpy(nglist, newsgroups+11);
- strtok(newsgroups, " \r\n,:");
- p = strtok(NULL, " \r\n,:");
-
-
- /* same loop here as before */
-
- while (p != NULL) {
- if (strcmp(find_news_group(p)->group, junk_group) != 0) {
- out_file = open_out_file(p);
- if (debug >= 2)
- printf("storing article in %s\n", p);
- posted = 1;
- where = ftell(out_file);
- rewind(spool_file);
- while (fgets(buf, 511, spool_file) != NULL)
- fputs(buf, out_file);
- fprintf(out_file, "\n@@@@END\n");
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write article file\n");
- exit(1);
- }
-
- out_file = open_index_file(p);
- gp = find_news_group(p);
- fprintf(out_file,"%08ld %08ld %09ld %s", where, gp->hi_num, t, subject);
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write index file\n");
- exit(1);
- }
- } else
- if (debug >= 2)
- printf("group %s doesn't exist\n", p);
- p = strtok(NULL, " \r\n,:");
- } /* while */
-
- if (!posted) {
- if (debug >= 1)
- printf("junking article %s\n", msg_id);
- out_file = open_out_file(junk_group);
- if (out_file) {
- where = ftell(out_file);
- rewind(spool_file);
- while (fgets(buf, 511, spool_file) != NULL)
- fputs(buf, out_file);
- fprintf(out_file, "\n@@@@END\n");
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write article file\n");
- exit(1);
- }
-
- out_file = open_index_file(junk_group);
- gp = find_news_group(junk_group);
- fprintf(out_file, "%08ld %08ld %09ld %s", where, gp->hi_num, t, subject);
- if (fclose(out_file)) {
- fprintf(stderr, "unbatch: can't write index file\n");
- exit(1);
- }
- }
- }
- add_hist_record(msg_id, nglist);
-
- }
- if (fclose(spool_file)) {
- fprintf(stderr, "unbatch: can't write spool file\n");
- exit(1);
- }
-
- unlink(tempname);
- } /* if */
- }
-
-
-
-
-
- /*--------------------------- unpack the batch ------------------------*/
- FILE *decode_batches(char *fn, int no_toss)
- {
- /*
- * take the batch, strip off the #! cunbatch, and feed the file to
- * uncompress, the opened uncompressed file is returned
- */
-
- FILE *in_file, *out_file;
- int res, buf_cnt, write_err = 0;
- char buf[1025];
- char name[128];
- char cname[128];
-
- buf_cnt = 0;
-
- /* open the batch file */
- strcpy(name, fn);
- if ((in_file = fopen(name, "rb")) == NULL) {
- fprintf(stderr, "unbatch: batchfile %s could not be opened\n", name);
- return(NULL);
- }
-
- /* check if it's compressed */
- res = fread(buf, 1, sizeof(BATCH_HEADER)-1, in_file);
- rewind(in_file);
- if (strncmp(buf, BATCH_HEADER, sizeof(BATCH_HEADER)-1) != 0) {
-
- /* batch is already uncompressed -- copy to temp file */
- if (debug >= 1)
- printf("unbatch: copying uncompressed batch (%s)\n", name);
- sprintf(name, "%s", my_stuff.temp_name);
- if ((out_file = fopen(name, "wb")) == NULL) {
- fprintf(stderr, "unbatch: cannot open output file %s\n", name);
- return(NULL);
- }
-
- while ((res = fread(buf, 1, 1024, in_file)) > 0) {
- if (fwrite(buf, 1, res, out_file) != res) {
- ++write_err;
- break;
- }
- }
- fclose(in_file);
- if (fclose(out_file) || write_err) {
- fprintf(stderr, "unbatch: can't copy batch (disk full?)\n");
- return(NULL);
- }
-
- } else {
-
- /* open the compressed */
- sprintf(name, "%s.z", my_stuff.temp_name);
- if ((out_file = fopen(name, "wb")) == NULL) {
- fprintf(stderr, "unbatch: cannot open output file %s\n", name);
- return(NULL);
- }
-
- while ((res = fread(buf, 1, 1024, in_file)) > 0) {
- if (fwrite(buf_cnt == 0 ? buf+12 : buf, 1,
- buf_cnt == 0 ? res-12 : res, out_file) != (buf_cnt == 0 ? res-12 : res)) {
- ++write_err;
- break;
- }
- buf_cnt++;
- }
-
- fclose(in_file);
- if (fclose(out_file) || write_err) {
- fprintf(stderr, "unbatch: can't copy batch (disk full?)\n");
- return(NULL);
- }
-
- unlink(my_stuff.temp_name);
- strcat(strcpy(cname, my_stuff.temp_name), ".z");
- sprintf(name, my_stuff.uncompress, cname);
- if (debug >= 1)
- printf("unbatch: decompressing batch (%s)\n", name);
- system(name);
- unlink(cname);
- }
-
- if (no_toss) return(NULL);
-
- /* open the uncompressed */
- sprintf(name, "%s", my_stuff.temp_name);
- if ((out_file = fopen(name, "rb")) == NULL) {
- fprintf(stderr, "unbatch: can't open uncompressed file %s\n", name);
- return(NULL);
- }
-
- return(out_file);
-
- }