[comp.sources.unix] v12i030: C News alpha release, Part05/14

rsalz@uunet.UU.NET (Rich Salz) (10/22/87)

Submitted-by: utzoo!henry (Henry Spencer)
Posting-number: Volume 12, Issue 30
Archive-name: cnews/part05



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 14)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README.FIRST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.FIRST'\"
else
echo shar: Extracting \"'README.FIRST'\" \(2991 characters\)
sed "s/^X//" >'README.FIRST' <<'END_OF_FILE'
XFor a number of reasons, notably continued slow progress and strong demand,
XGeoff and I have decided to release an "official alpha test" C news widely.
X
XThis IS NOT the definitive release.  As the word "alpha" implies, it
Xis not even beta test.  This release is NOT nicely packaged, it is NOT
Xbug-free, it does NOT have the full desired functionality (for example,
Xit doesn't have moderated-group security yet), it undoubtedly has some
Xportability and compatibility problems, it is not properly documented,
Xand it WILL be superseded by a later version in a conversion that is
XNOT guaranteed to be painless.  In other words, use at your own risk.
XIt is essentially our current working version.
X
XIf you don't have time to explore its idiosyncrasies and babysit its
Xproblems, you should not even try to put it up.  Note the redistribution
Xrestrictions in the copyright notices, by the way -- these are meant solely
Xto keep this alpha release under control, and will not be present in the
Xfinal release.
X
XWe strongly suggest, however, that anyone currently running one of our
Xold informal pre-alpha releases upgrade to this one.  It will be no harder
Xto install than the pre-alpha one was, and it fixes a near-endless list
Xof bugs, bad behaviors, and gaps in functionality.
X
X
XWe know that this release has problems of various kinds.  We intend to fix
Xthem.  We are interested in hearing about the more subtle ones.  We DO NOT
Xwant to see 2000 lines of diff listing!  Why?  First, because our source
Xwill have changed by the time your diffs arrive.  Second, because there is
Xa good chance that we are already aware of the problem you've found; we
Xmay even have fixed it already.  Send us a SHORT description of what you've
Xfound and what (if anything) you've done about it; if we want diffs, we
Xwill certainly ask.  The same applies to changes and improvements.
X
XIf you want us to consider changes/fixes/etc, send them to us, don't just
Xpost them to the net.  We reserve the right to ignore all posted changes
Xand "improvements" when preparing the definitive release.  For at least the
Xduration of the alpha release, only postings from us are officially part
Xof C news.
X
XReaders should not assume that comments saying "to do" in the source
Xor suggestively-named files reflect our current thinking on what needs
Xdoing or should be done.
X
XThe place to send comments, complaints, problem reports, etc. is NOT to
XGeoff or me personally, but to:
X
X	utzoo!cnews-alpha
X
XUtzoo connects to half the known universe (well, not quite, but try via
Xattunix, allegra, ihnp4, decvax, pyramid, floyd, hoptoad, kitty, linus,
Xmnetor, utai, utcsri, or watmath).  Sorry, we don't have a direct uunet
Xhookup at present.  Nor are we on the Arpa internet, although those of
Xyou with MX-comprehending mailers can try cnews-alpha@utzoo.toronto.edu
X(it is supposed to work).  If you are off in the wonderful (?) world of
XBitnet, try cnews-alpha@utzoo.utoronto or words to that effect.
X
X					Geoff Collyer
X					Henry Spencer
END_OF_FILE
if test 2991 -ne `wc -c <'README.FIRST'`; then
    echo shar: \"'README.FIRST'\" unpacked with wrong size!
fi
# end of 'README.FIRST'
fi
if test -f 'batch/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'batch/README'\"
else
echo shar: Extracting \"'batch/README'\" \(2263 characters\)
sed "s/^X//" >'batch/README' <<'END_OF_FILE'
XThis is the C News batching subsystem.  To install, inspect/change the
Xconfiguration stuff at the top of the Makefile, and then "make install".
X
XThe only thing in here that even needs compiling is batchmake.c; it needs
Xnone of the news include files etc., although it may need some of the
Xstuff in ../libc if your system does not have getopt(), error(), or the
Xfull set of string functions.  All other programs in here are shell files.
X
Xnewsbatch.8.p is a prototype manual page; the Makefile knows how to turn
Xit into a real one.  teststuff is a shell archive of test files; again,
Xthe Makefile knows what to do with them.
X
XThe sys file must direct the filenames to be batched for system xxx into
Xthe file $NEWSCTL/batch/b.xxx/togo .  Then arrangements must be made
Xfor sendbatches to be run periodically. 
X
XYou will need to revise queuelen and roomfor to work on your system --
Xtheir innards are system-dependent.  You may want to change the policies
Xdictated by queuemax, roomfor, and batchsize.  You might also want to
Xrevise batchmunch and batchxmit, although the defaults should work fairly
Xwell in ordinary situations on orthodox Unixes.  Note that one can override
Xthe defaults for specific feeds by placing non-default versions in suitable
Xplaces; see the manual page.  MAKE SURE YOU MAKE THEM EXECUTABLE.
X
XThe batchmunch and batchxmit files are set up for 2.11 compatibility, using
Xthe stupid "#! cunbatch" format; to just send the stuff compressed without
Xthe silly uncompressed header, take the 'echo' out of batchmunch.  (If you
Xare talking to an old system, you may also need to change 'rnews' in
Xbatchxmit to 'cunbatch'.)
X
XNote that because sendbatches suspends batching when space gets low or
Xqueues get long, outgoing news transmission can quietly stop if you're
Xusing a lot of disk for other things.  It is HIGHLY desirable to monitor
Xthe batcher backlogs, perhaps by a daily run of something resembling:
X
X	mail yourself </usr/lib/news/batchlog
X
XNote that the test procedure indicated at the end of "make install" checks
Xout sendbatches, batchmake, and batchprep in a simple way, but does not
Xtest the other stuff much.
X
XOh yes:  if your shell is too old to understand comments begun with #, you
Xare in trouble and have a lot of editing to do...
END_OF_FILE
if test 2263 -ne `wc -c <'batch/README'`; then
    echo shar: \"'batch/README'\" unpacked with wrong size!
fi
# end of 'batch/README'
fi
if test -f 'batch/batchmake.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'batch/batchmake.c'\"
else
echo shar: Extracting \"'batch/batchmake.c'\" \(3008 characters\)
sed "s/^X//" >'batch/batchmake.c' <<'END_OF_FILE'
X/*
X * batchmake - send a bunch of news articles as an unbatch script
X *
X * Usage: batchmake [-d dir] listfile
X *
X *	where listfile is a file containing a list, one per line, of
X *	full pathnames of files containing articles.  Only the first
X *	field of each line is looked at, so there can be more if needed
X *	for other things.
X *
X *	The -d option specifies a directory where most articles are
X *	likely to be; the program chdirs there to speed things up.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#ifndef READSIZE
X#define READSIZE 8192	/* allows for even 4.2 worst case file systems */
X#endif
Xchar buffer[READSIZE];
X
Xchar *progname;
X
Xchar *dir = NULL;		/* NULL means don't bother chdiring. */
Xint dirlen;			/* strlen(dir) */
Xint debug = 0;			/* Debugging? */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	int c;
X	int errflg = 0;
X	extern int optind;
X	extern char *optarg;
X	register FILE *list;
X	char article[BUFSIZ];
X	int ret;
X
X	progname = argv[0];
X	while ((c = getopt(argc, argv, "d:x")) != EOF)
X		switch (c) {
X		case 'd':	/* Directory containing many articles. */
X			dir = optarg;
X			dirlen = strlen(dir);
X			break;
X		case 'x':	/* Debugging. */
X			debug++;
X			break;
X		case '?':
X		default:
X			errflg++;
X			break;
X		}
X	if (errflg || optind != argc-1) {
X		(void) fprintf(stderr,
X			"Usage: batchmake [-d dir] listfile\n");
X		exit(2);
X	}
X
X	if (access(argv[optind], 0) < 0)
X		error("can't find `%s'", argv[optind]);
X	if (access(argv[optind], 04|02) < 0)
X		error("inadequate permissions on `%s'", argv[optind]);
X	list = fopen(argv[optind], "r");
X	if (list == NULL)
X		error("unable to open `%s'", argv[optind]);
X
X	if (dir != NULL && access(dir, 04|01) < 0)
X		error("inaccessible directory: `%s'", dir);
X	if (dir != NULL)
X		if (chdir(dir) < 0)
X			error("can't chdir to `%s'", dir);
X
X	while (fgets(article, sizeof article, list) != NULL)
X		process(article);
X
X	exit(0);
X}
X
X/*
X - process - process an article
X */
Xprocess(article)
Xchar *article;
X{
X	char *p;
X	register int artfile;
X	register int count;
X	struct stat sbuf;
X
X	*(article + strcspn(article, "\n\t ")) = '\0';
X	if (dir != NULL && strncmp(article, dir, dirlen) == 0 &&
X			article[dirlen] == '/')
X		p = article+dirlen+1;
X	else
X		p = article;
X
X	artfile = open(p, 0);
X	if (artfile < 0) {
X		/*
X		 * Can't read the article.  This isn't necessarily a
X		 * disaster, since things like cancellations will do
X		 * this.  Mumble and carry on.
X		 */
X		if (debug)
X			warning("can't find `%s'", p);
X		return;
X	}
X
X	if (fstat(artfile, &sbuf) < 0)
X		error("internal disaster, can't fstat", "");
X	if ((sbuf.st_mode&S_IFMT) != S_IFREG) {
X		close(artfile);
X		return;		/* Don't try to batch directories etc. */
X	}
X
X	(void) printf("#! rnews %ld\n", sbuf.st_size);
X	fflush(stdout);
X
X	while ((count = read(artfile, buffer, sizeof buffer)) > 0)
X		if (write(1, buffer, count) != count)
X			error("write failure in `%s'", article);
X	if (count < 0)
X		error("read failure in `%s'", article);
X
X	(void) close(artfile);
X}
END_OF_FILE
if test 3008 -ne `wc -c <'batch/batchmake.c'`; then
    echo shar: \"'batch/batchmake.c'\" unpacked with wrong size!
