home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 2.0
-
- 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
-
- 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.
-
-
-
- USAGE: unbatch
- -n means decompress the first batch, then stop before tossing
- -v means verbose, tell what we are doing
-
- */
-
-
- #include "defs.h"
- #include "unbatch.h"
-
- unsigned _stklen = 16384;
-
- INFO my_stuff;
- char iobuf[IOBUFSIZE];
-
- #ifdef system
- #undef system
- #endif
-
-
- /*------------------------------- main --------------------------------*/
- void 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;
-
- fprintf(stderr, "UNBATCH: (%s)\n", VERSION);
-
- /* if TRUE, then just uncompress, don't unbatch */
- no_toss = (argc == 2) && (strncmp("-n", argv[1], 2) == 0);
-
- if (!load_stuff()) {
- fprintf(stderr, "Couldn't read rc info\n");
- exit(1);
- }
-
- load_active_file();
- free_ng();
-
- sprintf(in_name, "%s*.*", my_stuff.incoming_dir);
- done = findfirst(in_name, &ffblk, 0);
- while (!done) {
-
- sprintf(name, "%s%s", my_stuff.incoming_dir, ffblk.ff_name);
- printf("unbatch: processing %s\n", name);
-
- /*
- Check for enough room. First, the batch in copied without
- the header. Thus, the same space is needed again. Then,
- the copied batch is uncompressed and read in over a pipe
- which doesn't need extra space. Only space for the
- articles is needed, slightly more than the uncompressed
- size of the batch, say 3 times as much. We need a total
- space of about four times the size of the original batch.
- And this is only if no different device is used for the
- temp files.
- */
-
- stat(name, &st);
-
- required_disk = st.st_size * 4L;
-
- 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 pipe */
- if ((tmp_file = decode_batch(name, in_name, no_toss)) != NULL) {
-
- open_hist_file();
- toss(tmp_file);
- close_hist_file();
-
- if (in_name[0]) {
- pclose(tmp_file);
- unlink(in_name);
- }
- else
- fclose(tmp_file);
-
- unlink(name);
-
- } else if (!no_toss) {
- printf("could not unpack compressed news batch %s\n", name);
- exit(1);
- }
-
- done = findnext(&ffblk);
-
- }
-
- close_active_file();
- }
-
-
- /*--------------------------- unpack the batch ------------------------*/
- void save_message(LINE *spool, char *newsgroups,
- char *subject, char *msg_id)
- {
- /*
- * 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
- */
- char buf[512], nglist[256], *group, *p;
- FILE *out_file = NULL;
- LINE *help;
- ACTIVE *gp;
- long where;
- time_t t;
- int saved = FALSE;
-
- time(&t);
- nglist[0] = 0;
-
- p = strtok(newsgroups, " \r\n,:");
- p = strtok(NULL, " \r\n,:");
-
- while (p != NULL) {
-
- group = p;
- p = strtok(NULL, " \r\n,:");
-
- gp = find_news_group(group);
- if (stricmp(gp->group, "junk") == 0 && (p != NULL || saved))
- continue;
-
- out_file = open_out_file(group);
- where = ftell(out_file);
- help = spool;
-
- setvbuf(out_file, iobuf, _IOFBF, IOBUFSIZE);
-
- for (help = spool; help != NULL; help = help->next)
- fputs(help->data, out_file);
-
- fprintf(out_file, "\n@@@@END\n");
- fclose(out_file);
-
- out_file = open_index_file(group);
- fprintf(out_file,"%08ld %08ld %09ld %s", where,
- gp->hi_num, t, subject);
- fclose(out_file);
-
- saved = TRUE;
- if ( nglist[0] )
- strcat(nglist, ",");
- strcat(nglist, group);
- }
-
- while (spool) {
- help = spool;
- spool = spool->next;
- free(help->data);
- free(help);
- }
-
- add_hist_record(msg_id, nglist);
- }
-
- void toss(FILE *tmp_file)
- {
- /*
- * Toss it into the appropriate files.
- */
- LINE *spool = NULL, *help;
- char buf[512], buf2[512], *p;
- char newsgroups[256], subject[256], msg_id[256];
- int in_header, control;
-
- strcpy(msg_id, "");
- strcpy(subject, "-- no subject --\n");
- strcpy(newsgroups, "");
-
- rewind(tmp_file);
- in_header = TRUE;
- control = FALSE;
-
- /* read the file */
- while (fgets(buf, 511, tmp_file) != NULL) {
-
- if (strstr(buf, "#! rnews") != NULL) {
-
- if (control)
- strcpy(newsgroups, "Newsgroups: control"); /* kludge */
-
- if (spool != NULL)
- save_message(spool, newsgroups, subject, msg_id);
-
- strcpy(subject, "-- no subject --\n");
- in_header = TRUE;
- control = FALSE;
- spool = NULL;
-
- } else {
- /* 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) {
- strcpy(buf2, buf);
- p = strtok(buf2, " \t\r\n"); p = strtok(NULL, " \t\r\n");
- strcpy(msg_id, p);
- }
- if (strnicmp(buf,"Newsgroups:",11) == 0)
- strcpy(newsgroups,buf);
- if (strnicmp(buf,"Subject:",8) == 0)
- strcpy(subject, buf+8);
- if (strnicmp(buf,"Control:",8) == 0)
- control = TRUE;
- /* add our system name to the path list */
- if (strnicmp(buf, "Path:", 5) == 0) {
- p = strtok(buf, " \t");
- p = strtok(NULL, " \t");
- strcpy(buf2, p);
- sprintf(buf, "Path: %s!%s", my_stuff.my_site, buf2);
- }
- }
-
- if (spool == NULL)
- spool = help = (LINE *) xmalloc(sizeof(LINE));
- else {
- help->next = (LINE *) xmalloc(sizeof(LINE));
- help = help->next;
- }
- help->next = NULL;
- help->data = (char *) xmalloc(strlen(buf) + 1);
- strcpy(help->data, buf);
- }
-
- }
-
- /* process the last one */
-
- if (control)
- strcpy(newsgroups, "Newsgroups: control"); /* kludge */
-
- if (spool != NULL)
- save_message(spool, newsgroups, subject, msg_id);
- }
-
-
-
-
-
- /*--------------------------- unpack the batch ------------------------*/
- FILE *decode_batch(char *fn, char *tn, 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, header;
- char buf[1025], out[256];
- char compr[16];
- long pos;
- short magic;
-
- buf_cnt = 0;
- header = FALSE;
- *tn = 0;
-
- /* open the batch file */
- if ((in_file = fopen(fn, "rb")) == NULL) {
- printf("batchfile %s could not be opened\n", fn);
- return(NULL);
- }
-
- if (fread(buf, 1, 12, in_file) == 0) {
- printf("batch %s is inexplicably too small\n", fn);
- return(NULL);
- }
-
- if (memcmp(buf, "#! rnews ", 9) == 0) {
- rewind(in_file);
- return(in_file);
- }
-
- if (memcmp(buf, "#! cunbatch\n", 12) == 0)
- header = TRUE;
- else if (memcmp(buf, "#! funbatch\n", 12) == 0)
- header = TRUE;
- else
- rewind(in_file);
-
- pos = ftell(in_file);
- fread(&magic, 1, sizeof(short), in_file);
- fseek(in_file, pos, SEEK_SET);
-
- if (magic == COMPRESS)
- strcpy(compr, "compress");
- else if (magic == FREEZE)
- strcpy(compr, "freeze");
- else {
- printf("batch %s has unknown compression type\n", fn);
- return(NULL);
- }
-
- if (header) {
- /* open the compressed */
- sprintf(tn, "%s\\unbatch.tmp", my_stuff.temp_name);
- if ((out_file = fopen(tn, "wb")) == NULL) {
- printf("cannot open output file %s\n", buf);
- return(NULL);
- }
-
- while ((res = fread(buf, 1, 1024, in_file)) > 0) {
- fwrite(buf, 1, res, out_file);
- buf_cnt++;
- }
-
- fclose(in_file);
- fclose(out_file);
-
- if (no_toss) {
- sprintf(out, "%s\\n_XXXXXX", my_stuff.temp_name);
- mktemp(out);
- sprintf(buf, "%s -d <%s >%s", compr, tn, out);
- system(buf);
- unlink(tn);
- return(NULL);
- }
-
- /* open the uncompressed */
- sprintf(buf, "%s -d <%s", compr, tn);
- if ((out_file = popen(buf, "rb")) == NULL) {
- printf("cannot open pipe to \"%s\"\n", buf);
- return(NULL);
- }
- }
- else {
- fclose(in_file);
- *tn = 0;
-
- if (no_toss) {
- sprintf(out, "%s\\n_XXXXXX", my_stuff.temp_name);
- mktemp(out);
- sprintf(buf, "%s -d <%s >%s", compr, fn, out);
- system(buf);
- return(NULL);
- }
-
- /* open the uncompressed */
- sprintf(buf, "%s -d <%s", compr, fn);
- if ((out_file = popen(buf, "rb")) == NULL) {
- printf("cannot open pipe to \"%s\"\n", buf);
- return(NULL);
- }
- }
-
- return(out_file);
- }
-