Vnews part 4 (of 7)

sources-request at genrad.UUCP sources-request at genrad.UUCP
Sun Jan 27 01:44:00 AEST 1985


# From: ka at hou3c
#
# Welcome to vnews release 2.11-B 1/17/85.
# This is part 4 out of 7.
# Feed me into sh (NOT csh).

if test ! -d lib
then	mkdir lib
fi

if test ! -d postnews
then	mkdir postnews
fi

cat > lib/routines.doc <<\!E!O!F!
..  Run this file through nroff (no macro packages needed)
..  To get page boundaries, pipe the output of nroff though pr.
.hy
.na
.ll 72
.de p
.sp
..
.de h
.in 0
.sp 2
.ne 4
.nr h +1
\\nh)\ \ \\$1
.p
..
.de i
.in +4
.fi
..
.de o
.sp
.in -4
.nf
..
.h "INTRODUCTION"
This file describes the contents of the lib directory.
.p
The rlib library is intended to simplify the task of writing
news reading programs.  Previously, there was no specific support
for writing news reading programs, and in order to take advantage
of existing software, programmers had to dig the routines out of the
netnews software themselves.  This library attempt collects a
number of routines, in some cases modified to make them more general
or to simplify the caller interface, into a central location where
all users can share them.  It is hoped that this library will unlimately
evolve into a collection of routines used not just by the news
reading software but by all the netnews software.
.p
There are certain limitations to this library.  Because this code
was designed and selected for its usefulness for use with vnews,
it may not always do things in ways appropriate for other programs.
On the other hand, certain functions that might be useful were
not included because they had too much vnews specific code in them.
In particular, writers of news reading programs will probably want
to copy the article selection routines out of vnews/artseq.c and
modify them to work for their particular application.  This does
not attempt to provide complete documentation on all the routines;
so you may have to consult the code for details.
.p
.h "BASIC INFORMATION"
The library source resides in a directory called
"lib".  In general, you should set
.br
	LIB = ../lib
.br
in your makefiles.  That way, your makefiles will run unchanged if
they are placed in a directory parallel to the lib directory.
You should compile your programs with -I$(LIB) so that they can
access header files in lib, and link with $(LIB)/rpathinit.o and
$(LIB)/rlib.a.  The file rpathinit.o contains the pathinit routine;
and rlib.a is an archive containing all the rest of the routines.
.p
To use many of these routines you must provide an error exit routine
called xerror; a typical version is:
.nf
	xerror(msg, a1, a2, a3, a4)  char *msg; {
		printf(msg, a1, a2, a3, a4);
		putchar('\\n');
		exit(2);
	}

.fi
There is a global variable called bfr which is a character array
of LBUFLEN (currently 1024) bytes.  Various routines in the library
use this for scratch space; you can use it as well.  Be careful not to
rely on the value of bfr if you call another routine that might modify
it.
The following library routines are guarenteed not to use bfr:  afree,
ainit, bcopy, bzero, ckmalloc, clrunread, findgroup, getaddr, getopt,
g_num, hfgets, hfree, hinit, inunread, launder, lcase, makehimask,
nextgrp, ngmatch, nstrip, prefix, prevgrp, rename, replyname, rmnf,
savestr, scopyn, setunread, and titmat.
For convenience, a declaration of bfr appears in libextern.h.
.h "HEADER FILES"
This section lists the various header files.  In some cases, you
will have to see the descriptions of the routines that use the
files for more details.
.i
.o
artfile.h
.i
This include defines for accessing the artfile.
.o
arthead.h
.i
This header file defines the arthead structure used to hold
and in-core copy of an article header.
.o
config.h
.i
This file specifies the version of UNIX you are running under.
(UNIX is a trademark of AT&T Bell Laboratories.)  It defines
index and rindex to be strchr and strrchr, if necessary.
It also defines BSDREL and USGREL.  The values of these for various
versions of UNIX are:
.nf
	VERSION		USGREL	BSDREL
	Version 6	6	6
	System III	30	6
	System V	50	6
	System V rel 2	52	6
	Version 7	6	7
	4.1 BSD		6	41
	4.2 BSD		6	42
.fi
.o
defs.h
.i
This file includes lots of news related defines.  It includes the file
newsdefs.h, which is generated by the setup program, and also has a
few defines of it's own.
Some of the useful defines are:
.nf
    Name	Default	  Description
    MAXGROUPS	300	  The maximum number of newsgroups
    BUFLEN	128/256	  The size of a general purpose char array
    LBUFLEN	1024	  The size of a big buffer
    DATELEN	48	  The maximum size of a date
    FPATHLEN	64	  The maximum length of a file name
    NAMELEN	64	  The maximum size of a message ID or address
    PATHLEN	512	  The maximum size of a Path: entry
.fi
.o
libextern.h
.i
Declares various global variables defined in the library.  Bfr is
declared here, as are the various variables set up by pathinit and
getuser.
.o
newsrc.h
.i
Defines for the .newsrc accessing routines.
.o
ng.h
.i
Defines for accessing the newgroups file.
.o
roptions.h
.i
Defines for the roptions routine.
.o
stroff.h
.i
This defines one macro called stroff(element, structure).  It returns
the offset of the specified element into the given structure.
.in -4
.p
The rest of this file details the various routines available.
.h PATHS
To avoid the necessity of hard coding paths, machine names, and so forth
in your program, these routines are provided.  Declarations for all the
variables set by these routines appear in libextern.h.
.i
.o
pathinit()
.i
This routine fills in the following character arrays:
.nf
.in +4
SPOOL:  The netnews spool directory.
LIB:  /usr/lib/news or equivelant.
FULLSYSNAME:  System name as known by neighbors.
DOMAIN:  Concatenated to FULLSYSNAME to form domain name.
XINEWS:  Path of inews program.
MAILPARSER:  Path of sendmail or recmail program.
.in -4
.fi
A number of other library routines assume that pathinit has been
called.
.o
isadmin()
.i
Returns nonzero if user is the netnews administrator or the
superuser.
.o
getpaths()
pgetpaths()
.i
Sets username to the user's login name and userhome to the user's
home directory.  The latter version always goes to the /etc/passwd
file and thus cannot be subverted by modifying the environment.
.h "NEWSGROUPS"
For convenience, each newsgroups is assigned a small integer which
uniquely identifies it.  These numbers will vary from machine to
machine and therefore can only be used locally.  The file
/usr/lib/news/groupfile maintains this mapping.  For reliability, a
backup copy is kept in /usr/lib/news/groupfile.bak.
.p
To access this file, #include\ "ng.h" and use the following routines.
.i
.o
gfopen()
gfclose()
.i
These routines open and close the newsgroup file.  The routine gfopen
also sets the global variable maxng to the largest newsgroup number
in use.
.o
ALL_GROUPS(g) { statement... }    (struct ngrec g)
.i
This macro sets up a loop through all the newsgroups.  The entries
in the ngrec structure are
.nf
      char  g_name[MAXNGNAME];	/* newsgroup name */
      short g_num;		/* newsgroup number */
      short g_flags;		/* various flags */
