[comp.sources.misc] v17i017: rkive - Usenet sources archiver, Part01/06

kent@sparky.imd.sterling.com (Kent Landfield) (02/25/91)

Submitted-by: Kent Landfield <kent@sparky.imd.sterling.com>
Posting-number: Volume 17, Issue 17
Archive-name: rkive/part01

		RKIVE 2.0 && ARTICLE 2.0

The following are a few of the changes made between the previous
versions of article and rkive and the 2.0 releases.
----
Article and rkive now supports comp.archives auxiliary headers and
archiving.

Article and rkive now supports comp.sources.apple2 format correctly.

Added compression recognition to Article so that it can deal
transparently with compressed/packed files. There is no longer
a need to "zcat filename | article".

Rkive can now accept articles on stdin.

Rkive is able to take the filename of articles to be archived
from a batch file created from the news system.

Added NNTP support so that the archives can be maintained on a remote
system(s) Now, an archive site can use multiple spool directories 
located on multiple systems to assure timely update and better news 
access reliability.

Rkive can use the X-Checksum-Snefru: header used in c.s.unix and 
c.s.misc to verify the inbound article. The snefru utility is
not supplied and is availble from your local c.s.u archives.

Added the ability to support globbing.  rkive now allows the user to
specify a match string to search for in the newsgroup. When a match is
found, that article is archive. Only articles that match the specific
patterns are archived. This mechanism works for all the different types
of archiving.

Added the ability for archive to execute external applications as
if it was done internally. It logs and writes index files for these
as specified in the rkive.cf configuration file.

Added the update_netdocs script and the appropriate entries in the 
supplied rkive.cf. This script provides an _example_ of how the
external archive mechanism works. It allows a site to maintain the
the set of periodic postings that are specified in the rkive.cf and
the update_netdocs. This script was a QUICK AND DIRTY EXAMPLE. It
needs rewriting to be really used. Please don't flame me about this
since it was just an example...

Added aditional format specifications to format.c so that the information
contained in the rkive.cf file could be supplied to external commands
for their specific use.

Added the ability for the person configuring the rkive.cf to specify
where the .patchlog and .archived files are to reside. 

Options can be passed with the commands specified in rkive.cf.
(e.g.  COMPRESS=compress -f)

Removed alot of duplicated code and added some more. :-)

Plus others I have forgotten...

I want to thank all the people who spent time sending me suggestions.
I especially want to thank the people who took the time to beta test 
this version for me.

Petri Ojala <ojala@finland.eu.net>
Chris Myers <chris@wugate.wustl.edu>
Neil Gorsuch <neil@cpd.com>
Karl Lovink <karl@ofssrv.syssup.tds.philips.nl>
David Schmidt <uunet!isc-br.isc-br.com!os-d!davids>
Mark J. Bailey <uunet!mjbtn!mjb>
Paul Vickers <paulv@logitek.co.uk>
Ed Vielmetti <emv@ox.com>
Heikki Suonsivu <hutcs.hut.fi!hsu>

Special thanks to Paul and Ed for showing me how dumb I really can be... :-)
And to Heikki, who supplied the basis for the globbing functionality, I'll
get that beer to you somehow... :-) :-) THANKS ALL!!!

			-Kent+
----
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 1 (of 6)."
# Contents:  rkive rkive/news_arc.c rkive/port rkive/port/README.port
#   rkive/rkive.cf
# Wrapped by kent@sparky on Sun Feb 24 16:11:21 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'rkive' ; then
    echo shar: Creating directory \"'rkive'\"
    mkdir 'rkive'
