nbatcher re-posting
Bob Esposito
espo at bpa.BELL-ATL.COM
Wed Aug 20 08:29:55 AEST 1986
This is a re-posting of the nbatcher source for spooling
news articles. The fixes are mostly the inclusion of
newlines where needed, but the most important one is to
prevent copies of the news articles being written to the
logfile, is some cases.
A copy was also sent to rs at mirror (mod.sources) for archive
purposes.
--
//////////////////////////////////////////
* Bob Esposito ...espo at bpa.bell-atl.com *
//////////////////////////////////////////
---------cut-here------------cut-here--------------cut-here--------------------
#!/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, "
More information about the Comp.sources.unix
mailing list