rsalz@uunet.uu.net (Rich Salz) (06/28/89)
Submitted-by: utzoo!henry Posting-number: Volume 19, Issue 88 Archive-name: cnews2/part11 : ---CUT HERE--- echo 'libfake/memcmp.c': sed 's/^X//' >'libfake/memcmp.c' <<'!' X/* X * memcmp - compare bytes X */ X Xint /* <0, == 0, >0 */ Xmemcmp(s1, s2, size) X char * s1; X char * s2; Xint size; X{ X register char *scan1; X register char *scan2; X register int n; X X scan1 = s1; X scan2 = s2; X for (n = size; n > 0; n--) X if (*scan1 == *scan2) { X scan1++; X scan2++; X } else X return(*scan1 - *scan2); X X return(0); X} ! echo 'libfake/memcpy.c': sed 's/^X//' >'libfake/memcpy.c' <<'!' X/* X * memcpy - copy bytes X */ X Xchar * Xmemcpy(dst, src, size) Xchar * dst; X char * src; Xint size; X{ X register char *d; X register char *s; X register int n; X X if (size <= 0) X return(dst); X X s = src; X d = dst; X if (s <= d && s + (size-1) >= d) { X /* Overlap, must copy right-to-left. */ X s += size-1; X d += size-1; X for (n = size; n > 0; n--) X *d-- = *s--; X } else X for (n = size; n > 0; n--) X *d++ = *s++; X X return(dst); X} ! echo 'libfake/memset.c': sed 's/^X//' >'libfake/memset.c' <<'!' X/* X * memset - set bytes X * X * CHARBITS should be defined only if the compiler lacks "unsigned char". X * It should be a mask, e.g. 0377 for an 8-bit machine. X */ X X#ifndef CHARBITS X# define UNSCHAR(c) ((unsigned char)(c)) X#else X# define UNSCHAR(c) ((c)&CHARBITS) X#endif X Xchar * Xmemset(s, ucharfill, size) X char * s; Xregister int ucharfill; Xint size; X{ X register char *scan; X register int n; X register int uc; X X scan = s; X uc = UNSCHAR(ucharfill); X for (n = size; n > 0; n--) X *scan++ = uc; X X return(s); X} ! echo 'libfake/index.c': sed 's/^X//' >'libfake/index.c' <<'!' X/* X * index - find first occurrence of a character in a string X */ X X#define NULL 0 X Xchar * /* found char, or NULL if none */ Xindex(s, charwanted) Xchar *s; Xchar charwanted; X{ X extern char *strchr(); X X return(strchr(s, charwanted)); X} ! echo 'libfake/strchr.c': sed 's/^X//' >'libfake/strchr.c' <<'!' X/* X * strchr - find first occurrence of a character in a string X */ X X#define NULL 0 X Xchar * /* found char, or NULL if none */ Xstrchr(s, charwanted) X char *s; Xregister char charwanted; X{ X register char *scan; X X /* X * The odd placement of the two tests is so NUL is findable. X */ X for (scan = s; *scan != charwanted;) /* ++ moved down for opt. */ X if (*scan++ == '\0') X return(NULL); X return(scan); X} ! echo 'libfake/rindex.c': sed 's/^X//' >'libfake/rindex.c' <<'!' X/* X * rindex - find last occurrence of a character in a string X */ X X#define NULL 0 X Xchar * /* found char, or NULL if none */ Xrindex(s, charwanted) Xchar *s; Xchar charwanted; X{ X extern char *strrchr(); X X return(strrchr(s, charwanted)); X} ! echo 'libfake/strcspn.c': sed 's/^X//' >'libfake/strcspn.c' <<'!' X/* X * strcspn - find length of initial segment of s consisting entirely X * of characters not from reject X */ X Xint Xstrcspn(s, reject) X char *s; X char *reject; X{ X register char *scan; X register char *rscan; X register int count; X X count = 0; X for (scan = s; *scan != '\0'; scan++) { X for (rscan = reject; *rscan != '\0';) /* ++ moved down. */ X if (*scan == *rscan++) X return(count); X count++; X } X return(count); X} ! echo 'libfake/strpbrk.c': sed 's/^X//' >'libfake/strpbrk.c' <<'!' X/* X * strpbrk - find first occurrence of any char from breakat in s X */ X X#define NULL 0 X Xchar * /* found char, or NULL if none */ Xstrpbrk(s, breakat) X char *s; X char *breakat; X{ X register char *sscan; X register char *bscan; X X for (sscan = s; *sscan != '\0'; sscan++) { X for (bscan = breakat; *bscan != '\0';) /* ++ moved down. */ X if (*sscan == *bscan++) X return(sscan); X } X return(NULL); X} ! echo 'libfake/strrchr.c': sed 's/^X//' >'libfake/strrchr.c' <<'!' X/* X * strrchr - find last occurrence of a character in a string X */ X X#define NULL 0 X Xchar * /* found char, or NULL if none */ Xstrrchr(s, charwanted) X char *s; Xregister char charwanted; X{ X register char *scan; X register char *place; X X place = NULL; X for (scan = s; *scan != '\0'; scan++) X if (*scan == charwanted) X place = scan; X if (charwanted == '\0') X return(scan); X return(place); X} ! echo 'libfake/strspn.c': sed 's/^X//' >'libfake/strspn.c' <<'!' X/* X * strspn - find length of initial segment of s consisting entirely X * of characters from accept X */ X Xint Xstrspn(s, accept) X char *s; X char *accept; X{ X register char *sscan; X register char *ascan; X register int count; X X count = 0; X for (sscan = s; *sscan != '\0'; sscan++) { X for (ascan = accept; *ascan != '\0'; ascan++) X if (*sscan == *ascan) X break; X if (*ascan == '\0') X return(count); X count++; X } X return(count); X} ! echo 'libfake/strtok.c': sed 's/^X//' >'libfake/strtok.c' <<'!' X/* X * Get next token from string s (NULL on 2nd, 3rd, etc. calls), X * where tokens are nonempty strings separated by runs of X * chars from delim. Writes NULs into s to end tokens. delim need not X * remain constant from call to call. X */ X X#define NULL 0 X Xstatic char *scanpoint = NULL; X Xchar * /* NULL if no token left */ Xstrtok(s, delim) Xchar *s; Xregister char *delim; X{ X register char *scan; X char *tok; X register char *dscan; X X if (s == NULL && scanpoint == NULL) X return(NULL); X if (s != NULL) X scan = s; X else X scan = scanpoint; X X /* X * Scan leading delimiters. X */ X for (; *scan != '\0'; scan++) { X for (dscan = delim; *dscan != '\0'; dscan++) X if (*scan == *dscan) X break; X if (*dscan == '\0') X break; X } X if (*scan == '\0') { X scanpoint = NULL; X return(NULL); X } X X tok = scan; X X /* X * Scan token. X */ X for (; *scan != '\0'; scan++) { X for (dscan = delim; *dscan != '\0';) /* ++ moved down. */ X if (*scan == *dscan++) { X scanpoint = scan+1; X *scan = '\0'; X return(tok); X } X } X X /* X * Reached end of string. X */ X scanpoint = NULL; X return(tok); X} ! echo 'libsmall/active.slow.c': sed 's/^X//' >'libsmall/active.slow.c' <<'!' X/* X * active file access functions (small, slow, on-disk version) X */ X X#include <stdio.h> X#include <sys/types.h> X#include "news.h" X#include "fgetmfs.h" X X/* private */ Xstatic long fpos = -1; /* set by actfind, read by actwrnum */ X X/* ARGSUSED */ Xstatust Xactfload(fp) XFILE *fp; X{ X return ST_OKAY; X} X X/* ARGSUSED */ Xstatust Xactfsync(fp) XFILE *fp; X{ X return ST_OKAY; X} X X/* X * search on stream "fp" for group "ng" and return a pointer X * to the active file line for it, or 0 if none. X * actload has previously been called. X */ Xchar * Xactfind(fp, ng, nglen) Xregister FILE *fp; Xregister char *ng; Xregister int nglen; X{ X static char *line = NULL; X X if (line != NULL) X free(line); X rewind(fp); X for (fpos = ftell(fp); (line = fgetms(fp)) != NULL; X fpos = ftell(fp), free(line)) X if (STREQN(line, ng, nglen) && line[nglen] == ' ') X return line; /* free on next entry */ X return NULL; X} X Xstatust Xactfwrnum(fp, line) /* overwrite last line found with "line" */ Xregister FILE *fp; Xchar *line; X{ X if (fseek(fp, fpos, 0) != EOF && /* back up */ X fputs(line, fp) != EOF && fflush(fp) != EOF) X return ST_OKAY; X else X return ST_DROPPED; X} ! echo 'libsmall/sys.slow.c': sed 's/^X//' >'libsmall/sys.slow.c' <<'!' X/* X * news sys file reading functions (slow, small, on-disk version) X */ X X#include <stdio.h> X#include <sys/types.h> X#include "news.h" X#include "system.h" X X/* exports */ Xboolean justone = YES; X X/* imports */ Xextern struct system *currsys, *firstsys; X Xstruct system * Xmysysincache() X{ X return NULL; X} X Xvoid Xremmysys(sys) Xstruct system *sys; X{ X /* no cache */ X} X Xvoid Xrewsys(fp) XFILE *fp; X{ X if (fp != NULL) X (void) rewind(fp); X} X X/* X * Free current sys entry & associated memory. Zero currsys too. X */ Xvoid Xfreecurrsys() X{ X if (currsys == NULL) X return; X nnfree(&currsys->sy_name); X nnfree(&currsys->sy_ngs); X nnfree(&currsys->sy_cmd); X nnafree(&currsys); X} ! echo 'libsmall/Makefile': sed 's/^X//' >'libsmall/Makefile' <<'!' X# libsmall makefile XINCLUDE=../include XDEFINES=-I$(INCLUDE) -I../relay XCOPTS= -O # -pg -p XCFLAGS= $(COPTS) $(DEFINES) XLINTFLAGS=-hau $(DEFINES) XLIB=libcnews.a X# RANLIB is ranlib on non-USG systems, echo on USG systems XRANLIB=ranlib X#RANLIB=: XSRCS=active.slow.c sys.slow.c XOBJS=active.slow.o sys.slow.o X# workaround for System V make bug XSHELL = /bin/sh X Xu: $(OBJS) X ar ruv ../libcnews.a $(OBJS) X Xall: $(OBJS) X X$(LIB): $(SRCS) X $(CC) $(CFLAGS) -c $? X ar rv $@ *.o X rm *.o X $(RANLIB) $@ X Xlint: X lint $(LINTFLAGS) $(SRCS) X Xclean: X rm -f *.o ! echo 'libstdio/Makefile': sed 's/^X//' >'libstdio/Makefile' <<'!' XSRC=fgets.c fputs.c rdwr.c XOBJ=fgets.o fputs.o rdwr.o X# PTR_TYPE is the type of _ptr in stdio.h, if not "char *" XDEFINES = '-DPTR_TYPE=unsigned char *' XCOPTS = -O XCFLAGS = $(DEFINES) $(COPTS) XLINTFLAGS = $(DEFINES) -ha XLIBS = ../libcnews.a X# workaround for System V make bug XSHELL = /bin/sh X Xu: $(OBJ) X ar ruv ../libcnews.a $(OBJ) X Xall: $(OBJ) stdiock.stock stdiock.fast runtrials X Xtrials: all X chmod +x runtrials X ./runtrials >junk X test ! -s junk X rm stdiock.stock stdiock.fast junk trial.out X Xlint: X lint $(LINTFLAGS) -u $(SRC) Xlintport: X lint -p $(LINTFLAGS) -u $(SRC) X Xstdiock.stock: stdiock.o $(LIBS) X $(CC) $(CFLAGS) stdiock.o $(LIBS) -o $@ Xstdiock.fast: stdiock.o $(OBJ) $(LIBS) X $(CC) $(CFLAGS) stdiock.o $(OBJ) $(LIBS) -o $@ X Xclean: X rm -f *.o stdiock stdiock.fast stdiock.stock *mon.out trial.out ! echo 'libstdio/fgets.c': sed 's/^X//' >'libstdio/fgets.c' <<'!' X#include <stdio.h> X#ifndef PTR_TYPE X#define PTR_TYPE char * /* type of _ptr in stdio.h */ X#endif 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 = (char *)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 /* X * warning: this will need to be changed for X * non-binary machines, if they exist. X */ 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 - (char *)fp->_ptr; X lim -= copy; X fp->_cnt -= copy; X if (copy < THRESHOLD) { X register char *rs = s, *bp = (char *)fp->_ptr; X X for (++copy; --copy > 0; ) X *rs++ = *bp++; X s = rs; X fp->_ptr = (PTR_TYPE)bp; X } else { X memcpy(s, (char *)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} ! echo 'libstdio/fputs.c': sed 's/^X//' >'libstdio/fputs.c' <<'!' X#include <stdio.h> X Xfputs(s, fp) Xregister char *s; Xregister FILE *fp; X{ X unsigned len = strlen(s); X X if (fwrite(s, 1, len, fp) < len) X return EOF; X return 0; X} ! echo 'libstdio/rdwr.c': sed 's/^X//' >'libstdio/rdwr.c' <<'!' X/* X * fread and fwrite (optimised version) X * Could do i/o to/from the user's buffer directly if the transfer is long X * enough. If there's a block-aligned block (or more) in the middle, could X * transfer it directly. X */ X X#include <stdio.h> X#ifndef PTR_TYPE X#define PTR_TYPE char * /* type of _ptr in stdio.h */ X#endif 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 = (char *)fp->_ptr; X X for (++copy; --copy > 0; ) X *rptr++ = *bp++; X ptr = rptr; X fp->_ptr = (PTR_TYPE)bp; X } else { X memcpy(ptr, (char *)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 = (char *)fp->_ptr; X X for (++copy; --copy > 0; ) X *bp++ = *rptr++; X ptr = rptr; X fp->_ptr = (PTR_TYPE)bp; X } else { X memcpy((char *)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} ! echo 'libstdio/stdiock.c': sed 's/^X//' >'libstdio/stdiock.c' <<'!' X/* X * If this compiles and runs successfully, your stdio is very probably X * compatible with stdio.fast, except on SunOS 4.x, for unknown reasons. X * Buffers by default; -u stops buffering. X * Writes on stdout by default; -i read from stdin. X */ X#include <stdio.h> X XFILE *fp = stdout; X Xmain(argc, argv) Xchar **argv; X{ X int wantbuf = 1, usestdin = 0; X char line[1024]; X static char buf[BUFSIZ]; X static char buggered[] = X"Your stdio appears to be buggered: fwrite of 4 bytes doesn't yield 4.\n"; X X for (; argc > 1; argv++, argc--) { X if (strcmp(argv[1], "-u") == 0) X wantbuf = 0; X if (strcmp(argv[1], "-i") == 0) { X usestdin = 1; X fp = stdin; X } X } X X evalfile("start"); X X if (wantbuf) { X setbuf(fp, buf); X evalfile("setbuf(buf)"); X } else { X setbuf(fp, (char *)NULL); X evalfile("setbuf(0)"); X } X X if (usestdin) { X (void) fgets(line, sizeof line, fp); X evalfile("fgets"); X } else { X if (fwrite("your", 1, 4, fp) != 4) X (void) write(1, buggered, strlen(buggered)); X evalfile("fwrite"); X X (void) fputs(" stdio seems to be ", stdout); X evalfile("fputs"); X } X X if (wantbuf && fp->_ptr == NULL) X (void) fputs("incompatible (_ptr) ", stdout); X else X (void) fputs("compatible (_ptr) ", stdout); X if (fp->_cnt >= 0 && fp->_cnt <= BUFSIZ) X (void) fputs("compatible (_cnt)", stdout); X else X (void) fputs("incompatible (_cnt)", stdout); X evalfile("test"); X X (void) fputs(" with stdio.fast\n", stdout); X evalfile("fputs"); X X (void) fflush(fp); X (void) fflush(stdout); X evalfile("fflush"); X X exit(0); X} X X/* write on stdout with using stdio. ugh */ Xevalfile(s) Xchar *s; X{ X static char ptr[] = "ptr "; X static char cnt[] = " cnt "; X static char *bufend = NULL; X static char buggered[] = X"Your stdio appears to be buggered: _ptr+_cnt does not yield a constant.\n"; X X if (fp->_ptr != NULL && fp->_cnt != 0) { X if (bufend == NULL) X bufend = (char *)fp->_ptr + fp->_cnt; X if (bufend != (char *)fp->_ptr + fp->_cnt) X (void) write(1, buggered, strlen(buggered)); X } X X (void) write(1, s, strlen(s)); X (void) write(1, "\t", 1); X (void) write(1, ptr, strlen(ptr)); X prn((int)fp->_ptr, 10); X (void) write(1, cnt, strlen(cnt)); X prn((int)fp->_cnt, 10); X (void) write(1, "\n", 1); X} X Xprn(i, rad) Xint i, rad; X{ X int quot, rem; X char c; X X if (i < 0) { X (void) write(1, "-", 1); X i = -i; X } X quot = i / rad; X rem = i % rad; X if (quot > 0) X prn(quot, rad); X c = rem + '0'; X (void) write(1, &c, 1); X} ! echo 'libstdio/LEGAL.STDIO': sed 's/^X//' >'libstdio/LEGAL.STDIO' <<'!' XPage 165 of The C Programming Language describes some of the workings Xof the UNIX stdio implementation. In particular, it describes the Xfunction of _ptr and _cnt. ! echo 'libstdio/LEGAL.NOTICE': sed 's/^X//' >'libstdio/LEGAL.NOTICE' <<'!' X/* X * Copyright (c) 1985, 1986 by Geoffrey Collyer. X * Written by Geoffrey Collyer. Not derived from AT&T code. X * X * Permission is granted to anyone to use this software for any X * purpose on any computer system, and to redistribute it freely, X * subject to the following restrictions: X * X * 1. The author is not responsible for the consequences of use of X * this software, no matter how awful, even if they arise X * from imperfections in it. X * X * 2. The origin of this software must not be misrepresented, either X * by explicit claim or by omission. X * X * 3. Altered versions must be plainly marked as such, and must not X * be misrepresented as being the original software. X */ ! echo 'libstdio/README': sed 's/^X//' >'libstdio/README' <<'!' XThis directory does not form a library; fgets.o, fputs.o and rdwr.o Xconstitute re-written stdio guts, thought to be compatible with the Xusual UNIX stdio implementation but a good deal faster than old Xversions. ! echo 'libstdio/runtrials': sed 's/^X//' >'libstdio/runtrials' <<'!' X#! /bin/sh Xfor whose in stock fast Xdo X for fp in "" -i X do X for buf in "" -u X do X echo stdiock.$whose $fp $buf: X ./stdiock.$whose $fp $buf <<! Xa line X! X echo '' X done X done Xdone | tee trial.out | egrep 'incompat|bugger' Xexit 0 # exit status of pipe is unportable anyway ! echo 'libusg/Makefile': sed 's/^X//' >'libusg/Makefile' <<'!' X# C news libusg makefile XINCLUDE = ../include XDEFINES=-I$(INCLUDE) XCOPTS=-O # -p XCFLAGS=$(COPTS) $(DEFINES) XLINTFLAGS=-hau $(DEFINES) X# workaround for System V make bug XSHELL = /bin/sh X XSRCS=clsexec.c fopenexcl.c ftime.c gethostname.c XOBJS=clsexec.o fopenexcl.o ftime.o gethostname.o X X# RANLIB is ranlib on non-USG systems, echo on USG systems XRANLIB=echo X Xu: $(OBJS) X ar ruv ../libcnews.a $(OBJS) X Xall: $(OBJS) X Xlibusg.a: $(SRCS) X $(CC) $(CFLAGS) -c $? X ar ru $@ *.o X rm *.o X $(RANLIB) $@ Xlint: X lint $(LINTFLAGS) $(SRCS) X Xclean: X rm -f *.o ! echo 'libusg/ftime.c': sed 's/^X//' >'libusg/ftime.c' <<'!' X/* X * Uglix ftime simulation X */ X X#include <ctype.h> X#include <sys/types.h> X#include <sys/timeb.h> /* see news/include */ X#include <sys/times.h> X X#define NULL 0 X#ifndef HZ X#define HZ 60 X#endif X X/* imports from libc */ Xextern time_t time(); Xextern time_t times(); /* only true on Uglix */ Xextern char *getenv(); X Xftime(tp) Xstruct timeb *tp; X{ X register char *tz; X#ifdef SANE X /* X * Since times() is not required to use the same time base for its X * return value as time() uses, we can't easily get sub-second resolution. X */ X struct tms timesbuf; X register int hz = times(×buf) % HZ; /* hertz beyond time(0) */ X X tp->millitm = (hz*1000L)/HZ; X#else X tp->millitm = 0; X#endif X tp->time = time(&tp->time); X tz = getenv("TZ"); X if (tz == NULL) /* just pick one */ X tz = "EST5EDT"; X while (*tz != '\0' && isascii(*tz) && !isdigit(*tz) && *tz != '-') X tz++; /* find hrs from greenwich */ X tp->timezone = atoi(tz) * 60; /* in minutes */ X while (*tz != '\0' && isascii(*tz) && (isdigit(*tz) || *tz == '-')) X tz++; /* find DST, if any */ X tp->dstflag = (*tz != '\0'); X} ! echo 'libusg/fopenexcl.c': sed 's/^X//' >'libusg/fopenexcl.c' <<'!' X/* X * fopenexcl(name) - fopen(name, "w") with error if name exists (USG) X */ X X#include <stdio.h> X#include <sys/types.h> X#include <fcntl.h> X XFILE * Xfopenexcl(name) Xregister char *name; X{ X /* This is the cheaper way. */ X register int fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0666); X X if (fd < 0) X return NULL; /* name existed or couldn't be made */ X else X return fdopen(fd, "w"); X} ! echo 'libusg/gethostname.c': sed 's/^X//' >'libusg/gethostname.c' <<'!' X/* X * Uglix gethostname simulation X */ X X#include <sys/types.h> X#include <sys/utsname.h> X X#define min(a, b) ((a) < (b)? (a): (b)) X Xint Xgethostname(buf, size) Xchar *buf; Xint size; X{ X struct utsname ugnm; X char *strncpy(); X X if (uname(&ugnm) < 0) X return -1; X (void) strncpy(buf, ugnm.nodename, min(sizeof ugnm.nodename, size)); X return 0; X} ! echo 'libusg/clsexec.c': sed 's/^X//' >'libusg/clsexec.c' <<'!' X/* X * set close on exec (on Uglix) X */ X X#include <stdio.h> X#include <fcntl.h> X Xvoid Xfclsexec(fp) XFILE *fp; X{ X (void) fcntl(fileno(fp), F_SETFD, 1); X} ! echo 'libv7/Makefile': sed 's/^X//' >'libv7/Makefile' <<'!' X# C news libv7 makefile XINCLUDE = ../include XDEFINES=-I$(INCLUDE) XCOPTS=-O # -p XCFLAGS=$(COPTS) $(DEFINES) XLINTFLAGS=-hau $(DEFINES) X# workaround for System V make bug XSHELL = /bin/sh X XSRCS = clsexec.c fopenexcl.c gethostname.c getcwd.c XOBJS = clsexec.o fopenexcl.o gethostname.o getcwd.o X X# RANLIB is ranlib on non-USG systems, echo on USG systems XRANLIB=ranlib X Xu: $(OBJS) X ar ruv ../libcnews.a $(OBJS) X Xall: $(OBJS) X Xlibv7.a: $(SRCS) X $(CC) $(CFLAGS) -c $? X ar ru $@ *.o X rm *.o X $(RANLIB) $@ Xlint: X lint $(LINTFLAGS) $(SRCS) X Xclean: X rm -f *.o ! echo 'libv7/gethostname.c': sed 's/^X//' >'libv7/gethostname.c' <<'!' X/* X * v7 gethostname simulation X * taken from pathalias and cleaned up. Thanks, peter. X */ X X#include <stdio.h> X X/* imports from libc */ Xextern char *index(), *strncpy(); Xextern FILE *fopen(), *popen(); X X/* forwards */ Xvoid readhostfile(); X X#define MAXHOST 256 X#define min(a,b) ((a) < (b)? (a): (b)) X Xstatic char defhost[] = "INSERT-YOUR-HOST-NAME-HERE"; Xstatic char *namefiles[] = { X "/etc/whoami", X "/etc/systemid", X NULL X}; X Xint Xgethostname(hostname, size) Xregister char *hostname; Xint size; X{ X register FILE *whoami; X register char **namep; X X *hostname = '\0'; X X /* try files in namefiles */ X for (namep = namefiles; *namep != NULL; namep++) { X readhostfile(hostname, size, *namep); X if (*hostname != '\0') X return 0; X } X X /* try /usr/include/whoami.h */ X if ((whoami = fopen("/usr/include/whoami.h", "r")) != NULL) { X while (!feof(whoami)) { X char sysname[MAXHOST]; X X if (fgets(sysname, MAXHOST, whoami) == NULL) X break; X if (sscanf(sysname, "#define sysname \"%[^\"]\"", X hostname) > 0) X break; X } X (void) fclose(whoami); X if (*hostname != '\0') X return 0; X } X X /* ask uucp */ X if ((whoami = popen("PATH=/bin:/usr/bin:/usr/ucb uuname -l", "r")) != NULL) { X register char *ptr; X X (void) fgets(hostname, size, whoami); X (void) pclose(whoami); X if ((ptr = index(hostname, '\n')) != NULL) X *ptr = '\0'; X } X if (*hostname != '\0') X return 0; X X /* aw hell, i give up! is this a real unix? */ X (void) strncpy(hostname, defhost, min(sizeof defhost, size)); X return 0; X} X Xstatic void Xreadhostfile(hostname, size, file) /* read host name from file */ Xchar *hostname, *file; Xint size; X{ X register FILE *whoami; X X if ((whoami = fopen(file, "r")) != NULL) { X register char *ptr; X X (void) fgets(hostname, size, whoami); X (void) fclose(whoami); X if ((ptr = index(hostname, '\n')) != NULL) X *ptr = '\0'; X } X} ! echo 'libv7/getcwd.c': sed 's/^X//' >'libv7/getcwd.c' <<'!' X/* X * SystemV getcwd simulation, courtesy peter honeyman X */ X X#include <stdio.h> X X/* imports from libc */ Xextern FILE *popen(); Xextern char *rindex(); X Xchar * Xgetcwd(path, size) Xregister char *path; Xint size; X{ X register char *nlp; X register FILE *fp; X X fp = popen("PATH=/bin:/usr/bin pwd", "r"); X if (fp == NULL) X return 0; X if (fgets(path, size, fp) == NULL) { X (void) pclose(fp); X return 0; X } X if ((nlp = rindex(path, '\n')) != NULL) X *nlp = '\0'; X (void) pclose(fp); X return path; X} ! echo 'libv7/fopenexcl.c': sed 's/^X//' >'libv7/fopenexcl.c' <<'!' X/* X * fopenexcl(name) - fopen(name, "w") with error and errno==EEXIST, X * if name exists (V7/V8/V9) X */ X X#include <stdio.h> X#include <errno.h> X X#define F_OK 0 X Xextern int errno; X XFILE * Xfopenexcl(name) Xregister char *name; X{ X if (access(name, F_OK) >= 0) { /* name exists */ X errno = EEXIST; X return NULL; /* refuse to write on name */ X } else X return fopen(name, "w"); /* try to create name */ X} ! echo 'libv7/clsexec.c': sed 's/^X//' >'libv7/clsexec.c' <<'!' X/* X * set close on exec (on Unix) X */ X X#include <stdio.h> X#include <sgtty.h> X Xvoid Xfclsexec(fp) XFILE *fp; X{ X (void) ioctl(fileno(fp), FIOCLEX, (struct sgttyb *)NULL); X} X ! echo 'libv8/Makefile': sed 's/^X//' >'libv8/Makefile' <<'!' X# C news libv8 makefile XINCLUDE = ../include XDEFINES=-I$(INCLUDE) XCOPTS=-O # -p XCFLAGS=$(COPTS) $(DEFINES) XLINTFLAGS=-hau $(DEFINES) X# workaround for System V make bug XSHELL = /bin/sh X XSRCS = clsexec.c fopenexcl.c gethostname.c XOBJS = clsexec.o fopenexcl.o gethostname.o X X# RANLIB is ranlib on non-USG systems, echo on USG systems XRANLIB=ranlib X Xu: $(OBJS) X ar ruv ../libcnews.a $(OBJS) X Xall: $(OBJS) X Xlibv8.a: $(SRCS) X $(CC) $(CFLAGS) -c $? X ar ru $@ *.o X rm *.o X $(RANLIB) $@ Xlint: X lint $(LINTFLAGS) $(SRCS) X Xclean: X rm -f *.o ! echo 'libv8/README': sed 's/^X//' >'libv8/README' <<'!' XThough it is undocumented, V8 contains an Uglix uname(3) emulation Xin the C library. In V9, uname(3) is documented. ! echo 'libv8/fopenexcl.c': sed 's/^X//' >'libv8/fopenexcl.c' <<'!' X/* X * fopenexcl(name) - fopen(name, "w") with error and errno==EEXIST, X * if name exists (V7/V8/V9) X */ X X#include <stdio.h> X#include <errno.h> X X#define F_OK 0 X Xextern int errno; X XFILE * Xfopenexcl(name) Xregister char *name; X{ X if (access(name, F_OK) >= 0) { /* name exists */ X errno = EEXIST; X return NULL; /* refuse to write on name */ X } else X return fopen(name, "w"); /* try to create name */ X} ! echo 'libv8/clsexec.c': sed 's/^X//' >'libv8/clsexec.c' <<'!' X/* X * set close on exec (on Unix) X */ X X#include <stdio.h> X#include <sgtty.h> X Xvoid Xfclsexec(fp) XFILE *fp; X{ X (void) ioctl(fileno(fp), FIOCLEX, (struct sgttyb *)NULL); X} X ! echo 'libv8/gethostname.c': sed 's/^X//' >'libv8/gethostname.c' <<'!' X/* X * Uglix gethostname simulation X */ X X#include <sys/types.h> X#include <sys/utsname.h> X X#define min(a, b) ((a) < (b)? (a): (b)) X Xint Xgethostname(buf, size) Xchar *buf; Xint size; X{ X struct utsname ugnm; X char *strncpy(); X X if (uname(&ugnm) < 0) X return -1; X (void) strncpy(buf, ugnm.nodename, min(sizeof ugnm.nodename, size)); X return 0; X} ! echo 'man/inews.1': sed 's/^X//' >'man/inews.1' <<'!' X.\" =()<.ds a @<NEWSARTS>@>()= X.ds a /usr/spool/news X.\" =()<.ds b @<NEWSBIN>@>()= X.ds b /usr/lib/newsbin X.\" =()<.ds c @<NEWSCTL>@>()= X.ds c /usr/lib/news X.\" =()<.ds m @<NEWSMASTER>@>()= X.ds m usenet X.TH INEWS 1 "7 June 1989" "C News" X.SH NAME Xinews \- `user-friendly' news-posting front-end for rnews X.SH SYNOPSIS X.B inews X.B \-p X[ file ... ] X.br X.B inews X[ X.B \-h X] X[ X.B \-x Xexcluded-site X] X[ X.B \-A X] X[ X.B \-M X] X[ X.B \-V X] X[ X.B \-W X] X.br X.\" silly B options follow X[ X.B \-a XApproved:-contents X] X[ X.B \-c XControl:-contents X] X[ X.B \-d XDistribution:-contents X] X[ X.B \-e XExpires:-contents X] X[ X.B \-f XFrom:-contents X] X[ X.B \-n XNewsgroups:-contents X] X[ X.B \-o XOrganization:-contents X] X[ X.B \-r XReply-To:-contents X] X[ X.B \-t XSubject:-contents X] X[ X.B \-C Xnewsgroup X] X[ X.B \-F XReferences:-contents X] X[ Xfile ... X] X.SH DESCRIPTION X.I Inews Xinstalls locally Xand Xbroadcasts a (network) news article X(\fIi\fPnjects it into the X.I news Xflow), Xread from X.IR file s Xor standard input if none, Xnormally Xby giving it as standard input to X.IR rnews (1), Xafter adding and altering headers, Xnotably X.BR Message-ID: , X.BR From: Xand X.BR Path: , Xdeleting invisible characters, Xand Xappending the first four lines of X.BR $HOME/.signature , Xif any. XThe article will instead be mailed Xto the moderators of the moderated newsgroups in the X.B Newsgroups: Xheader, Xif any are found. X.PP X.B "inews -p" Xis exactly equivalent to X.BR rnews . XNormal usage is simply X.BR "inews -h" , Xwhich assumes the presence of at least X.B Subject: Xand X.B Newsgroups: Xheaders. X.B \-h Xtells X.I inews Xthat the article starts with headers; Xotherwise it starts with the article body. X.B \-x Xprevents transmission to site X.IR excluded-site . X.B \-A Xwaits until enough space becomes free in X.BR \*a . X.B \-M Xdoes nothing, Xfor B news compatibility. X.B \-V Xcauses X.I relaynews Xto emit a log file line on stdout Xafter processing is complete, Xby having X.I relaynews Xnot redirect stdout and stderr Xto X.B \*c/log Xand X.B \*c/errlog. X.B \-W Xwaits for X.I relaynews Xto complete, Xinstead of running it in the background and not waiting. X.PP XThe remaining options are inherited from B news Xand exist only for backward-compatibility with news readers. X.I "They should not be used by humans," Xas they are equivalent to Xadding the obvious headers, Xwith two small twists: X.B \-f Xgenerates X.BI "From:" " From:-contents" Xwhich generates a X.BI "Sender:" " user" @ "host" Xheader Xif there is no X.B Sender: Xheader in the input, Xand X.B \-C Xgenerates X.BI "Control: newgroup" " newsgroup" Xand X.BI "Newsgroups:" " newsgroup" Xheaders. X.SH FILES X.PD 0 X.TP 2i X.B \*c/active Xcontains (un)moderated flag X.TP X.B \*c/mailpaths Xroutes to moderators, Internet gateway X.TP X.B \*c/mailname Xthe name of this cluster of machines for purposes of mail, Xincluding any domain X.TP X.B \*c/server Xthe hostname of this cluster's server X.TP X.B \*c/whoami Xthe name of this cluster for purposes of news X.TP X.B \*b/inject/anne.jones Xheader censor X.TP X.IB $HOME /.signature Xyour name and network addresses X(no line-printer graphics, please) X.TP X.BR /tmp/in * Xtemporaries X.PD X.SH "SEE ALSO" X.IR mail (1), X.IR rnews (1) X.SH DIAGNOSTICS X.I inews Xcan take several seconds to run, Xso it almost immediately begins running in the background; Xerror messages may appear somewhat later, Xperhaps in the midst of other activity. X.SH HISTORY XWritten by Geoff Collyer Xat the University of Toronto Xas part of the C news project. X.SH BUGS X.I Inews Xshould be unnecessary; Xits only useful function is adding X.B Message-ID: Xheaders Xand Xmost novices use X.IR Pnews , Xwhich could invoke X.I rnews Xdirectly. ! echo 'man/README': sed 's/^X//' >'man/README' <<'!' XThese are the manual pages for C News proper; one or two other pages for Xauxiliary programs that you might want to install in their own right are Xscattered here and there in other directories. X XThese pages use the .TH macro in the following way: X X .TH <title> <chapter> "<date>" "C News" X XOn some systems the last argument gets ignored, or put in a funny place Xin headers or footers. There is no portable fix, as people have messed Xwith the -man macros in too many different ways. X XThe only fonts used are the standard R, I, and B. ! echo 'man/postnews.1': sed 's/^X//' >'man/postnews.1' <<'!' X.\" =()<.ds c @<NEWSCTL>@>()= X.ds c /usr/lib/news X.TH POSTNEWS 1 "9 June 1989" "C News" X.SH NAME Xpostnews \- simple interactive news-posting interface X.SH SYNOPSIS X.B postnews X[newsgroup] X.SH DESCRIPTION X.I Postnews Xprovides a simple interactive interface for posting news. XIt prompts the user for the \fInewsgroup\fR if it is not given as an argument X(more than one group can be given, with groups separated by commas but no Xwhite space), Xprompts for the article's subject, Xdrops the user into his choice of text editor with a prototype Xarticle, Xchecks (when the editor terminates) that the article has been edited Xreasonably, and then posts it. X.PP XIf the article has not been written out from the editor, or if the Xediting instructions in the prototype do not appear to have been Xfollowed, \fIpostnews\fR gives the user a choice between abandoning Xthe posting or re-editing it. X.SH FILES X\*c/postdefltgroup default newsgroup (nonexistent means no default) X.br X\*c/postdefltdist default distribution (nonexistent means `world') X.SH SEE ALSO Xinews(1) X.SH HISTORY XWritten at U of Toronto by Henry Spencer. X.SH BUGS XThere are zillions of marginally-useful features that it could have Xbut doesn't. ! echo 'man/newsaux.8': sed 's/^X//' >'man/newsaux.8' <<'!' X.\" =()<.ds a @<NEWSARTS>@>()= X.ds a /usr/spool/news X.\" =()<.ds b @<NEWSBIN>@>()= X.ds b /usr/lib/newsbin X.\" =()<.ds c @<NEWSCTL>@>()= X.ds c /usr/lib/news X.\" =()<.ds m @<NEWSMASTER>@>()= X.ds m usenet X.TH NEWSAUX 8 "22 June 1989" "C News" X.SH NAME Xspacefor \- check available space for news X.br Xqueuelen \- get length of outbound-news uucp queues X.br Xsizeof \- get size of file(s) for news X.br Xctime, getdate \- convert dates to and from internal representation for news X.br Xnewshostname \- get host name for news X.br Xgngp \- search text using a newsgroup pattern X.br Xnewshist \- extract history line for news article(s) X.br Xnewslock \- do locking for news X.br Xnewsdaily \- maintain news log files and report problems X.br Xnewswatch \- keep an eye on news system for difficulties X.br Xnewsboot \- clean up news debris on reboot X.br Xlocknews \- lock news system for manual tinkering X.br Xaddgroup, delgroup \- add and delete newsgroups, locally only X.SH SYNOPSIS X.B \*b/spacefor Xfilesize location [ site ] X.br X.B \*b/queuelen Xsite X.br X.B \*b/sizeof Xfile ... X.br X.B \*b/ctime Xdecimaldate X.br X.B \*b/getdate Xprintabledate X.br X.B \*b/newshostname X.br X.B \*b/gngp X[ X.B \-a X] Xngpattern file ... X.br X.B \*b/maint/newshist Xmsgid ... X.br X.B \*b/newslock Xlocktemp lockname X.br X.B \*b/maint/newsdaily X[ guru ... ] X.br X.B \*b/maint/newswatch X[ guru ... ] X.br X.B \*b/maint/newsboot X.br X.B \*b/maint/locknews X.br X.B \*b/maint/addgroup Xgroup {\fBy\fR|\fBn\fR|\fBm\fR|\fBx\fR|\fB=\fIrealgroup\fR} X.br X.B \*b/maint/delgroup Xgroup X.SH DESCRIPTION XThese programs are minor utilities used by various parts of C News. X.PP X.I Spacefor Xdetermines how many files of size \fIfilesize\fR can fit in \fIlocation\fR X(\fBincoming\fR, \fBarticles\fR, \fBcontrol\fR, \fBarchive\fR, Xor \fBoutbound\fR to \fIsite\fR) Xwithout cramping things unduly. XThe precise locations of these places, and how low space gets before Xit is unduly cramped, are site-specific. X.I Spacefor Xinvokes \fIdf\fR(1) to determine the available space. X.PP X.I Queuelen Xreports how many news batches \fIuucp\fR has queued up for \fIsite\fR. X.PP X.I Sizeof Xreports the total number of bytes in the \fIfile\fR(s). X(This may seem redundant with \fIls\ \-l\fR, but the format of \fIls\ \-l\fR Xvaries between systems and \fIsizeof\fR looks after all that.) X.PP X.I Ctime Xand X.I getdate Xconvert dates in human-readable form Xto (\fIgetdate\fR) and from (\fIctime\fR) decimal ASCII representations Xof Unix's internal integer dates. XTheir functionality resembles that of their namesakes in the C library. X.PP X.I Newshostname Xreports the name of this system for news purposes. XThis may differ from the name of the particular CPU it is run on; Xa cluster of CPUs sharing a filesystem tree would all have the same X\fInewshostname\fR name. XTypically \fInewshostname\fR gets the name from \fI\*c/whoami\fR; Xfailing that, it consults various other possible sources X(e.g. the \fIhostname\fR command). X.PP X.I Gngp Xresembles \fIgrep\fR except that its search is based on newsgroup patterns X(e.g. `comp', which matches `comp', `comp.lang', `comp.lang.c', ...; X`comp,!comp.lang.c' which matches `comp' and `comp.lang' but not X`comp.lang.c'; etc.). X\fIGngp\fR prints only the line(s) that Xcontain a substring that matches the \fIngpattern\fR. XNormally the substring must run from a point in the line to its end. XIf the X\fB\-a\fR Xflag is given, the eligible substrings start at the beginning of the Xline and end at white space or the end of the line. X.PP X.I Newshist Xprints the history line for each article identified by a \fImsgid\fR. X.PP X.I Newslock Xmakes a link named \fIlockname\fR to the file \fIlocktemp\fR, Xand returns exit status 0 for success, 1 if the link could not be made X(typically because \fIlockname\fR already existed). XThis is used for shell-file locking in C News. XIt is a subset of \fIln\fR(1) except that (a) no error messages are Xever produced and (b) the link is guaranteed to fail if \fIlockname\fR Xalready exists. X(Some brain-damaged versions of \fIln\fR helpfully remove \fIlockname\fR Xin that case, making them useless for locking.) X.PP X.I Newsdaily Xperforms minor maintenance chores Xthat typically should be done once a day for the news system: Xsaving copies of log files and truncating them, Xreporting logged errors, and checking for anomalies suggesting something Xis wrong. X\fINewsdaily\fR saves one generation of old \fIlog\fR files and three Xgenerations of old \fIerrlog\fR files. XIt reports problems to the named \fIguru\fRs X(default: `\*m'). X.PP X.I Newswatch Xlooks for indications of news problems on a shorter time scale than those Xreported by \fInewsdaily\fR, notably strangely-persistent lock files that Xmay indicate a news-system failure. XIt typically should be run a few times a day. X.PP X.I Newsboot Xshould be run from \fI/etc/rc\fR or the system's equivalent on reboot. XIt cleans up files that the news system might have left lying about Xif the system crashed while news was being processed, Xnotably old lock files. X.PP X.I Locknews Xlocks the news system, starts up a shell for the user, and waits around to Xunlock the news system when that shell terminates. XThis simplifies manual maintenance. X.PP X.I Addgroup Xand X.I delgroup Xrespectively add a newsgroup (with a specified flags field for the X\fIactive\fR file, normally `y' [see \fInews\fR(5)]) and delete a Xnewsgroup manually, with proper locking. XThe effect is purely local; no control message (to propagate the Xchange to other machines) is sent. X.SH FILES X.ta 6c X.nf X/usr/spool/uucp/* uucp queues X\*c/whoami news host name X\*c/history history file X\*c/history.pag \fIdbm\fR database for history file X\*c/history.dir \fIdbm\fR database for history file X\*c/L.* lock temporaries X\*c/LOCK* lock files X\*c/log current news log X\*c/log.o previous news log X\*c/errlog current news-error log X\*c/errlog.o* old news-error logs X\*a/in.coming input-spooling area X\*a/out.going output-batching area X\*c/watchtime last time \fInewswatch\fR was run X\*c/active list of current newsgroups X\*c/active.old backup copy created by \fIaddgroup\fR and \fIdelgroup\fR X.SH SEE ALSO Xdf(1), uucp(1), ls(1), ctime(3), getdate(3), hostname(1), Xgrep(1), news(5), expire(8), newsbatch(8), rnews(8) X.SH DIAGNOSTICS X.I Locknews Xcomplains and exits if it is unable to lock the news system; this is Xtypically a matter of either inadequate permissions or news activity Xalready in progress. X.SH HISTORY XWritten at U of Toronto by Henry Spencer and Geoff Collyer. X.SH BUGS X.I Spacefor Xand X.I queuelen Xare unfortunately somewhat system-specific, since \fIdf\fR output and X\fIuucp\fR file layout vary between different versions. X.PP XThe need for \fIsizeof\fR and \fInewslock\fR is a botch. X.PP X\fILocknews\fR is a bit crude. X.PP X\fIAddgroup\fR does not create the directory(-ies) for the new group; XC News creates them as necessary but some news-reader programs disapprove. X.PP X\fIDelgroup\fR does not remove files or directories from \*a, although it Xprints a reminder to do so. ! echo 'man/newsmail.8': sed 's/^X//' >'man/newsmail.8' <<'!' X.\" =()<.ds a @<NEWSARTS>@>()= X.ds a /usr/spool/news X.\" =()<.ds b @<NEWSBIN>@>()= X.ds b /usr/lib/newsbin X.\" =()<.ds c @<NEWSCTL>@>()= X.ds c /usr/lib/news X.\" =()<.ds m @<NEWSMASTER>@>()= X.ds m usenet X.TH NEWSMAIL 8 "22 June 1989" "C News" X.SH NAME Xmailnews, sendnews \- send unbatched news as mail X.br Xrecenews, recpnews \- receive mailed news X.br Xbdecode \- decode encoded mailed news X.SH SYNOPSIS X.B \*b/relay/mailnews Xaddress ... X.br X.B \*b/relay/sendnews Xaddress ... X.br X.B \*b/input/recenews X.br X.B \*b/input/recpnews X.br X.B \*b/input/bdecode X[ file ] X.SH DESCRIPTION XSometimes it is necessary to transmit news via mail, Xto deal with network connections that have no notion of arbitrary file Xtransfer or non-mail traffic. XThese programs handle unbatched transmission and Xbatched or unbatched reception. X(Batched transmission is handled by the batching subsystem; Xsee \fInewsbatch\fR(8).) X.PP X.I Mailnews Xaccepts news from its standard input, encodes it using \fIbencode\fR X(see \fIbencode\fR(1) or \fInewsbatch\fR(8)) to ensure that stupid mailers Xdo not corrupt it, and mails it to the \fIaddress\fRes. X.PP X.I Sendnews Xdoes likewise, but uses an inferior method of mailer protection X(prepending `N' to each line) which does not protect against all forms Xof mailer brain-damage. XIt is provided for backward compatibility; its use is discouraged. X.PP X.I Mailnews Xand X.I sendnews Xare located in the default path of transmission commands in the \fIsys\fR Xfile (see \fInews\fR(5)) so that they can be used from there without Xgiving a full pathname. X.PP X.I Recenews Xreceives encoded news sent by \fImailnews\fR or a batcher, Xdecodes it, and feeds it to \fIrnews\fR (see \fIrnews\fR(8)). X.I Recpnews Xdoes likewise for mail protected with `N'. XNormally one should arrange that mail arriving at the mailbox ``enews'' Xis sent to \fIrecenews\fR Xand likewise for ``rnews'' (the name is historical, for compatibility Xagain) and \fIrecpnews\fR. X.PP X.I Bdecode Xpasses standard input, or the \fIfile\fR if there is one, to standard Xoutput, decoding the \fIbencode\fR encoding and stripping off Xdebris prepended and appended by mailers. X.SH SEE ALSO Xbencode(1), mail(1), news(5), newsbatch(8), rnews(8) X.SH HISTORY XWritten at U of Toronto by Henry Spencer, with contributions by Geoff Collyer. X.I Bdecode Xwritten at University of Waterloo by Reg Quinton and Ken Lalonde. ! echo 'man/news.5': sed 's/^X//' >'man/news.5' <<'!' X.\" =()<.ds a @<NEWSARTS>@>()= X.ds a /usr/spool/news X.\" =()<.ds b @<NEWSBIN>@>()= X.ds b /usr/lib/newsbin X.\" =()<.ds c @<NEWSCTL>@>()= X.ds c /usr/lib/news X.\" =()<.ds m @<NEWSMASTER>@>()= X.ds m usenet X.de Is\" indentation start X.in +0.5i X.. X.de Ie\" indentation end X.in -0.5i X.. X.de Es\" example start X.LP X.nf X.ft B X.Is X.. X.de Ee\" example end X.Ie X.ft R X.fi X.LP X.. X.TH NEWS 5 "8 June 1989" "C News" X.SH NAME Xnews \- USENET network news articles, batches, related files X.SH DESCRIPTION XThere are two formats of news articles: X.BR A " and " B. X.B A Xformat is obsolete, Xbut Xlooks like this: X.Es XA\fIarticle-ID Xnewsgroups Xpath Xdate Xtitle XBody of article X.Ee XA X.B B Xformat X.I article Xconsists of a series of headers Xand then the body. XA header Xline is defined X(approximately) Xas a line Xat the start of the article Xor immediately following a header line Xwith a capital letter Xas the first character and Xa colon immediately following the first word, Xof alphanumerics and dashes, Xon the line X(a specialisation of RFC 822 format). XContinued headers are as per RFC 822. XUnrecognized headers are ignored. XNews is stored in the same format transmitted, Xsee ``Standard for the Interchange of USENET Messages'' X(RFC 1036 nee 850) Xfor a full description. XThe following headers are among those recognized: X.LP X.Is X.B From: X.IB user @ "host.domain[.domain ...]" " (" X.IB "Full Name" ) X.br X.B Newsgroups: X.I "news groups" X.br X.B Message-ID: X.BI < "Unique RFC822 message-id" > X.br X.B Subject: X.I descriptive title X.br X.B Date: X.I date posted X.br X.B Expires: X.I expiration date X.br X.B Reply-To: X.I address for mail replies X.br X.B References: X.IR "Message-ID of article this is a follow-up to" . X.br X.B Control: X.I text of a control message X.Ie X.LP XHere is an example of an article: X.Es XPath: att!eagle!jerry XFrom: jerry@eagle.uucp (Jerry Schwarz) XNewsgroups: news.announce XSubject: Usenet Etiquette -- Please Read XMessage-ID: <642@eagle.UUCP> XDate: Friday, 19 Nov 82 16:14:55 EST XFollowup-To: news.misc XExpires: Saturday, 1 Jan 83 00:00:00 EST XOrganization: Bell Labs, Murray Hill X XThe body of the article comes here, after a blank line. X.Ee XA X.I "news batch" Xconsists of zero or more articles, Xeach preceded by a line of the form X.Es X.BI "#! rnews" " byte-count" X.Ee Xwhere X.I byte-count Xis the number of bytes in the following article, Xwhere each newline is counted as a single byte, Xeven if it is stored as a CR-LF or Xsome other representation. XSpaces are significant: Xone before and one after X.BR rnews . XNews batches are usually transmitted X.IR compress ed. X.LP XVarious peculiar optional encapsulations of news batches exist Xwhich consist of doing something to the X(probably compressed) Xbatch, Xthen prepending a X.BI #! " goo" Xline to the output, Xwhere X.I goo Xreflects the form of encapsulation; Xknown values of X.I goo Xinclude X.B cunbatch X(the null encapsulation), Xand X.B c7unbatch X(encode the batch using only seven bits per character). X.LP XThe X.I sys Xfile line has four fields, Xeach separated by colons: X.LP X.IB system-name / exclusion1 ,\c X.IB exclusion2... : subscriptions /\c X.IB distributions :\c X.IB flags : "transmission command" X.PP XA X.B # Xas the first character in a line denotes a comment. XBlank lines are ignored. XA logical line may be continued to the next physical line by Xputting a X.B \e Xat the end of the line. X.PP XOf the \fIsys\fR fields, Xonly the X.I system-name Xneed be present. XIf a field and all the fields after it are omitted, Xthe colon immediately before that field and all the colons Xafter it may be omitted too. XThe optional subfields X(\c X.IR exclusion s Xand X.IR distributions ) Xand their leading slashes Xmay be omitted. X.PP XThe X.I system name Xis the name of the system being sent to, Xand Xis checked against site names in X.B Path: Xheaders to avoid sending an article back Xto a site that has seen it. XThe special name X.B ME Xstands for the name of the machine news is running on, Xas determined by some operating-system dependent means Xsuch as X.IR hostname (2) Xor X.IR uname (2). XThe X.IR exclusion s Xare also checked against the X.B Path: Xheader and articles are not sent to X.I system name Xif they have visited any of the X.IR exclusions . X.PP XThe X.I subscriptions Xis the list of newsgroups to be transmitted to the X.IR system X(or received if X.I system Xis the current site); Xthey are matched against the X.B Newsgroups: Xheader of each article Xand any matching articles are transmitted: X.B all Xmatches any single word, Xstopping at periods and commas; X.B comp Xalso implies X.BR comp.all , Xrecursively; X.B !talk X.I mismatches Xall the X.B talk Xgroups; Xorder is unimportant; X.B comp,comp.sys.sun,!comp.sys Xmatches all the X.B comp Xgroups, X.I except Xthe X.B comp.sys Xgroups X.I "but including" X.BR comp.sys.sun . XThe X.I distributions Xare matched similarly with the X.B Distribution: Xheader, Xbut only when sending articles; X.I distributions Xdo not affect receipt of articles. XIf no X.I distributions Xare supplied, Xthe X.I subscriptions Xwill be matched against X.B Distribution: Xinstead. X.PP XThe X.I flags Xare a set of letters describing how the article should be transmitted. XValid flags include X.B f X(interpret X.I "transmission command" Xas a file name and write the name and size in bytes of each Xarticle on the end of it), X.B F X(like X.B f Xbut omit the size), X.B I X(like X.B F Xbut write Message-ID:s instead of filenames), X.B n X(like X.B F Xbut write a Message-ID: after each filename), X.BI L n X(only send articles Xgenerated within X.I n Xhops of here; X0 is the default value for X.IR n ), X.B m X(transmit only moderated groups), X.B u X(transmit only unmoderated groups). XThere are other obsolete ones. X.LP XThe X.I transmission command Xis executed by the shell with the article Xto be transmitted as the standard input. XThe default is X.RI "`uux \- \-z \-r " sysname !rnews' Xfor a command; Xthe PATH searched includes \*b/relay, Xso that the commands described in \fInewsmail\fR(8) Xare available as alternatives to \fIuux\fR. XIf one of the \fIflags\fR has caused Xthis field to be taken as a filename, Xthe default is X.RI \*a/out.going/ sysname /togo; Xif a filename is given but it does not start with `/', it is assumed Xto be relative to the X\*a/out.going Xdirectory. X.LP XSome examples: X.Es X# line indicating what we are willing to receive; note local groups on end XME:comp,news,sci,rec,misc,soc,talk,to,can,ont,tor,ut X X# sample insignificant feed not using batching Xhuey:news.config,to.huey/all::uux - -r -gd huey!rnews X X# sample major batched feed, including (unnecessary) explicit file name Xdewey:comp,news,sci,rec,misc,soc,talk,to.dewey,can,ont,tor,ut/all:f:dewey/togo X X# sample long-haul feed; note no local groups Xdonald:comp,news,sci,rec,misc,soc,talk,to.donald/all:f: X X# sample local-postings-only feed direct to major site (gets them out fast) Xscrooge:comp,news,sci,rec,misc,soc,talk,to.scrooge/all:Lf: X X# sample ihave/sendme link X# Send ihave telling louie what we have -- batcher turns the batch into a X# giant control message and posts it to "to.louie". (#1) Xlouie:rec.music.synth/all,!sendme,!ihave:I:louie.ihave/togo X# Send sendme in response to ihave from louie -- again, turned by batcher X# into giant control message posted to "to.louie". (#3) Xlouie-send-ids:to.louie/ihave:I:louie.sendme/togo X# Transmit said giant control messages by normal batching. (#2,#4) Xlouie-ctl:to.louie/all,!sendme,!ihave:f:louie/togo X# Send articles in response to sendme messages from louie. (#5) Xlouie-real:to.louie/sendme:f:louie/togo X# Actually the last two could be combined. X.Ee X(The ``to.\fIsysname\fR'' groups are normal newsgroups used for testing Xindividual news feeds.) X.PP XSomewhere in the X.I sys Xfile, Xthere must be a line for the host system. XThis line has no X.IR flags " or " commands . X.LP XThe X.I active Xfile contains one line per Xlocally-valid news group. XEach line consists of four blank-separated fields: Xnewsgroup name, Xhighest local article number assigned, Xlowest local article number in use (approximately), Xand Xa flag. XBoth article-number fields are at least five digits wide. X(Some older news software may expect exactly five digits.) XThe current flag values are X.B y X(a normal unmoderated group), X.B n X(like X.B y Xbut local postings disallowed), X.B m X(a normal moderated group), X.B x X(a locally-disabled group, Xno articles will be filed here), Xand X.B = X(followed by the real group Xunder which to file articles in this group; Xarticles are treated exactly as if their X.B Newsgroups: Xheader specified the real group instead of the original one; Xhighest and lowest fields are ignored). XAn example: X.Es Xcomp.org.usrgroup 0000000006 00004 y Xtalk.bizarre 0000296123 292136 n Xcomp.sys.sun 0000000175 00173 m Xlist.sun-spots 0000000076 00076 =comp.sys.sun Xcomp.os.vms 0000000000 00000 x X.Ee XThe X.I history Xfile contains one line for each article received. XEach line consists of three tab-separated fields: Xa X.IR Message-ID: , Xthe arrival time as seconds since midnight, XJan 1, 1970 Xand Xthe X.B Expires: Xvalue X(a dash indicates there was none) Xseparated by a tilde, Xand Xthe list of links to this article. XIf an article has been expired or cancelled without being seen first, Xthe list of links and the tab before it are omitted. XAn example: X.Es X<3451@hcr.UUCP> 581905588~- comp.text/1317 comp.sources.wanted/4200 X<9383@alice.UUCP> 611934511~- X.Ee X.SH SEE ALSO X.IR checknews (1), X.IR compress (1), X.IR inews (1), X.IR postnews (1), X.IR readnews (1), X.IR rn (1), X.IR vnews (1), X.IR getdate (3), X.IR expire (8), X.IR newsbatch (8), X.IR newsmail (8), X.IR relaynews (8), X.IR recnews (8), X.IR rnews (8), X.IR sendnews (8), X.IR uurec (8), X.IR newsinvaders (9.1) X.br XARPA Internet RFCs 1036 and 850 X.SH BUGS XB format articles must not start with X.BR A , Xto distinguish them from X.B A Xformat, Xwhich is only a problem if moderators put X.B Approved: Xfirst. X.br X.B Control: Xand X.B Newsgroups: Xare not required to be the first headers, Xif present. X.br XPeople insist on making their whacko local encapsulation schemes X.RB ( cunbatch , Xetc.) X.IR rnews 's Xproblem. X.br XOne could argue that RFC 822 Xis less than an ideal base for article format. ! echo done -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.