fi
# end of 'batch/batchmake.c'
fi
if test -f 'expire/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expire/Makefile'\"
else
echo shar: Extracting \"'expire/Makefile'\" \(2199 characters\)
sed "s/^X//" >'expire/Makefile' <<'END_OF_FILE'
X# If you don't have a dirent.h header file, add -I. to CFLAGS and see README.
XDEFINES = -DEXP
XCFLAGS = -O $(DEFINES) -I../include
XLINTFLAGS = $(DEFINES) -Dvoid=int
XLDFLAGS = -i
XOBJS=expire.o
XLIBS= ../libcnews/libcnews.a ../libc/*.a
XD = NEWSARTS=`pwd` NEWSCTL=`pwd`
XTHEM = expire histconv histdups histinfo histslash lowest mkdbm mkhistory \
X	olddate oldfile upact xargs
XNEWSBIN = /usr/lib/newsbin
X
Xexpire: $(OBJS)
X	$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -ldbm -o $@
X
Xhistinfo: histinfo.o
X	$(CC) $(LDFLAGS) histinfo.o $(LIBS) -o $@
X
Xxargs:	xargs.o
X	$(CC) $(LDFLAGS) xargs.o -o $@
X
Xlowest:	lowest.o
X	$(CC) $(LDFLAGS) lowest.o -o $@
X
Xlowest.o:	lowest.c
X	@echo 'If this cannot find dirent.h, see README for instructions.'
X	$(CC) $(CFLAGS) -c lowest.c
X
Xlint:
X	lint -ha $(LINTFLAGS) expire.c -ldbm
X
Xtidy:
X	rm -f junk history history.pag history.dir history.o active
X	rm -f history.n* mon.out testctl lowest oldfile xargs
X	rm -f active.old active.new
X	rm -rf ns mod unmod arch
X
Xclean:	tidy
X	rm -f *.o expire olddate histslash mkdbm histinfo
X
Xolddate:	olddate.o
X	$(CC) $(LDFLAGS) olddate.o $(LIBS) -o $@
X
Xoldfile:	oldfile.o
X	$(CC) $(LDFLAGS) oldfile.o $(LIBS) -o $@
X
Xhistslash:	histslash.o
X	$(CC) $(LDFLAGS) histslash.o $(LIBS) -o $@
X
Xmkdbm:	mkdbm.o
X	$(CC) $(LDFLAGS) mkdbm.o $(LIBS) -ldbm -o $@
X
Xr:	testctl mod unmod history active ns arch expire
X	NEWSARTS=`pwd`/ns NEWSCTL=`pwd` NEWSBIN=`pwd`/.. expire -a `pwd`/arch -p testctl
X
Xtestctl:	testctl.p
X	sed "s;X;`pwd`;g" testctl.p >$@
X
Xmod:
X	rm -rf mod
X	mkdir mod
X
Xunmod:
X	rm -rf unmod
X	mkdir unmod
X
Xarch:
X	rm -rf arch
X	mkdir arch
X
Xhistory:	ns histinfo histslash xargs mkdbm
X	NEWSARTS=`pwd`/ns NEWSCTL=`pwd` NEWSBIN=`pwd`/.. mkhistory >$@
X	mkdbm <$@
X	mv it.pag $@.pag
X	mv it.dir $@.dir
X	rm -f ns/mon.out
X	@echo `find ns -type f -print | wc -l` articles in ns
X	@echo `egrep '^body$$' ns.p | wc -l` should be there
X	@echo `wc -l history` lines in history
X	@echo all three of those numbers should be the same!
X	touch history
X
Xactive:	active.p
X	cp active.p $@
X
Xns:	ns.p oldfile olddate
X	rm -rf ns
X	ns.p
X
Xtryup:	upact ns active lowest
X	NEWSARTS=`pwd`/ns NEWSCTL=`pwd` NEWSBIN=`pwd`/.. sh -x upact
X
Xinstall:	$(THEM)
X	mkdir $(NEWSBIN)/expire
X	cp $(THEM) $(NEWSBIN)/expire
END_OF_FILE
if test 2199 -ne `wc -c <'expire/Makefile'`; then
    echo shar: \"'expire/Makefile'\" unpacked with wrong size!
fi
# end of 'expire/Makefile'
fi
if test -f 'expire/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expire/README'\"
else
echo shar: Extracting \"'expire/README'\" \(2324 characters\)
sed "s/^X//" >'expire/README' <<'END_OF_FILE'
Xexpire is the biggie here.  See manual page.
X
XFor those of you running 2.10.2 or later, expire does not update the
X"oldest" field in the active file.  This is done by upact.  Run it now
Xand then, say once a week.  lowest is part of upact.
X
Xmkhistory will produce, on its standard output, a rebuilt history file
Xreflecting the actual /usr/spool/news contents.
X
Xmkdbm rebuilds the dbm files for a history file.  History file comes in
Xon stdin, dbm files are created as it.pag and it.dir.
X
Xhistconv will convert B history files to C format, in a simplistic
Xway; it ignores the possibility of files with explicit expiry dates.  If
Xthis isn't satisfactory, mkhistory is your only recourse.
X
Xhistdups, histinfo, and histslash are parts of mkhistory.
X
Xolddate and oldfile are auxiliary programs for testing expire.
X
XThe .p files are for testing expire.  Test by saying "make r"; see
Xthe Makefile.  One wart is that the results of the tests have to be
Xchecked by hand -- there is no automatic comparison against the right
Xanswers.
X
XYou should put something like "rm -f /usr/lib/news/history.n*" in your
X/etc/rc, since files by that name will be left around if your system
Xcrashes in the middle of an expire, and expire will balk at running if
Xthey are present -- expire is quite paranoid about proceeding if there
Xappears to be something seriously wrong.
X
XSeveral things here assume that there are no entirely-numeric directory
Xnames in the article tree.
X
XPortability notes:
X
XYou'll need getopt(3), a full string(3) (strspn, strtok, etc.), and POSIX-
Xcompatible directory functions.  See libc.  
X
XYou'll need dbm or some substitute [see inews/vers/uglix/dbm.c].
X
XThe getdate() routine supplied here wants a V7-style ftime() structure
Xfor information on time zone etc.  If you haven't got ftime(), you'll
Xhave to fudge this somehow.
X
XYou'll need xargs(1) for mkhistory; note that one is supplied just in case.
X
XA specific problem of directory functions is that since Berkeley botched
Xthe name of the header file for them, there is no entirely standard place
Xfor it.  This stuff assumes that it is available as <dirent.h>, as per POSIX;
Xif this is not correct, you'll have to add -I. to CFLAGS and make a file
X"dirent.h" containing something like "#include <whatever_the_name_is.h>".
XYou may also need to add "#define dirent direct".
END_OF_FILE
if test 2324 -ne `wc -c <'expire/README'`; then
    echo shar: \"'expire/README'\" unpacked with wrong size!
fi
# end of 'expire/README'
fi
if test -f 'expire/histinfo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expire/histinfo.c'\"
else
echo shar: Extracting \"'expire/histinfo.c'\" \(2487 characters\)
sed "s/^X//" >'expire/histinfo.c' <<'END_OF_FILE'
X/*
X * histinfo - print history file lines for the named articles
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>		/* for modified time (date received) */
X#include "newspaths.h"
X
X#define MAXLINE 1024
X#define STRLEN(s) (sizeof(s) - 1)	/* s must be a char array */
X
Xchar *progname;
Xint debug;
X
XFILE *efopen();
X
Xchar *spdir;
Xint spdirlen;
X
X/*
X * main - parse arguments and handle options
X */
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	int c;
X	int errflg = 0;
X	FILE *in;
X	extern int optind;
X	extern char *optarg;
X
X	progname = argv[0];
X	while ((c = getopt(argc, argv, "d")) != EOF)
X		switch (c) {
X		case 'd':
X			++debug;
X			break;
X		default:
X			errflg++;
X			break;
X		}
X	if (errflg) {
X		(void) fprintf(stderr, "usage: %s [-d]\n", progname);
X		exit(2);
X	}
X
X	spdir = spoolfile((char *)NULL);
X	spdirlen = strlen(spdir);
X	
X	if (optind == argc)
X		process(stdin, "stdin");
X	else
X		for (; optind < argc; optind++) {
X			in = efopen(argv[optind], "r");
X			process(in, argv[optind]);
X			(void) fclose(in);
X		}
X	exit(0);
X}
X
X/*
X * process - process input file
X */
Xprocess(in, inname)
XFILE *in;
Xchar *inname;
X{
X	char *nl, *files;
X	char line[MAXLINE], msgid[MAXLINE], expiry[MAXLINE];
X	char datercv[30];
X	struct stat statb;
X	static char msgidnm[] =  "Message-ID: ";
X	static char expnm[] =    "Expires: ";
X	char *rindex(), *strcpy();
X
X	/* set defaults */
X	(void) strcpy(expiry, "-");
X	(void) strcpy(msgid, "<swill@trash>");
X
X	/* read until EOF or blank line (end of headers) */
X	while (fgets(line, sizeof line, in) != NULL && strcmp(line, "\n") != 0) {
X		if ((nl = rindex(line, '\n')) != NULL)
X			*nl = '\0';			/* trim newline */
X		if (strncmp(line, msgidnm, STRLEN(msgidnm)) == 0)
X			(void) strcpy(msgid, line+STRLEN(msgidnm));
X		else if (strncmp(line, expnm, STRLEN(expnm)) == 0)
X			(void) strcpy(expiry, line+STRLEN(expnm));
X	}
X
X	/* generate the file name */
X	files = inname;
X	if (strncmp(files, spdir, spdirlen) == 0 &&
X	    files[spdirlen] == '/')
X		files += spdirlen + 1;	/* skip spool dir. & slash */
X
X	/* generate the date received */
X	(void) fstat(fileno(in), &statb);
X	(void) sprintf(datercv, "%ld", statb.st_mtime);
X
X	/* whomp out the history line */
X	(void) fputs(msgid, stdout);
X	(void) putchar('\t');
X	(void) fputs(datercv, stdout);
X	(void) putchar('~');
X	(void) fputs(expiry, stdout);
X	(void) putchar('\t');
X	(void) fputs(files, stdout);
X	(void) putchar('\n');
X	(void) fflush(stdout);
X}
X
X/*
X * unprivileged - no-op to keep pathname stuff happy
X */
Xvoid
Xunprivileged()
X{
X}
END_OF_FILE
if test 2487 -ne `wc -c <'expire/histinfo.c'`; then
    echo shar: \"'expire/histinfo.c'\" unpacked with wrong size!
