home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
com
/
utils
/
smplnews
/
unbatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-02
|
10KB
|
396 lines
/*
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);
}