.fi
The only flag currently in use is G_MOD, which indicates a
moderated or fa.all group.
.h "ARTFILE"
Artfile keeps track of all the
articles in the system.
To use these routines, #include "artfile.h".
Artfile.h contains two typedefs.  An ARTNO is the number of an article
within a newsgroup.  This is currently defined to be int, but will be
changed to "long" when article numbers reach 32000.
A DPTR is the address of an article record in artfile.  The value
of a DPTR is only valid within a given program; therefore if you
want to pass the identity of an article to another program, you
should pass the message-ID of the article.  There is a special
value DNULL used to indicate a null DPTR.

There is one artrec structure for each article on the system.
The artrec structure contains the following entries of interest:
      long  a_subtime;		/* when article was posted */
      long  a_rectime;		/* when article was received */
      long  a_exptime;		/* when article expires (0 if not specified) */
      DPTR  a_parent;		/* article this is a followup to */
      DPTR  a_children;		/* linked list of followups */
      DPTR  a_childchain;	/* link for followup chain */
      short a_flags;		/* various flags */
      char  a_ngroups;		/* number of newsgroups article posted to */
      struct artgroup {
            short a_ngnum;	/* newsgroup number */
            short a_artno;	/* article number */
            DPTR  a_ngchain;	/* next article in this newsgroup */
      } a_group[MAXNG];		/* list of groups article posted to */
      char *a_ident;		/* message id */
      char *a_title;		/* article subject line */
      char *a_from;		/* author of article (real name omitted) */
      char *a_file;		/* file containing article */
      char  a_nkwords;		/* number of keywords on article */
      char *a_kword[A_MAXKW];	/* keywords */