fi
# end of 'expire/histinfo.c'
fi
if test -f 'include/news.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/news.h'\"
else
echo shar: Extracting \"'include/news.h'\" \(2826 characters\)
sed "s/^X//" >'include/news.h' <<'END_OF_FILE'
X/*
X * definitions unique to news
X */
X
X#define MAXLINE 512
X#define MAXFILE 100		/* maximum file name length */
X#define MAXCOMP 14		/* maximum file name component length */
X#define MAXHOST 64
X#define ARTNUMWIDTH 5		/* article-number width */
X
X#define SPOOLTMP ".tmpXXXXXX"
X#ifndef STDPATH
X#define STDPATH "/bin:/usr/bin:/usr/ucb"	/* standard search path */
X#endif
X
X/* status bits */
X#define ST_OKAY		0	/* nothing wrong */
X#define ST_SHORT	(1<<1)	/* article shorter than byte count; truncated? */
X#define ST_ACCESS	(1<<2)	/* no access permission */
X#define ST_NUKED	(1<<3)	/* article was deliberately dropped - OK */
X#define ST_DROPPED	(1<<4)	/* article was accidentally dropped */
X#define ST_DISKFULL	(1<<5)	/* disk full - give up */
X
X/* newsgroup specific definitions */
X#define NGSEP ','		/* separates groups */
X#define NGNEG '!'		/* preceding a pattern, negates it */
X#define NGDELIM '.'		/* within a group */
X#define FNDELIM '/'		/* within a group, on disk */
X#define SFNDELIM "/"		/* string of FNDELIM */
X
X#define max(a,b) ((a) > (b)? (a): (b))
X#define min(a,b) ((a) < (b)? (a): (b))
X#define iswhite(c) ((c) == ' ' || (c) == '\t')
X/* STREQ is an optimised strcmp(a,b)==0 */
X#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
X/* STREQN is an optimised strncmp(a,b,n)==0; assumes n > 0 */
X#define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)
X#define STRLEN(s) (sizeof (s) - 1)	/* s must be a char array */
X#ifdef SLOW
X#define INDEX(src, chr, dest) (dest) = index(src, chr)
Xchar *index();
X#else
X#define INDEX(src, chr, dest) \
X	for ((dest) = (src); *(dest) != '\0' && *(dest) != (chr); ++(dest)) \
X		; \
X	if (*(dest) == '\0') \
X		(dest) = NULL		/* N.B.: missing semi-colon */
X#endif
X
X#define YES 1
X#define NO 0
X
X/* signal types (mostly for Suns): tailor to suite local tastes */
X#ifdef sun
Xtypedef int (*sigret_t)();
Xtypedef void (*sigarg_t)();
X#else
Xtypedef int (*sigret_t)();
Xtypedef int (*sigarg_t)();
X#endif
X
X/* imports from news */
Xextern int remote;
Xextern char *progname;
Xextern FILE *fopenclex(), *fopenwclex();	/* open w close-on-exec */
Xextern char *strsave(), *hostname(), *getwd();
Xextern char *fgetmfs();			/* internal interface */
X#define fgetms(fp) fgetmfs(fp, 0)	/* unbounded read */
X#define cfgetms(fp) fgetmfs(fp, 1)	/* unbounded read with continuation */
X
X/* imports from libc */
Xextern char *strcpy(), *strcat(), *strncpy(), *strncat();	/* strings.h */
Xextern char *index(), *rindex();	/* strings.h */
Xextern FILE *popen();			/* stdio.h */
Xextern char *sprintf();			/* stdio.h */
Xextern struct passwd *getpwnam();	/* pwd.h */
Xextern struct group *getgrnam();	/* grp.h */
Xextern time_t time();			/* sys/times.h? */
Xextern char *ctime();			/* sys/timeb.h? */
Xextern long atol();
Xextern char *malloc(), *realloc();
Xextern char *emalloc();
Xextern char *mktemp();
Xextern char *getenv();
END_OF_FILE
if test 2826 -ne `wc -c <'include/news.h'`; then
    echo shar: \"'include/news.h'\" unpacked with wrong size!
