home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
snews-20.zip
/
RNEWS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-02
|
10KB
|
427 lines
/*
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);
}