.fi
A_flags&A_NOFILE will be true if this article does not appear in the
spool directory.  Currently, this can occur if a followup is received
before the original article.  In that case, a dummy entry will be made
for the original article until it arrives.  Later, this may also
indicate that the article has been cancelled or expired.
.p
Currently, keywords are not stored in artfile.  However, most of the
code is in place so that this can be changed if keywords are needed.
.i
.o
afopen()
.i
Open artfile.  A corresponding close routine could be written if there
is a need.
.o
ainit(a)  struct artrec *a;
afree(a)  struct artrec *a;
.i
Ainit initializes and artrec structure and afree frees up the storage
associated with it.  Both of these routines are currently no-ops
but that may change in the future.
.o
lookart(msgid, a)  char *msgid; struct artrec *a;
.i
Get the record for the article.  Returns the address of the record,
or DNULL on failure.
.o
readrec(dp, a)  DPTR dp; struct artrec *a;
.i
Read an article record given its address.
.o
BKWD_GROUP(ngnum, artno, dp, a) { statements... }
.i
This macro sets up a "for" loop to fetch all the articles in the
newsgroup numbered ngnum.  For each article, artno is set to the
article number within the group, a is set to the article record, and
dp is set to the address of the article record.  The highest
numbered records are produced first.
This means you will normally have to sort the articles before you
display them.
On the other hand, this order has the advantage that you can stop
scanning the newsgroup when you reach
the lowest numbered article marked unread in the .newsrc file.
.h ".NEWSRC PROCESSING ROUTINES"
These routines maintain an in-core copy of the .newsrc file and the
the groupfile.  You should #include "newsrc.h" which defines the
ngentry structure.  (There is one such structure for each group.)
.i
.o
openrc()
.i
Open the .newsrc file, creating it if necessary.  A file pointer is
returned.  Getuser must be called before this routine is used.
.o
readinrc(fp)  FILE *fp;
.i
Read in the .newsrc and groupfile files.  fp is the file pointer
returned by openrc, or NULL in which case only the groupfile
is read.  This routine should be called before any of the following
routines are used.
To use this routine, you must provide a routine called "wewant",
which takes the name of a newsgroup, and returns true if the
newsgroup should be appended to the .newsrc file.  Wewant generally
tests whether the user asked for the group in the -n option.
.o
writeoutrc()
.i
Write out an updated version of the .newsrc file.  This routine
is a no-op if readinrc was not called, or was called with a NULL
argument
.o
nextgrp(ngp)  struct ngentry *ngp;
.i
Returns the next group in the .newsrc file, or the first group if
ngp is NULL.
.o
prevgrp(ngp)
.i
Returns the previous group in the .newsrc file.
.o
setupgrp(ngp, max)  struct ngentry *ngp; ARTNO max;
.i
Make the specified group the current group.  Max is the maximum article
number apprearing in the group, which will be the first article number
generated by the BKWD_GROUP macro.  The global variable minartno is set
to the smallest unread article and maxartno is set to max.
.o
isunread(artno)
setunread(artno)
clrunread(artno)
.i
These routines test, set, or clear the "unread article" indication for
a given article.  The group of the article is the group specified in the
last call to setupgrp.
.o
findgroup(name)
.i
Return the address of the ngentry strucure for the group.
.o
numtong(num)
.i
Takes a newsgroup number and returns the address of the ngentry
for the newsgroup.  Currently this routine does not check its argument
for validity.
.o
g_num(ngp)
.i
Return the number of the group.
.h "ARTICLE HEADERS"
The netnews code includes some routines for dealing with article
headers, but they currently require about 5K to store a headers
and still don't allocate enough space to store the "References:"
line.  These routines use dynamicly allocated memory.
To use them, #include "arthead.h".
.i
.o
hinit(hp)  struct arthead *hp;
hfree(hp)  struct arthead *hp;
.i
These routines initialize and free the storage associated with an
arthead structure.  Hinit does not have to be called for static
or global variables since they are initialize to zero automaticly.
.o
gethead(hp, fp)
.i
This routine reads in a news header.  It returns fp on success and
NULL on failure.
.o
hxchg(hp1, hp2)
.i
This routine exchanges the value of two arthead structures.  There is
no way to copy an arthead structure, but an exchange operation will
serve for most purposes.
.o
hfgets(buf, buflen, fp)
.i
Reads a USENET header line.  This routine is like fgets except that
1) it handles continuation lines, and 2) it always reads in the
entire line, even if it doesn't fit.  The part that doesn't fit is
discarded.
.h "DATE CONVERSION"
.i
.o
cgtdate(datestr)
.i
This routine converts a date string to UNIX internal format.
Because this routine is so big (a little over 10K), there
is also a program called /usr/lib/news/cgtdate which invokes
this routine on its argument and writes the converted value
(in decimal) to the standard output.
.o
getadate(datestr)
.i
This routine converts a date in RFC 822 format to UNIX internal
format.
.h "MISCELLANEOUS NETNEWS ORIENTED ROUTINES"
.i
.o
cancel(ofp, hp, notauthor)
.i
The article whose header has been read into hp is cancelled.  If
the notauthor flag is set, the article will be cancelled locally
only rather than net-wide.  Ofp is a file pointer that is used
to write an error message on if the attempt to fork fails.
.o
dirname(group, buf)
.i
Generates the name of the directory containing the newsgroup
in buf and returns buf.
.o
getaddr(name, result)  char *name;  char result[NAMELEN];
.i
Given the contents of a "From:" line to the right of the colon,
place the machine address in "result".  (E. g.  generate "user at x"
from "user at x (Real Name)".
.o
launder(newsgroups)
.i
This routine should be called when generating followups.  It does
the net.general to net.followup conversion.
.o
makehimask(sublist, newsgroup)
.i
Unless the newsgroup is specificly asked for in the subscription list,
append !newsgroup to the subscription list.  Used to keep people from
seeing groups like control unless they really want to.
.o
ngmatch(nglist, sublist)  char *nglist, *sublist;
.i
Returns nonzero if one of the newsgroups in nglist is matched by
an entry in the subscription list.  Unlike the 2.10 netnews routine
or the same name, neither argument needs a trailing comma.
.o
replyname(hp, buf)
.i
Generates the name of the person to send replies to this article to.
.o
roptions(argv, rcfp)
.i
This routines does the readnews option processing.  Argv is the
arguments to the program.  Rcfp is refers to the .newsrc file; it
is used to read the "options " line at the top of the .newsrc file.
To access the options set by roptions, #include "roptions.h".
.o
rmnf(s)
.i
Remove any trailing " - (nf)" from the string.  Returns nonzero if
removed.
.o
titmat(titles, curtitle)
.i
See if curtitle contains one of the strings listed in titles.
The global variable "titles" is set by the roptions routine.
.o
tomsgid(id)
.i
The argument should be a message ID or an article ID.  If it
appears to be the latter, it is converted to a message ID.
.h "STRING AND MEMORY UTILITY ROUTINES"
The remaining routines are not very netnews specific.
.i
.o
bcopy(from, to, n)
.i
Copy n bytes.
.o
bzero(block, n)
.i
Clear n bytes of memory.
.o
ckmalloc(nbytes)
.i
Invokes malloc and calles xerror if the malloc fails.  All the
routines in rlib call ckmalloc instead of malloc.
.o
lcase(s)
.i
Convert the string to all lower case.
.o
nstrip(s)  char *s;
.i
Strip off trailing newlines, tabs, and spaces.  Returns nonzero if a
newline was present.
.o
prefix(s, pfx)
.i
Return nonzero if pfx is a prefix of s.
.o
savestr(s)  char *s;
.i
Return a copy of s in a block of memory obtained from ckmalloc.
.o
scopyn(from, to, n)
.i
Copy a character string, truncating the string if necessary for make
it fit.  "n" is the size of the destination.  Unlike strncpy, this
routine always terminates the result with a nul.
.o
sindex(s1, s2)
.i
Return a pointer to the first occurance of the string s2 within s1,
or NULL if not found.
.o
strpbrk(s1, s2)
.i
Return a pointer to the first character of s1 that also occurs in s2,
or NULL if no such character exists.
.o
strspn(s1, s2)
strcspn(s1, s2)
.i
Return the length of the longest prefix of s1 sonsisting of characters
in (for strspn), or not in (for strcspn), s2.
.o
strtok(s1, s2)
.i
The System III strtok routine.
.h "OTHER UTILITY ROUTINES"
.i
.o
ckfopen(file, mode)
.i
Calls fopen, and invokes xerror if the fopen fails.
.o
opendir(name)
closedir(dirp)
readdir(dirp)
rewinddir(dirp)
.i
The Berkeley directory access routines.
Opendir opens a directory and returns a (DIR *) pointer, or NULL on failure.
Readdir reads the next directory entry and returns a ponter to a struct direct,
or NULL on eof.
Closedir closes a directory.
Rewinddir goes back to the beginning of a directory and clears any buffered
information.
.o
getopt(argc, argv, optlist)
.i
The System III command argument parsing routine.
.o
rename(from, to)
.i
Rename a file, deleting any existing file named "to".
.h SYNOPSYS
This section gives an alphabetical listing of all the routines
in the library:
.sp
.nf
void addrc(ngp)  struct ngentry *ngp;
void afopen()
void afree(a)  struct artrec *a;
void ainit(a)  struct artrec *a;
void bcopy(from, to, n)  char *from, *to; int n;
char bfr[LBUFLEN];
void bzero(mem, n)  char *mem; int n;
int  cancel(ofp, hp, notauthor)  FILE *ofp; struct arthead *hp; int notauthor;
time_t cgtdate(datestr)  char *datestr;
FILE *ckfopen(filename, mode)  char *filename, *mode;
char *ckmalloc(nbytes)  int nbytes;
void closedir(dirp)  DIR *dirp;
void clrunread(artno)  ARTNO artno;
char *dirname(group, buf)  char *group, *buf;
struct ngentry *findgroup(name)  char *name;
long getadate(datestr)  char *datestr;
char *getaddr(full, mach)  char *full, mach[NAMELEN];
FILE *gethead(hp, fp)  struct arthead *hp; FILE *fp;
int getopt(argc, argv, optstr)  int argc; char **argv; char *optstr;
void getuser();
void gfclose();
void gfopen();
int g_num(ngp)  struct ngentry *ngp;
char *hfgets(buf, buflen, fp)  char *buf; int buflen; FILE *fp;
void hfree(hp)  struct arthead *hp;
void hinit(hp)  struct arthead *hp;
void hxchg(hp1, hp2)   struct arthead *hp1, *hp2;
char *index(str, c)  char *str; char c;
int isadmin();
int isre(title)  char *title;
int isunread(artno)  ARTNO artno;
void launder(newsgroups) char *newsgroups;
void lcase(str)  char *str;
DPTR lookart(msgid, a)  char *msgid; struct artrec *a;
void makehimask(sublist, group)  char *sublist, *group;
struct ngentry *nextgrp(curgrp)  struct ngentry *curgrp;
void pathinit();
int ngmatch(nglist, sublist)  char *nglist, *sublist;
int nstrip(str)  char *str;
DIR *opendir(name)  char *name;
FILE *openrc()
void pgetuser()
int prefix(str, pfx)  char *str, *pfx;
struct ngentry *prevgrp(curgrp)  struct ngentry *curgrp;
struct direct *readdir(dirp)  DIR *dirp;
void readrec(dp, a)  DPTR dp; struct artrec *a;
void readinrc(rcfp)  FILE *rcfp;
int rename(from, to)  char *from, *to;
char *replyname(hp, buf)  struct arthead *hp; char buf[PATHLEN];
void rewinddir(dirp)  DIR *dirp;
int rmnf(title)  char *title;
void roptions(argv, rcfp)  char **argv; FILE *rcfp;
char *savestr(str)  char *str;
void scopyn(from, to, tosize)  char *from, *to; int tosize;
void setunread(artno)  ARTNO artno;
void setupgrp(ngp, max)  struct ngentry *ngp; ARTNO max;
char *sindex(s1, s2)  char *s1, *s2;
char *strcspn(s1, s2)  char *s1, *s2;
char *strpbrk(s1, s2)  char *s1, *s2;
char *strspn(s1, s2)  char *s1, *s2;
char *strtok(s1, s2)  char *s1, *s2;
int titmat(titles, title)  char **titles, *title;
void tomsgid(id)  char *id;
void writeoutrc();
.fi
!E!O!F!

cat > lib/setup.doc <<\!E!O!F!
..  Run this file through nroff (no macro packages needed)
..  To get page boundaries, pipe the output of nroff though pr.
.hy
.na
.ll 72
.de p
.sp
..
.de h
.in 0
.sp 2
.ne 4
.nr h +1
\\nh)\ \ \\$1
.p
..
.de i
\f3\\$1\f1\\$2
..
.de b
\f2\\$1\f1\\$2
..
.de n
.sp
.in 0
\\$1
.in 4
..
.ce
Configuring the Netnews Software
.sp 3
The setup program is used to configure the netnews software.  To run it,
simply type "sh setup".  The setup program reads if file called "config",
which you must create, and sets up the netnews library.  The setup program
attempts to provide sensible defaults, but you must never the less provide
certain entries.
.p
Lines in the config file beginning with a "#" are considered to be comment
lines and are ignored.  Other lines should consist of a parameter name
followed by a value.  Certain parameters are boolean flags which should
be set to "yes" or "no".  If the name of a boolean flag is given without
specifying a value, the flag is set to "yes"
A sample config file appears below:
.sp
.nf
	newsusr news
	newsgrp news
	myorg BTL, Holmdel, NJ.
	mydomain .UUCP
	spool /tools/netnews/spool
	notify
	internet no