fi
# end of 'include/news.h'
fi
if test -f 'lib.proto/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib.proto/README'\"
else
echo shar: Extracting \"'lib.proto/README'\" \(2418 characters\)
sed "s/^X//" >'lib.proto/README' <<'END_OF_FILE'
XThis README file is badly out of date but better than nothing.
X
Xactive		local, newsgroups, highest (& lowest) article #s, (y/n/m flag)
Xanne.jones	link to mary.brown
Xarbitron	local, shell script, run monthly to generate readership survey
Xbatch		binary, generates outgoing news batches
Xbatcher		local, shell script, invoke batch
Xcaesar		binary, caesar cypher, used by readnews
Xcompress	shell script, invokes the real compress & fiddles exit status
Xcontrol		local, directory of shell scripts invoked by control messages
Xcvt.hist	converts old 3-field history file to new 4-field history file
Xerrlog		stderr of realinews, should be zero length; if not, read it
Xexpire		binary, removes old articles
Xexplist		local, tells expire what criteria to use
Xgngp		g/newsgroup-pattern/p, used by inews
Xhelp		readnews help file
Xhistdups	awk file, used by mkhistory
Xhistinfo	binary, used by mkhistory
Xhistory		local, ascii history file, used by realinews & expire
Xhistory.dir	local, dbm(3) history file bits
Xhistory.pag	local, dbm(3) history file keys and values
Xhistslash	used by mkhistory
Xinews		shell script, invokes realinews without -p
Xkill.groups	for future expansion
Xkill.people	for future expansion
Xlocalgroups	local, used by control/checkgroups
Xlog		stdout of realinews, fairly boring
Xmary.brown	local (can be tailored), shell script, censor used by inews
Xmkdbm		regenerates dbm(3) history file from ascii one
Xmkhistory	regenerates history file from articles (in /usr/spool/news)
Xmodroutes	local, routes to backbones for various mod groups
Xnewshist	binary, looks up history entry by message-id
Xnewsreply	local, shell script, generate mail reply address from article
Xnewsreply.from	domain mailer version of above
Xnewsreply.path	non-domain mailer version of above
Xnukehist	shell script, clears the decks for debugging
Xorganisation	local, value for Organization: header generated by inews
Xprof		directory of profiling results
Xrealinews	binary, a lean, mean, news relayin' machine
Xrecmail		binary, receive news by mail
Xrecnews		binary, receive news somehow
Xrn		directory, rn's private files
Xrnews		shell script, invokes realinews with -p
Xsendnews	shell script, mails news articles to ./uurec
Xsys		local, controls distribution of articles to other sites & programs
Xtest		directory, timing and test runs
Xuucpmapmuncher	local, shell script, mails mod.map to someone for unwrapping
Xuurec		shell script, unwraps news sent by ./sendnews
END_OF_FILE
if test 2418 -ne `wc -c <'lib.proto/README'`; then
    echo shar: \"'lib.proto/README'\" unpacked with wrong size!
fi
# end of 'lib.proto/README'
fi
if test -f 'lib.proto/control/checkgroups' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib.proto/control/checkgroups'\"
else
echo shar: Extracting \"'lib.proto/control/checkgroups'\" \(2010 characters\)
sed "s/^X//" >'lib.proto/control/checkgroups' <<'END_OF_FILE'
X#! /bin/sh
X: checkgroups - check active file for missing or extra newsgroups.
X:	stdin must a checkgroups news article, sends mail to $NOTIFY
X:	after updating $nl/newsgroups from $nl/localgroups
X: v1.4 of 9/4/84, adapted to C news
XPATH=/bin:/usr/bin:/usr/ucb; export PATH
XNEWSCTL=${NEWSCTL-/usr/lib/news}; export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}; export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}; export NEWSARTS
XNOTIFY=usenet
X
X# generate newsgroups from localgroups & stdin
Xcp $NEWSCTL/localgroups $NEWSCTL/newsgroups
Xsed '1,/^$/d' >>$NEWSCTL/newsgroups	# behead the article (snuff headers)
X
X# generate list of approved newsgroups from $nl/newsgroups
Xecho junk >/tmp/$$a
Xecho control >>/tmp/$$a
X# [^.]*\. in next two egreps was net.|mod.|fa., which is inadequate - geoff
Xsed 's/[ \	].*//' $NEWSCTL/newsgroups |
X	egrep "^([^.]*\.|general)" >>/tmp/$$a
Xsort -u /tmp/$$a -o /tmp/$$a
X
X# generate list of locally-present newsgroups from $nl/active
Xegrep "^([^.]*\.|general|junk|control)" $NEWSCTL/active |
X	sed 's/ .*//' | sort  -u >/tmp/$$b
X
X# compare 'em & note differences
Xcomm -13 /tmp/$$a /tmp/$$b >/tmp/$$remove
Xcomm -23 /tmp/$$a /tmp/$$b >/tmp/$$add
X
Xif test -s /tmp/$$remove; then
X	echo "The following newsgroups are not valid and should be removed."
X	sed "s/^/	/" /tmp/$$remove
X	echo ""
X	echo "You can do this by executing the command:"
X	echo "	$NEWSCTL/control/rmgroup \\"
X	sed 's;.*;		& \\;' /tmp/$$remove
X	echo ""
Xfi 2>&1 >/tmp/$$out
X
Xif test -s /tmp/$$add; then
X	echo "The following newsgroups were missing." # "and were added."
X	sed "s/^/	/" /tmp/$$add
X	echo ""
X
X#	for i in `cat /tmp/$$add`
X#	do
X# *** "Subject: cmsg " is a hideous botch of a kludge-hack; avoid it!
X#		inews -h <<!
X#Control: newgroup $i
X#Newsgroups: control
X#Subject: newgroup $i
X#Distribution: general
X#
X#Create $i locally.
X#!
X#	done
X
Xfi 2>&1 >>/tmp/$$out
X
Xif test -s /tmp/$$out; then
X	(echo "Subject: Problems with your active file"; echo "";
X	 cat /tmp/$$out) | mail $NOTIFY
Xfi
X
Xrm -f /tmp/$$*		# clean up temporaries
END_OF_FILE
if test 2010 -ne `wc -c <'lib.proto/control/checkgroups'`; then
    echo shar: \"'lib.proto/control/checkgroups'\" unpacked with wrong size!
