home *** CD-ROM | disk | FTP | other *** search
- From espo@bpa.BELL-ATL.COM Tue Aug 19 06:07:02 1986
- Received: by mirror.UUCP (4.12/UUCP-Project/rel-1.0/07-25-86)
- id AA23998; Tue, 19 Aug 86 06:04:50 edt
- Received: from bpa.UUCP by seismo.CSS.GOV with UUCP; Mon, 18 Aug 86 13:18:19 EDT
- Received: by bpa.BELL-ATL.COM (4.12/UUCP-Project/rel-1.0/07-25-86)
- id AA22779; Mon, 18 Aug 86 07:24:43 edt
- Date: Mon, 18 Aug 86 07:24:43 edt
- From: espo@bpa.BELL-ATL.COM (Bob Esposito)
- Message-Id: <8608181124.AA22779@bpa.BELL-ATL.COM>
- To: rs@mirror.ARPA
- Subject: nbatcher source
- Status: R
-
-
- Rich,
-
- Since the fixes are not in a patch format, here's the entire
- source in shar format. I will post it to net.sources as
- requested. Thanks,
-
-
- --
- //////////////////////////////////////////
- * Bob Esposito ...espo@bpa.bell-atl.com *
- //////////////////////////////////////////
-
-
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # define.c
- # main.c
- # parse.c
- # checkwork.c
- # nbatcher.c
- # logger.c
- # nbatcher.h
- # bst.c
- # README
- # nbatcher.ctl
- # nbatcher.doc
- # nbatcher.1
- # Makefile
- echo x - extracting define.c
- sed 's/^X//' << 'SHAR_EOF' > define.c
- X/* char sccsid[] = "@(#)define.c 1.4 8/14/86"; */
- X
- X/*******************************************************
- X * define.c - global defines for nbatcher.
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ******************************************************/
- X
- X#include <stdio.h>
- X#include "nbatcher.h"
- X
- XFILE *lfp,
- X *tfp,
- X *log = NULL;
- X
- Xlong n_bytes,
- X cu_bytes;
- X
- Xchar *tfile = NULL;
- X
- Xshort vflg = 0,
- X nfiles = 10;
- X
- Xint fcnt = 0,
- X scnt = 0;
- X
- SHAR_EOF
- echo x - extracting main.c
- sed 's/^X//' << 'SHAR_EOF' > main.c
- Xchar sccsid[] = "nbatcher 1.4 8/14/86";
- X
- X/********************************************
- X *
- X * main.c - for nbatcher
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ********************************************/
- X
- X#include <stdio.h>
- X#include "nbatcher.h"
- X
- Xmain()
- X{
- X int uid, nowork;
- X FILE *cfp;
- X char fbuf[BUFSIZ];
- X
- X uid = getuid();
- X
- X if (uid && uid != NEWSUID)
- X xerror ("permission denied - not NEWSUSER\n");
- X
- X if (chdir(LIBDIR) < 0)
- X xerror ("can't chdir to %s\n", LIBDIR);
- X
- X if ((cfp=fopen("nbatcher.ctl", "r")) == NULL)
- X xerror ("no `batcher.ctl' file found\n");
- X
- X if (isatty(0)) {
- X vflg = TRUE;
- X (void) fprintf(stderr, "%s\n", sccsid);
- X }
- X
- X nowork = TRUE;
- X while ((fgets(fbuf, sizeof(fbuf), cfp)) != NULL) {
- X if (fbuf[0] == '*' || fbuf[0] == '\n')
- X continue;
- X parse_entry (fbuf);
- X if (!work_to_do())
- X continue;
- X batch_it ();
- X nowork = FALSE;
- X }
- X
- X fclose (cfp);
- X fclose (tfp);
- X unlink (tfile);
- X if (vflg == TRUE && nowork == TRUE)
- X (void) fprintf(stderr, "no work to do\n");
- X exit (0);
- X}
- X
- SHAR_EOF
- echo x - extracting parse.c
- sed 's/^X//' << 'SHAR_EOF' > parse.c
- X/* char sccsid[] = "@(#)parse.c 1.4 8/14/86"; */
- X
- X/****************************************************************
- X *
- X * parse.c - nbatcher line parser for the control file
- X *
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ****************************************************************/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <ctype.h>
- X#include "nbatcher.h"
- X
- X#define MAX_BYTES 1000000L /* max allowable bytes */
- X
- Xparse_entry (line)
- Xchar *line;
- X{
- X register char *p;
- X short num, upper;
- X short lower, dash;
- X long l_num;
- X
- X upper = 23; /* upper hour limit */
- X lower = 0; /* lower hour limit */
- X dash = 0;
- X
- X clear_entry (&ep); /* zero out the structure */
- X
- X p = (char *) ep.site;
- X
- X /* get the site name and copy
- X it to the structure */
- X
- X while (*line && *line != COLON)
- X *p++ = *line++;
- X *p = '\0';
- X if (*++line == '\n' || *line == '\0')
- X xerror ("illegal number of fields\n");
- X
- X /* check that its valid */
- X
- X if (ep.site[0] == '\0')
- X xerror ("null site name in control file\n");
- X
- X /* now, parse the hour string and check
- X for valid syntax */
- X
- X p = (char *) ep.hour;
- X while (*line && *line != COLON)
- X *p++ = *line++;
- X
- X *p = '\0';
- X if (*++line == '\n' || *line == '\0')
- X xerror ("illegal number of fields\n");
- X
- X if (ep.hour[0] == '\0')
- X xerror ("null hour string in control file\n");
- X
- X /* now re-scan the hour in structure and
- X weed out the badies */
- X
- X if (ep.hour[0] == '*' && ep.hour[1] != '\0')
- X xerror ("invalid hour string syntax: %s\n", ep.hour);
- X else if (ep.hour[0] == '*')
- X goto h_skip;
- X
- X if (strcmp(ep.hour, "off", 3) == 0 && ep.hour[3] != '\0')
- X xerror ("invalid hour string syntax: %s\n", ep.hour);
- X else if (strncmp(ep.hour, "off", 3) == 0)
- X goto h_skip;
- X
- X p = (char *) ep.hour;
- X if (!isdigit(*p))
- X xerror ("non-numeric char in hour string: %c\n", *p);
- X
- X while (*p) {
- X num = 0;
- X do {
- X num = num*10 + (*p - '0');
- X } while (isdigit(*++p));
- X
- X if (num < lower || num > upper)
- X xerror ("illegal hour: %d\n", num);
- X
- X if (!*p)
- X break;
- X
- X if (*p == '-' && dash)
- X xerror ("syntax error in hour field\n");
- X else if (*p == '-')
- X dash = TRUE;
- X
- X if (*p != ',' && *p != '-')
- X xerror ("non-numeric char in hour string: %c\n", *p);
- X else if (!isdigit(*++p))
- X xerror ("syntax error in hour field\n");
- X
- X }
- X
- X /* now that thats over with, let do the compression
- X field. Only 9-16 is allowed, except a null field
- X indicates no compression for this site. */
- X
- Xh_skip:
- X num = 0;
- X while (*line && *line != COLON) {
- X if (!isdigit(*line))
- X xerror ("non-numeric in compression field\n");
- X num = num*10 + (*line++ - '0');
- X }
- X if (*++line == '\n' || *line == '\0')
- X xerror ("illegal number of fields\n");
- X
- X if (num != 0 && (num < 9 || num > 16))
- X xerror ("illegal compression bits: %d\n", num);
- X
- X ep.c_bits = num;
- X
- X /* now check the max. bytes for UUCP queue.
- X Note: There is a max. allowable # of bytes
- X here, set at 1MB. Change it at your
- X own risk.
- X */
- X
- X l_num = 0;
- X while (*line && *line != COLON) {
- X if (!isdigit(*line))
- X xerror ("non-numeric in max. bytes field\n");
- X
- X l_num = l_num*10 + (*line++ - '0');
- X }
- X
- X if (l_num > MAX_BYTES)
- X xerror ("%ld max. bytes exceeds allowable maximun\n", l_num);
- X
- X if (l_num != 0)
- X ep.m_bytes = l_num;
- X else
- X ep.m_bytes = DFL_BYTES;
- X
- X /* and finally the command line (if there is one) */
- X
- X p = (char *) ep.command;
- X
- X if (*++line != '\n' && *line != '\0') {
- X while (*line && *line != '\n')
- X *p++ = *line++;
- X
- X *p = '\0';
- X }
- X}
- X
- X#ifdef USE_PORT_CODE
- Xxerror (fmt, a1, a2)
- Xchar *fmt;
- Xchar *a1, *a2;
- X{
- X char buf[BUFSIZ];
- X
- X sprintf (buf, fmt, a1, a2);
- X printf ("\nnbatcher: %s\n", fmt);
- X exit (99);
- X}
- X
- X#else
- Xxerror (fmt, argp)
- Xchar *fmt;
- Xint argp;
- X{
- X char buf[BUFSIZ];
- X char fbuf[BUFSIZ];
- X FILE prwbuf;
- X register char *cp;
- X
- X prwbuf._flag = _IOWRT;
- X prwbuf._file = _NFILE;
- X prwbuf._cnt = 32767;
- X prwbuf._ptr = (unsigned char *)buf;
- X prwbuf._base = (unsigned char *)buf;
- X sprintf (fbuf, "\n%s: %s", "nbatcher", fmt);
- X _doprnt (fbuf, (char *)&argp, &prwbuf);
- X putc ('\0', &prwbuf);
- X for (cp = buf; *cp != '\0'; cp++)
- X putchar (*cp);
- X
- X exit (99);
- X}
- X#endif /* USE_PORT_CODE */
- X
- Xclear_entry (s)
- Xchar *s;
- X{
- X register int i;
- X
- X for (i=0; i<sizeof(struct file_entry); *s++ = '\0', i++)
- X ;
- X
- X}
- SHAR_EOF
- echo x - extracting checkwork.c
- sed 's/^X//' << 'SHAR_EOF' > checkwork.c
- X/* char sccsid[] = "@(#)checkwork.c 1.4 8/14/86"; */
- X
- X/************************************************************
- X *
- X * checkwork.c - look to see if there's any work
- X * to do for a site.
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ************************************************************/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/utsname.h>
- X#include <sys/dir.h>
- X#include <ctype.h>
- X#include <time.h>
- X#include "nbatcher.h"
- X
- Xwork_to_do ()
- X{
- X register char *p;
- X struct tm *localtime(), *tp;
- X struct stat st;
- X char buf[BUFSIZ];
- X long time(), clock;
- X int hour;
- X short num, upper, lower;
- X
- X sprintf (buf, "%s/%s", BATCHDIR, ep.site);
- X
- X if (stat(buf, &st) < 0)
- X xerror ("bad stat on %s\n", buf);
- X
- X /* if the size of the batch file is
- X zero, return FALSE
- X */
- X
- X if (st.st_size == 0)
- X return (FALSE);
- X
- X /* now see if it time to do anything */
- X
- X clock = time ((long *)0);
- X tp = localtime (&clock);
- X hour = tp->tm_hour;
- X
- X p = (char *) ep.hour;
- X
- X if (*p == '*') /* match any hour */
- X return (check_uucp());
- X
- X if (strncmp(p, "off", 3) == 0) /* just what it says, off */
- X return (FALSE);
- X
- X /* parse thru hour field to see if
- X this is the hour to do work */
- X
- X num = 0;
- X do {
- X num = num*10 + (*p - '0');
- X } while (isdigit(*++p));
- X if (num == hour)
- X return (check_uucp());
- X
- X if (*p == '-') {
- X lower = num;
- X p++;
- X num = 0;
- X do {
- X num = num*10 + (*p - '0');
- X } while (isdigit(*++p));
- X upper = num;
- X
- X if (lower < upper) { /* normal hour range */
- X if (hour >= lower && hour <= upper)
- X return (check_uucp());
- X } else if (lower > upper) { /* 24 hr. cycle thru */
- X if (hour >= lower || hour <= upper)
- X return (TRUE);
- X } else
- X return (FALSE);
- X }
- X
- X if (*p == ',') {
- X p++;
- X while (*p) {
- X num = 0;
- X do {
- X num = num*10 + (*p - '0');
- X } while (isdigit(*++p));
- X if (num == hour)
- X return (check_uucp());
- X p++;
- X }
- X }
- X
- X return (FALSE);
- X}
- X
- X/* If check_uucp cannot find the remote site
- X * directory, just bypass the byte counting
- X * routine. This is necessary because the
- X * uucpcleanup daemon, on some sites, removes
- X * the site directory when there's nothing there.
- X */
- X
- Xcheck_uucp()
- X{
- X struct utsname utsn;
- X struct direct dp;
- X struct stat st;
- X FILE *dfp;
- X char u_name[9], buf[80];
- X short prefix_len;
- X
- X if (uname(&utsn) < 0)
- X xerror ("can't get local nodename\n");
- X
- X sprintf (buf, "%s/%s", UUCPDIR, ep.site);
- X if (chdir(buf) < 0) {
- X fprintf (stderr, "\nnbatcher: can't chdir to %s - bypassing UUCP check\n", buf);
- X return (TRUE);
- X }
- X
- X if ((dfp=fopen(".", "r")) == NULL) {
- X fprintf (stderr, "\nnbatcher: fopen error on %s - bypassing UUCP check\n", UUCPDIR);
- X return (TRUE);
- X }
- X
- X sprintf (buf, "D.%s", utsn.nodename);
- X prefix_len = (short) strlen(buf);
- X n_bytes = 0;
- X while ((fread((char *)&dp, sizeof(dp), 1, dfp)) == 1) {
- X if (dp.d_ino == 0 || dp.d_name[0] == '.')
- X continue;
- X if (strncmp(dp.d_name, buf, prefix_len))
- X continue;
- X if (stat(dp.d_name, &st) < 0) {
- X fprintf (stderr, "\nnbatcher: bad stat on UUCP_file %s - bypassing\n", dp.d_name);
- X continue;
- X }
- X n_bytes += st.st_size;
- X if (n_bytes > ep.m_bytes) {
- X fclose (dfp);
- X return (FALSE);
- X }
- X }
- X fclose (dfp);
- X if (chdir(LIBDIR) < 0)
- X xerror ("can't chdir back to %s\n", LIBDIR);
- X
- X return (TRUE);
- X}
- SHAR_EOF
- echo x - extracting nbatcher.c
- sed 's/^X//' << 'SHAR_EOF' > nbatcher.c
- X/* char sccsid[] = "@(#)nbatcher.c 1.4 8/14/86"; */
- X
- X/****************************************************
- X *
- X * nbatcher.c - where it really happens.
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ***************************************************/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <time.h>
- X#include "nbatcher.h"
- X
- Xbatch_it ()
- X{
- X struct stat st;
- X FILE *bfp, *afp;
- X char fbuf[BUFSIZ], lckfile[40];
- X char tbuf[80];
- X short count;
- X int c;
- X
- X if (chdir(BATCHDIR) < 0)
- X xerror ("can't chdir to %s\n", BATCHDIR);
- X
- X /* we create a lock file for two purposes,
- X first to make sure a previous nbatcher
- X didn't blowup and leave the lock file
- X laying around, and second to put the
- X remaining news article filenames when
- X we go over the max UUCP bytes and there's
- X still files remaining for batching.
- X */
- X
- X sprintf (lckfile, ".%s.lock", ep.site);
- X if (!access(lckfile, 0))
- X xerror ("lockfile already exists for %s\n", ep.site);
- X
- X if ((lfp=fopen(lckfile, "w")) == NULL)
- X xerror ("can't create lockfile for %s\n", ep.site);
- X
- X /* now that we've locked ourselves for this site,
- X lets carry on */
- X
- X if ((bfp=fopen(ep.site, "r")) == NULL)
- X xerror ("can't open %s/%s for reading\n", BATCHDIR, ep.site);
- X
- X if (tfile == NULL) {
- X tfile = mktemp("/tmp/bnewsXXXXXX");
- X if ((tfp=fopen(tfile, "w")) == NULL)
- X xerror ("can't open %s for writing\n", tfile);
- X }
- X
- X count = fcnt = scnt = 0;
- X cu_bytes = 0;
- X while ((fgets(fbuf, sizeof(fbuf), bfp)) != NULL) {
- X fbuf[strlen(fbuf)-1] = '\0'; /* remove the newline */
- X if ((afp=fopen(fbuf, "r")) == NULL) {
- X fprintf (stderr, "\nbypassing article %s: can't read it\n",
- X fbuf);
- X continue;
- X }
- X if (fstat(fileno(afp), &st) < 0)
- X xerror ("fstat failed on %s\n", fbuf);
- X
- X cu_bytes += st.st_size;
- X
- X /* if the max byte count is exceeded,
- X save the remaining files for later */
- X
- X if ((cu_bytes + n_bytes) > ep.m_bytes) {
- X fprintf (lfp, "%s\n", fbuf); /* put the '\n' back */
- X while ((fgets(fbuf, sizeof(fbuf), bfp)) != NULL)
- X fputs (fbuf, lfp);
- X fclose (bfp);
- X fclose (lfp);
- X fclose (afp);
- X unlink (ep.site);
- X if (link(lckfile, ep.site) < 0)
- X xerror ("can't link lockfile to %s\n", ep.site);
- X unlink (lckfile);
- X chown (ep.site, NEWSUID, NEWSGID);
- X if (count)
- X spoolit ();
- X if (cu_bytes - st.st_size)
- X log_it (cu_bytes - st.st_size);
- X
- X return;
- X }
- X sprintf (tbuf, "#! rnews %ld\n", st.st_size);
- X fputs (tbuf, tfp);
- X while ((c=getc(afp)) != EOF)
- X putc (c, tfp);
- X fclose (afp);
- X
- X if (++count == nfiles) {
- X spoolit ();
- X count = 0;
- X }
- X fcnt++;
- X }
- X
- X /* The final spool if lest than nfiles
- X is encountered. The zero out the
- X batchfile and unlink the lock file */
- X
- X spoolit ();
- X fclose (bfp);
- X fclose (lfp);
- X close (creat(ep.site, 0664));
- X chown (ep.site, NEWSUID, NEWSGID);
- X unlink (lckfile);
- X
- X /* here we log what we've done, and
- X if vflg is set, a copy to stdout
- X as well */
- X
- X log_it (0);
- X if (chdir(LIBDIR) < 0)
- X xerror ("can't chdir back to %s\n", LIBDIR);
- X
- X}
- X
- Xspoolit ()
- X{
- X struct stat st;
- X char cmd[BUFSIZ], cfile[80];
- X FILE *pfp;
- X int c;
- X
- X fclose (tfp);
- X stat (tfile, &st);
- X
- X /* if for some reason the temp file
- X is zero, just return */
- X
- X if (st.st_size == 0)
- X return;
- X
- X /* if ep.c_bits is set use COMPRESS to compress
- X the temp file first
- X */
- X
- X if (ep.c_bits) {
- X sprintf (cmd, "%s -b%d %s", COMPRESS, ep.c_bits, tfile);
- X if (system(cmd) != 0)
- X xerror ("system(%s) failed\n", cmd);
- X
- X strcpy (cfile, tfile);
- X strcat (cfile, ".Z");
- X if ((tfp=fopen(cfile, "r")) == NULL)
- X xerror ("can't open %s for reading\n", cfile);
- X
- X /* if ep.command has a specific command
- X for UUCP spooling, use it. If not,
- X use UUX.
- X */
- X
- X if (ep.command[0] != '\0')
- X strcpy (cmd, ep.command);
- X else
- X sprintf (cmd, "%s %s!rnews", UUX, ep.site);
- X
- X /* now popen the command for writing
- X and send it the contents of tempfile */
- X
- X if ((pfp=popen(cmd, "w")) == NULL)
- X xerror ("popen failed on %s\n", cmd);
- X
- X /********************************************
- X * for version 2.10.3 and above,
- X * prepend `#! cunbatch'.
- X *
- X * NOTE: The remote site MUST be able to
- X * except this format, or it will
- X * be lost!!!
- X *******************************************/
- X
- X fputs ("#! cunbatch\n", pfp);
- X while ((c=getc(tfp)) != EOF)
- X putc (c, pfp);
- X
- X pclose (pfp);
- X fclose (tfp);
- X unlink (cfile);
- X } else { /* regular batching here */
- X if ((tfp=fopen(tfile, "r")) == NULL)
- X xerror ("can't open %s for reading\n", tfile);
- X
- X /* if ep.command has a specific command
- X for UUCP spooling, use it. If not,
- X use UUX.
- X */
- X
- X if (ep.command[0] != '\0')
- X strcpy (cmd, ep.command);
- X else
- X sprintf (cmd, "%s %s!rnews", UUX, ep.site);
- X
- X if ((pfp=popen(cmd, "w")) == NULL)
- X xerror ("popen failed on %s\n", cmd);
- X
- X while ((c=getc(tfp)) != EOF)
- X putc (c, pfp);
- X
- X pclose (pfp);
- X fclose (tfp);
- X }
- X if ((tfp=fopen(tfile, "w")) == NULL)
- X xerror ("can't re-open %s\n", tfile);
- X
- X scnt++;
- X}
- SHAR_EOF
- echo x - extracting logger.c
- sed 's/^X//' << 'SHAR_EOF' > logger.c
- X/* char sccsid[] = "@(#)logger.c 1.4 8/14/86"; */
- X
- X/***************************************************
- X *
- X * logger.c - log info about nbatcher
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X **************************************************/
- X
- X#include <stdio.h>
- X#include <time.h>
- X#include "nbatcher.h"
- X
- Xlog_it (bytes)
- Xlong bytes;
- X{
- X struct tm *localtime(), *tp;
- X long time(), clock;
- X char logfile[80], buf[BUFSIZ];
- X char pbuf[BUFSIZ];
- X
- X sprintf (logfile, "%s/%s", LIBDIR, "nbatcher.log");
- X if (log == NULL) {
- X if ((log=fopen(logfile, "a")) == NULL)
- X fprintf (stderr, "\ncan't append to logfile\n");
- X }
- X
- X if (log != NULL)
- X rewind (log, 0L, 2); /* just incase */
- X
- X clock = time ((long *)0);
- X tp = localtime (&clock);
- X sprintf (buf, "%.2d/%.2d %.2d:%.2d %s: %d %s batched, %d %s queued\n",
- X tp->tm_mon+1, tp->tm_mday, tp->tm_hour, tp->tm_min, ep.site,
- X fcnt, (fcnt==1 ? "file" : "files"), scnt,
- X (scnt==1 ? "file" : "files"));
- X
- X if (bytes)
- X sprintf (pbuf, "%s\tmax bytes reached. UUCP bytes was %ld, byte count = %ld\n",
- X buf, n_bytes, bytes);
- X else
- X sprintf (pbuf, "%s", buf);
- X
- X if (vflg)
- X fprintf (stdout, "%s",pbuf);
- X
- X if (log != NULL)
- X fputs (pbuf, log);
- X
- X}
- SHAR_EOF
- echo x - extracting nbatcher.h
- sed 's/^X//' << 'SHAR_EOF' > nbatcher.h
- X/* char sccsid[] = "@(#)nbatcher.h 1.4 8/14/86"; */
- X
- X/******************************************************
- X * nbatcher.h - defines for nbatcher source
- X *
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X *****************************************************/
- X
- X/* things you might want to change */
- X
- X#define UUCPDIR "/usr/spool/uucp" /* uucp spool directory */
- X#define COMPRESS "/usr/bin/compress -F -q" /* where compress resides */
- X#define UUX "/usr/bin/uux - -r" /* default command */
- X#define DFL_BYTES 100000L /* default max. UUCP bytes */
- X#define NEWSUID 47 /* USENET used id */
- X#define NEWSGID 80 /* USENET group id */
- X
- X/* things you shouldn't change */
- X
- X#define FALSE 0
- X#define TRUE 1
- X#define COLON ':'
- X
- Xstruct file_entry { /* structure of control file */
- X char site[30]; /* name of remote site */
- X char hour[80]; /* string for hour to batch */
- X short c_bits; /* # of compression bits */
- X long m_bytes; /* max. # of bytes on UUCP queue */
- X char command[128]; /* command string */
- X} ep;
- X
- Xextern FILE *lfp, /* lockfile pointer */
- X *tfp, /* tempfile pointer */
- X *log; /* logfile pointer */
- X
- Xextern long n_bytes; /* # of bytes already on UUCP queue */
- Xextern long cu_bytes; /* cumculative bytes of batch files */
- X
- Xchar *mktemp(),
- X *strcpy(),
- X *strcat();
- X
- Xextern char *tfile; /* temp file */
- X
- Xextern short vflg, /* verbose flag */
- X nfiles; /* number of news articles per
- X UUCP batch file */
- X
- Xint system();
- X
- Xextern int fcnt, /* number of files batched */
- X scnt; /* spool count */
- SHAR_EOF
- echo x - extracting bst.c
- sed 's/^X//' << 'SHAR_EOF' > bst.c
- X/* char sccsid[] = "@(#)bst.c 1.4 8/14/86"; */
- X
- X/****************************************************************
- X * bst.c - a utility for indicating how many
- X * news articles are ready for batching
- X * for each site in the BACTHDIR directory.
- X *
- X * R.J. Esposito
- X * Bell of Penna.
- X * June 1986
- X *
- X ****************************************************************/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X
- X
- Xchar buf[512];
- XFILE *dd;
- Xstruct direct dp;
- Xstruct stat st;
- X
- Xmain()
- X{
- X int fd, j;
- X int bcnt, lcnt;
- X
- X if(chdir(BATCHDIR) != 0) {
- X perror(BATCHDIR);
- X exit(1);
- X }
- X
- X if((dd=fopen(".", "r")) == NULL) {
- X printf("can't open %s\n", BATCHDIR);
- X exit(1);
- X }
- X
- X while((fread((char *)&dp, sizeof(dp), 1, dd)) == 1) {
- X if(dp.d_ino == 0 || dp.d_name[0] == '.')
- X continue;
- X if(stat(dp.d_name, &st) != 0) {
- X printf("can't stat %s\n", dp.d_name);
- X exit(1);
- X }
- X if(st.st_size <= 0 )
- X continue;
- X if((fd=open(dp.d_name, 0)) < 0) {
- X printf("can't open %s\n", dp.d_name);
- X exit(1);
- X }
- X lcnt = 0;
- X while((bcnt=read(fd,buf,512)) > 0) {
- X for(j=0; j<=bcnt; j++)
- X if(buf[j] == '\n')
- X lcnt += 1;
- X }
- X close(fd);
- X printf("%s\t %d article", dp.d_name, lcnt);
- X printf("%c\n", lcnt > 1 ? 's' : ' ');
- X }
- X}
- SHAR_EOF
- echo x - extracting README
- sed 's/^X//' << 'SHAR_EOF' > README
- XThe program provides a better way to handling batching of USENET news
- Xto neighboring sites. IT works with 2.10B and later, including
- X2.10.3B, which provides compression batching.
- X
- XPlease send any questions and bug reports to me (bpa!espo) for
- Xdistribution to the net. This software is public domain, and cannot be
- Xsold for any profit.
- X
- XNbatcher was written for UNIX (trademark of AT&T) System V, but should
- Xbe compatible with most version currently being used today. It is
- Xpresently running on a VAX (trademark of DEC) 11/780 feeding 5 remote
- Xsites with news. Two important issues MUST be noted here.
- X
- XSince nbatcher checks the UUCP directory for each site listed in the
- Xcontrol file, directory configuration should be UUCPDIR/sitename, e.g.
- X/usr/spool/uucp/foo for site foo. But since not everyone is generic,
- XI've allowed nbatcher to skip over the UUCP byte counting routine if
- Xthis is not so. In addition to this, some uucpcleanup daemons remove
- Xthe site directory if there's nothing spooled there. When this
- Xhappens, nbatcher will notify you of this and continue on.
- X
- XThe other issue is that you MUST configure your NEWSLIB/sys file using the
- Xbatch syntax as described in the USENET Installation document. Field 3
- Xshould contain the `F' flag indicating a batched transmission for that
- Xsite and field 4 should contain the filename where news article's full
- Xpathname will be appended to. Nbatcher requires that the filename in
- Xfield 4 match the sitename in the control file. For example, the entry:
- X foo:net,mod,usa,na,to.foo:F:/usr/spool/batchnews/foo
- Xsays that all news articles going to site `foo' will be batched, using
- Xthe file `foo' in /usr/spool/batchnews. Nbatcher's control file entry:
- X foo:3,14,22:16:150000:
- Xwill get the news article's full pathname from /usr/spool/batchnews/foo
- Xfor batching. This requirement MUST be adhered to for nbatcher to work
- Xcorrectly. I believe most sites that batch news use this type of
- Xconfiguration, since its easy to keep track of a remote site's work.
- XNote that the name of the directory "/usr/spool/batchnews" is set
- Xin the Makefile.
- X
- XThe manual page describes the control file, as does nbatcher.doc. Note
- Xthat even though nbatcher indicates max bytes has been reached, if that
- Xsite gets compressed batches, the next time nbatcher runs for that site
- Xwork could get scheduled.
- X
- XAlso included is a utility program called "bst," BatchSTatus, which
- Xshows who many news articles are currently in the batch file for each
- Xsystem. Just type "make bst" for that and copy it to where you want,
- Xusually LIBDIR. Note that bst does reads on the directory structure
- Xdirectly.
- X
- XInstallation is simple: look at the first few #define's in nbatcher.h;
- Xalso edit the Makefile for the appropriate BATCHDIR and LIBDIR for your
- Xsite. Type "make" or "make install."
- X
- XNOTE: Read the comments in parse.c concerning MAX_BYTES. This is the
- Xmaximum amount of bytes per site that's allowed in the control file for
- Xm_bytes. Change it at your own risk!
- X
- X Bob Esposito bpa!espo
- X Bell of Penna.
- SHAR_EOF
- echo x - extracting nbatcher.ctl
- sed 's/^X//' << 'SHAR_EOF' > nbatcher.ctl
- X*
- X* NBATCHER.CTL
- X* Edit and install in your NEWSLIB directory.
- X*
- X* Comments start with *; data lines look like:
- X* site:hours:bits:queue_size:command
- X* Where
- X* site = name of the remote site
- X* hour = when to do work (* is all, off is never, 22-4 is ok)
- X* bits = passed on to compress via -b; null gets default
- X* queue_size = Max # bytes allowed in UUCP queue before postponing
- X* command = optional command line
- X*
- X* See manpage and README for more info.
- SHAR_EOF
- echo x - extracting nbatcher.doc
- sed 's/^X//' << 'SHAR_EOF' > nbatcher.doc
- X
- XDETAILED DESCRIPTION OF nbatcher.ctl FILE
- X
- X Document for nbatcher
- X
- XAs distributed, the nbatcher.ctl contains a terse summary of its
- Xformat. For each site you feed news to, providing that site uses the
- X":F:BATCHDIR/site" batching syntax in the sys file, a corresponding
- Xentry should exist in nbatcher.ctl Each line is a five-field,
- Xcolon-separated entry indicating what to do for that site.
- X
- XThe format is:
- X site:hour:c_bits:m_bytes:command
- XThe site field is the name of the UUCP site that will get the batched
- Xnews. There MUST be a file in the BATCHDIR (in my case
- X/usr/spool/batchnews) matching this name that contains a listing of
- Xfiles to batch. This is where rnews puts the news article filenames
- Xwhen batching is used. Nbatcher will complain about mismatches.
- X
- XNext is the hour field. The syntax directly imitates the crontab entry
- Xfor hour. If hour = "*", than assume a match for every hour. If hour
- X= "off", then no work will ever be spooled for this site. (This is the
- Xonly difference from crontab). You can specify a specific hour, like 8
- Xor 09 or 22. Or a range of hours, like 10-15, meaning check for work
- Xfrom 10 AM thru 3 PM. (you can also cycle thru a 24 hr. period by
- Xsaying 22-4, which will assume a match for 10PM thru 4AM). Also, hours
- Xcomma separated like 7,14,21, says check for work at 7 AM, 4PM and 9PM
- Xonly. This gives lots of flexibility for sites that feed multiple
- Xremotes.
- X
- XNext is the c_bits field, which has a value of 9-16, or may be left
- Xblank. If non-null, this field is directly passed on to compress with
- Xthe -b flag. If it is null, then no compression is done for this
- Xsite.
- X
- XThe m_bytes field is the maximum number of bytes allowed on the UUCP
- Xqueue at any time. It defaults to 100K bytes, and if its greater than
- X1MB (see parse.c about MAX_BYTES), than it uses 1MB as the default
- Xnumber of bytes.
- X
- XWhat nbatcher does is first check the UUCPDIR for that site and sums up
- Xthe number of bytes already on-queue. The size of each news article is
- Xaccumulated prior to batching to the tempfile, and this accumulation +
- Xthe UUCP on-queue bytes are checked to see if they surpass the m_bytes
- Xvalue. If not, things proceed normally. But if it would exceed the
- Xmax value, then spool whats already been batched, and save the
- Xremainder of the articles for the next scheduled batch.
- X
- XThis is so noted in the nbatcher.log file, showing the UUCP bytes that
- Xwere on-queue (if any), and the number of bytes that were spooled.
- XAlso, if nbatcher is run from a terminal instead of from cron, a copy
- Xof what gets logged is sent to the terminal.
- X
- XThe last field is the command field. This optional field is used for
- Xspecific UUCP command execution. As written, it defaults to "uux - -r
- Xsite!rnews". Since my uux doesn't require the -z option for rnews, I
- Xleft it out of the UUX define in nbatcher.h This can easily be changed
- Xfor your own taste, or just use the command field.
- X
- XExample:
- X site-A:3,10:16:450000:
- XCheck for work for site-A at 3AM and 10AM. Use compress with
- X16 bits and only spool up to 450K bytes, using "uux - -r site-A!rnews".
- X
- XAnother example:
- X foo:23-4::300000:uux - -r -z foo!rnews
- XCheck for work for foo between 11PM and 4AM. No compression is used
- Xand spool up to 300K bytes using the command field.
- X
- XThis format should help ease UUCP congestion on the local site for
- Xnews. I currently feed 5 remote sites, compressed and non-compressed
- Xformats, and have noticed a vast improvement in disk space as well as
- Xout port availability for UUCP. It has allowed me to check for work
- Xfor all sites every hour, since there's a limit on how much gets
- Xqueued. And if the remote doesn't answer on the hourly UUCP poll, so
- Xwhat!! Nbatcher just won't spool any more until the m_bytes limit
- Xon-queue is reduced.
- X
- XThe best results is to run nbatcher, via cron as the USENET
- Xadministrator (NEWSUID), at least once per hour.
- X
- XNbatcher was designed to weed out any illegal syntax in the control
- Xfile, but its not bug-proof, so use some discretion.
- X
- XBob Esposito
- XBell of Penna.
- XJune 1986
- SHAR_EOF
- echo x - extracting nbatcher.1
- sed 's/^X//' << 'SHAR_EOF' > nbatcher.1
- X.TH NBATCHER 1 LOCAL
- X.SH NAME
- Xnbatcher \- new batching system for news
- X.SH SYNOPSIS
- X.B nbatcher
- X.IR "(run out of " cron ".)"
- X.SH DESCRIPTION
- X.PP
- X.I Nbatcher
- Xis a program designed to send batched USENET data out
- Xin an orderly and controlled fashion, while providing alternative
- Xtransmission methods. As such, it is a replacement for
- X.I csendbatch
- Xand the like, which typically require many entries in
- X.IR crontab .
- X.I Nbatcher
- Xis intended to be run hourly out of
- X.I cron
- Xas the USENET administrator (NEWSID).
- X.PP
- X.I Nbatcher
- Xscans the file
- X.I nbatcher.ctl
- Xin the NEWSLIB directory to determine if work should be spooled
- Xfor a system. In the control file, lines starting with asterisks
- Xare ignored; data lines are comprised of five colon\-separated
- Xfields:
- X.RS
- Xsite:hour:bits:queue_size:command
- X.RE
- X.TP
- XThe ``site'' field is the USENET neighbor; it is the same as the site in the
- Xnews
- X.I sys
- Xfile.
- X.TP
- XThe ``hours'' field is patterned after
- X.IR cron's.
- XIf the hour is ``off,'' no work is spooled for the site. An hour of
- X``*'' matches every hour. It is also possible to specify specific
- Xhours, (e.g., 8, 09, or 22), a comma-separated list (e.g., 8,09,22),
- Xor a twenty\-four range, like 10-\15 for 10am through 3pm and 22\-4,
- Xfor 10pm through 4am.
- X.TP
- XThe ``bits'' field specifies the number of bits to use in compression;
- Xit should be a number between nine and 16, inclusive, or null. If
- Xa number is specified, it is passed on to the
- X.I compress
- Xprogram via the ``\-b'' flag.
- X.TP
- XThe ``queue_size'' field specifies the maximum number of bytes allowed
- Xin the UUCP queue for this site. The default is 100K.
- XThe UUCP queue size is determined by lookin in the
- X.IR /usr/spool/uucp/ site
- Xdirectory; if it doesn't exist, the check is bypassed. If there is
- Xdata in the UUCP queue,
- X.I nbatcher
- Xwill only queue up as many USENET transfers as will fit within the limit
- Xspecified by the ``queue_size'' field.
- X.TP
- XThe ``command'' field is used to specific the UUCP command that should
- Xbe used to queue the job; the default is ``uux \- \-r site!rnews'';
- Xnote the absence of the ``\-z'' flag.
- X.PP
- XTo set up a USENET neighbor to be controlled by nbatcher, the news
- X.I sys
- Xentry for the neighbor must be modified to specify the ``F'' flag,
- Xand the file used to contain the article names must be
- X.RI BATCHDIR/sysname ,
- Xwhere BATCHDIR is set in the Makefile as distributed.
- X.SH "FILES"
- XNEWSLIB/nbatcher.log
- X.br
- X.in +1i
- Xa logfile of failures, postponements, etc.
- X.in -1i
- X.SH BUGS
- XParsing of the control file is fairly robust, but not perfect.
- SHAR_EOF
- echo x - extracting Makefile
- sed 's/^X//' << 'SHAR_EOF' > Makefile
- X#
- X# Makefile for nbatcher Version 1.4
- X#
- X# R.J. Esposito
- X# Bell of Penna.
- X# June 1986
- X#
- X
- X# You MUST define BATCHDIR as the place where USENET
- X# puts the articles to be batched.
- X#
- X# LIBDIR is where you USENET library is and also
- X# MUST be defined.
- X#
- X# Define PCODE for parse.c if you don't have/can't use
- X# _doprnt.
- X
- XBATCHDIR = /usr/spool/batchnews
- XLIBDIR = /misc/lib/usenet
- X
- XCFLAGS = -O -c
- XLFLAGS = -s
- XDFLAGS = -DBATCHDIR='"$(BATCHDIR)"' -DLIBDIR='"$(LIBDIR)"'
- X# PCODE = -DUSE_PORT_CODE
- X
- XOBJS = define.o main.o parse.o checkwork.o nbatcher.o logger.o
- X
- XSRC = define.c main.c parse.c checkwork.c nbatcher.c logger.c nbatcher.h bst.c
- XDOCS = README nbatcher.ctl nbatcher.doc nbatcher.1
- X
- Xall: $(OBJS)
- X $(CC) $(DFLAGS) $(LFLAGS) -o nbatcher $(OBJS)
- X chmod 0755 nbatcher
- X
- Xinstall: all
- X cp nbatcher $(LIBDIR)
- X chmod 0755 $(LIBDIR)/nbatcher
- X cp nbatcher.ctl $(LIBDIR)/nbatcher.ctl
- X chmod 0644 $(LIBDIR)/nbatcher.ctl
- X
- Xdefine.o: nbatcher.h define.c
- X $(CC) $(CFLAGS) $(DFLAGS) define.c
- X
- Xmain.o: nbatcher.h main.c
- X $(CC) $(CFLAGS) $(DFLAGS) main.c
- X
- Xparse.o: nbatcher.h parse.c
- X $(CC) $(CFLAGS) $(DFLAGS) $(PCODE) parse.c
- X
- Xcheckwork.o: nbatcher.h checkwork.c
- X $(CC) $(CFLAGS) $(DFLAGS) checkwork.c
- X
- Xnbatcher.o: nbatcher.h nbatcher.c
- X $(CC) $(CFLAGS) $(DFLAGS) nbatcher.c
- X
- Xlogger.o: nbatcher.h logger.c
- X $(CC) $(CFLAGS) $(DFLAGS) logger.c
- X
- Xbst: bst.c
- X $(CC) $(CFLAGS) $(DFLAGS) bst.c
- X $(CC) $(LFLAGS) -o bst bst.o
- X
- Xclean:
- X rm -f *.o *.shar
- X
- Xclobber: clean
- X rm -f nbatcher
- X
- X
- Xshar:
- X shar -v $(SRC) $(DOCS) Makefile > nbatcher.shar
- SHAR_EOF
- exit
-
-