.fi
.p
The first four lines are required entries which you must provide values for.
.n newsusr
This is the owner (user name) of
.i inews .
If you are a superuser, you should probably create a new user id
(traditionally
.b news )
and use this id.
If you are not a superuser, you can use your own user id.
If you are able to, you should create a mail alias
.b usenet
and have mail to this alias forwarded to you.
This will make it easier for other sites to find the right person
in the presence of changing jobs and out of date or nonexistent
directory pages.
.n newsgrp
This is the group (name) to which
.i inews
belongs.
The same considerations as NEWSUSR apply.
.n myorg
This should be set to the name of your organization.
Please keep the name short, because it will be printed, along with
the electronic address and full name of the author of each message.
40 characters is probably a good upper bound on the length.
If the city and state or country of your organization are not obvious,
please try to include them.
If the organization name begins with a `/', it will be taken
as the name of a file.  The first line in that file will be used
as the organization.
This permits the same binary to be used on many different machines.
A good file name would be `/usr/lib/news/organization'.
For example, an organization might read ``Bell Labs, Murray Hill'',
or ``U.C. Berkeley'' or ``MIT'' or
``Computer Corp. America, Cambridge, Mass''.
.n mydomain
When generating internet addresses, this domain will be appended
to the local site name to form mailing address domains.
For example, on system ucbvax with user root, if MYDOMAIN is
set to ``.UUCP'', addresses generated will read ``root at ucbvax.UUCP''.
If MYDOMAIN is ``.Berkeley.ARPA'', the address would be
``root at ucbvax.Berkeley.ARPA''.
If your site is in more than one domain, use your primary domain.
The domain always begins with a period, unless the local site name
contains the domain; in this case MYDOMAIN should be the null string.
.in 0
.p
The following entries are not required for the setup program, but
the defaults used by the setup program may not work for you.
.n admin
This is the login name of the USENET administrator for this machine.
This may be different from newsusr.  The default is the person running
the setup program.
.n internet
If your system has a mailer that understands ARPA Internet
syntax addresses (user at domain) turn this on, and replies
will use the From or Reply-To headers.
Otherwise, set it to no and replies will use the Path header.
The default value for this parameter is "yes" because everyone
was supposed to install an internet mailer back in January of
1984.
.n sys
This is the version of UNIX you are running under.  (UNIX is a
trademark of AT&T Bell Laboratories.)  The following verions
of UNIX are defined:
.nf
    sys3	AT&T System III
    sys5	AT&T System V release 1
    sys5r2	AT&T System V release 2
    v7		AT&T Version 7 UNIX
    4.1bsd	Berkeley release 4.1
    4.2bsd	Berkeley release 4.2