fi
# end of 'lib.proto/control/checkgroups'
fi
if test -f 'libc/fgetmfs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/fgetmfs.c'\"
else
echo shar: Extracting \"'libc/fgetmfs.c'\" \(2122 characters\)
sed "s/^X//" >'libc/fgetmfs.c' <<'END_OF_FILE'
X/*
X * fgetmfs - read an arbitrarily long, possibly continued line;
X * return a pointer to it, in malloced memory.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <fgetmfs.h>
X
X/* One could make these arguments, with defaults. */
X#define INITLN 90		/* initial allocation per line */
X#define GROWLN 200		/* additional allocation size */
X
X/* imports from libc */
Xchar *malloc(), *realloc(), *rindex();
X
Xchar *
Xfgetmfs(fp, cont)		/* fget malloced, flagged string */
XFILE *fp;
Xint cont;			/* honour \ continuations? */
X{
X	register unsigned sz;
X	register char *line;
X	register char *segment;
X	register char *morep;
X	register int another = 0;
X
X	/* allocate room for an initial segment of a line */
X	sz = INITLN;
X	line = malloc(sz);
X	if (line == NULL)
X		return NULL;		/* no memory, can't go on */
X	segment = line;
X	morep = line + sz - 2;
X	do {
X		register char *nlp;
X
X		/* read the first segment of a line */
X		*morep = '\0';			/* mark end of segment */
X		if (fgets(segment, (int)sz-(segment-line), fp) == NULL) {
X			free(line);		/* EOF: give up */
X			return NULL;
X		}
X		while (*morep != '\0' && *morep != '\n') {	/* line didn't fit */
X			/* extend the allocation */
X			sz += GROWLN;
X			line = realloc(line, sz);
X			if (line == NULL)
X				return NULL;	/* no memory, can't go on */
X			segment = line + sz - GROWLN - 1;
X			morep = line + sz - 2;
X
X			/* read the next segment */
X			*morep = '\0';
X			if (fgets(segment, GROWLN+1, fp) == NULL) {
X				free(line);	/* EOF: give up */
X				return NULL;
X			}
X		}
X
X		/* got a whole line: is it to be continued? */
X		if (cont && (nlp = rindex(line, '\n')) != NULL &&
X		    nlp > line && *--nlp == '\\') {
X			*nlp = '\0';		/* delete "\\\n" */
X			segment = nlp;
X			another = 1;		/* read next line */
X		    	if (cont == CONT_NOSPC) {
X				register int c;
X
X				/* discard leading whitespace */
X				while ((c = getc(fp)) != EOF && c != '\n' &&
X				   isascii(c) && isspace(c))
X					;
X				if (c != EOF)
X					(void) ungetc(c, fp);
X		    	}
X		} else
X			another = 0;
X	} while (another);
X#ifdef pdp11
X	line = realloc(line, strlen(line)+1);	/* save space */
X#endif
X	return line;
X}
END_OF_FILE
if test 2122 -ne `wc -c <'libc/fgetmfs.c'`; then
    echo shar: \"'libc/fgetmfs.c'\" unpacked with wrong size!
fi
# end of 'libc/fgetmfs.c'
fi
if test -f 'libc/getopt.3' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/getopt.3'\"
else
echo shar: Extracting \"'libc/getopt.3'\" \(2755 characters\)
sed "s/^X//" >'libc/getopt.3' <<'END_OF_FILE'
X.TH GETOPT 3 local
X.DA 25 March 1982
X.SH NAME
Xgetopt \- get option letter from argv
X.SH SYNOPSIS
X.ft B
Xint getopt(argc, argv, optstring)
X.br
Xint argc;
X.br
Xchar **argv;
X.br
Xchar *optstring;
X.sp
Xextern char *optarg;
X.br
Xextern int optind;
X.ft
X.SH DESCRIPTION
X.I Getopt
Xreturns the next option letter in
X.I argv
Xthat matches a letter in
X.IR optstring .
X.I Optstring
Xis a string of recognized option letters;
Xif a letter is followed by a colon, the option is expected to have
Xan argument that may or may not be separated from it by white space.
X.I Optarg
Xis set to point to the start of the option argument on return from
X.IR getopt .
X.PP
X.I Getopt
Xplaces in
X.I optind
Xthe
X.I argv
Xindex of the next argument to be processed.
XBecause
X.I optind
Xis external, it is normally initialized to zero automatically
Xbefore the first call to 
X.IR getopt .
X.PP
XWhen all options have been processed (i.e., up to the first
Xnon-option argument),
X.I getopt
Xreturns
X.BR EOF .
XThe special option
X.B \-\-
Xmay be used to delimit the end of the options;
X.B EOF
Xwill be returned, and
X.B \-\-
Xwill be skipped.
X.SH SEE ALSO
Xgetopt(1)
X.SH DIAGNOSTICS
X.I Getopt
Xprints an error message on
X.I stderr
Xand returns a question mark
X.RB ( ? )
Xwhen it encounters an option letter not included in
X.IR optstring .
X.SH EXAMPLE
XThe following code fragment shows how one might process the arguments
Xfor a command that can take the mutually exclusive options
X.B a
Xand
X.BR b ,
Xand the options
X.B f
Xand
X.BR o ,
Xboth of which require arguments:
X.PP
X.RS
X.nf
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int c;
X	extern int optind;
X	extern char *optarg;
X	\&.
X	\&.
X	\&.
X	while ((c = getopt(argc, argv, "abf:o:")) != EOF)
X		switch (c) {
X		case 'a':
X			if (bflg)
X				errflg++;
X			else
X				aflg++;
X			break;
X		case 'b':
X			if (aflg)
X				errflg++;
X			else
X				bproc();
X			break;
X		case 'f':
X			ifile = optarg;
X			break;
X		case 'o':
X			ofile = optarg;
X			break;
X		case '?':
X		default:
X			errflg++;
X			break;
X		}
X	if (errflg) {
X		fprintf(stderr, "Usage: ...");
X		exit(2);
X	}
X	for (; optind < argc; optind++) {
X		\&.
X		\&.
X		\&.
X	}
X	\&.
X	\&.
X	\&.
X}
X.RE
X.PP
XA template similar to this can be found in
X.IR /usr/pub/template.c .
X.SH HISTORY
XWritten by Henry Spencer, working from a Bell Labs manual page.
XBehavior believed identical to the Bell version.
X.SH BUGS
XIt is not obvious how
X`\-'
Xstanding alone should be treated;  this version treats it as
Xa non-option argument, which is not always right.
X.PP
XOption arguments are allowed to begin with `\-';
Xthis is reasonable but reduces the amount of error checking possible.
X.PP
X.I Getopt
Xis quite flexible but the obvious price must be paid:  there is much
Xit could do that it doesn't, like
Xchecking mutually exclusive options, checking type of
Xoption arguments, etc.
END_OF_FILE
if test 2755 -ne `wc -c <'libc/getopt.3'`; then
    echo shar: \"'libc/getopt.3'\" unpacked with wrong size!
fi
# end of 'libc/getopt.3'
fi
if test -f 'libc/stdio.fast/fgets.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/stdio.fast/fgets.c'\"
else
echo shar: Extracting \"'libc/stdio.fast/fgets.c'\" \(2693 characters\)
sed "s/^X//" >'libc/stdio.fast/fgets.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include "memcpy.h"
X
X#define THRESHOLD 12			/* memcpy vs in-line threshold */
X
Xchar *
Xfgets(s, lim, fp)			/* optimised version */
Xchar *s;
Xint lim;
Xregister FILE *fp;
X{
X	char *rets = s;			/* normal return by default */
X
X	--lim;				/* leave room for terminating null */
X	while (lim > 0) {		/* room left in s */
X		int origbytesleft;
X		char *nlp = NULL;	/* points at newline */
X
X		/*
X		 * Find next newline (if any) by running through the
X		 * stdio buffer until it runs out or a newline is seen.
X		 * This dominates the running time for long lines.
X		 */
X		{
X			register char *bp = fp->_ptr;
X			register int loops;
X			/* bytes to the end of s or the stdio buffer */
X			register int bytesleft = fp->_cnt;	/* to EOB */
X
X			if (bytesleft > lim)	/* buffer longer than s */
X				bytesleft = lim; /* only copy to s's end */
X			origbytesleft = bytesleft;
X
X			/*
X			 * This code uses Duff's Device (tm Tom Duff)
X			 * to unroll the newline recogniser:
X			 * for (++bytesleft; --bytesleft > 0; )
X			 *	if (*bp++ == '\n') {
X			 *		nlp = bp;	# NB points after \n
X			 *		break;
X			 *	}
X			 * Sorry the code is so ugly.
X			 */
X			if (bytesleft > 0) {
X				/* TODO: #ifdef for non-twos-complement mchs */
X				loops = (bytesleft+8-1) >> 3;	/* /8 round up */
X
X				switch (bytesleft&(8-1)) {	/* %8 */
X				case 0: do {
X#define SPOTNL if (*bp++ == '\n') { nlp = bp; break; }
X						SPOTNL;
X					case 7:	SPOTNL;
X					case 6:	SPOTNL;
X					case 5:	SPOTNL;
X					case 4:	SPOTNL;
X					case 3:	SPOTNL;
X					case 2:	SPOTNL;
X					case 1:	SPOTNL;
X					} while (--loops > 0);
X				}
X			}
X		}
X		/*
X		 * If no newline was seen, copy remaining bytes from stdio
X		 * buffer; else copy up to and including the newline.
X		 * Adjust counts, then copy the bytes & adjust pointers.
X		 * This dominates the running time for short lines.
X		 */
X		{
X			register int copy;
X
X			if (nlp == NULL)
X				copy = origbytesleft;
X			else
X				copy = nlp - fp->_ptr;
X			lim -= copy;
X			fp->_cnt -= copy;
X			if (copy < THRESHOLD) {
X				register char *rs = s, *bp = fp->_ptr;
X
X				for (++copy; --copy > 0; )
X					*rs++ = *bp++;
X				s = rs;
X				fp->_ptr = bp;
X			} else {
X				memcpy(s, fp->_ptr, copy);
X				s += copy;
X				fp->_ptr += copy;
X			}
X		}
X		/*
X		 * Quit if we saw a newline or "s" is full,
X		 * else refill the stdio buffer and go again.
X		 */
X		if (nlp != NULL || lim <= 0)
X			break;
X		else if (fp->_cnt <= 0) {		/* buffer empty */
X			register int c = getc(fp);	/* fill buffer */
X
X			if (c == EOF) {
X				if (s == rets)		/* s is empty */
X					rets = NULL;
X				break;			/* EOF return */
X			} else {
X				if ((*s++ = c) == '\n')
X					break;		/* newline return */
X				--lim;
X			}
X		}
X	}
X	*s = '\0';	/* terminate s */
X	return rets;
X}
END_OF_FILE
if test 2693 -ne `wc -c <'libc/stdio.fast/fgets.c'`; then
    echo shar: \"'libc/stdio.fast/fgets.c'\" unpacked with wrong size!
