home *** CD-ROM | disk | FTP | other *** search
- /*
- SNEWS 2.0
-
- rnews - 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.
-
- Derived from unbatch.c by Kai Uwe Rommel
-
-
- USAGE: rnews
- -x<debug> when debug>9 means verbose, tell what we are doing
-
- */
-
-
- #include "defs.h"
- #include "rnews.h"
-
- unsigned _stklen = 16384;
-
- INFO my_stuff;
- char iobuf[IOBUFSIZE];
- int verbose, slave;
- int pidc, pidr;
-
- extern char _far *_pgmptr;
-
-
- /*------------------------------- main --------------------------------*/
- void main(int argc, char *argv[])
- {
- int arg;
- FILE *tmp_file;
-
- slave = (strcmp(argv[0], "slave") == 0);
-
- if (argc > 1 && strncmp(argv[1], "-x", 2) == 0) {
- verbose = (atoi(argv[1] + 2) >= 9);
- argc--;
- argv++;
- }
-
- if (verbose && !slave)
- fprintf(stderr, "RNEWS: (%s)\n", VERSION);
-
- if (!load_stuff()) {
- fprintf(stderr, "Couldn't read rc info\n");
- exit(1);
- }
-
- load_active_file();
- open_hist_file();
- free_ng();
-
- if (argc == 1) {
-
- if (isatty(0)) {
- if (!verbose)
- fprintf(stderr, "RNEWS: (%s)\n", VERSION);
- fprintf(stderr, "\nusage: rnews [-v] [file ...]\n");
- exit(1);
- }
-
- setmode(fileno(stdin), O_BINARY);
- tmp_file = fdopen(dup(fileno(stdin)), "rb");
- decode_batch(tmp_file, "<stdin>");
-
- }
- else
- for (arg = 1; arg < argc; arg++)
- if ((tmp_file = fopen(argv[arg], "rb")) != NULL) {
- decode_batch(tmp_file, argv[arg]);
- fclose(tmp_file);
- }
-
- close_hist_file();
- close_active_file();
-
- exit(0);
- }
-
-
- /*--------------------------- unpack the batch ------------------------*/
- void write_logentry(char *line)
- {
- static FILE *logfile;
- char buf[256];
-
- if (logfile == NULL) {
- strcpy(buf, my_stuff.spool_dir);
- strcat(buf, "rnews.log");
- logfile = fopen(buf, "a");
- }
-
- if (logfile) {
- _strdate(buf);
- buf[5] = '-';
- _strtime(buf + 6);
- buf[11] = 0;
- fprintf(logfile, "%s %s\n", buf, line);
- }
- }
-
- long 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], log[1024], *group, *p;
- FILE *out_file = NULL;
- LINE *help;
- ACTIVE *gp;
- long where;
- time_t t;
- int saved = FALSE;
- long lines = 0, bytes = 0, cross = 0;
-
- for (help = spool; help; help = help->next) {
- lines++;
- bytes += strlen(help->data);
- }
-
- for (p = subject; *p && isspace(*p); p++);
- strcpy(buf, "(");
- strcat(buf, p);
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = 0;
- buf[19] = 0;
- strcat(buf,")");
-
- if (verbose)
- sprintf(log, "%4ld %6ld %-20.20s to:", lines, bytes, buf);
-
- 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;
-
- if (verbose) {
- strcat(log, " ");
- strcat(log, gp->group);
- }
-
- 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);
-
- if (saved)
- cross++;
- else
- saved = TRUE;
-
- if ( nglist[0] )
- strcat(nglist, ",");
- strcat(nglist, group);
- }
-
- if (verbose) {
- write_logentry(log);
- fprintf(stderr, "%s\n", log);
- }
-
- while (spool) {
- help = spool;
- spool = spool->next;
- free(help->data);
- free(help);
- }
-
- add_hist_record(msg_id, nglist);
- return cross;
- }
-
- 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;
- long lines = 0, articles = 0, cross = 0, bytes = 0;
-
- strcpy(msg_id, "");
- strcpy(subject, "-- no subject --\n");
- strcpy(newsgroups, "");
-
- 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) {
- cross += save_message(spool, newsgroups, subject, msg_id);
- articles++;
- }
-
- 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);
-
- lines++;
- bytes += strlen(buf);
- }
-
- }
-
- /* process the last one */
-
- if (control)
- strcpy(newsgroups, "Newsgroups: control"); /* kludge */
-
- if (spool != NULL) {
- cross += save_message(spool, newsgroups, subject, msg_id);
- articles++;
- }
-
- sprintf(buf,
- "Delivered %ld articles, %ld crossposts, %ld lines, %ldk bytes.",
- articles, cross, lines, (bytes + 512) / 1024);
- write_logentry(buf);
- fprintf(stderr, "rnews: %s\n", buf);
- }
-
-
- /*--------------------------- unpack the batch ------------------------*/
- FILE *create_pipe(char *compressor)
- {
- int pipe1[2], pipe2[2], oldout;
-
- _pipe(pipe1, 4096, O_BINARY);
- _pipe(pipe2, 4096, O_BINARY);
- noinherit(pipe1[1]);
- noinherit(pipe2[0]);
-
- oldout = dup(1);
-
- close(0);
- dup2(pipe1[0], 0);
- close(pipe1[0]);
- close(1);
- dup2(pipe2[1], 1);
- close(pipe2[1]);
-
- pidc = spawnlp(P_NOWAIT, compressor, compressor, "-d", NULL);
-
- close(0);
- dup2(pipe2[0], 0);
- close(pipe2[0]);
- close(1);
- dup2(oldout, 1);
- close(oldout);
-
- pidr = spawnlp(P_NOWAIT, _pgmptr, "slave", verbose ? "-x9" : NULL, NULL);
-
- close(0);
-
- return fdopen(pipe1[1], "wb");
- }
-
- void close_pipe(FILE *stream)
- {
- fclose(stream);
-
- cwait(NULL, pidc, WAIT_CHILD);
- cwait(NULL, pidr, WAIT_CHILD);
- }
-
- void decode_batch(FILE *in_file, char *fn)
- {
- /*
- * take the batch, strip off the !cunbatch, and feed the file to
- * uncompress, the opened uncompressed file is returned
- */
-
- FILE *out_file;
- int res, header;
- char buf[1024], *compressor;
- long pos;
- short magic;
-
- if (fgets(buf, sizeof(buf), in_file) == NULL) {
- fprintf(stderr, "batch %s is inexplicably too small\n", fn);
- return;
- }
-
- if (memcmp(buf, "#! rnews ", 9) == 0) {
- if (verbose)
- fprintf(stderr, "Unpacking %s ...\n", fn);
- toss(in_file);
- return;
- }
-
- if (memcmp(buf, "#! cunbatch\n", 12) == 0)
- header = TRUE;
- else if (memcmp(buf, "#! funbatch\n", 12) == 0)
- header = TRUE;
- else
- header = FALSE;
-
- if (header)
- fread(&magic, 1, sizeof(short), in_file);
- else
- memcpy(&magic, buf, sizeof(short));
-
- if (magic == COMPRESS)
- compressor = "compress";
- else if (magic == FREEZE)
- compressor = "freeze";
- else {
- fprintf(stderr, "batch %s has unknown compression type\n", fn);
- return;
- }
-
- out_file = create_pipe(compressor);
-
- if (out_file == NULL) {
- fprintf(stderr, "Cannot create pipe for %s.\n", fn);
- return;
- }
-
- if (verbose)
- fprintf(stderr,"Piping compressed %s to '%s -d' and slave 'rnews' ...\n",
- fn, compressor);
-
- if (header)
- fwrite(&magic, 1, sizeof(short), out_file);
- else
- fputs(buf, out_file);
-
- while ((res = fread(buf, 1, 1024, in_file)) > 0)
- fwrite(buf, 1, res, out_file);
-
- close_pipe(out_file);
- }
-