.fi
Hopefully, this list will be expanded in the future.  For now,
simply choose the one that is closest to your version.
If you omit this paramter, setup will normally select the correct value.
.n path
This is the path search used by the setup program.  The default is
the value of $PATH.
.in 0
.p
The remaining parameters can be tuned as you see fit, but netnews
should run OK if you just use the defaults.
.n small
True if you are running on a 16 bit machine such as a PDP-11.
The default is yes if you are running on a PDP-11 under USG UNIX,
and no otherwise.
.n dftsub
The default subscription list.  If a user does not specify any list of
newsgroups, this will be used.  Popular choices are
.b all
and
.b general,all.general .
The default is
.b all .
.n admsub
This newsgroup (or newsgroup list) will always be selected unless the
user specifies a newsgroup list that doesn't include ADMSUB on the
command line.  That is, as long as the user doesn't use the
.b -n
flag to readnews on the command line, ADMSUB will always be selected.
The default is
.b general,all.announce .
The intent of this parameter is to have certain newsgroups which users
are required to subscribe to.
.n umask
Mask for
.i umask(2)
system call.
Set to something like 022 for a secure system.
Unsecure systems might want 002 or 000.
This mask controls the mode of news files created by the software.
Insecure modes would allow people to edit the files directly.
.n dftexp
The default number of days after which an article will expire.
2 weeks (14 days) is the default choice.
.n tmail
This is the version of the Berkeley
.i Mail
program that has the \-T option.
If left undefined, the
.b -M
option to
.i readnews
will be disabled.
.n page
The default program for which articles will be piped to for paging.
This can be disabled or changed by the environment variable PAGER.
If you have it, the Berkeley
.i more
command should be used, since the + option allows the headers to
be skipped.
If not specified, setup will look around your system in an attempt
to find a suitable program.
.n dfteditor
This is the full path name of the default editor to use during
followups and replies.
It should be set to the most popular text editor on your system.
As distributed,
.b vi
is used.
.n sendmail
This is the name of a sendmail program that understands the
.b -t
option.
.n mailer
This is the name of the mail program that recmail will invoke.
Unless you specify "internet no", this must be a mail program
that understand internet addresses.  The default is mail.
.n home
Some sites will want to run the same version of the object
code on multiple computers.  If home is defined, then the
directories lib and spool are assumed to be relative to the
login directory of the user home.
.n compadmin
Normally, the numeric user id of the netnews administrator
(specified by admin) is compiled into the netnews programs.
If compadmin is set to "yes", then the individual netnews
program will search the password file to know the numeric user id
of the netnews administrator.
.n myname
The name of your machine.  If you don't specify this, the netnews
programs will determine your system name either by using the
uname or gethostname system calls or by scanning /usr/include/whoami.h.
.n uname
Set this if the uname system call is available locally,
even though you are not a USG system.
This defaults to "yes" if you are on a USG system.
.n ghname
Define this if the 4.2BSD gethostname system call is available.
This defaults to "yes" if you are running 4.2 BSD.
.n v7mail
Define this if your system uses V7 mail conventions.
The V7 mail convention is that a mailbox contains several messages
concatenated, each message beginning with a line reading
``From user date'' and ending in a blank line.
If this is defined, articles saved will have these lines added
so that mail can be used to look at saved news.
.n spool
This directory contains subdirectories in which
news articles will be stored.
It is normally /usr/spool/news.
.PP
Briefly, for each newsgroup (say
.b net.general )
there will be a subdirectory /usr/spool/news/net/general
containing articles, whose filenames are sequential numbers, e.g.
/usr/spool/news/net/general/1, etc.
.PP
Each article file is in a mail-compatible format.
It begins with a number of header lines,
followed by a blank line, followed by the body of the article.
The format has deliberately been chosen to be compatible with the
ARPANET standard for mail documented in RFC 822.
.PP
You should place news in an area of the disk with enough free space
to hold news you intend to keep on line.
The total volume of news in net.all currently runs about 3MB/week.
If you expirenews after the default 2 weeks, you will need about 6MB
of disk space (plus some extra as a safety margin and to allow for
increased traffic in the future.)
If you only receive some of the newsgroups, or expire news after
a different interval, these figures can be adjusted accordingly.
Other newsgroup classes do not add much to the volume;
fa.all accounts for only about 80KB/week, and btl.all+bell.all
are only about 450KB/week.
.n lib
This directory will contain various system files.
It is normally /usr/lib/news.
.n bin
This is the directory in which
.i inews ,
.i readnews ,
and
.i checknews
are to be installed.
This is normally /usr/bin.
If you decide to set BINDIR to a local binary directory, you
should consider that the
.b rnews
command must be in a directory that can be found by
.b uuxqt ,
which only searches /bin and /usr/bin unless you modify uuxqt.
.n maxgroups
The maximum number of newsgroups that the software will support.
You may have to increase this as the network grows.
.n "buflen, lbuflen, datelen, fpathlen, namelen, pathlen"
See the description of defs.h in the file routines.doc for
a description of these.  Decreasing these values to save space
should not be done lightly.
!E!O!F!

cat > lib/setupgrp.c <<\!E!O!F!
#include <stdio.h>
#include <ctype.h>
#include "config.h"
#include "defs.h"
#include "newsrc.h"
#include "artfile.h"

char *savestr(), *ckmalloc();

/*
 * Set up the bit map, curng, ngsize, and groupdir for this newsgroup.
 * If no newsrc was read in then we don't bother with the bit map.
 */


char *bitmap;			/* which articles have been read */
ARTNO minartno;			/* first unread article */
ARTNO maxartno;			/* last article */


setupgrp(ngp, max)
	struct ngentry *ngp;
	ARTNO max;
	{
	int mapsize = (max >> 3) + 1;

	if (curng != NULL) {
		updaterc();
		free(bitmap);
	}
	curng = ngp;
	maxartno = max;
	bitmap = ckmalloc(mapsize);

/*
 * Set up the bit map.
 *
 * The key to understanding this piece of code is that a bit is set iff
 * that article has NOT been read.  Thus, we fill in the holes when
 * commas are found (e.g. 1-20,30-35 will result in filling in the 21-29
 * hold), and so we assume the newsrc file is properly ordered, the way
 * we write it out. 
 */
    {
	register char	*p, punct = ',';
	register ARTNO	cur = 0;
	ARTNO	next;

	bzero(bitmap, mapsize);

	/* check for first unread article */
	p = ngp->ng_bits;
	if (p == NULL)
		p = "";
	if (p[0] == '1' && p[1] == '-') {
		p += 2;
		cur = atoi(p);
		while (isdigit(*p))
			p++;
	}
	minartno = cur + 1;

	/* process rest of bit string */
	while (*p) {
		while (!isdigit(*p) && *p)
			p++;
		if (!*p)
			break;
		next = atoi(p);
		if (next > maxartno)		/* "Can't happen" */
			next = maxartno + 1;
		if (punct == ',') {
			while (++cur < next) {
				setunread(cur);
			}
		}
		cur = next;
		while (!ispunct(*p) && *p)
			p++;
		punct = *p;
	}
	while (++cur <= maxartno)
		setunread(cur);
	return 0;
    }
}



updaterc()
{
	register int	cur, next = 1;
	register char	*ptr;
	extern	int rcreadok;
	extern	char bfr[];

	if (!rcreadok || !curng)
		return;
	bfr[0] = bfr[1] = '\0';
	for (;;) {
		ptr = &bfr[strlen(bfr)];
		while (next <= maxartno && isunread(next))
			next++;
		if (next > maxartno)
			break;
		cur = next;
		while (next <= maxartno && ! isunread(next))
			next++;
		if (cur + 1 == next)
			sprintf(ptr, ",%d", cur);
		else
			sprintf(ptr, ",%d-%d", cur, next - 1);
	}
	if (curng->ng_bits != NULL)
		free(curng->ng_bits);
	curng->ng_bits = savestr(bfr + 1);	/* the +1 skips the leading comma */
}
!E!O!F!

cat > lib/str.h <<\!E!O!F!
/* string declarations */

char *index(), *rindex(), *sindex(), *strpbrk();
char *ckmalloc(), *savestr(), *nsavestr();
#define scopy(from, to)	strcpy(to, from)
#define equal(s1, s2)	(strcmp(s1, s2) == 0)
!E!O!F!

cat > lib/strcspn.c <<\!E!O!F!
/*
 * strcspn - find length of initial segment of s1 consisting entirely
 * of characters not from s2
 */