fi
# end of 'libc/stdio.fast/fgets.c'
fi
if test -f 'libc/stdio.fast/rdwr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/stdio.fast/rdwr.c'\"
else
echo shar: Extracting \"'libc/stdio.fast/rdwr.c'\" \(2257 characters\)
sed "s/^X//" >'libc/stdio.fast/rdwr.c' <<'END_OF_FILE'
X/*
X * fread and fwrite (optimised version)
X * TODO: i/o to/from the user's buffer directly if the transfer is long enough.
X *	If there's a block-aligned block (or more) in the middle, do it directly.
X */
X
X#include <stdio.h>
X#include "memcpy.h"
X
X#define THRESHOLD 12			/* memcpy vs in-line threshold */
X
Xtypedef unsigned char putc_t;		/* cast putc args to this type */
X
Xint
Xfread(ptr, size, count, fp)
Xchar *ptr;
Xint size, count;
Xregister FILE *fp;
X{
X	register unsigned bytes = count * size;
X	unsigned origbytes = bytes;
X
X	while (bytes > 0) {	/* bytes still to be read */
X		{
X			/* all of bytes in buffer */
X			register int copy = fp->_cnt;
X
X			if (copy > bytes)	/* buffer longer than ptr */
X				copy = bytes;	/* only fill ptr */
X			bytes -= copy;	/* adjust to reflect next loop */
X			fp->_cnt -= copy;
X			if (copy < THRESHOLD) {
X				register char *rptr = ptr, *bp = fp->_ptr;
X
X				for (++copy; --copy > 0; )
X					*rptr++ = *bp++;
X				ptr = rptr;
X				fp->_ptr = bp;
X			} else {
X				memcpy(ptr, fp->_ptr, copy);
X				ptr += copy;
X				fp->_ptr += copy;
X			}
X		}
X		if (bytes > 0) {	/* more to read, but buffer is empty */
X			register int c = getc(fp);	/* refill buffer */
X
X			if (c == EOF)
X				break;
X			else {
X				*ptr++ = c;
X				--bytes;
X			}
X		}
X	}
X	if (size == 0)
X		return count;			/* or 0 */
X	else
X		return (origbytes - bytes) / size;
X}
X
Xint
Xfwrite(ptr, size, count, fp)
Xchar *ptr;
Xint size, count;
Xregister FILE *fp;
X{
X	register unsigned bytes = count * size;
X	unsigned origbytes = bytes;
X
X	while (bytes > 0) {	/* bytes still to be written */
X		{
X			register int copy = fp->_cnt;
X
X			if (copy > bytes)	/* buffer longer than ptr */
X				copy = bytes;	/* only empty ptr */
X			bytes -= copy;	/* adjust to reflect next loop */
X			fp->_cnt -= copy;
X			if (copy < THRESHOLD) {
X				register char *rptr = ptr, *bp = fp->_ptr;
X
X				for (++copy; --copy > 0; )
X					*bp++ = *rptr++;
X				ptr = rptr;
X				fp->_ptr = bp;
X			} else {
X				memcpy(fp->_ptr, ptr, copy);
X				ptr += copy;
X				fp->_ptr += copy;
X			}
X		}
X		if (bytes > 0)	/* more to write, but buffer is full */
X			if (putc((putc_t)*ptr, fp) == EOF) /* flush buffer */
X				break;
X			else {
X				ptr++;
X				--bytes;
X			}
X	}
X	if (size == 0)
X		return count;			/* or 0 */
X	else
X		return (origbytes - bytes) / size;
X}
END_OF_FILE
if test 2257 -ne `wc -c <'libc/stdio.fast/rdwr.c'`; then
    echo shar: \"'libc/stdio.fast/rdwr.c'\" unpacked with wrong size!
fi
# end of 'libc/stdio.fast/rdwr.c'
fi
if test -f 'libc/strings/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/strings/Makefile'\"
else
echo shar: Extracting \"'libc/strings/Makefile'\" \(2552 characters\)
sed "s/^X//" >'libc/strings/Makefile' <<'END_OF_FILE'
X# String library.
X
X# Configuration settings:  how should "size_t", "void *", "const" be written?
X# "size_t" is what's needed to hold the result of sizeof; beware of problems
X# with compatibility here, because X3J11 uses this for e.g. the third
X# argument of strncpy() as well.  You may need to make it "int" even if
X# this is a lie.  "void *" is the generic pointer type, "char *" in most
X# existing implementations.  "const" is the keyword marking read-only
X# variables and parameters, unimplemented in most existing implementations.
X# These things need to be defined this way because they must be fitted into
X# both the .h files and the .c files; see the make instructions for string.h
X# farther down.
XSIZET = int
XVOIDSTAR = char *
XLVOIDSTAR = char*	# Lint shell file has problems with * alone.  Barf.
XCONST = 
X
XCONF = -DSIZET=$(SIZET) -DVOIDSTAR='$(VOIDSTAR)' -DCONST='$(CONST)'
XLCONF = -DSIZET=$(SIZET) -DVOIDSTAR='$(LVOIDSTAR)' -DCONST='$(CONST)'
X
X# Things you might want to put in CFLAGS or LINTFLAGS.
X# -DCHARBITS=0377		Required if compiler lacks "unsigned char".
X# -Dvoid=int			Required if compiler lacks "void".
X# -DUNIXERR			Unix-like errno stuff, can test strerror().
X# -DBERKERR			Like UNIXERR but for Berklix (4BSD).
X# -I.				string.h from here, not /usr/include.
X
XCFLAGS = -O $(CONF) -DUNIXERR -I.
XLINTFLAGS = -hpan $(LCONF) -DUNIXERR -Dvoid=int -DCHARBITS=0377 -I.
XLDFLAGS = -i
X
X# Name lists.
XSTRING = index.o rindex.o strcat.o strchr.o strcmp.o strcpy.o strcspn.o \
X	strlen.o strncat.o strncmp.o strncpy.o strpbrk.o strrchr.o strspn.o \
X	strtok.o strstr.o memcpy.o memccpy.o memcmp.o memchr.o memset.o \
X	bcopy.o bcmp.o bzero.o strerror.o
XCSTRING = index.c rindex.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c \
X	strlen.c strncat.c strncmp.c strncpy.c strpbrk.c strrchr.c strspn.c \
X	strtok.c strstr.c memcpy.c memccpy.c memcmp.c memchr.c memset.c \
X	bcopy.c bcmp.c bzero.c strerror.c
XDTR = README Makefile $(CSTRING) tester.c string.h.proto
X
X# Locations, for installation (somewhat system-dependent).
XDEST=..
X
Xtester.o:	string.h
X
Xmv:	$(STRING)
X	mv $(STRING) $(DEST)
X
Xr:	tester
X	@echo 'No news is good news.  Note: strerror() test is VERY system-dependent.'
X	tester
X
Xtester:	tester.o $(STRING)
X	cc $(LDFLAGS) tester.o $(STRING) -o tester
X
Xstring.h:	string.h.proto
X	sed 's/SIZET/$(SIZET)/g;s/VOIDSTAR /$(VOIDSTAR)/g' string.h.proto >string.h
X
Xmemory.h:	string.h
X	egrep mem string.h >memory.h
X
Xlint:	string.h
X	lint $(LINTFLAGS) tester.c $(CSTRING)
X
Xclean:
X	rm -f tester a.out *.o string.h memory.h dtr
X
Xdtr:	$(DTR)
X	makedtr $(DTR) >dtr
END_OF_FILE
if test 2552 -ne `wc -c <'libc/strings/Makefile'`; then
    echo shar: \"'libc/strings/Makefile'\" unpacked with wrong size!
