[net.sources] source to another batching system

smk@linus.UUCP (Steven M. Kramer) (05/26/83)

There is a bnproc going around that reads its arguments and processes
each one.  An enhancement to also read stdin will make another (I
think better) batching scheme work.  The bnproc should
be used instead of existing bnproc's out there.  The other code should
be used ONLY in 2.10 systems that are sending since it relies on the F
option in the second field.  Note our lib dir for news is /usr/local/lib/news
and this must be changed.  Also, we put this in /usr/src/cmd/news/batch
so that ../src/defs.h will find the news defn file.  Also, don't forget
to include bnproc in uuxqt.c.
	(The code is vaxine!ptw's idea, the posting was all mine.)

echo x - Makefile
cat >Makefile <<'!E!O!F!'
# definitions
LIBDIR = /usr/local/lib/news
# must be accessible to uuxqt
BINDIR = /usr/local
CFLAGS = -O
LFLAGS = -s

OBJECTS = bnproc unbnews

all:  ${OBJECTS}

bnproc:	bnproc.c
	cc -o bnproc $(CFLAGS) $(LFLAGS) bnproc.c

unbnews:	unbnews.c
	cc -o unbnews $(CFLAGS) $(LFLAGS) unbnews.c

install: all
	cp unbnews $(LIBDIR)
	cp unbatchnews.sh $(LIBDIR)/unbatchnews
	/etc/chown news $(LIBDIR)/unbnews \
		$(LIBDIR)/unbatchnews
	/etc/chgrp news $(LIBDIR)/unbnews \
		$(LIBDIR)/unbatchnews
	chmod 755 $(LIBDIR)/unbnews \
		$(LIBDIR)/unbatchnews
	cp bnproc $(BINDIR)
	/etc/chown news $(BINDIR)/bnproc
	/etc/chgrp news $(BINDIR)/bnproc
	chmod 755 $(BINDIR)/bnproc

clean:
	rm -f ${OBJECTS}
!E!O!F!
echo x - README
cat >README <<'!E!O!F!'
These small programs provide a rudimentary news batching scheme.  They are
designed to use the 2.10 news :F: flag to give batch news without the =batch
hack to uucp and without spooling forwarded news.

The scheme is this.  When news is "sent" to another system, net news lists the
path of the news item in a file.  Every now and then, a daemon named "unbnews"
is run which takes the list of news items and "cats" them together to a "uux"
command at the other sites.  Uux runs "bnproc" at the other sites which
separate the articles and passes them to rnews for posting.

Note that the regular news passing scheme still works.  And that news can be
batched in both directions without duplicate articles bouncing back and forth.
This bnproc is also compatible with the bnproc of johnl@ima.UUCP, only the
unbnews side is slightly less space-consuming.

Rough installation instructions:

Do a "make" and a "make install" to get unbatchnews, unbnews, and bnproc at
both sites involved.

At the sending site, change the sys file entries for sites you batch to:

	<site>:net.all,fa.all:F:/usr/spool/tmp/<site>

This causes 2.10 news to list news items for <site> in the named file.

At the sending site, add a line like this to /usr/lib/crontab

45 0,6,12,18 * * * /usr/lib/news/unbatchnews <site1> <site2>

To forward the batched news as often as you like.

If the sender polls the receiver, run this program when news is to
go out.  If the receiver polls the sender, run this program shortly
before the poll is expected.

!E!O!F!
echo x - bnproc.c
cat >bnproc.c <<'!E!O!F!'
/*
 * bnproc: break up and process the batched news files
 */

# include <stdio.h>

/*	Bring in the news definitions file
	for SYSPATH information.	*/
# include "../src/defs.h"

char   *default_env[] =
{
    SYSPATH, NULL
};
char    buf[BUFSIZ];
extern char **environ;
FILE * popen ();
void process ();

main (ac, av)
int     ac;
char   *av[];
{
    register int    args;

    process ((char *) NULL);

    for (args = 1; args < ac; args++)
	process (av[args]);

    return 0;
}

void process (filename)
register char  *filename;
{
    register int    stat;
    register    FILE * input_file;
    register    FILE * pfn;
    long    size;

    if (filename == NULL)
	input_file = stdin;
    else
    {
	input_file = fopen (filename, "r");
	if (input_file == NULL)
	{
	    fprintf (stderr, "Can't open %s\n", filename);
	    return;
	}
    }

    environ = default_env;

    while (!feof (input_file) && !ferror (input_file) &&
	    fgets (buf, BUFSIZ - 2, input_file) != NULL)
    {
	long    atol ();
	register int    c;

	size = atol (buf);
	if (size <= 0)
	    break;
	if ((pfn = popen ("rnews", "w")) == NULL)
	{
	    fprintf (stderr, "Can't fork %s\n", "rnews");
	    exit (-2);
	}


	while ((--size >= 0) && !feof (input_file) &&
		!ferror (input_file) &&
		((c = getc (input_file)) != EOF))
	    fputc (c, pfn);

	stat = pclose (pfn);
	if (stat != 0)
	{
	    fprintf (stderr, "Error delivering news\n");
	    exit (stat);
	}
    }
    (void) fclose (input_file);
}
!E!O!F!
echo x - unbatchnews.sh
cat >unbatchnews.sh <<'!E!O!F!'
#! /bin/csh
# Send accumulated batch news to sites
set log = batchnews.log
cd /usr/spool/tmp
date >> $log
foreach site ($*)
	if (-e $site) then
		mv $site send${site}
		/usr/local/lib/news/unbnews $site < send${site} >>& $log
		rm -f send${site}
	else
		echo "	No news for $site" >> $log
	endif
end
!E!O!F!
echo x - unbnews.c
cat >unbnews.c <<'!E!O!F!'
/*
 * unbnews: unbatch news items and hand them to uucp
 * expects list of news items to send on stdin
 */

/*
 *      Syntax: unbnews host < filelist
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

FILE * popen ();
char   *sprintf ();

main (ac, av)
char  **av;
{
    register char   c;
    register    FILE * newsfile;
    register    FILE * uuxcom;
    register int    stat;
    register unsigned int   count;
    register    off_t sizes;
    struct stat statbuf;
    char    uxbuf[BUFSIZ],
            newsitem[BUFSIZ];

    if (ac != 2)
    {
	fprintf (stderr, "Usage: unbnews host < filelist\n");
	exit (-1);
    }
    (void) sprintf (uxbuf, "uux - -z -gD '%s!bnproc'", av[1]);
    if ((uuxcom = popen (uxbuf, "w")) == NULL)
    {
	fprintf (stderr, "Can't fork %s\n", uxbuf);
	exit (-2);
    }
    count = 0;
    sizes = 0;

    while (gets (newsitem) != NULL)
    {
	if ((newsfile = fopen (newsitem, "r")) == NULL)
	{
	    fprintf (stderr, "Can't open %s for %s\n",
		    newsitem, av[1]);
	    continue;
	}
	(void) fstat (fileno (newsfile), &statbuf);
	count++;
	sizes += statbuf.st_size;
	fprintf (uuxcom, "%ld\n", statbuf.st_size);
	while (--statbuf.st_size >= 0 &&
		(int) (c = getc (newsfile)) != EOF)
	    putc (c, uuxcom);
	(void) fclose (newsfile);
    }

    if ((stat = pclose (uuxcom)) != 0)
    {
	fprintf (stderr, "Error sending news\n");
	exit (stat);
    }
    printf ("\tsystem %s: sent %u files (size = %ld bytes)\n",
	    av[1], count, sizes);
}
!E!O!F!