fi
if test -f 'rkive/news_arc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/news_arc.c'\"
else
echo shar: Extracting \"'rkive/news_arc.c'\" \(28314 characters\)
sed "s/^X//" >'rkive/news_arc.c' <<'END_OF_FILE'
X/*
X** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
X**
X** Permission is hereby granted to copy, distribute or otherwise 
X** use any part of this package as long as you do not try to make 
X** money from it or pretend that you wrote it.  This copyright 
X** notice must be maintained in any copy made.
X**
X*/
X
X#if !defined(lint) && !defined(SABER)
Xstatic char SID[] = "@(#)news_arc.c	2.2 2/23/91";
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <time.h>
X#include <ctype.h>
X#include "article.h"
X#include "cfg.h"
X
X/*
X** Defines for the type of "problems"
X** encountered in saving the articles.
X*/
X#define DUP_PROB    	0
X#define NAME_PROB   	1
X#define VOL_PROB    	2
X#define TYPE_PROB	3
X#define CHECKHASH_PROB  4
X#define MSNG_HASH_PROB  5
X#define CA_NAME_PROB    6
X#define EXTERNAL_PROB   7
X
Xint test = 0;
Xint inum = 0;
Xint problem_article;
X
Xextern struct group_archive *newsgrp;
Xextern int overwrite;
X
Xint  fclose();
Xint  stat();
Xint unlink();
Xint  do_checkhash();
Xint  remove_suffix();
Xchar *strchr();
Xchar *strcpy();
Xchar *strcat();
Xchar *do_problem();
Xchar *basename();
Xchar *suffix();
Xchar *expand_name();
Xchar *copy_article();
XFILE *efopen();
Xvoid init_article();
Xvoid store_line();
Xvoid dump_article();
Xvoid record_problem();
X
Xvoid get_header(filename)
X    char *filename;
X{
X    char *dp;
X    int header_ok = 0;
X    int last = TEXT;
X    FILE *gfp;
X
X    init_article();
X
X    gfp = efopen(filename,"r");
X
X    (void) strcpy(article.newsarticle, filename);
X
X    while (fgets(s,sizeof s,gfp) != NULL) {
X        if (debug)
X            (void) fprintf(logfp, "BUF = [%s]",s);
X
X        if (!isalpha(*s) || (strchr(s,':') == NULL)) {
X           header_ok++;
X           if (header_ok >= 2) {
X               if (*s == '\n' && last == BLANK)
X                   continue;
X               break;
X           }
X           if (*s == '\n')
X              last = BLANK;
X           else 
X              last = TEXT;
X           continue;
X        }
X
X        last = TEXT;
X        dp = s;
X        while (*++dp)
X           if (*dp == '\n')
X               *dp = '\0';
X
X        store_line();
X    }
X    (void) fclose(gfp);
X
X    if (debug)
X        dump_article();
X}
X
X#ifdef REDUCE_HEADERS
X
Xstruct hdrstokeep {
X	char 	*ststr;
X	int	stbytes;
X};
X
Xstruct hdrstokeep hdrs[] = {
X{	"From:",		(sizeof "From:")		},
X{	"Newsgroups:",		(sizeof "Newsgroups:")		},
X{	"Subject:",		(sizeof "Subject:")		},
X{	"Message-ID:",		(sizeof "Message-ID:")		},
X{	"Date:",		(sizeof "Date:")		},
X{	"Approved:",		(sizeof "Approved:")		},
X{	"X-Checksum-Snefru:",	(sizeof "X-Checksum-Snefru:")	},
X{	NULL,			0				},
X};
X
Xint keep_line(argstr)
X    char *argstr;
X {
X    int strncmp();
X
X    struct hdrstokeep *pt;
X
X    pt = &hdrs[0];
X    while ((pt->ststr) != NULL) {
X        if (strncmp(argstr, pt->ststr, (pt->stbytes-1)) == 0) 
X            return(TRUE);
X        pt++;
X    }
X    return(FALSE);
X}
X#endif /* REDUCE_HEADERS */
X
Xint copy(source, target)
X    char *source, *target;
X{
X    char *strchr();
X    int fputs();
X
X    FILE *from, *to;
X    char fbuf[BUFSIZ];
X
X#ifdef REDUCE_HEADERS
X    int inheader;
X
X    inheader = TRUE;  
X#endif /* REDUCE_HEADERS */
X
X    if (verbose) {
X        (void) fprintf(logfp,"archive <%s> to <%s>\n",source,target);
X        if (test) 
X            return(0);
X    }
X    if ((from = fopen(source, "r")) == NULL) {
X        (void) fprintf(errfp,"%s: cannot open %s\n",progname,source);
X        return (-1);
X    }
X    if ((to = fopen(target, "w")) == NULL) {
X        (void) fclose(from);
X        (void) fprintf(errfp,"%s: cannot create %s\n",progname,target);
X        return (-1);
X    }
X
X    while (fgets(fbuf, BUFSIZ, from) != NULL) {
X#ifdef REDUCE_HEADERS
X        /*
X        ** Read the source and do not print any headers 
X        ** unless specified in the "keep" headers table.
X        */
X        if (inheader) {
X            /* 
X            ** Have I encountered a line without a line type ? 
X            */
X            if (!isalpha(*fbuf) || (strchr(fbuf,':') == NULL)) 
X                inheader = FALSE;
X
X            else {
X                /*
X                ** Determine the type of the header line and 
X                ** decide if this is a line to be kept or pitched.
X                */
X                if (!keep_line(fbuf))
X                    continue;
X            }
X        }
X#endif /* REDUCE_HEADERS */
X        if (fputs(fbuf, to) == EOF) {
X            (void) unlink(target);
X            (void) fclose(from);
X            (void) fclose(to);
X            (void) fprintf(errfp,"%s: bad copy to %s\n",progname,target);
X            return (-1);
X        }
X    }
X    (void) fclose(from);
X    (void) fclose(to);
X    return(0);
X}
X
X/*
X** mkparents:
X**
X** If any parent directories in 
X** fullname don't exist, create them.
X*/
X
Xint mkparents(fullname)
Xchar *fullname;
X{
X    int access();
X    int makedir();
X    char *strrchr();
X
X    register char *p;
X    char b[MAXNAMLEN];
X    int rc;
X
X    (void) strcpy(b, fullname);
X
X    if ((p = strrchr(b, '/')) != NULL) 
X            *p = '\0';
X    else                  /* no directories in fullname */
X       return(0);
X
X    if (*b == '\0')           /* are we at the root ? */
X        return(0);
X
X    if (access(b, 0) == 0)
X        return(0);
X
X    if (mkparents(b) == -1)
X        return(-1);
X
X    if ((rc = makedir(b, DIR_MODE, newsgrp->owner, newsgrp->group)) != 0) 
X        record_problem("makedir failed attempting to make %O", b, newsgrp);
X
X    return(rc);
X}
X
Xchar *copy_article(ng, filename,path)
Xstruct group_archive *ng;
Xchar *filename;
Xchar *path;
X{
X    void write_archived();
X    void write_patch_log();
X
X    if (copy(filename,path) != 0) {  
X        (void) fprintf(errfp,"copy failed for %s to %s\n",filename,path);
X        return(NULL);
X    }  
X
X    /* 
X    ** Write the message-id to the .archived file in the newsgroup's
X    ** BASEDIR directory since we do not want it rearchived tomorrow.
X    */
X    write_archived(header.ident, path);
X
X    /*
X    ** Check if the file is a patch. If so, log
X    ** the patch information into the patch log
X    ** in a *non-configurable* format so that
X    ** applications can be written to access the
X    ** file's "known format".
X    */
X
X    if (article.rectype == PATCH)
X        write_patch_log(ng,path);
X
X    /*
X    ** Return the path to the archived file.
X    */
X    return(path);
X}
X
Xchar *save_article (filename,ng)
Xchar *filename;
Xstruct group_archive *ng;
X{
X    char *format_output();
X    void check_archive_name();
X    void chronpath();
X
X    char *final_path;
X    char *kp;
X
X    char cmdline[BUFSIZ];
X    char command[BUFSIZ];
X    static char path[MAXNAMLEN];
X    struct stat sb;
X
X    problem_article = FALSE;
X    path[0] = '\0';
X
X    /*
X    ** The news article has been read and the header
X    ** information is filled into the appropriate
X    ** data structures.
X    */
X
X    /*
X    ** If the Snefru header exists, check the article checksum for validity.
X    */
X    if (header.x_checksum_snefru[0]) {
X	if (*(ng->checkhash)) {
X	    if (do_checkhash(ng->checkhash, filename) != 0)
X		return(do_problem(CHECKHASH_PROB,ng,filename,path));
X	}
X	else if(*checkhash) {
X	    if (do_checkhash(checkhash, filename) != 0)
X		return(do_problem(CHECKHASH_PROB,ng,filename,path));
X	}
X    }
X    else {
X	if (*(ng->checkhash) || *checkhash)
X		return(do_problem(MSNG_HASH_PROB,ng,filename,path));
X    }
X
X    /*
X    ** Build the path string for the final resting spot
X    ** for the new archive member.
X    */
X    switch(ng->type) {
X    case ARCHIVE_NAME:
X            /*
X            ** The header's archive_name contains the filename in
X            ** an "elm/part06" format.
X            */
X
X            if ((article.volume == -1) || (!header.archive_name[0])) {
X                /* 
X                ** If the posting is an administration (ADM) posting
X		** then create a valid Archive-Name:. In other words,
X                ** cheat bigtime... c.s.apple2 uses these headers and does 
X		** not put in any auxiliary headers. They should be pitched
X		** in that newsgroup, according to Jonathan, but I like to
X		** keep a copy of everything that goes through the newsgroup.
X		** The history thing ya know.. :-)
X                */
X                if (article.rectype == ADMINISTRATION)
X                    (void) sprintf(header.archive_name,".admin/ADM%d",article.issue);
X                else
X                    return(do_problem(NAME_PROB, ng,filename,path));
X            }
X            /*
X            ** Assure the address is relative and
X            ** that some prankster can not do nasty
X            ** things to your system files by having
X            ** an Archive-name line like:
X            **    ../../../../../etc/passwd
X            */
X
X            check_archive_name(header.archive_name);
X
X            /* 
X            ** Check to see if the article is a patch. If so,
X            ** check to see if the administrator wishes to
X            ** store the patch with the initially posted
X            ** articles. This really relys on the archive name
X            ** being correct.
X            */
X            
X            if (article.rectype == PATCH && ng->patch_type == PACKAGE)
X                /*
X                ** Store the patch in the volume specified with the
X                ** Archive-name: specified file name.
X                */
X#ifdef ZEROFILL
X                (void) sprintf(path,"%s/%s%.02d/%s", ng->location, VOLUME,
X#else
X                (void) sprintf(path,"%s/%s%d/%s", ng->location, VOLUME,
X#endif 
X		            article.patch_volume, header.archive_name);
X
X            else 
X#ifdef ZEROFILL
X                (void) sprintf(path,"%s/%s%.02d/%s", ng->location, VOLUME,
X#else
X                (void) sprintf(path,"%s/%s%d/%s", ng->location, VOLUME,
X#endif 
X		        article.volume, header.archive_name);
X            break;
X    case VOLUME_ISSUE:
X            /*
X            ** The article filename contains the filename in
X            ** a "v01i001" format.
X            */
X            if ((article.volume == -1) || (!article.filename[0])) 
X                return(do_problem(VOL_PROB,ng,filename,path));
X
X#ifdef ZEROFILL
X            (void) sprintf(path,"%s/%s%.02d/%s", ng->location, VOLUME,
X#else
X            (void) sprintf(path,"%s/%s%d/%s", ng->location, VOLUME,
X#endif
X		        article.volume, article.filename);
X            break;
X    case ARTICLE_NUMBER:
X            /*
X            ** Store in same filename - thanks news...
X            */
X            (void) sprintf(path,"%s/%s", ng->location, filename);
X            break;
X    case CHRONOLOGICAL:
X            /*
X            ** The chronpath() is called to create a path for an article
X            ** to be stored in chronological ordering. We need to be sure
X            ** that the issue number is not in use. This is necessary to
X            ** handle multiple runs of the program on the same day.
X            **
X            ** The idea here is to have the program check to see if the
X            ** issue number to be used is available. 
X            ** There should be no duplicates here ever... :-)
X            ** [ just don't blow away your .archived file... :-( ]
X            */
X            do {
X                ++inum;
X		chronpath(ng->location, path, inum);
X            } while (stat(path ,&sb) == 0); 
X            break;
X    case ONLY_ARCHIVE_NAME:
X            /*
X            ** This is for searching for articles with an Archive-name:
X            ** no other information.  The header's archive_name contains 
X            ** the filename in an "elm/part06" format.
X            */
X            if (!header.archive_name[0])
X                return(NULL);
X    
X            /*
X            ** Assure the address is relative and that some prankster can 
X            ** not do nasty things to your system files by having an 
X            ** Archive-name line like:
X            **    ../../../../../etc/passwd
X            */
X            check_archive_name(header.archive_name);
X
X            (void) sprintf(path,"%s/%s",ng->location,header.archive_name);
X            break;
X    case COMP_ARCHIVES:
X            /*
X            ** Comp.archives supplies an Archive-name: but no volume
X            ** so it has to be treated as an separate type of archiving.
X            ** It could have been squeezed into ARCHIVE-NAME but that
X            ** does not allow for easy changes in the future for either.
X            **
X            ** The header's archive_name contains the filename in
X            ** an "elm/part06" format.
X            */
X
X            if (!header.archive_name[0])
X                return(do_problem(CA_NAME_PROB, ng,filename,path));
X    
X            /*
X            ** Assure the address is relative and
X            ** that some prankster can not do nasty
X            ** things to your system files by having
X            ** an Archive-name line like:
X            **    ../../../../../etc/passwd
X            */
X
X            check_archive_name(header.archive_name);
X
X            (void) sprintf(path,"%s/%s",ng->location,header.archive_name);
X            break;
X     case EXTERNAL_COMMAND:
X            /*
X            ** This type of archiving is being handled by a script/application
X            ** outside of the rkive program. In this situation, rkive is being
X            ** used to locate the articles to be archived, pipe the information
X            ** about the article to the external command to process and wait for
X            ** a success/failure status to be returned.  At that point, rkive
X            ** logs the status. Compression is bypassed regardless of whether or
X            ** not it is specified. Index records are written with the info as
X            ** specified by the format. This means that the external command 
X            ** will have to know about duplicates, reposts and compression. The
X            ** execution command string will be expanded to see if the external 
X            ** command specified in the rkive.cf file has any parameters to be 
X            ** filled in...
X            */ 
X
X            /*
X            ** Need to build a path to the archive location if there was one.
X            ** Just using Article-Number for the file name. If there is a better
X            ** idea here, I am all ears... 
X            */
X            (void) sprintf(path,"%s/%s", ng->location, filename);
X
X            /* 
X            ** Make any required parent directories along the way.
X            ** Done so that the external applications will have a
X            ** base directory in which to perform there "thing".
X            */
X            if (mkparents(path) == -1)
X                return(NULL);
X
X            /*
X            ** Expand and build the command line to execute.
X            ** The file to be archived will always be the first command line 
X            ** argument regardless of what is supplied in the ARCHIVE_CMD line.
X            **
X            ** First separate the command from the options.
X            **    If a space is found after the cmdline is striped put a
X            **    null there and then replace it with a space after the check...
X            ** Rebuild the command string.
X            */
X
X            if (*ng->arch_command) 
X                (void) strcpy(command, ng->arch_command);
X            else if (*arch_command) 
X                (void) strcpy(command, ng->arch_command);
X            else
X                return(do_problem(EXTERNAL_PROB,ng,filename,path));
X            
X            if ((kp = strchr(command,' ')) != NULL)
X                *kp = '\0';
X
X            (void) sprintf(cmdline,"%s %s/%s/%s", 
X                     command, spooldir, newsgrp->ng_path, filename);
X
X            if (kp != NULL) {  /* There are options to be stored... */
X                *kp = ' ';
X                (void) strcat(cmdline,kp);
X            }
X            
X            kp = format_output(cmdline, filename, ARCHIVE);
X
X            /* 
X            ** Execute the command and wait for a completion status.
X            ** If a problem exists then alert the administrator to the problem
X            */
X
X            if (verbose)
X                (void) fprintf(logfp,"executing <%s>\n",kp);
X
X            if (!test) {
X                if (system(kp) != 0)
X                    return(do_problem(EXTERNAL_PROB,ng,filename,path));
X            }
X
X
X            /*
X             ** Write the message-id to the .archived file in the newsgroup's
X             ** BASEDIR directory since we do not want it rearchived tomorrow.
X             */
X             write_archived(header.ident, path);
X
X             /*
X             ** Check if the file is a patch. If so, log
X             ** the patch information into the patch log
X             ** in a *non-configurable* format so that
X             ** applications can be written to access the
X             ** file's "known format".
X             */
X
X             if (article.rectype == PATCH)
X                 write_patch_log(ng,path);
X
X             /*
X             ** Return the path to the archived file.
X             */
X             return(path);
X            
X    default:
X            /*
X            ** We have got problems....
X            */
X            return(do_problem(TYPE_PROB,ng,filename,path));
X    }
X
X#ifdef ADD_REPOST_SUFFIX
X    if (article.repost == TRUE)
X        /*
X        ** The ADD_REPOST_SUFFIX code adds the REPOST_SUFFIX
X	** to any file that has been indicated as a repost
X	** by the moderator. This should not be used with 
X	** Archive-Name archiving on a filesystem with 14
X	** character filename limits or filename truncation
X	** can occur. You have been warned... :-(
X	**
X 	** After adding the REPOST_SUFFIX, the filename is
X	** treated as any other file with the duplication
X	** checks and all...
X	*/
X	(void) strcat(path,REPOST_SUFFIX);
X#endif /* ADD_REPOST_SUFFIX */
X
X    /* 
X    ** expand the path to the file to include the 
X    ** compression suffix if necessary.
X    */
X
X    final_path = expand_name(path, ng);
X
X    /*
X    ** Make any necessary directories 
X    ** along the way. 
X    */
X    if (mkparents(path) == -1)
X        return(NULL);
X
X    /*
X    ** Check to assure that there is not already 
X    ** a file with the same file name. If so
X    ** copy (or archive) the file to the problems 
X    ** directory. 
X    **
X    ** This works for REPOSTS as well.
X    ** If the REPOST arrives and there is
X    ** no file currently at the archive location, the
X    ** REPOST is installed in the correct archive 
X    ** location.
X    ** If there is a file that exists when a REPOST
X    ** arrives, the REPOST is then handled in do_problem().
X    */
X
X    if ((stat(final_path ,&sb) == 0) && !overwrite)  /* duplicate found */
X        return(do_problem(DUP_PROB,ng, filename, final_path));
X
X    return(copy_article(ng, filename, path));
X}
X
X
Xchar *do_problem(type_of_problem, ng, file, path)
Xint type_of_problem;
Xstruct group_archive *ng;
Xchar *file;
Xchar *path;
X{
X    void set_ownership();
X
X#ifdef MV_ORIGINAL
X    char crnt_path[MAXNAMLEN];
X#endif /*MV_ORIGINAL */
X
X    char pmess[BUFSIZ];
X    int nm;
X    struct stat sb;
X
X    problem_article = TRUE;
X
X    /* ALERT THE ADMINISTRATOR THAT A PROBLEM WAS ENCOUNTERED 
X    **
X    ** A problem has been encountered. It could be that there is an
X    ** format mismatch or there is already a file with the same 
X    ** issue/archive/msg-id name.
X    ** Copy the problem file to the problems directory. 
X    ** Alert the Administrator that a problem was received.
X    */
X    
X    (void) sprintf(pmess,"PROBLEM: Article %s in %s ",file,ng->ng_name);
X
X    switch( type_of_problem ) {
X       case NAME_PROB:
X          (void) strcat(pmess,"does not support Archive-Name Archiving.\n");
X          break;
X       case VOL_PROB:
X          (void) strcat(pmess,"does not support Volume-Issue Archiving.\n");
X          break;
X       case TYPE_PROB:
X          (void) strcat(pmess,"has an invalid archive TYPE specified.\n");
X          break;
X       case CHECKHASH_PROB:
X          (void) strcat(pmess,"failed Snefru checkhash test.\n");
X          break;
X       case MSNG_HASH_PROB:
X          (void) strcat(pmess,"is missing expected Snefru header.\n");
X          break;
X       case DUP_PROB:
X          if (article.repost != TRUE) 
X              (void) strcat(pmess,"is a Duplicate article.\n");
X          else 
X             (void) strcat(pmess,"is a Reposted article.\n");
X          (void) sprintf(pmess,"%s\tExisting Archived path - %s", pmess,path);
X          break;
X       case CA_NAME_PROB:
X          (void)strcat(pmess,"does not have a valid Archive-name specified.\n");
X          break;
X       case EXTERNAL_PROB:
X          (void)strcat(pmess,"System of External command returned Non-zero value...\n");
X    }
X
X    /* print the message out to the screen, crontab output, etc */
X
X    (void) fprintf(errfp,"%s\n",pmess);
X
X    /* log the initial detection message. */
X
X    record_problem(pmess, file, ng);
X
X    /* Handling Repostings.
X    **
X    ** MV_ORIGINAL
X    **     The original article is placed into a "original" directory in 
X    **     the problems directory (if duplicated). The inbound reposted
X    **     article is placed into the archive in the correct position.
X    **
X    ** ADD_REPOST_SUFFIX 
X    **     If ADD_REPOST_SUFFIX is defined, all reposts will have the 
X    **     string specified in REPOST_SUFFIX appended to the archive
X    **     filename so that a repost of elm/part07 would appear in
X    **     the archive as elm/part07-repost prior to any compression.
X    **     The addition of the suffix was done in save_article().
X    **     Handle this as the true duplicated article that it is.
X    **
X    ** No Reposting Defines specified:
X    **    The inbound article would be placed into the archive in the 
X    **    correct position only if the initial article is not in the archive.
X    **    Otherwise the reposted article is placed in the problems directory 
X    **    as a normal duplicate article as it is now.
X    */
X
X#ifdef MV_ORIGINAL
X    if ((article.repost == TRUE) && (ng->type != EXTERNAL_COMMAND)) {
X        /*
X        ** save the duplicated path 
X        ** Caution: may have compression suffix attached
X        */
X        (void) strcpy(crnt_path, path);
X
X        /* create the storage path for original copy */
X        /* no slash needed between Originals and crnt_path below.. */
X
X        (void) sprintf(path,"%s/%s%s",problems_dir,"Originals",crnt_path);
X
X        /* Display and record the actions */ 
X        (void) sprintf(pmess,"\tMoving %s (original)\n\tto %s",crnt_path,path);
X        (void) fprintf(errfp,"%s\n",pmess);
X        record_problem(pmess, file, ng);
X
X        /* Make any necessary directories along the way. */
X        if (mkparents(path) == -1)
X            return(NULL);
X
X        /* copy the original out of the way */
X        if (copy(crnt_path,path) != 0) {
X            (void) fprintf(errfp,"copy failed for %s to %s\n", crnt_path, path);
X            return(NULL);
X        }
X
X        set_ownership(path, path, ng);
X
X        /* restore the destination path for inbound article */
X        (void) strcpy(path,crnt_path);
X
X        /* remove the existing file */
X        (void) unlink(path);
X        /*
X        ** Must assure that "path" does not have a .Z type
X        ** of suffix used in compression. If it does, it must 
X	** be removed before continuing. This is cheating and
X        ** will probably break but what the hell.
X        */
X        (void) remove_suffix(path);
X    }
X    else 
X
X#endif /* MV_ORIGINAL */
X
X    /*
X    ** Build the path string for the location of the article in 
X    ** the problems directory. Place the file in the appropriate 
X    ** directory in Article-Number format. First check to see if
X    ** that Article-Number named file does not exist. This extra 
X    ** check is being done to assure that no conflict exists for
X    ** NNTP sites.  In this manner problems will be assured to
X    ** be stored as uniquely named, separate files. 
X    */
X
X    (void) sprintf(path,"%s/%s/%s",problems_dir,ng->ng_path,file);
X
X    nm = 1;
X
X    while (stat(path, &sb) == 0) {
X         (void) sprintf(path,"%s/%s/%s.%d",problems_dir,ng->ng_path,file,nm);
X         ++nm;
X    }
X
X    /* Display and record the actions */ 
X    (void) sprintf(pmess,"\tStoring Article %s at %s\n", file, path);
X    (void) fprintf(errfp,"%s\n",pmess);
X    record_problem(pmess, file, ng);
X
X    /* Make any necessary directories along the way. */
X    if (mkparents(path) == -1)
X        return(NULL);
X
X    return(copy_article(ng, file, path));
X}
X
X
X#ifndef NO_MONTH_DIR
Xstatic char *month[] = {	
X	"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
X	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
X};
X#endif /* NO_MONTH_DIR */
X
Xvoid chronpath(dirloc, path, seqnum)
X    char *dirloc;
X    char *path;
X    int seqnum;
X{
X    long time();
X    struct tm *localtime();
X
X    long clk;
X    struct tm *crnt;
X    static struct tm now;
X    static int no_time = 1;
X
X    if (no_time) {
X       clk = time((long *)0);
X       crnt = localtime(&clk); 
X       no_time = 0;
X       now = *crnt;
X    }
X#ifdef NO_MONTH_DIR
X    /*
X    ** Format:
X    ** 	/usenet/alt/sources/volume89/890629.01
X    */
X# ifdef ZEROFILL
X    (void) sprintf(path,"%s/%s%.02d/%.02d%.02d%.02d.%.02d",dirloc, 
X# else
X    (void) sprintf(path,"%s/%s%d/%.02d%.02d%.02d.%.02d",dirloc, 
X# endif
X                     VOLUME, now.tm_year,
X                     now.tm_year,now.tm_mon+1,now.tm_mday,seqnum);
X#else /*!NO_MONTH_DIR*/
X    /*
X    ** Format:
X    ** 	/usenet/alt/sources/volume89/Jun/890629.01
X    */
X# ifdef ZEROFILL
X    (void) sprintf(path,"%s/%s%.02d/%s/%.02d%.02d%.02d.%.02d",dirloc, 
X# else
X    (void) sprintf(path,"%s/%s%d/%s/%.02d%.02d%.02d.%.02d",dirloc, 
X# endif
X                     VOLUME, now.tm_year, month[now.tm_mon],
X                     now.tm_year,now.tm_mon+1,now.tm_mday,seqnum);
X#endif /* NO_MONTH_DIR */
X}
X
Xvoid write_patch_log(ng, path)
X    struct group_archive *ng;
X    char *path;
X{
X    int strlen();
X
X    char *sp;
X    FILE *plfp;
X    struct stat sb;
X
X    if (test)
X        return;
X
X    /* 
X    ** The .patchlog file is used to record the
X    ** information specific to patches that come
X    ** through the newsgroup.
X    **
X    ** The format of the .patchlog file is:
X    ** #
X    ** #    Patch log for comp.sources.whatever
X    ** #
X    ** # Path To                   Patch       Package     Initial
X    ** # Patchfile             Volume  Issue     Name   Volume   Issue
X    ** #
X    ** volume4/conquer4/Part04    6     86    conquer4     4      42-49
X    ** volume4/conquer4/Part06    6     88    tests3       4      42,47,51
X    ** volume6/conquer4/Part07    6     89    Unknown      6      89
X    */
X
X    /*
X    ** If this is the first time that an entry is written to the
X    ** patch log, add a header on top of the file for informational
X    ** purposes only... Output in the patch log is not intended
X    ** to be centered under these columns... :-) I'm laaaazy.
X    */
X    if ((stat(ng->patchlog ,&sb) != 0)) {
X        if (mkparents(path) == -1) 
X            return;          /* unable to build parent directories */
X
X        plfp = efopen(ng->patchlog,"a+");
X
X        (void) fprintf(plfp,"#\n#\tPatch log for %s\n#\n", ng->ng_name);
X
X        (void) fprintf(plfp,"# %-27s%-12s%-15s%-s\n", 
X                    "Path To", "Patch", "Package", "Initial");
X
X        (void) fprintf(plfp,"# %-22s%-18s%-10s%-15s\n#\n", 
X                    "Patchfile", "Volume  Issue", "Name",
X                    "Volume  Issue");
X        (void) fclose(plfp);
X    }
X
X    /* 
X    ** Get rid of the base directory.
X    */
X    sp = path + (strlen(ng->location)+1);
X
X    plfp = efopen(ng->patchlog,"a+");
X    (void) fprintf(plfp,"%-25s %3d   %5d  %-14s  %3d  %s\n", sp,
X            article.volume, article.issue, article.package_name,
X            article.patch_volume, article.patch_issue);
X    (void) fclose(plfp);
X    return;
X}
X
X
Xint do_checkhash(hashit,filename)
Xchar *hashit;
Xchar *filename;
X{
X    int system();
X
X    char *kp;
X    char *comp_cmd;
X    char cmd[BUFSIZ];
X
X    /* 
X    ** get the basename of the command to use.
X    ** strip off possible arguments.
X    */
X
X    (void) strcpy(cmd, hashit);
X    if ((kp = strchr(cmd,' ')) != NULL)
X        *kp = '\0';
X    else if ((kp = strchr(cmd,'\t')) != NULL)
X        *kp = '\0';
X
X    comp_cmd = basename(cmd);
X
X    if (verbose)
X       (void) fprintf(logfp,"%s %s\n", comp_cmd, filename);
X
X    /*
X    ** build command to execute.
X    */
X    (void) sprintf(cmd,"%s %s", hashit, filename);
X
X    if (!test) 
X       return(system(cmd) >> 8);
X    else
X       return(0);
X}
X
END_OF_FILE
if test 28314 -ne `wc -c <'rkive/news_arc.c'`; then
    echo shar: \"'rkive/news_arc.c'\" unpacked with wrong size!
fi
# end of 'rkive/news_arc.c'
fi
if test ! -d 'rkive/port' ; then
    echo shar: Creating directory \"'rkive/port'\"
    mkdir 'rkive/port'
fi
if test -f 'rkive/port/README.port' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/port/README.port'\"
else
echo shar: Extracting \"'rkive/port/README.port'\" \(1110 characters\)
sed "s/^X//" >'rkive/port/README.port' <<'END_OF_FILE'
X			port/README
X
XThis directory contains source needed to bring up rkive on other systems.
XI have been successful in bringing rkive up on a wide range of machines
Xbut some machines have a couple pieces missing... :-(
X
XIf your system does not have getopt() then use getopt.c This source was
Xposted to comp.sources.unix in volume3 so there is no problem supplying
Xit here... You will have to edit the makefile and uncomment the GETOPTO
Xand GETOPTC entries for including getopt.c.
X
XIf you are on a sequent and do not have Doug Gwyn's POSIX Directory access
Xlibrary installed, you need to edit the makefile and assure that the
XSsequent's SFLAGS is uncommented.
X
XI recommend that you get Doug's Directory access library if you do not
Xhave POSIX compatible directory access routines already supplied on your 
Xsystem.  If you need a copy, send me some email and I will gladly send you
Xa copy...
X
XIf you run across something else that can be added to this directory to
Xmake rkive more portable, please send it to me and I will include it in
Xfuture releases.  Thanks.
X
X			Kent Landfield
X			kent@sparky.imd.sterling.com
X
END_OF_FILE
if test 1110 -ne `wc -c <'rkive/port/README.port'`; then
    echo shar: \"'rkive/port/README.port'\" unpacked with wrong size!
fi
# end of 'rkive/port/README.port'
fi
if test -f 'rkive/rkive.cf' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/rkive.cf'\"
else
echo shar: Extracting \"'rkive/rkive.cf'\" \(22268 characters\)
sed "s/^X//" >'rkive/rkive.cf' <<'END_OF_FILE'
X#
X#        @(#)rkive.cf	2.2 2/23/91
X#
X#        An rkive.cf template.
X#        Copy and edit this to reflect the local archive conditions.
X#        After editing, run ckconfig to display how rkive will interpret
X#        the local specifications.
X#
X#        The format of the configuration file is as follows:
X#
X######################################################################
X#
X#        Global variables
X#               SPOOLDIR - the base directory for the news subsystem
X#               PROBLEMS - The name of the base directory used to store any
X#                          duplicate or "problem" articles. All articles are
X#                          stored under this directory in a newsgroup/volume
X#                          directory.
X#                   TYPE - This is the archive type (or the archive key)
X#                          There are 6 possible keys:
X#                               Volume-Issue, Archive-Name,
X#                               Chronological, Article-Number,
X#                               Comp-Archives, External-Command,
X#                               or Only-Archive-Name.
X#                          These are used to determine if you wish the 
X#                          articles archived in a 
X#                                /basedir/amiga/Volume1/v001i22 or
X#                                /basedir/amiga/Volume1/sitonit or
X#                                /basedir/amiga/Volume89/890619001 or
X#                                /basedir/amiga/Volume1/44 format
X#                          Comp-Archives is used only for the comp.archives
X#                          newsgroup or newsgroups that supply Archive-name: 
X#                          but do not supply a volume number. 
X#                          External-Command is used if you want to have an 
X#                          external program/script deal with the article. 
X#                          The External-Command type must be accompanied with
X#                          an ARCHIVE_CMD entry with specifies the external 
X#                          program for rkive to use.
X#                          Only-Archive-Name is used to archive only those
X#                          articles that contain an Archive-name: header line.
X#                PATCHES - This variable determines the way in which patches
X#                          are installed into the archive. If the PATCHES
X#                          entry is not defined either globally or within
X#                          the newsgroup, the article is handled as a regular
X#                          article and is stored according to the specified
X#                          parameters of the newsgroup. The following are
X#                          the valid possible values for the PATCHES variable:
X#                             PATCHES=Historical 
X#                                 This is the same as if no PATCHES entry
X#                                 existed at all. It is useful if Historical
X#                                 patches archiving is the default but there
X#                                 are certain newsgroups that have it specified
X#                                 differently.
X#                             PATCHES=Package 
X#                                 Package patches archiving allows the inbound
X#                                 patch to be placed with the directory with
X#                                 the initially posted articles. In this manner
X#                                 all parts and fixes of a package are together
X#                                 making it easier for software retrieval by
X#                                 uucp requests and mail request facilities
X#                                 such as netlib.
X#                   MAIL - If specified, all actions are mailed to the
X#                          list of users specified. The user names are
X#                          a comma separated list. It is not necessary to
X#                          specify any users. 
X#                  OWNER - The unix login name for the owner of the 
X#                          archive files after they are stored in the archive.
X#                  GROUP - The unix group value for the group ownership of 
X#                          the archive files after they are stored in the 
X#                          archive.
X#                   MODE - The modes of the files residing in the archive.
X#                    LOG - The location of the master log in which all 
X#                          actions are logged. 
X#             LOG_FORMAT - The format of the records of the master log file.
X#                          See the man page for article for a discussion of
X#                          the available selection format capabilities.
X#                  INDEX - The location of the master index (if one is kept).
X#                          The index can be used to interface with the netlib 
X#                          source retrieval software facility.
X#           INDEX_FORMAT - The format of the records of the master log file.
X#                          See the man page for article for a discussion of
X#                          the available selection format capabilities.
X#               COMPRESS - The location of the compression utility if the 
X#                          files are to be reduced.
X#              CHECKHASH - The location of the checkhash utility if  the
X#                          files  are  to  be tested for transit damage.
X#                          Currently,  only  comp.sources.unix  supports
X#                          this test with the X-Checksum-Snerfu: header.
X#                          If this variable is specified, it  must  con-
X#                          tain  the  full  path  to the command used to
X#                          perform the test.
X#                   NNTP - The location of the NNTP server where the articles
X#                          are to be archived from. This can be specified
X#                          globally if all or most newsgroups are archived
X#                          from a single NNTP server. 
X#            ARCHIVE_CMD - This is the path to an external command to pass
X#                          all articles to that are in need of archiving.
X#                          This is used when with the archive specification
X#                          TYPE=External-Command.  This command line may
X#                          be augmented with variables specified in the 
X#                          rkive.cf file. See article.1 for a description
X#                          of the format specification characters available.
X#                  MATCH - rkive allows you to use globbing to determine if
X#                          an article is to be archived or not. This is the
X#                          specification by which articles must match to be
X#                          archived. The match specification may span
X#                          multiple lines. A \ at the end of a line is used
X#                          to indicate that the specification is continued on 
X#                          another line.
X#
X######################################################################
XSPOOLDIR=/usr/spool/news      
XPROBLEMS=/usenet/problems
XTYPE= Volume-Issue
X#TYPE= External-Command
X#ARCHIVE_CMD=update_netdocs
XPATCHES=Historical
XMAIL=kent
XOWNER=src
XGROUP=archive
XMODE=0444
X#LOG=/usenet/archive.log
X#LOG_FORMAT= "%B %a\t%T"
X#INDEX= /usenet/index
X#INDEX_FORMAT= "%O\t%a\t%T"
XCOMPRESS=/usr/ucb/compress -f
X#CHECKHASH=/usr/local/bin/checkhash -s
X
X######################################################################
X#
X#     Each Newsgroup to be archived has an entry with the following
X#     possible variables. (Note that all variables are not necessary)
X#        
X#       BASEDIR - This is the path to the base directory of the archive
X#       TYPE    - This is the archive type (or the archive key)
X#                 There are 6 possible keys:
X#                       Volume-Issue, Archive-Name,
X#                       Chronological, Article-Number,
X#                       Comp-Archives, External-Command.
X#                       or Only-Archive-Name.
X#                These are used to determine if you wish the articles
X#                archived in a 
X#                        /basedir/amiga/Volume1/v001i22 or
X#                        /basedir/amiga/Volume1/sitonit or
X#                        /basedir/amiga/Volume89/890619001 or
X#                        /basedir/amiga/Volume1/44 format
X#                Comp-Archives is used only for the comp.archives
X#                newsgroup or newsgroups that supply Archive-name: 
X#                but do not supply a volume number. 
X#                External-Command is used if you want to have an 
X#                external program/script deal with the article. 
X#                The External-Command type must be accompanied with
X#                an ARCHIVE_CMD entry with specifies the external 
X#                program for rkive to use.
X#                Only-Archive-Name is used to archive only those
X#                articles that contain an Archive-name: header line.
X#      PATCHES - This variable determines the way in which patches
X#                are installed into the archive. If the PATCHES
X#                entry is not defined either globally or within
X#                the newsgroup, the article is handled as a regular
X#                article and is stored according to the specified
X#                parameters of the newsgroup. The following are
X#                the valid possible values for the PATCHES variable:
X#                PATCHES=Historical 
X#                       This is the same as if no PATCHES entry
X#                       existed at all. It is useful if Historical
X#                       patches archiving is the default but there
X#                       are certain newsgroups that have it specified
X#                       differently.
X#                PATCHES=Package 
X#                       Package patches archiving allows the inbound
X#                       patch to be placed with the directory with
X#                       the initially posted articles. In this manner
X#                       all parts and fixes of a package are together
X#                       making it easier for software retrieval by
X#                       ftp, uucp requests and mail request facilities
X#                       such as netlib.
X#         MAIL - If specified, all actions are mailed to the
X#                list of users specified. The user names are
X#                a comma separated list.
X#        OWNER - The unix login name for the owner of the archive files 
X#                after they are stored in the archive.
X#        GROUP - The unix group value for the group ownership of the archive 
X#                files after they are stored in the archive.
X#         MODE - The modes of the files residing in the archive.
X#          LOG - The location of the log in which all actions are logged. 
X#   LOG_FORMAT - The format of the records of the master log file.
X#                See the man page for article for a discussion of
X#                the available selection format capabilities.
X#        INDEX - The location of the master index (if one is kept).
X#                The index can be used to interface with the netlib 
X#                source retrieval software facility.
X# INDEX_FORMAT - The format of the records of the master log file.
X#                See the man page for article for a discussion of
X#                the available selection format capabilities.
X#     COMPRESS - The location of the compression utility if the files 
X#                are to be reduced.
X#    CHECKHASH - The location of the checkhash utility if  the
X#                files  are  to  be tested for transit damage.
X#                Currently,  only  comp.sources.unix  supports
X#                this test with the X-Checksum-Snerfu: header.
X#                If this variable is specified, it  must  con-
X#                tain  the  full  path  to the command used to
X#                perform the test.
X#         NNTP - The location of the NNTP server where the articles
X#                are to be archived from.  This can be specified either
X#                globally, if all or most newsgroups are archived
X#                from a single NNTP server, or on a by newsgroup basis.
X#                If specified globally and you wish to archive a 
X#                newsgroup from your local system, add the following
X#                entry to the newsgroup specifications. 
X#                          NNTP: local
X#                This tells rkive to negate the global value. Case 
X#                does not matter in the specification of local.
X#  ARCHIVE_CMD - This is the path to an external command to pass
X#                all articles to that are in need of archiving.
X#                This is used when with the archive specification
X#                TYPE=External-Command.  This command line may
X#                be augmented with variables specified in the 
X#                rkive.cf file. See article.1 for a description
X#                of the format specification characters available.
X#        MATCH - rkive allows you to use globbing to determine if
X#                an article is to be archived or not. This is the
X#                specification by which articles must match to be
X#                archived. The match specification may span
X#                multiple lines. A \ at the end of a line is used
X#                to indicate that the specification is continued on 
X#                another line.
X# ARCHIVED_LOG - rkive requires that it be able to determine if an article
X#                has been previously archived. By default, rkive uses
X#                a file named .archived ($BASEDIR/.archived) which stores the
X#                message-id of the previously archived articles. If it is
X#                inconvient to store the .archived file in the base directory
X#                of the archive, a alternate path/location can be specified
X#                by the use of ARCHIVED_LOG.
X#     PATCHLOG - rkive writes an entry to a file called .patchlog when it
X#                it encounters a Patch-To: line.  By default, rkive uses
X#                a file named .patchlog ($BASEDIR/.patchlog) If it is
X#                inconvient to store the .patchlog file in the base directory
X#                of the archive, a alternate path/location can be specified
X#                by the use of PATHLOG.
X#		
X######################################################################
X$$comp.sources.amiga		
X	BASEDIR: /usenet/amiga 
X	TYPE: Volume-Issue
X        INDEX: /usenet/amiga/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.atari.st
X	BASEDIR: /usenet/atari/st
X	TYPE: Volume-Issue
X        INDEX: /usenet/atari/st/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.games		
X	BASEDIR: /usenet/games
X	TYPE: Volume-Issue
X        INDEX: /usenet/games/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.mac		
X	BASEDIR: /usenet/mac
X	TYPE: Chronological
X        INDEX: /usenet/misc/index
X        INDEX_FORMAT: "%O\t%T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.misc		
X	BASEDIR: /usenet/misc
X	TYPE: Volume-Issue
X        INDEX: /usenet/misc/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.unix        	
X        BASEDIR: /usenet/unix
X	TYPE: Volume-Issue
X        INDEX: /usenet/unix/index
X        INDEX_FORMAT: "%B %a %T" 
X#       CHECKHASH: /usr/local/bin/checkhash -s
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.x		
X	BASEDIR: /usenet/x
X	TYPE: Volume-Issue
X        INDEX: /usenet/x/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.sun		
X	BASEDIR: /usenet/sun
X	TYPE: Volume-Issue
X        INDEX: /usenet/sun/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.bugs
X	BASEDIR: /usenet/patches/bugs
X	TYPE: Chronological
X        INDEX: /usenet/patches/bugs/index
X        INDEX_FORMAT: "%B\t%S" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.3b1
X	BASEDIR: /usenet/3b1
X	TYPE: Volume-Issue
X        INDEX: /usenet/3b1/index
X        INDEX_FORMAT: "%B\t%S" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.sources.apple2
X	BASEDIR: /usenet/apple2
X	TYPE: Volume-Issue
X        INDEX: /usenet/apple2/index
X        INDEX_FORMAT: "%B\t%S" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$alt.sources
X	BASEDIR: /usenet/alt/sources
X	TYPE: Only-Archive-Name
X        INDEX: /usenet/alt/sources/index
X        INDEX_FORMAT: "%B\t%S" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$alt.sources.amiga
X	BASEDIR: /usenet/alt/sources.amiga
X	TYPE: Chronological
X        INDEX: /usenet/alt/sources.amiga/index
X        INDEX_FORMAT: "%O\t%T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$alt.sources.patches
X	BASEDIR: /usenet/alt/src.patches
X	TYPE: Chronological
X        INDEX: /usenet/alt/src.patches/index
X        INDEX_FORMAT: "%B\t%S" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$u3b.sources
X	BASEDIR: /usenet/u3b
X	TYPE: Chronological
X        INDEX: /usenet/u3b/index
X        INDEX_FORMAT: "%O\t%T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$unix-pc.sources
X	BASEDIR: /usenet/unix-pc
X	TYPE: Article-Number
X        INDEX: /usenet/unix-pc/index
X        INDEX_FORMAT: "%O\t%T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$vmsnet.sources
X	BASEDIR: /usenet/vmsnet
X	TYPE: Chronological
X        INDEX: /usenet/vmsnet/index
X        INDEX_FORMAT: "%O\t%T" 
X	COMPRESS: /usr/ucb/compress -f
X
X$$comp.archives
X	BASEDIR: /usenet/archives
X	TYPE: Chronological
X        INDEX: /usenet/archives/index
X        INDEX_FORMAT: "%B %a %T" 
X	COMPRESS: /usr/ucb/compress -f
X
X
X#$$space.shuttle
X#        BASEDIR: /pub/ftp/pub/archive/sci.space.shuttle
X#        TYPE: Article-Number
X#        LOG: /pub/ftp/pub/archive/sci.space.shuttle/log
X#        INDEX: /pub/ftp/pub/archive/sci.space.shuttle/index
X#        LOG_FORMAT: "%O %S"
X#        MATCH: subject glob-matches "space news from * AW&ST*" \
X#        or subject glob-matches "Shuttle Status for ??/??/?? (Forwarded)*" \
X#        or ( subject glob-matches "* (Forwarded)*" and \
X#                not subject glob-matches "Re:*" )
X
X$$sci.space
X        BASEDIR: /usenet/sci.space
X        TYPE: Article-Number
X        LOG: /usenet/sci.space/log
X        INDEX: /usenet/sci.space/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "space news from * AW&ST*" \
X        or subject glob-matches "Voyager Status for ??/??/?? (Forwarded)*" \
X        or subject glob-matches "Voyager Update*" \
X        or \
X        subject glob-matches "NASA Headline News for ??/??/?? (Forwarded)*" \
X        or subject glob-matches "News of the Week,*" \
X        or subject glob-matches "Magellan Update - ??/??/??" \
X        or subject glob-matches "Hubble Space Telescope Update - ??/??/??" \
X        or ( subject glob-matches "* (Forwarded)*" and \
X                not subject glob-matches "Re:*" )
X
X$$comp.misc
X        BASEDIR: /usr/doc/news
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        ARCHIVED_LOG: /usr/doc/.admin/misc.archived
X        PATCHLOG: /usr/doc/.admin/misc.patchlog
X        INDEX: /usr/doc/.admin/index
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "Anonymous FTP list"
X
X$$comp.mail.misc
X        BASEDIR: /usr/doc/.admin
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "Inter-Network Mail Guide"
X
X$$comp.std.unix
X        BASEDIR: /usr/doc/.admin
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "Access to UNIX-Related Standards" \
X        or subject glob-matches "Calendar of UNIX-related Events" \
X        or subject glob-matches "Access to UNIX User Groups" \
X        or subject glob-matches "Access to UNIX-Related Publications"
X
X$$comp.windows.x
X        BASEDIR: /usr/doc/.admin
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "Frequently Asked Questions about X *"
X
X$$news.admin
X        BASEDIR: /usr/doc/.admin
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "Checkgroups message *" \
X        or subject glob-matches "How to Create a New Trial Newsgroup" \
X        or subject glob-matches "How to Construct the Mailpaths File" 
X
X$$news.announce.newusers
X        BASEDIR: /usr/doc/.admin
X        TYPE: External-Command
X        ARCHIVE_CMD: /usr/local/lib/rkive/update_netdocs $m $o $g $U
X        LOG: /usr/doc/.admin/log
X        INDEX: /usr/doc/.admin/index
X        LOG_FORMAT: "%O %S"
X        MATCH: subject glob-matches "How to Get Information about Networks" \
X        or subject glob-matches "USENET Software: History and Sources" \
X        or subject glob-matches "A Primer on How to Work With the Usenet Community" \
X        or subject glob-matches "Answers to Frequently Asked Questions" \
X        or subject glob-matches "Emily Postnews Answers Your Questions on Netiquette" \
X        or subject glob-matches "Hints on writing style for Usenet" \
X        or subject glob-matches "Regional Newsgroup Hierarchies *" \
X        or subject glob-matches "Rules for posting to Usenet" \
X        or subject glob-matches "How to Create a New Newsgroup" \
X        or subject glob-matches "List of Periodic Informational Postings" \
X        or subject glob-matches "List of Active Newsgroupsj" \
X        or subject glob-matches "Alternative Newsgroup Hierarchies" \
X        or subject glob-matches "List of Moderators" \
X        or subject glob-matches "Publicly Accessible Mailing Lists" 
X
END_OF_FILE
if test 22268 -ne `wc -c <'rkive/rkive.cf'`; then
    echo shar: \"'rkive/rkive.cf'\" unpacked with wrong size!
fi
# end of 'rkive/rkive.cf'
fi
echo shar: End of archive 1 \(of 6\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.