fi
# end of 'libc/strings/Makefile'
fi
if test -f 'libc/strings/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libc/strings/README'\"
else
echo shar: Extracting \"'libc/strings/README'\" \(2642 characters\)
sed "s/^X//" >'libc/strings/README' <<'END_OF_FILE'
XThis is a public-domain reimplementation of string(3) and friends, notably
Xmemory(3) and bstring(3) (except ffs).  Not derived from licensed software.
XThis code may be used on any computer system for any purpose by anyone.
X
XRelative to my old net.sources posting, this one adds some functions and
Xfixes one or two obscure bugs.  There has been another string library
Xposted in recent times, with many more functions; I haven't inspected it
Xand can't comment on its relationship to mine.  Alas, the manual pages
Xfor this stuff are copyright by various people other than me, so I can't
Xinclude them.  See your local Unix manuals.
X
XThis distribution implements precisely the union of the string functions
Xof the SVID, 4BSD, X3J11, and V7.  Included is a large test program that
Xexercises everything quite thoroughly.  (Note that some existing libraries,
Xincluding e.g. V7, flunk one or more of these tests.)
X
XIn the event of conflict between the definitions from various places, the
Xnewer or more portable one is chosen.  That is, X3J11 overrules the SVID,
Xwhich in turn overrules older Unixes.
X
XThe code is written for maximal portability.  Some efficiency has been
Xsacrificed in the cause of meticulously avoiding possible portability
Xproblems.  For example, this code never assumes that a pointer can be
Xmoved past the end of an array and then backed up.  Many of these functions
Xcan be implemented more efficiently if machine-dependent assumptions are
Xmade; memcpy is a particular glaring case.
X
XSimplistically:  put this stuff into a source directory, inspect Makefile
Xfor compilation options that need changing to suit your local environment,
Xand then do "make r".  This compiles the functions and the test program and
Xruns the tests.  If there are no complaints, put string.h in /usr/include
X(you may also want to "make memory.h" and put it in /usr/include) and add
Xthe functions (*.o except for tester.o) to your C library.  The internal
Xinterdependencies are:
X
X	index	needs	strchr
X	rindex	needs	strrchr
X	bcopy	needs	memcpy
X	bcmp	needs	memcmp
X	bzero	needs	memset
X
XI haven't included an implementation of Berkeley's ffs function partly
Xbecause it's not trivial to do in a portable way, and partly because I
Xdon't really see it as a string function.
X
XA weakness in the tester program is that it uses quite short strings for
Xeverything, and pays no real attention to alignment issues.  Optimized
Ximplementations of things like memcpy would need a more elaborate set of
Xtest cases to put them through their full paces.
X
X				Henry Spencer @ U of Toronto Zoology
X				{allegra,ihnp4,decvax,pyramid}!utzoo!henry
X				Wed Jun 25 19:21:34 EDT 1986
END_OF_FILE
if test 2642 -ne `wc -c <'libc/strings/README'`; then
    echo shar: \"'libc/strings/README'\" unpacked with wrong size!
fi
# end of 'libc/strings/README'
fi
if test -f 'newsbin.proto/control/checkgroups' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'newsbin.proto/control/checkgroups'\"
else
echo shar: Extracting \"'newsbin.proto/control/checkgroups'\" \(2010 characters\)
sed "s/^X//" >'newsbin.proto/control/checkgroups' <<'END_OF_FILE'
X#! /bin/sh
X: checkgroups - check active file for missing or extra newsgroups.
X:	stdin must a checkgroups news article, sends mail to $NOTIFY
X:	after updating $nl/newsgroups from $nl/localgroups
X: v1.4 of 9/4/84, adapted to C news
XPATH=/bin:/usr/bin:/usr/ucb; export PATH
XNEWSCTL=${NEWSCTL-/usr/lib/news}; export NEWSCTL
XNEWSBIN=${NEWSBIN-/usr/lib/newsbin}; export NEWSBIN
XNEWSARTS=${NEWSARTS-/usr/spool/news}; export NEWSARTS
XNOTIFY=usenet
X
X# generate newsgroups from localgroups & stdin
Xcp $NEWSCTL/localgroups $NEWSCTL/newsgroups
Xsed '1,/^$/d' >>$NEWSCTL/newsgroups	# behead the article (snuff headers)
X
X# generate list of approved newsgroups from $nl/newsgroups
Xecho junk >/tmp/$$a
Xecho control >>/tmp/$$a
X# [^.]*\. in next two egreps was net.|mod.|fa., which is inadequate - geoff
Xsed 's/[ \	].*//' $NEWSCTL/newsgroups |
X	egrep "^([^.]*\.|general)" >>/tmp/$$a
Xsort -u /tmp/$$a -o /tmp/$$a
X
X# generate list of locally-present newsgroups from $nl/active
Xegrep "^([^.]*\.|general|junk|control)" $NEWSCTL/active |
X	sed 's/ .*//' | sort  -u >/tmp/$$b
X
X# compare 'em & note differences
Xcomm -13 /tmp/$$a /tmp/$$b >/tmp/$$remove
Xcomm -23 /tmp/$$a /tmp/$$b >/tmp/$$add
X
Xif test -s /tmp/$$remove; then
X	echo "The following newsgroups are not valid and should be removed."
X	sed "s/^/	/" /tmp/$$remove
X	echo ""
X	echo "You can do this by executing the command:"
X	echo "	$NEWSCTL/control/rmgroup \\"
X	sed 's;.*;		& \\;' /tmp/$$remove
X	echo ""
Xfi 2>&1 >/tmp/$$out
X
Xif test -s /tmp/$$add; then
X	echo "The following newsgroups were missing." # "and were added."
X	sed "s/^/	/" /tmp/$$add
X	echo ""
X
X#	for i in `cat /tmp/$$add`
X#	do
X# *** "Subject: cmsg " is a hideous botch of a kludge-hack; avoid it!
X#		inews -h <<!
X#Control: newgroup $i
X#Newsgroups: control
X#Subject: newgroup $i
X#Distribution: general
X#
X#Create $i locally.
X#!
X#	done
X
Xfi 2>&1 >>/tmp/$$out
X
Xif test -s /tmp/$$out; then
X	(echo "Subject: Problems with your active file"; echo "";
X	 cat /tmp/$$out) | mail $NOTIFY
Xfi
X
Xrm -f /tmp/$$*		# clean up temporaries
END_OF_FILE
if test 2010 -ne `wc -c <'newsbin.proto/control/checkgroups'`; then
    echo shar: \"'newsbin.proto/control/checkgroups'\" unpacked with wrong size!