int
strcspn(s1, s2)
char *s1;
char *s2;
{
	register char *scan1;
	register char *scan2;
	register int count;

	count = 0;
	for (scan1 = s1; *scan1 != '\0'; scan1++) {
		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
			if (*scan1 == *scan2++)
				return(count);
		count++;
	}
	return(count);
}
!E!O!F!

cat > lib/stroff.h <<\!E!O!F!
#define stroff(member, str)	((char *)&((struct str *)0)->member - (char *)0)
!E!O!F!

cat > lib/strpbrk.c <<\!E!O!F!
#include "config.h"
#if USGREL < 30
/*
 * strpbrk - find first occurrence of any char from s2 in s1
 *	     Written by Henry Spencer.
 */

#define	NULL	0

char *				/* found char, or NULL if none */
strpbrk(s1, s2)
char *s1;
char *s2;
{
	register char *scan1;
	register char *scan2;

	for (scan1 = s1; *scan1 != '\0'; scan1++) {
		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
			if (*scan1 == *scan2++)
				return(scan1);
	}
	return(NULL);
}
#endif
!E!O!F!

cat > lib/strpbrk.u3b <<\!E!O!F!
	.file	"strpbrk.u3b"	# think of this line as an offering to the gods

# char *strpbrk(s1, s2)  char *s1, *s2;
# Finds first occurance in s1 of a character in s2.

	.text
	.globl	strpbrk
	.align	4
strpbrk:
	save	&2			# save r7 and r8
	movw	0(%ap), %r0		# r0 = s1
	movw	4(%ap), %r8		# r8 = s2
	movw	&0, %r2			# string termination character
	jmp	L2
L1:					# while (*s1 != '\0') {
	  movw	  %r8, %r7		#   get s2
	  locce	  %r7, %r1, %r2		#   strchr(s2, *s1)
	  je	  L4			#   if found, return
	  addw2	  &1, %r0		#   increment s1
L2:	  movb	  0(%r0), %r1		#   get *s1
	  jne	  L1			#   loop if not at end of string
	movw	&0, %r0			# set s1 to NULL
L4:	ret	&2			# and return s1
!E!O!F!

cat > lib/strspn.c <<\!E!O!F!
/*
 * strspn - find length of initial segment of s1 consisting entirely
 * of characters from s2
 */

int
strspn(s1, s2)
char *s1;
char *s2;
{
	register char *scan1;
	register char *scan2;
	register int count;

	count = 0;
	for (scan1 = s1; *scan1 != '\0'; scan1++) {
		for (scan2 = s2; *scan2 != '\0'; scan2++)
			if (*scan1 == *scan2)
				break;
		if (*scan2 == '\0')
			return(count);
		count++;
	}
	return(count);
}
!E!O!F!

cat > lib/strtok.c <<\!E!O!F!
/*
 * Get next token from string s1 (NULL on 2nd, 3rd, etc. calls),
 * where tokens are nonempty strings separated by runs of
 * chars from s2.  Writes NULs into s1 to end tokens.  s2 need not
 * remain constant from call to call.
 */

#define	NULL	0

static char *scanpoint = NULL;

char *				/* NULL if no token left */
strtok(s1, s2)
char *s1;
register char *s2;
{
	register char *scan;
	char *tok;
	register char *scan2;

	if (s1 == NULL && scanpoint == NULL)
		return(NULL);
	if (s1 != NULL)
		scan = s1;
	else
		scan = scanpoint;

	/*
	 * Scan leading delimiters.
	 */
	for (; *scan != '\0'; scan++) {
		for (scan2 = s2; *scan2 != '\0'; scan2++)
			if (*scan == *scan2)
				break;
		if (*scan2 == '\0')
			break;
	}
	if (*scan == '\0') {
		scanpoint = NULL;
		return(NULL);
	}

	tok = scan;

	/*
	 * Scan token.
	 */
	for (; *scan != '\0'; scan++) {
		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
			if (*scan == *scan2++) {
				scanpoint = scan+1;
				*scan = '\0';
				return(tok);
			}
	}

	/*
	 * Reached end of string.
	 */
	scanpoint = NULL;
	return(tok);
}
!E!O!F!

cat > lib/titmat.c <<\!E!O!F!
/*
 * Match title.
 */

titmat(title, titlist)
      char *title;
      register char **titlist;
      {
      char *sindex();

      while (*titlist) {
            if (sindex(title, *titlist))
                  return 1 ;
            titlist++ ;
      }
      return 0 ;
}


char *
sindex(s1, s2)
      register char *s1 ;		/* string being searched */
      register char *s2 ;		/* string being scanned for */
      {

      if (*s2 == '\0')
            return s1 ;
      while (*s1) {
            if (*s1 == *s2 && prefix(s1, s2))
                  return s1 ;
            s1++ ;
      }
      return 0 ;
}
!E!O!F!

cat > lib/tomsgid.c <<\!E!O!F!
#include "config.h"
#include "defs.h"

/*
 * Convert an article id to a message id if it's not already a message id.
 */

tomsgid(id)
      char *id ;
      {
      char lbuf[NAMELEN];
      register char *p ;
      char *index() ;

      if (id[0] != '<') {
            strcpy(lbuf, id);
            p = index(lbuf, '.');
            if (p == 0) {
                  return;
            }
            *p++ = '\0';
            /*
             * It may seem strange that we hardwire ".UUCP" in
             * here instead of MYDOMAIN.  However, we are trying
             * to guess what the domain was on the posting system,
             * not the local system.  Since we don't really know
             * what the posting system does, we just go with the
             * majority - almost everyone will be a .UUCP if they
             * didn't fill in their Message-ID.
             */
            sprintf(id, "<%s@%s%s>", p, lbuf, ".UUCP");
      }
}
!E!O!F!

cat > lib/vprintf.h <<\!E!O!F!
/*
 * These defines allow you to define routines that call printf on their
 * arguments in a way that at least marks them as machine dependent.
 * Example:
 *
 * fatal(VPARGS)
 *	VPDCL;
 *	{
 *	VFPRINTF(stderr, VPARGS);
 *	exit(1);
 * }
 *
 * Later:  use varargs.h.
 */

#define VPARGS msg, a1, a2, a3, a4
#define VPDCL char *msg;
#define VPRINTF(args) printf(VPARGS)
#define VFPRINTF(fp, args) fprintf(fp, VPARGS)
#define VSPRINTF(s, args) sprintf(s, VPARGS)
!E!O!F!

cat > lib/write.c <<\!E!O!F!
#include <stdio.h>
#include "af.h"
#include "libextern.h"

long lseek();


/*
 * Write a record to the data base.  We can't use stdio because fseek
 * doesn't work under 4.1 BSD.
 */

writerec(a, fd)
      struct artrec *a ;
      int fd ;
      {
      int i ;
      register char *p, *q ;
      char **pp ;

      bfr[0] = A_PREFIX ;
      bcopy((char *)a, bfr + 1, A_WRTLEN) ;
      bcopy((char *)a->a_group, bfr + 1 + A_WRTLEN, i = a->a_ngroups * sizeof(*a->a_group)) ;
      p = bfr + 1 + A_WRTLEN + i ;
      pp = &a->a_ident ;
      i = (a->a_flags & A_DUMMY)? 1 : 4 + a->a_nkwords ;
      while (--i >= 0) {
            for (q = *pp++ ; *p++ = *q++ ; ) ;
      }
      if (write(fd, bfr, p - bfr) != p - bfr)
            xerror("Write error in writerec") ;
}



writeptr(p, dp)
      DPTR p, dp ;
      {
      if (lseek(affd, (long)dp, 0) < 0)
            xerror("seek %ld failed, writeptr %ld", dp, p) ;
      if (write(affd, (char *)&p, sizeof p) != sizeof p)
            xerror("write failed, writeptr(%ld, %ld)", p, dp) ;
}
!E!O!F!

cat > postnews/artlist.c <<\!E!O!F!
/*
 * This routine generates a list of articles for postnews.
 */

#include <stdio.h>
#include <sys/types.h>
#include "config.h"
#include "artfile.h"
#include "ng.h"



artlist(ngname, pattern)
      char *ngname, *pattern ;
      {
      static struct ngrec ng ;
      struct artrec a ;
      ARTNO artno ;
      DPTR dp ;
      static int first = 1 ;

      if (first || strcmp(ngname, ng.g_name) != 0) {
            gfopen() ;
            ALL_GROUPS(ng) {
                  if (strcmp(ng.g_name, ngname) == 0)
                        goto found ;
            }
            xerror("%s does not appear in groupfile", ngname) ;
found:
            gfclose() ;
      }
      if (first) {
            afopen() ;
            first = 0 ;
      }
      fputs("NUMB  AUTHOR		TITLE\n", stdout) ;
      BKWD_GROUP(ng.g_num, artno, dp, a) {
            if (a.a_flags & A_DUMMY)
                  continue ;
            if (sindex(a.a_title, pattern) || sindex(a.a_from, pattern)) {
                  printf("%-5d %.16s\t", artno, a.a_from) ;
                  if (strlen(a.a_from) < 10)
                        putchar('\t') ;
                  if (strlen(a.a_from) < 2)
                        putchar('\t') ;
                  printf("%.40s\n", a.a_title) ;
            }
      }
}
!E!O!F!

cat > postnews/distlist <<\!E!O!F!
# This file contains descriptions of the various distributions, and is
# used to build the /usr/lib/news/distributions file which is used by
# postnews.  Unfortunately, this list is probably not complete.  Please
# mail any additions to ihnp4!hou3c!ka.

local	Local to this site
unm	University of New Mexico
um	University of Maryland
wat	Universtiy of Waterloo
atl	Atlanta
ba	SF Bay Area
chi	Chicago
cmh	Columbus, Ohio
la	Los Angeles
ho	AT&T Holmdel location
ih	AT&T Indian Hill location
cb	AT&T Columbus location
mh	AT&T Murrey Hill location
dr	AT&T IS Denver location
ont	Onterio
ca	California
ga	Georgia
nj	New Jersey
ny	New York
oh	Ohio
or	Oregon
ne	New England
intel	Intel
tek	Tektronix
btl	AT&T Bell Labs
att	AT&T
bell	Bell operating companies
usa	United States
can	Canada
na	North America
uk	United Kingdom
eunet	Europe
world	Everywhere on Usenet in the world (same as net)
!E!O!F!

cat > postnews/genmakefile <<\!E!O!F!
LIB=../lib
. $LIB/makedefs
exec > makefile
cat <<!
# makefile 2.11-B 1/12/85

LIB=$LIB
!
cat $LIB/makedefs
cat <<\!

POSTNEWS = postnews.o artlist.o $(LIB)/rpathinit.o $(LIB)/rlib.a
POSTREPLY = postreply.o $(LIB)/rpathinit.o $(LIB)/rlib.a
POSTNM = postnm1.o postnm2.o postnm3.o postnm4.o postnm5.o $(LIB)/rpathinit.o $(LIB)/rlib.a
RECMAIL = recmail.o
CFLAGS = $(DEBUG) -I$(LIB)
DEBUG = -O

all: makefile postnews postreply postnm distributions gparent.wm

makefile: genmakefile $(LIB)/makedefs
	genmakefile
	@echo 'Makefile changed, so restart make.'
	@sh -c 'exit 22'

install: all $(LIBDIR)/distributions $(LIBDIR)/moderators
	-/bin/mv $(BINDIR)/postnews $(BINDIR)/opostnews
	/bin/cp postnews postnm gparent $(BINDIR)
	/bin/cp postreply $(LIBDIR)/postreply

postnews: $(POSTNEWS)
	$(CC) $(DEBUG) -o $@ $(POSTNEWS)

postreply: $(POSTREPLY)
	$(CC) $(DEBUG) -o $@ $(POSTREPLY)

postnm: $(POSTNM)
	$(CC) $(DEBUG) -o $@ $(POSTNM)

recmail: $(RECMAIL)
	$(CC) $(DEBUG) -o $@ $(RECMAIL)

distributions: distlist
	makedist > distributions

gparent.wm: gparent.wm.c
	$(CC) gparent.wm.c
	a.out > gparent.wm
	rm a.out

$(LIBDIR)/distributions: distributions
	-/bin/mv $(LIBDIR)/distributions $(LIBDIR)/odistributions
	/bin/cp distributions $(LIBDIR)/distributions

$(LIBDIR)/moderators:
	/bin/cp moderators $@

postnews.o postreply.o recmail.o: $(FRC)
postnm1.o postnm2.o postnm3.o postnm4.o postnm5.o: postnm.h $(FRC)

FRC:
!
!E!O!F!
chmod +x postnews/genmakefile

cat > postnews/gparent <<\!E!O!F!
#!/bin/sh
a=${1-${A?}}
sed -e '1,/^$/d' -e 's/^/> /' $a
!E!O!F!
chmod +x postnews/gparent

cat > postnews/gparent.ml <<\!E!O!F!
; This mlisp macro reads in the body of the article being followed up,
; preceding each line with a "> ".
; It is intended to be bound to ^X^Y.

(defun
    (gparent
	(end-of-file)
	(save-excursion
	    (set-mark)
	    (insert-file (getenv "A"))
	    (re-search-forward "^$")
	    (next-line)
	    (erase-region)
	    (re-replace-string "^" "> ")
	)
    )
)
!E!O!F!