fi
# end of 'newsbin.proto/control/checkgroups'
fi
if test -f 'rnews/setnewsids/makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/setnewsids/makefile'\"
else
echo shar: Extracting \"'rnews/setnewsids/makefile'\" \(2159 characters\)
sed "s/^X//" >'rnews/setnewsids/makefile' <<'END_OF_FILE'
X# makefile for C news setnewsids
X
X# define NOSTOREVAL if your dbm store() returns no value (as in orig. v7)
X# -I. for fcntl.h if present
XDEFINES= -I../../include -I../. -DSTATIC=
X# -Dvoid=int			# if your compiler doesn't understand void's
X# -DMAXLONG=017777777777L	# if your compiler lacks "unsigned long" type
X# -Dindex=strchr -Drindex=strrchr	# if not on (System III or V or PWB)
X
XCFLAGS=-O $(DEFINES) # -pg # -Z: John Bruner's Z0MAGIC (unmapped first page)
XLIBS= ../memcpy.o ../../libcnews/*.a -ldbm ../../libc/*.a # -lstdio
XLLIBS=-llocal
XPROPTS=-l132
XP=impr -p
X
XPOSSDEPFILES=fcntl.h gethostname.c getwd.c dbm.c mkdir.c ftime.c clsexec.c memcpy.c
X# adjust next three lines for your OS; sources are links to vers/*/*.c
XDEPHDR=
XDEPSRC= clsexec.c memcpy.c zeropad.c
XDEPOBJ= clsexec.o memcpy.o zeropad.o
X
XLIBSRCS= ../../libcnews/*.c
XLIBOBJS= ../../libcnews/../libcnews.a ../../libc/../libc.a
XSRC=setnewsids.c
XOBJ=setnewsids.o
XFILES=$(SRC)
XLINT=lint
XLINTFLAGS=-haz $(DEFINES)
X
Xall: setnewsids
X
XTODO.grep: TODO
X	-egrep TODO TODO ../../include/*.h *.h *.c sh/* >$@
X	-egrep TODO ../../libc/memcpy.fast/src/*.c ../../libcnews/*.c >>$@
X
Xv7 v8 v9 usg bsd42: clean
X	for file in vers/$@/*.c; do ln $$file; done
X	@echo 'Now edit makefile DEPSRC and DEPOBJ definitions to match:'
X	@echo vers/$@/*.c | sed 's;vers/$@/;;g'
X
Xsetnewsids: $(OBJ) ../../libcnews/*.c
X	$(CC) $(CFLAGS) $(OBJ) $(LIBS) -o $@
Xlint: $(SRC)
X	$(LINT) $(LINTFLAGS) $(SRC) $(LIBS) $(LLIBS) | egrep -v ':$$'
Xlintport: $(SRC)
X	$(LINT) $(LINTFLAGS) -p $(SRC) $(LIBS) $(LLIBS)
X
Xprint: $(FILES)
X	pr $(PROPTS) $? | $P
X	touch print
Xdistr: $(FILES)
X	(echo setnewsids update of `date`; echo ""; bundle $?) | /bin/mail cnews-updates
X	touch distr
Xclean:
X	rm -f core a.out setnewsids *.o $(POSSDEPFILES)
X
X# header dependencies follow
Xsetnewsids.o: ../../include/news.h ../../include/newspaths.h
Xactive.o: ../../include/news.h
Xcontrol.o: ../../include/news.h headers.h
Xfileart.o: ../../include/news.h headers.h
Xheaders.o: ../../include/news.h headers.h
Xhistory.o: ../../include/news.h headers.h
Xhostname.o: ../../include/news.h
Xsys.o: ../../include/news.h system.h
Xtransmit.o: ../../include/news.h headers.h system.h
END_OF_FILE
if test 2159 -ne `wc -c <'rnews/setnewsids/makefile'`; then
    echo shar: \"'rnews/setnewsids/makefile'\" unpacked with wrong size!
fi
# end of 'rnews/setnewsids/makefile'
fi
if test -f 'rnews/vers/usg/dbm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/usg/dbm.c'\"
else
echo shar: Extracting \"'rnews/vers/usg/dbm.c'\" \(2521 characters\)
sed "s/^X//" >'rnews/vers/usg/dbm.c' <<'END_OF_FILE'
X/*
X * Incredibly slow Uglix dbm simulation.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#define MAXFILE 140
X#define MAXLINE 1024
X
Xstatic char pagname[MAXFILE];
Xstatic FILE *db;
Xstatic int dbrdonly;
X
Xtypedef struct {
X	char *dptr;
X	int dsize;
X} datum;
X
Xdbminit(file)
Xchar *file;
X{
X	char *strcat(), *strcpy();
X
X	dbrdonly = 0;
X	strcpy(pagname, file);
X	strcat(pagname, ".pag");
X	if ((db = fopen(pagname, "r+")) == NULL) {
X		db = fopen(pagname, "r");
X		dbrdonly = 1;
X	}
X	if (db == NULL) {
X		warning("cannot open database %s\n", file);
X		return -1;
X	}
X	return 0;
X}
X
Xdatum
Xfetch(key)
Xdatum key;
X{
X	datum item;
X
X	rewind(db);
X	while (getitem(&item, db) != EOF)		/* read key */
X		if (strncmp(item.dptr, key.dptr, key.dsize) == 0)
X			if (getitem(&item, db) == EOF)	/* read data */
X				break;
X			else
X				return item;
X	/* EOF */
X	item.dptr = NULL;
X	item.dsize = 0;
X	return item;
X}
X
Xdelete(key)
Xdatum key;
X{
X	datum item;
X	FILE *temp;
X	FILE *tmpfile();
X
X	if (dbrdonly)
X		return -1;
X	temp = tmpfile();
X	if (temp == NULL)
X		return -1;
X	/* copy from db to temp, omitting key & its data */
X	rewind(db);
X	while (getitem(&item, db) != EOF)
X		if (strncmp(item.dptr, key.dptr, key.dsize) == 0) {
X			if (getitem(&item, db) == EOF)	/* toss data too */
X				return -1;
X		} else
X			if (putitem(&item, temp) == EOF)
X				return -1;
X	/* copy back from temp to db */
X	rewind(temp);
X	db = freopen(pagname, "w+", db);
X	while (getitem(&item, temp) != EOF)
X		if (putitem(&item, db) == EOF)
X			return -1;
X	return 0;
X}
X
Xstore(key, dat)
Xdatum key, dat;
X{
X	if (dbrdonly)
X		return -1;
X#ifdef REALDBM			/* else, it's only for news */
X	if (delete(key) == -1)
X		return -1;
X#endif
X	if (putitem(&key, db) == EOF || putitem(&dat, db) == EOF)
X		return -1;
X	return 0;
X}
X
Xdatum
Xfirstkey()
X{
X	datum trash;
X	datum nextkey();
X
X	rewind(db);
X	return nextkey(trash);
X}
X
Xdatum
Xnextkey(key)			/* simplistic version, ignores key */
Xdatum key;
X{
X	static datum dat;
X
X	if (getitem(&dat, db) == EOF)
X		dat.dptr = NULL;
X	return dat;
X}
X
Xstatic int
Xgetitem(datump, fp)			/* points at static storage */
Xdatum *datump;
XFILE *fp;
X{
X	static char data[MAXLINE];
X
X	if (fread((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1)
X		return EOF;
X	datump->dptr = data;
X	if (fread(data, datump->dsize, 1, fp) != 1)
X		return EOF;
X	return 0;
X}
X
Xstatic int
Xputitem(datump, fp)
Xdatum *datump;
XFILE *fp;
X{
X	if (fwrite((char *)&datump->dsize, sizeof datump->dsize, 1, fp) != 1)
X		return EOF;
X	if (fwrite(datump->dptr, datump->dsize, 1, fp) != 1)
X		return EOF;
X	return 0;
X}
END_OF_FILE
if test 2521 -ne `wc -c <'rnews/vers/usg/dbm.c'`; then
    echo shar: \"'rnews/vers/usg/dbm.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/usg/dbm.c'
fi
echo shar: End of archive 5 \(of 14\).
##  End of shell archive.
exit 0