cat > postnews/gparent.wm.c <<\!E!O!F!
/*
 * Since the gparent macro for Warren Montgomery's emacs
 * contains control characters, it cannot be distributed
 * directly over the net.  This C program will write the
 * macro to the standard output.
 */

#define SIZE 95

char gparent[SIZE] = {
      0030,0031,0034,0147,0160,0141,0162,0145,0156,0164,
      0040,0055,0040,0151,0156,0163,0145,0162,0164,0040,
      0142,0157,0144,0171,0040,0157,0146,0040,0157,0162,
      0151,0147,0151,0156,0141,0154,0040,0141,0162,0164,
      0151,0143,0154,0145,0012,0276,0000,0030,0074,0101,
      0012,0305,0025,0030,0022,0030,0030,0000,0030,0074,
      0136,0044,0012,0223,0016,0027,0030,0055,0033,0061,
      0064,0000,0030,0074,0076,0040,0012,0030,0074,0136,
      0012,0222,0122,0033,0062,0010,0030,0055,0033,0061,
      0064,0030,0030,0032,0012
};

main() {
      int i ;

      for (i = 0 ; i < SIZE ; i++)
            putchar(gparent[i]);
      return 0;
}
!E!O!F!

cat > postnews/letter <<\!E!O!F!
To: uucp-news at cbosgd
Subject: A new program: postnm
Message-ID: <467517088 at hou3c.UUCP>

This program is not quite finished yet, but I thought I would let you
know about it.

NAME:
	Postnm - post news and/or mail

SYNOPSYS:
	postnm -x [ file ]

DESCRIPTION:

Postnm reads and article from the file, or from the standard input if
no filename is specified.  If the article header contains a Newsgroup:
line, the article is posted.  If it contains To:, Cc:, or Bcc: lines,
the article is mailed to the specified recipients.

Postnm attempts to pass only valid articles to inews.  Postnm cannot
guarentee to pass only valid mail to the mail program because of the
lack of standardization of mail under UNIX.  Therefore, tries to accept
a variety of mail formats and to pass them through to the mailer
unchanged.

The input to the program should look like a USENET article or a piece
of RFC822 mail.  Some headers supported by postnm are:

To:, Cc:, and Bcc:
	These lines are scanned for address to be passed to the mail
	program.  Commas between the addresses are optional.  Any RFC
	822 address should be accepted as long as it is formatted
	sensibly (no comments within the address, and no white space
	except within angle brackets or around the at sign).  Some
	legal address lines are:
		To: "Kenneth Almquist" @ hou3c.UUCP  (That's me)
		To: Kenneth Almquist <@cbosgd.UUCP: ka at hou3c.UUCP>
	The address is passed to the mailer uninterpreted except that
	comments and any enclosing angle brackets are deleted.

Newsgroups:, Followup-To:
	Newsgroups on these lines are separated by white space and/or
	commas.

From:, Reply-To:
	On posted news, these lines will be converted to the format:
		From: user at machine (Real Name)

References:
	This line is passed through to news.  If you don't include an
	In-reply-to: line, one will be generated from the References:
	line.

Command:
	This specifies that the article is a reply or a followup.  If
	"Command: reply" is specified, any Newsgroup: line will be
	ignored.  If "Command: followup" is specified, any "To:" line
	will be ignored.  This way, if you type a followup command and
	then decide that your reply really isn't of interest to the
	entire net, you can edit this line.

Other headers are supported.  In addition, any unsupported header is
passed thorough unchanged if it does not appear to be a misspelling of
a supported header.

Although postnm will read from its standard input if no file is given,
typing an article directly into postnm from the terminal is
expressly frowned upon because that mode of operation makes it
difficult to correct errors.  Therefore, postnm will not save the
article in dead.article if an error occurs.
				Kenneth Almquist
!E!O!F!

cat > postnews/makedist <<\!E!O!F!
: This shell procedure creates the distributions file.

. ../lib/makedefs

dlist=`sed -e '/^#/d' -e 's/[^:]*://' -e 's/:.*//' -e 's/,/ /g' -e 's/  */ /g' $LIBDIR/sys | tr ' ' '
' | sed -e '/^!/d' -e 's/\..*//' | sort | uniq`

exec < distlist
while read dist desc
do	case "$dist" in
	""|\#*)	;;
	local|world)
		echo "$dist	$desc"
		;;
	*)	ndlist=
		for x in $dlist
		do	if test "$x" = "$dist"
			then	echo "$dist	$desc"
			else	ndlist="$ndlist $x"
			fi
		done
		dlist="$ndlist"
		;;
	esac
done
ndlist=
for x in $dlist
do	case "$x" in
	fa|mod|net|ug|to|all)
		;;
	*)	grep "^$x " $LIBDIR/active > junk
		if test -s junk
		then	:
		else	ndlist="$ndlist $x"
		fi
		rm junk
		;;
	esac
done
if test "$ndlist" != "" -a "$ndlist" != " "
then	echo "The following distributions are not known to me: $ndlist" >&2
	echo "Please add descriptions of them to postnews/distlist." >&2
	exit 1
fi
exit 0
!E!O!F!
chmod +x postnews/makedist

cat > postnews/moderators <<\!E!O!F!
net.announce	announce at cbosgd.UUCP
net.announce.newusers	usenet at gatech.UUCP
mod.map		mark at cbosgd.UUCP
mod.map.news	map at cbosgd.UUCP
mod.map.uucp	uucpmap at cbosgd.UUCP
mod.motss	motss at bbncca.UUCP
mod.movies	movies at ecsvax.UUCP
mod.music	gregbo at hou2e.UUCP
mod.newslists	usenet at gatech.UUCP
mod.singles	singles at nsc.UUCP
mod.sources	sources at genrad.UUCP
mod.std.c	std-c at cbosgd.UUCP
mod.std.mumps	std-mumps at plus5.UUCP
mod.unix	unix at masscomp.UUCP
fa.arms-d	arms-d at ucbvax.UUCP
fa.arpa-bboard	arpa-bboard at ucbvax.UUCP
fa.bitgraph	INFO-BITGRAPH at MIT-MC.ARPA
fa.human-nets	human-nets at brl-bmd.UUCP
fa.info-mac	info-mac at uw-beaver.UUCP
fa.info-vax	info-vax at ucbvax.UUCP
fa.laser-lovers	laser-lovers at uw-beaver.UUCP
fa.poli-sci	poli-sci at ucbvax.UUCP
fa.telecom	telecom at brl-bmd.UUCP
fa.raliroad	railroad at ucbvax.UUCP
!E!O!F!

echo Part 4 of 7 extracted.



More information about the Mod.sources mailing list