[comp.sources.misc] v17i019: rkive - Usenet sources archiver, Part03/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 19
Archive-name: rkive/part03

#! /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 3 (of 6)."
# Contents:  rkive/README rkive/header.c rkive/rkive.h
# Wrapped by kent@sparky on Sun Feb 24 16:11:22 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'rkive/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/README'\"
else
echo shar: Extracting \"'rkive/README'\" \(15961 characters\)
sed "s/^X//" >'rkive/README' <<'END_OF_FILE'
X
X                 USENET Sources Archiver             
X
X                 @(#)README	2.2 2/23/91
X
X             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.  The copyright 
X   notice must be maintained in any copy made.
X  
X   If you make modifications to this software that you feel 
X   increases it usefulness for the rest of the community, please 
X   email the changes, enhancements, bug fixes as well as any and 
X   all ideas to me. This software is going to be maintained and 
X   enhanced as deemed necessary by the community.
X  		
X			-Kent+
X  		   uunet!sparky!kent
X                   kent@sparky.imd.sterling.com
X  
X------------------------------------------------------------------
X                       DISCLAIMER
X------------------------------------------------------------------
XUse of this software constitutes acceptance for use in an AS IS 
Xcondition. There are NO warranties with regard to this software.  
XIn no event shall the author be liable for any damages whatsoever 
Xarising out of or in connection with the use or performance of this 
Xsoftware.  Any use of this software is at the user's own risk.
X-------------------------------------------------------------------
X
X
XWhen made, this package currently contains 3 executables:
X
X	o  rkive    - a USENET newsgroup archiver,
X	o  article  - print formatted news article header information, and
X        o  ckconfig - an rkive configuration file check program.
X
X
XThis package was initially designed for archiving comp.sources.all newsgroups.
XIt does however, support archiving of non-moderated, non-sources newsgroups.
X
X                        -----
X                        rkive 
X                        -----
X
Xrkive reads a configuration file to determine such things as:
X
X	o where the news directory resides,
X	o where each newsgroup is to be archived,
X	o the type of archiving to be done for each newsgroup,
X	o the ownership and modes of the archived members,
X
Xas well as additional optional features such as:
X
X        o which users/accounts to mail the archived member information to,
X	o the location and format of log files, 
X	o the location and format of index files,
X	o the compression program to use (if desired). 
X
XIt is intended that rkive be run by cron on a daily basis. In this manner,
Xsoftware is archived and available for retrieval from the archives on the
Xday it reaches the machine.  It allows for the archives to be managed by
Xthe same or different people (or accounts).  It supports the building
Xof indexes for later review or to interface to the netlib type of mail
Xretrieval software. It also supports mailing notifications of the archiving
Xto a specified list of users or aliases. The indexes and log file formats
Xare specifiable by the person configuring the rkive configuration file.
X
X-------------------------------------------------------------------
XThe following defines are possible. Please note that the Directory
XCreation defines are specified in Makefile while the rest are specified
Xin rkive.h.
X
X***************************
Xrkive.h - General Defines
X***************************
X
X-D REDUCE_HEADERS   :   Archived article header reduction code.
X	Disk space is saved by removing header lines that have no 
X	further use after the article is stored in the archive.
X	As currently defined, all headers *except* for From:, Newsgroups:, 
X	Subject:, Message-ID:, Approved:, and Date: are removed if this 
X        is defined.
X	The list of headers to be saved can be added to or reduced by
X	modifying the table "hdrs" in news_arc.c.
X
X-D SUBJECT_LINE     :   Specify that the local mailer has -s option
X        such as /usr/bin/mailx or /usr/ucb/Mail.
X
X*************************************
XMakefile - Directory Creation Defines
X*************************************
X
X-D HAVE_MKDIR       : use the mkdir() function in the system library. 
X	(AT&T 5.2 or earlier systems are probably out of luck..)
X
X-D USE_SYSMKDIR     : have rkive system off /bin/mkdir.
X	(not recommended for *real* use...)
X
XIf you do not define either, the function makedir() will create the 
Xdirectory itself. I suggest that if you do not have mkdir() in your
Xsystem libraries, use the builtin if you can. *Please* verify you can
Xuse it *first*.
X
X---------------------------
XArchive Member Compression:
X---------------------------
XIf you wish to have your archived articles compressed you may do so by
Xspecifying the disk path to the compression program as the value for
XCOMPRESS in the rkive configuration file. It is important that *if* you
Xuse a compression program other that "compress" or "pack" that you add
Xan entry to the compression routine table in the file suffix.h.
XCurrently, this program recognizes just ".z" and ".Z" suffixes.
X
X----------------
XREPOST Handling:
X----------------
XWarning:
X	Repost handling is not a configurable parameter within the 
X	rkive configuration file at this time.
X
XADD_REPOST_SUFFIX define added.
X    This define allows the administrator to configure the software to
X    add "-repost" (or whatever is defined in REPOST_SUFFIX) to the
X    end of all files that are marked as REPOST by the newsgroup moderator.
X    The suffix is added prior to compression. This feature should only be 
X    configured/exist on systems whose filename limits are greater than 14.
X
XMV_ORIGINAL define added.
X    This define allows the administrator to configure the software to
X    move the original article into a "originals" directory in the 
X    problems directory. The inbound reposted article is placed into 
X    the archive in the correct position.
X
XIf neither define is specified then the inbound article is placed into 
Xthe archive in the correct position only if the initial article is not 
Xin the archive.  Otherwise the reposted article is placed in the problems 
Xdirectory as normal duplicate articles are now.
X
X-----------------
XPATCHES Handling:
X-----------------
Xrkive supports the Auxiliary header "Patch-To:". The Patch-To: line
Xexists for articles that are patches to previously posted software. 
XThe Patch-To: line only appears in articles that are posted, "Official", 
Xpatches. The initial postings would not contain the Patch-To: auxiliary 
Xheader line.
X
XAuxiliary Headers For Patch Postings:
X
X	Submitted-by: Kent Landfield <kent@sparky>
X	Posting-number: Volume 23, Issue 14
X->	Patch-To: rkive: Volume 19, Issue 98-101
X	Archive-name: rkive/patch1
X
XPatch-To: syntax
X	Patch-To: package-name: Volume X, Issue x[-y,z]
X
XPatch-To: examples. These are examples and do not reflect the
Xaccurate volume/issue numbering for rkive.
X
XIn the first example, the article that contains the following line
Xis a patch to a single part posting.
X	Patch-To: rkive: Volume 19, Issue 98
X
XThis example shows that the 122-124 indicates the patch applies to
Xa multi-part posting. The '-' is used to mean "article A through article
XB, inclusive..
X	Patch-To: rkive: Volume 19, Issue 98-101
X
XIf a patch applies to multiple part postings that are not consecutive, the
X',' is used to separate the part issue numbers. It is possible to mix both
X',' and '-' on a single Patch-To: line.
X	Patch-To: rkive: Volume 99, Issue 122,125,126,127
X	Patch-To: rkive: Volume 22, Issue 122,125-127
X
XThere are two different types of handling with regards to patches. 
X
X	Package     - This type of archiving of patches places the patches
X                      in the same directory that the initial source was
X                      posted to. This type of archiving is only available
X                      to newsgroup archives that are using Archive-Name
X                      archiving.
X                   
X	Historical  - This type of archiving patches is done by sites that 
X                      want to place the patches in the volume/issue in 
X                      which the patch originally arrived.
X
XArchive recognizes that the Patch-To: line indicates the article is 
Xa patch.  For Archive-Name archiving which has specified "Package" 
Xpatches archiving in the configuration file, rkive puts the article 
Xinto the directory that contained the initial posting (volume19/rkive). 
XFor Archive-Name that has not specified Package archiving or for 
XVolume/Issue archiving, the article would still be labeled as
Xvolume23/rkive/patch1 or volume23/v23i014 respectively.
X
Xrkive also writes a .patchlog file in the BASEDIR for the newsgroup
Xthat is used to track patches to originally posted software. The
X.patchlog is going to be used for the "random software downloader :-)"
Xso that complete software packages (sources and patches) can be requested
Xfrom sites that do not use combined Archive-Name and Package archiving.
XThe format of the .patchlog file is:
X
X#
X#	Patch log for comp.sources.whoknows
X#
X# Path To                    Patch       Package        Initial
X# Patchfile             Volume  Issue     Name      Volume  Issue  
X#
Xvolume6/bb/patch01          6     86       bb          3    70-73
X            or if volume issue format..
Xvolume6/v06i86              6     86       bb          3    70-73
X
X-------------------------
XArticle Header Reduction:
X-------------------------
XArticles that are stored just as they arrived on your system are potentially
Xwasting disk space. Certain rfc822/rfc1036 header lines are of little use
Xafter the article is archived.  If you wish to have the headers "trimmed" 
Xwhen the file is archived, assure that REDUCE_HEADERS is defined. Currently 
Xall header lines that are *not* either;
X
X    From:, Newsgroups:, Subject:, Message-ID: Approved:, and Date:
X
Xwill be removed. This can produce a savings of as much as 200 to 500 
Xbytes per archived article.
X
XSee news_arc.c if you wish to add or subtract header lines to be kept.
XThe modifications need to be made to the hdrstokeep table just above the
Xkeep_line() function.
X
X---------
XSecurity:
X---------
Xrkive sets the ownership, group and modes on the archived members according
Xto the information specified in the configuration file. Currently though,
Xrkive uses the default umask for creating the log and index files.
X
Xrkive will not archive files outside of the BASEDIR specified in the 
Xconfiguration file so a "prankster" can not do nasty things to your
Xsystem files by having an Archive-name line like:
X	Archive-name: ../../../../../../etc/passwd
X
XIt will also not overwrite duplicate files. They are stored underneath
Xthe problems directory specified in the configuration file. The admin 
Xis alerted to the fact and it then becomes a manual cleanup problem.
X
X                        -------
X                        article 
X                        -------
X
XArticle allows you to view the article headers in much the same manner
Xthat you use a printf statement.  This was initially done for debugging
Xpurposes but I quickly found that it was extremely useful in dealing
Xwith news articles in general. It works great in shell scripts to view
Xarticles that need to be read.... Also super for perusing the archives
Xdirectly and generating indexes to the archives in *many* different 
Xways...:-)  If you do not want to use rkive for archiving sources or
Xnewsgroups, do yourself a favor and compile article. It will be worth
Xthe time it takes...
X
X                        --------
X                        ckconfig 
X                        --------
X
XThis program is used by the admin to verify just how rkive will 
Xinterpret the variable specifications in an archive configuration
Xfile. If you have problems, it will bomb out when it encounters
Xthe problem. Not real smart but it does the job..
X
X------------------------------------------------------------------------
XThis software set was developed under an archiving model similar to
Xthat maintained currently on uunet. It was intended that the archiving
Xfacilities were more of a "site" facility and not an individuals
Xfacility. (That is unless the individual owned the site :-)). I have
Xeven used rkive for maintaining private (many on a single machine)
Xarchives. rkive will accept an rkive.cf file specified on the
Xcommand line so it would be possible for an individual to have their own
Xmini archive directory structure. This is not recommended if the site is
Xdoing archiving since the software will store multiple copies thus wasting
Xmore disk space than it is worth.
X------------------------------------------------------------------------
XCredits:
X--------
XI have to give credit to where credit is do.
X
XI used the code in header.c of the News 2.11 as the basis of ideas for
Xdealing with the article headers. The code I have written is not the same
Xbut most of the concepts and some of the flow control resulted from reviewing
Xhow it was "suppose to be done". (rfcs only go so far.. :-)) For that I
Xthank Rick Adams and the authors of B news for the excellent code to study
Xfrom.. :-)
X
XI would also like to thank my beta testers for the headaches of dealing
Xwith me, with forcing different ideas on me at a time when I was "almost"
Xwilling to listen :-) and for the "full redistribution of sources" when
XI had a new version. 
X------------------------------------------------------------------------
X
XPlease read all the directions below before you proceed any 
Xfurther, and then follow them carefully.  
X
X                    --------------
X                     Installation
X                    --------------
X
XThis package uses Doug Gwyn's directory access routines posted in
Xcomp.sources.unix/volume9 (with the bug fix as well). You may need
Xto get a copy if you don't already have one and your system does 
Xnot support POSIX Compatible directory access routines.  rkive was
Xwritten using the POSIX directory routines to make the code cleaner
Xand easier to test. If you want to waste your time moving it to any
Xother directory reading routines, don't send me your patches. These
Xare the only patches I will not even consider including in the baseline
Xsources.  Now with my rudeness aside... :-)
X
X1)  Take the time to format and read the man pages prior to continuing.
X		make man | less/pg/more
X
X2)  Review/modify rkive.h to make sure system defines are correct.  
X
X3)  Determine the method for directory creation and edit the Makefile
X    accordingly.
X
X4)  make
X
X    This will attempt to make the software in the current directory.
X
X5)  Put rkive, ckconfig, and article into a public directory 
X    (normally /usr/local/bin), and put a template of the rkive
X    configuration file  (if one does not exist) into an rkive specific
X    library directory (normally as /usr/local/lib/rkive/rkive.cf).  Place 
X    the man pages in the appropriate man directories for your site.
X
X
X6)  I have set up an account for the source archives.  This is not really 
X    necessary but is a personal preference. Archive needs to be run as 
X    root *if* you do not have the mkdir () and wish to use the builtin
X    since it needs to use mknod() to create directories. It also needs
X    to run as root if the owner/group specified in the rkive.cf is 
X    different from the user it is being run under.
X
X    ---x--x--x  1 root archive    43048 Apr  9 16:38 /usr/local/bin/rkive
X    ---x--x--x  1 src  archive    14836 Apr  9 16:38 /usr/local/bin/article
X    ---x--x--x  1 src  archive    27448 Apr  9 16:38 /usr/local/bin/ckconfig
X    -r--r--r--  1 src  archive     6173 Apr  9 16:40 /usr/local/lib/rkive.cf
X
X7)  Re-read the manual entry for rkive.1 and rkive.5.
X
X8)  Modify the template rkive configuration file to reflect the local
X    archive conditions. ckconfig should be used in order to check the
X    information that you have just entered/modified in the rkive.cf file. 
X
X9)  VERY IMPORTANT! If you have a problem, there's someone else out there 
X    who either has had or will have the same problem.  Please send all 
X    patches, ideas, etc to kent@sparky.imd.sterling.com (or uunet!sparky!kent)
X    so that I can continue to improve the functionality and portability of 
X    this package. 
END_OF_FILE
if test 15961 -ne `wc -c <'rkive/README'`; then
    echo shar: \"'rkive/README'\" unpacked with wrong size!
fi
# end of 'rkive/README'
fi
if test -f 'rkive/header.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/header.c'\"
else
echo shar: Extracting \"'rkive/header.c'\" \(26184 characters\)
sed "s/^X//" >'rkive/header.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[] = "@(#)header.c	2.2 2/23/91";
X#endif
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include "article.h"
X
Xint fprintf();
X
Xint its(s1)
Xregister char *s1;
X{
X    int strlen();
X    int strncmp();
X
X    if (strncmp(s,s1,strlen(s1)) == 0)
X        return(TRUE);
X    return(FALSE);
X}
X
Xint line_type()
X{
X    if (its("Path: "))
X        return PATH;
X    if (its("From: "))
X        return FROM;
X    if (its("Newsgroups: "))
X        return NEWSGROUP;
X    if (its("Subject: "))
X        return SUBJECT;
X    if (its("Keywords: "))
X        return KEYWORDS;
X    if (its("Date: "))
X        return DATE;
X    if (its("Message-ID: "))
X        return MSG_ID;
X    if (its("Lines: "))
X        return NUMLINES;
X    if (its("Approved: "))
X        return APPROVED;
X
X    /* The following are the auxilliary headers used by */
X    /* the moderators of the sources groups. In some    */
X    /* cases, line checks are done with "historical"    */
X    /* auxilliary headers. Most of the moderators have  */
X    /* now standardized on comp.sources.unix's format.  */
X
X    /* Archive header lines for comp.sources.unix     */
X    /* for comp.sources.amiga, comp.sources.atari.st, */
X    /* comp.sources.misc, and comp.sources.x.         */
X
X    if (its("Submitted-by: "))         
X        return SUBMITTED_BY;
X    if (its("Posting-number: "))       
X        return POSTING_NUMBER;
X    if (its("Archive-name: "))
X        return ARCH_NAME;
X
X    /* Auxiliary header used as a backward reference   */
X    /* to the location of the initially posted sources */
X    /* in the event of a patch. This line only exists  */
X    /* if the current article is a patch.              */
X
X    if (its("Patch-To: "))
X        return PATCH_TO;
X    if (its("Patch-to: "))
X        return PATCH_TO;
X
X    /* The X-Checksum-Snefru archive is being used by  */
X    /* comp.sources.unix and comp.sources.misc to      */
X    /* verify articles.                                */
X
X    if (its("X-Checksum-Snefru: "))
X        return X_CHECKSUM_SNEFRU;
X
X    /* The following lines are used by comp.sources.games  */
X    /* currently to indicate the environmental keywords    */
X    /* indicating what is required by the software to run. */
X
X    if (its("Environment: "))
X        return ENVIRONMENT;
X    if (its("Supersedes: "))
X        return SUPERSEDES;
X 
X    /* Archive header lines for historical purposes */
X    /* once used in comp.sources.misc               */
X
X    if (its("Submitted-By: "))        
X        return SUBMITTED_BY;
X    if (its("comp.sources.misc: "))
X        return POSTING_NUMBER;
X    if (its("Archive-Name: "))
X        return ARCH_NAME;
X
X    /* Archive header lines for supporting the  */
X    /* uunet comp.sources.misc article archives */
X
X    if (its("subject: "))
X        return SUBJECT;
X    if (its("from: "))
X        return FROM;
X
X    /* Archive header lines used in comp.sources.games   */
X    /* Archive-name is the same as comp.sources.unix     */
X
X    if (its("Submitted by: "))        
X        return SUBMITTED_BY;
X    if (its("Comp.sources.games: "))
X        return POSTING_NUMBER;
X
X    /* Archive header lines for historical purposes */
X    /* once used in mod.sources articles.           */
X
X    if (its("Mod.sources: "))       
X        return POSTING_NUMBER;
X
X    /* The following lines are used by comp.archives */
X    /* to as auxiliary header lines.  Archive-name   */
X    /* is also used.                                 */
X
X    if (its("Original-posting-by: "))       
X        return ORIGINAL_POSTING_BY;
X    if (its("Original-subject: "))       
X        return ORIGINAL_SUBJECT;
X    if (its("Archive-site: "))       
X        return ARCHIVE_SITE;
X    if (its("Archive-directory: "))       
X        return ARCHIVE_DIRECTORY;
X    if (its("Reposted-by: "))       
X        return REPOSTED_BY;
X    if (its("Archive: "))
X	return ARCHIVE_;
X
X    /* The following lines are used by comp.sources.apple2 */
X    /* to indicate the type of the system the software     */
X    /* is to run on and the version of the software.       */
X
X    if (its("Architecture: "))
X        return ARCHITECTURE;
X    if (its("Version-number: "))
X        return VERSION_NUMBER;
X 
X    /* The remainder are other types of lines included */
X    /* headers and are includes for formatting output  */
X    /* and for potential future use.                   */
X
X    if (its("References: "))
X        return REFERENCES;
X    if (its("Organization: "))
X        return ORGANIZATION;
X    if (its("Distribution: "))
X        return DISTRIBUTION;
X    if (its("Xref: "))
X        return XREF;
X    if (its("Expires: "))
X        return EXPIRE;
X    if (its("Article-I.D.: "))
X        return ARTICLEID;
X    if (its("Reply-To: "))
X        return REPLY_TO;
X    if (its("Control: "))
X        return CONTROL;
X    if (its("Sender: "))
X        return SENDER;
X    if (its("Followup-To: "))
X        return FOLLOWUP_TO;
X    if (its("Summary: "))
X        return SUMMARY;
X
X    return OTHER;
X}
X
Xvoid data(hpfield, size, fldname, header_id)
Xchar *hpfield;
Xint  size;
Xchar *fldname;
Xint  header_id;
X{
X    register char *ptr;
X    register char *p;
X    char *strncpy();
X    char *strcpy();
X    char *strchr();
X
X    for (ptr = strchr(s, ':'); isspace(*++ptr); )
X        ;
X    if (*ptr != '\0') {
X        (void) strncpy(hpfield, ptr, size - 1);
X        /*
X         * Strip trailing newlines, blanks, and tabs from hpfield.
X         */
X        for (p = hpfield; *p; ++p)
X             ;
X        while (--p >= hpfield && (*p == '\n' || *p == ' ' || *p == '\t'))
X             ;
X        *++p = '\0';
X    }
X
X    (void) strcpy(header.header[header_id], hpfield);
X
X    if (debug)
X       (void) fprintf(logfp,"%s: %s\n",fldname, hpfield);
X}
X
Xvoid dump_article()
X{
X    char *type_str;
X
X    switch(article.rectype) {
X             case PATCH  : type_str = "PATCH";
X                           break;
X      case ADMINISTRATION: type_str = "ADMINISTRATION"; 
X                           break;
X      case INFORMATIONAL : type_str = "INFORMATIONAL"; 
X                           break;
X                 default : type_str = "NORMAL"; 
X                           break;
X    }
X
X    (void) fprintf(logfp,"Article:           [%s]\n",article.newsarticle);
X    (void) fprintf(logfp,"   newsgroup:      [%s]\n",article.newsgroup);
X    (void) fprintf(logfp,"   filename:       [%s]\n",article.filename);
X    (void) fprintf(logfp,"   volume:         [%d]\n",article.volume);
X    (void) fprintf(logfp,"   issue:          [%d]\n",article.issue);
X    (void) fprintf(logfp,"   record type:    [%s]\n", type_str);
X    if (article.rectype == PATCH) {
X        (void) fprintf(logfp,"   patch volume:   [%d]\n",article.patch_volume);
X        (void) fprintf(logfp,"   patch issue:    [%s]\n",article.patch_issue);
X    }
X    (void) fprintf(logfp,"   reposted:       [%s]\n", 
X                   article.repost ? "YES": "NO");
X    (void) fprintf(logfp,"   description:    [%s]\n",article.description);
X    (void) fprintf(logfp,"   author's name:  [%s]\n",article.author_name);
X    (void) fprintf(logfp,"   author's logon: [%s]\n\n",article.author_signon);
X}
X
Xvoid init_article()
X{
X    article.newsgroup[0] = '\0';
X    article.newsarticle[0] = '\0';
X    article.filename[0] = '\0';
X    article.volume = -1;
X    article.issue = -1;
X    article.rectype = NORMAL;
X    article.repost = FALSE;
X    article.patch_volume = -1;
X    article.package_name[0] = '\0';
X    article.patch_issue[0] = '\0';
X    article.description[0] = '\0';
X    article.author_name[0] = '\0';
X    article.author_signon[0] = '\0';
X
X    header.from[0] = '\0';         	/* From:                 */
X    header.path[0] = '\0';         	/* Path:                 */
X    header.nbuf[0] = '\0';         	/* Newsgroups:           */
X    header.subject[0] = '\0';      	/* Subject:              */
X    header.ident[0] = '\0';        	/* Message-ID:           */
X    header.replyto[0] = '\0';      	/* Reply-To:             */
X    header.references[0] = '\0';   	/* References:           */
X    header.subdate[0] = '\0';      	/* Date: (submission)    */
X    header.subtime = 0;            	/* subdate in secs       */
X    header.expdate[0] = '\0';      	/* Expires:              */
X    header.ctlmsg[0] = '\0';       	/* Control:              */
X    header.sender[0] = '\0';       	/* Sender:               */
X    header.followup_to[0] = '\0';  	/* Followup-to:          */
X    header.distribution[0] = '\0'; 	/* Distribution:         */
X    header.organization[0] = '\0'; 	/* Organization:         */
X    header.numlines[0] = '\0';     	/* Lines:                */
X    header.intnumlines = 0;        	/* Integer Version       */
X    header.keywords[0] = '\0';     	/* Keywords:             */
X    header.summary[0] = '\0';      	/* Summary:              */
X    header.approved[0] = '\0';     	/* Approved:             */
X    header.xref[0] = '\0';         	/* Xref:                 */
X    header.supersedes[0] = '\0';   	/* Supersedes:           */
X    header.submitted_by[0] = '\0'; 	/* Submitted_by:         */
X    header.posting_num[0] = '\0';  	/* Posting-number:       */
X    header.archive_name[0] = '\0'; 	/* Archive-name:         */
X    header.patch_to[0] = '\0';     	/* Patch-To:             */
X    header.x_checksum_snefru[0] = '\0';	/* X-Checksum-Snefru: 	 */
X    header.orig_poster[0] = '\0';	/* Original-posting-by:  */
X    header.orig_subject[0] = '\0';	/* Original-subject:     */
X    header.archive_site[0] = '\0';	/* Archive-site:         */
X    header.archive_dir[0] = '\0';	/* Archive-directory:    */
X    header.reposter[0] = '\0';		/* Reposted-by:          */
X    header.architecture[0] = '\0';	/* Architecture:         */
X    header.version_number[0] = '\0';	/* Version-number:       */
X    header.archive[0] = '\0';		/* Archive:		 */
X    header.environment[0] = '\0';	/* Environment:		 */
X}
X
Xvoid store_line()
X{
X    int atoi();
X    char *strchr(), *strcpy(), *strstrip(), *substr();
X    char *dp, *sp;
X    char wrk[256];
X
X    switch(line_type()) {
X
X    case PATH: /*PATH REQUIRED************************/
X        data(header.path, sizeof(header.path), "PATH:", PATH);
X        break;
X
X    case FROM: /*FROM REQUIRED************************/
X        data(header.from, sizeof(header.from), "FROM:", FROM);
X        break;
X
X    case NEWSGROUP: /*NEWSGROUP REQUIRED**************/
X        data(header.nbuf, sizeof(header.nbuf), "NEWSGROUPS:", NEWSGROUP);
X        if ((sp = strchr(s,':')) != NULL) {
X             do {
X                 ++sp;
X             } while(!isalpha(*sp));
X             /* remove all crossposting labels */
X             if ((dp = strchr(sp,',')) != NULL)
X                 *dp = '\0';
X             (void) strcpy(article.newsgroup,sp);
X        }
X        break;
X
X    case SUBJECT: /*SUBJECT REQUIRED******************/
X        data(header.subject, sizeof(header.subject), "SUBJECT:", SUBJECT);
X        /* 
X        ** Save the subject as the description for articles
X        ** that have no volume/issue format. Later in the
X        ** code, this subject line minus the volume/issue
X        ** is stored back in the .description element if
X        ** the volume/issue indicator is found.
X        */
X        (void) strcpy(article.description, header.subject);
X
X        /*
X        ** Check to see if this article is a repost of
X        ** a previously posted article.
X        */
X        if (substr(s, "REPOST") != NULL)
X            article.repost = TRUE;
X
X        /*
X        ** Time to get the filename. Assure that it is in a 
X        ** volume/issue (v01INF1 or v01ADM1 or v01SRC001 or
X        ** v01i001) format.
X        */
X        if ((sp = strchr(s,'v')) == NULL) 
X            return;          /* no volume indicator */
X
X        /* 
X        ** Is there a number that follows 
X        ** the volume indicator ? 
X        */
X        if (*(sp+1) < '0' || *(sp+1) > '9')
X            return;   /* The volume number is missing */
X
X        /*
X        ** Is there a second ':' as well ?
X        */
X        (void) strcpy(article.filename,sp);
X        if ((dp = strchr(article.filename,':')) == NULL) 
X            return;   /* not in v01i001: format */
X
X        /*
X        ** terminate the article's filename and 
X        ** store the article's description 
X        */
X        *dp = '\0';
X        (void) strcpy(article.description, strstrip(++dp));
X
X        /*
X        ** Store the filename in a work 
X        ** buffer so I can stomp on it. 
X        */
X        (void) strcpy(wrk, article.filename);
X
X        ++sp; /* increment past the 'v' */
X
X        /* 
X        ** This is an informational posting.
X        */
X        if ((dp = substr(wrk, "INF")) != NULL) {
X            article.rectype = INFORMATIONAL;
X            article.issue = atoi((dp+3));
X        }
X
X        /* 
X        ** This is an administration posting.
X        */
X        else if ((dp = substr(wrk, "ADM")) != NULL) {
X            article.rectype = ADMINISTRATION;
X            article.issue = atoi((dp+3));
X        }
X
X        /* 
X        ** This is a comp.sources.apple2 posting.
X        ** Why this is needed, I don't know...
X        */
X        else if ((dp = substr(wrk, "SRC")) != NULL) {
X            article.issue = atoi((dp+3));
X        }
X
X        /*
X        **  check to see if there is an issue indicator 
X        */
X        else if ((dp = strchr(wrk,'i')) != NULL) {
X             /* parse the issue from the filename */
X             article.issue = atoi(dp+1);
X        }
X        else
X            return;   /* proven guilty. not volume/issue format */
X
X        /* parse the volume from the filename */
X        *dp = '\0';
X        article.volume = atoi(sp);
X
X        break;
X
X    case DATE:
X        data(header.subdate, sizeof(header.subdate), "DATE:", DATE);
X        break;
X
X    case EXPIRE:
X        data(header.expdate, sizeof(header.expdate), "EXPIRES:", EXPIRE);
X        break;
X
X    case MSG_ID:
X        data(header.ident, sizeof(header.ident), "MESSAGE-ID:", MSG_ID);
X        break;
X
X    case REPLY_TO:
X        data(header.replyto, sizeof(header.replyto), "REPLY-TO:", REPLY_TO);
X        break;
X
X    case REFERENCES:
X        data(header.references, sizeof(header.references), "REFERENCES:", REFERENCES);
X        break;
X
X    case SENDER:
X        data(header.sender, sizeof(header.sender), "SENDER:", SENDER);
X        break;
X
X    case FOLLOWUP_TO:
X        data(header.followup_to, sizeof(header.followup_to),"FOLLOWUP-TO:", FOLLOWUP_TO);
X        break;
X
X    case CONTROL:
X        data(header.ctlmsg, sizeof(header.ctlmsg),"CONTROL:", CONTROL);
X        break;
X
X    case DISTRIBUTION:
X        data(header.distribution, sizeof(header.distribution),"DISTRIBUTION:", DISTRIBUTION);
X        break;
X
X    case ORGANIZATION:
X        data(header.organization, sizeof(header.organization),"ORGANIZATION:", ORGANIZATION);
X        break;
X
X    case NUMLINES:
X        data(header.numlines, sizeof(header.numlines),"LINES:", NUMLINES);
X        header.intnumlines = atoi(header.numlines);
X        break;
X
X    case KEYWORDS:
X        data(header.keywords, sizeof(header.keywords), "KEYWORDS:",KEYWORDS);
X        break;
X
X    case APPROVED:
X        data(header.approved, sizeof(header.approved), "APPROVED:",APPROVED);
X        break;
X
X    case ENVIRONMENT:
X        data(header.environment, sizeof(header.environment),"ENVIRONMENT:",ENVIRONMENT);
X        break;
X
X    case SUPERSEDES:
X        data(header.supersedes, sizeof(header.supersedes),"SUPERSEDES:",SUPERSEDES);
X        break;
X
X    case XREF:
X        data(header.xref, sizeof(header.xref),"XREF:",XREF);
X        break;
X
X    case SUMMARY:
X        data(header.summary, sizeof(header.summary),"SUMMARY:", SUMMARY);
X        break;
X
X    case POSTING_NUMBER:
X        data(header.posting_num, sizeof(header.posting_num), "POSTING_NUMBER:", POSTING_NUMBER);
X        /*
X        ** Well we almost have a standard here...
X        **
X        ** comp.sources.amiga, comp.sources.atari.st, comp.sources.games
X        ** comp.sources.sun, comp.sources.x, comp.sources.unix all use 
X        ** Posting-Number: lines as follows:
X        **    Volume #, Issue #
X        ** indicates a source posting while
X        **    Volume #, Info #
X        ** is used for all the periodic and administration postings.
X        ** For informational only... c.s.u once used
X        **    Volume #, Number # 
X        ** to indicate a source posting. Really. Check volume 10...
X        ** 
X        ** comp.sources.misc uses the same Posting-number: lines for
X        ** source postings but used 
X        **    Volume #, Administrivia #
X        ** for all the periodic and administration postings.
X        ** In the future, comp.sources.misc will use the Info format
X        ** in order to move towards a standard.
X        **
X        ** comp.sources.apple2 uses the following Posting-number:
X        ** lines for the INF, source and Administration postings.
X        **    Volume 1, Information: 1
X        **    Volume 1, Source:1
X        **    Volume 1, Administrivia: 17
X        **
X        ** If the volume number and issue cannot be determined from
X        ** the subject line then lets give it a try here...
X        */
X        if (article.volume == -1 || article.issue == -1) {
X            if ((sp = strchr(s,'V')) != NULL) {
X                do {
X                    ++sp;
X                } while((*sp) && (!isdigit(*sp)));
X 
X                /* Is there something there... */
X
X                if (!*sp)
X                    return;
X
X                /*
X                ** Time to get the volume number..
X                ** Save it off so that the string can
X                ** be stomped on..  What I am going to do here
X                ** is to assure that I have both a volume and
X                ** an issue number prior to setting any variables
X                ** the describe the article type...
X                */
X                (void) strcpy(wrk,sp);
X                if ((dp = strchr(wrk,',')) != NULL)
X                    *dp++ = '\0';
X                else          /* bad format, bail out... */
X                    return;
X    
X                /*
X                ** Now let's position to the type of the posting..
X                */
X                while((*dp) && (!isalpha(*dp)))
X                     ++dp;
X
X                if (!*dp)      /* Is there something there... */
X                    return;
X
X                /*
X                ** Now it is time to get the Info,Issue,Administrivia,
X                ** Information or Source number....
X                */
X                sp = dp;
X            
X                do {
X                    ++sp;
X                } while((*sp) && (!isdigit(*sp)));
X 
X                if (!*sp)      /* Is there something there... */
X                    return;
X
X                /*
X                ** We have a seemingly valid Posting-number: line.
X                ** Now we can start setting values...
X                */
X                article.volume = atoi(wrk);
X                article.issue = atoi(sp);
X
X                /*
X                ** Determine the type of the posting and
X                ** set the rectype variable.
X                */
X                if (strncmp(dp,"Info",4) == 0) 
X                    /* covers c.s.u and c.s.a2 as well */
X                    article.rectype = INFORMATIONAL;
X
X                if (strncmp(dp,"Administrivia",4) == 0) {
X                    if (strcmp(article.newsgroup,"comp.sources.misc") == 0)
X                        article.rectype = INFORMATIONAL;
X                    else /* comp.sources.apple2 */
X                        article.rectype = ADMINISTRATION;
X                }
X                /*
X                ** fill in the volume/issue filename
X                */
X                if (strcmp(article.newsgroup,"comp.sources.apple2") == 0) {
X                    if (article.rectype == INFORMATIONAL) 
X                        (void) sprintf(article.filename,"v%3.3dINF%3.3d",
X                                          article.volume, article.issue);
X                    else if (article.rectype == ADMINISTRATION) 
X                            (void) sprintf(article.filename,"v%3.3dADM%3.3d",
X                                              article.volume, article.issue);
X                    else 
X                            (void) sprintf(article.filename,"v%3.3dSRC%3.3d",
X                                              article.volume, article.issue);
X                }
X                else {
X                    if (article.rectype == INFORMATIONAL) 
X                        (void) sprintf(article.filename,"v%2.2dINF%1.1d",
X                                          article.volume, article.issue);
X                    else
X                        (void) sprintf(article.filename,"v%2.2di%3.3d",
X                                        article.volume, article.issue);
X                }
X            }
X        }
X        break;
X
X    case SUBMITTED_BY:
X        data(header.submitted_by, sizeof(header.submitted_by), "SUBMITTED_BY:", SUBMITTED_BY);
X        /* 
X        ** Save the author's name and sign on if specified 
X        ** Can be in any of the following formats:
X	**	kent@sparky.uucp 
X	**	kent@sparky.imd.sterling.com (Kent Landfield)
X	**	Kent Landfield <kent@sparky.imd.sterling.com>
X        */
X        if ((sp = strchr(s,':')) != NULL) {
X            (void) strcpy(article.author_signon,(sp+2));
X            /*
X            ** Has a name been attached to the signon ?
X            */
X            if ((dp = strchr(article.author_signon,'<')) != NULL) {
X                *(dp-1) = '\0';
X                (void) strcpy(article.author_name, article.author_signon);
X                (void) strcpy(article.author_signon, ++dp);
X                /*
X                ** Save the name, removing the <>.
X                */
X                if ((dp = strchr(article.author_signon,'>')) != NULL)
X                    *dp = '\0';
X            }
X            else if ((dp = strchr(article.author_signon,'(')) != NULL) {
X                *(dp-1) = '\0';
X                /*
X                ** Save the name, removing the ().
X                */
X                (void) strcpy(article.author_name, ++dp);
X                if ((dp = strchr(article.author_name,')')) != NULL)
X                    *dp = '\0';
X            }
X        }
X        break;
X
X    case ARCH_NAME:
X        data(header.archive_name,sizeof(header.archive_name),"ARCH_NAME:", ARCH_NAME);
X        break;
X
X    case PATCH_TO:
X        data(header.patch_to,sizeof(header.patch_to),"PATCH_TO:", PATCH_TO);
X        article.rectype = PATCH;        /* set the article type */
X
X        /*
X	** Parse the initially posted article's package-name, volume 
X        ** and issue.  The format of the auxiliary header is:
X        ** 
X        ** Patch-To: rkive: Volume 5, Issue 110
X        ** Or in the case of multipart initial postings,
X        ** Patch-To: rkive: Volume 5, Issue 110-120
X        ** Or in the case of multipart non-sequential initial postings,
X        ** Patch-To: rkive: Volume 5, Issue 110, 115, 116-120
X        **
X        */
X
X        /* 
X        ** First get the package-name
X        */
X
X        dp = strchr(s,':');    /* This exists or we would not be here */
X        while ((*++dp == ' ') || *dp == '\t');  /* skip spaces, tabs  */
X
X        sp = dp;
X        if ((dp = strchr(sp,':')) != NULL) {
X             *dp = '\0';
X             /* 
X             ** Now let's check to see if the moderator got it right...
X             ** Check to assure that a valid archive-name has been 
X             ** specified in the Patch-To: line...
X             */
X             if (strchr(sp,' ') != NULL)  {
X                 dp = s;  /* reset to start of string if no package-name */
X                 (void) strcpy(article.package_name,"Unknown");
X             }
X             else 
X                 (void) strcpy(article.package_name,sp);
X        }
X        else {
X             dp = s;  /* reset to start of string if no package-name */
X             (void) strcpy(article.package_name,"Unknown");
X        }
X            
X        /* 
X        ** Next, get the volume number.
X        */
X
X        ++dp;
X        while (*dp && (!isdigit(*dp)))
X              ++dp;
X        sp = dp;
X        while (*dp && (isdigit(*dp)))
X              ++dp;
X        *dp = '\0';
X        article.patch_volume = atoi(sp);
X
X        /* 
X        ** Now get the issue number. 
X        ** It is stored as a string but error check that
X        ** just numbers, '-' and ',' are in the string.
X        */
X
X        ++dp;
X        while (*dp && (!isdigit(*dp)))
X              ++dp;
X
X        sp = article.patch_issue;
X        while (*dp && (isdigit(*dp) || *dp == '-' || 
X                         *dp == ',' || *dp == ' ')) {
X              if (*dp != ' ')
X                  *sp++ = *dp;
X              ++dp;
X        }
X        *sp = '\0';
X        break;
X
X    case X_CHECKSUM_SNEFRU:
X        data(header.x_checksum_snefru,sizeof(header.x_checksum_snefru),"X_CHECKSUM_SNEFRU:", X_CHECKSUM_SNEFRU);
X        break;
X
X    case ORIGINAL_POSTING_BY:
X        data(header.orig_poster,sizeof(header.orig_poster),"ORIGINAL_POSTING_BY:",ORIGINAL_POSTING_BY);
X        break;
X
X    case ORIGINAL_SUBJECT:
X        data(header.orig_subject,sizeof(header.orig_subject),"ORIGINAL-SUBJECT:",ORIGINAL_SUBJECT);
X        break;
X
X    case ARCHIVE_SITE:
X        data(header.archive_site,sizeof(header.archive_site),"ARCHIVE_SITE:",ARCHIVE_SITE);
X        break;
X
X    case ARCHIVE_DIRECTORY:
X        data(header.archive_dir,sizeof(header.archive_dir),"ARCHIVE_DIRECTORY:",ARCHIVE_DIRECTORY);
X        break;
X
X    case REPOSTED_BY:
X        data(header.reposter,sizeof(header.reposter),"REPOSTED_BY:",REPOSTED_BY);
X        break;
X
X    case ARCHITECTURE:
X        data(header.architecture,sizeof(header.architecture),"ARCHITECTURE:",ARCHITECTURE);
X        break;
X
X    case VERSION_NUMBER:
X        data(header.version_number,sizeof(header.version_number),"VERSION_NUMBER:",VERSION_NUMBER);
X        break;
X
X    case ARCHIVE_:
X        data(header.archive,sizeof(header.archive),"ARCHIVE:",ARCHIVE_);
X	break;
X    }
X    return;
X}
END_OF_FILE
if test 26184 -ne `wc -c <'rkive/header.c'`; then
    echo shar: \"'rkive/header.c'\" unpacked with wrong size!
fi
# end of 'rkive/header.c'
fi
if test -f 'rkive/rkive.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rkive/rkive.h'\"
else
echo shar: Extracting \"'rkive/rkive.h'\" \(9824 characters\)
sed "s/^X//" >'rkive/rkive.h' <<'END_OF_FILE'
X/*
X** 	@(#)rkive.h	2.2 2/23/91
X**
X**	This is the rkive source configuration header file. 
X**	Please examine and change to suite your own site's needs..
X**
X*/
X
X/*
X** The default owner, group and modes of the archived files
X** need to be stated below. The values are only used if the
X** appropriate values are not in the configuration file.
X*/ 
X
X#define OWNER    0
X#define GROUP    3
X#define MODES    0444
X#define DIR_MODE 0755         /* directory creation modes */
X
X/* 
X** If you have a smart mailer that supports a "-s subject" command
X** and you wish to have the subject line added when archived mail
X** is sent, define SUBJECT_LINE. 
X*/
X
X#define SUBJECT_LINE 
X
X#ifdef SUBJECT_LINE
X#define MAIL        "/usr/ucb/Mail"	/* mail program to use */
X# ifdef NOTDEF
X#  define MAIL        "/usr/local/bin/elm"
X#  define MAIL        "/usr/bin/mailx" 	 /* mail program to use */
X#  define MAIL        "/usr/local/bin/mush"
X# endif /*NOTDEF*/
X#else
X#define MAIL        "/bin/mail"	 /* mail program to use */
X#endif
X
X/*
X** The PROBLEMS_DIR is the default directory to use in the event 
X** problems are encountered such as duplicate article names and 
X** the execution flags do not specify overwriting. 
X**
X** The new, inbound article is stored in the PROBLEMS_DIR in the 
X** problems_dir/newsgroup/volume/filename so that the administrator 
X** can review and fix the problem whenever time becomes available...
X**
X** The PROBLEMS_DIR define is used only if the administrator has not 
X** specified the PROBLEMS path variable inside of the LOCATION 
X** (config) file.
X*/
X
X#define PROBLEMS_DIR "/usenet/problems"  
X
X/* 
X** Home directory for news    
X*/
X
X#define SPOOLDIR     "/usr/spool/news"   
X
X/* 
X** Location of the default rkive configuration file.
X*/
X
X#define LOCATION     "/usr/local/lib/rkive/rkive.cf"  
X
X/*
X** Defines to control the handling of repostings.
X**
X** ADD_REPOST_SUFFIX && REPOST_SUFFIX
X**
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**
X**     CAUTION: This should *not* be used on a filesystem with
X**		14 character file name limits. If you are going
X**		to be making your archive available to the general
X**		community do *not* use this. The portability of
X**		filenames is greatly reduced. This has been added
X**		with much hesitation. The rational was that there
X**		was no reason to punish/limit the functionality
X**		just because of limitations of a specific "brand"
X**		of unix and since that "brand" was correcting its
X**		"error" in the future, why not put it in now ?
X**		This is not a configuration item on a per newsgroup
X**		basis. It might be useful for Historical archiving
X**		using only Volume/Issue archiving with no COMPRESSION.
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** 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 is now.
X*/
X
X/* #define ADD_REPOST_SUFFIX */
X#define MV_ORIGINAL 
X
X#ifdef ADD_REPOST_SUFFIX 
X#define REPOST_SUFFIX  "-repost" 
X#endif
X
X/* 
X** If you wish your volume directories to be Volume, VOL, vOLuMe
X** or any other such nonsense, change the VOLUME define below.
X*/
X
X#define VOLUME       "volume"
X
X/*
X** Very small change to construct change the volume directory names 
X** from "volume1" to "volume01". In this manner all of the archive
X** volume directories appear in lexical order instead of jumbled 
X** together in directory listings. This option was "requested"...
X*/
X
X/*#define ZEROFILL*/
X
X/* 
X** If you wish to have the headers "trimmed" when the file is archived,
X** assure that REDUCE_HEADERS is defined. Currenlty all header lines that
X** are not either;
X**    From:, Newsgroups:, Subject:, Message-ID: Approved:, and Date:
X** will be removed. See news_arc.c if you wish to add or subtract header
X** lines to keep. This can produce a savings of between 200 to 500 bytes
X** per archived article.
X*/
X
X#define REDUCE_HEADERS 
X
X/* 
X** The following define specifies a default format for generating
X** index file records in the event that there is no index format
X** specified for either the newsgroup or for the global default.
X** See article.1 for a discussion of the different types of selection
X** characters available for use in the format specifications.
X*/
X
X#define DEFAULT_INDEX_FORMAT       "%B\t%S"
X
X/* 
X** The following define specifies a default format for generating
X** log file records in the event that there is no log format
X** specified for either the newsgroup or for the global default.
X*/
X#define DEFAULT_LOG_FORMAT         "%O\t%T"
X
X/*
X** The size of the group array. If you are archiving the world
X** you might need to bump this up...
X*/
X
X#define NUM_NEWSGROUPS  32
X
X/**********************************************************************
X*******************  NO CHANGES REQUIRED PAST HERE  *******************
X**********************************************************************/
X
X/*
X** check to assure repost defines are in order...
X*/
X
X#if defined(ADD_REPOST_SUFFIX) + defined(MV_ORIGINAL) > 1
X#include "ERROR - Can only specify a maximum of one way to handle reposts!"
X#endif
X
X#include <dirent.h>
X
Xint fprintf();
X
X/*
X** Standard stuff
X*/
X
X#ifndef TRUE
X#define TRUE   1
X#endif
X
X#ifndef FALSE
X#define FALSE  0
X#endif
X
X/*
X** The MAXNAMLEN define is here for systems such as SCO
X** that have MAXNAMLEN in other then dirent.h
X**         Samuel Lam <uunet!van-bc!skl> 
X*/
X#ifndef MAXNAMLEN
X#define MAXNAMLEN  255
X#endif 
X
X/*
X** retrieve_article() return values
X*/
X#define ERROR_ENCOUNTERED -1
X#define DONE 0
X#define RETRIEVED 1
X
X/*
X** retrieve_article() from defines
X*/
X#define FROM_DISK       0
X#define FROM_NAME       1
X#define FROM_BATCHFILE  2
X#ifdef NNTP
X# define FROM_NNTP      3
X#endif /*NNTP*/
X
X/*
X** archive type defines 
X**
X** These defines are used to determine which type of archiving 
X** methods the administrator has requested for the newsgroup.
X**
X*/
X
X#define ARCHIVE_NAME     0	/* Archive as "elm/part03"  */
X                                /* and moderator info also. */
X#define VOLUME_ISSUE     1	/* Archive as "v16i003"     */
X#define ARTICLE_NUMBER   2	/* Archive with same name   */
X				/* as the file to archive   */
X#define CHRONOLOGICAL    3	/* Archive as "890619002"   */
X                                /* or YYMMDDIII format      */
X#define COMP_ARCHIVES    4	/* Archive for comp.archives*/
X#define EXTERNAL_COMMAND 5	/* Archive by piping the    */
X                                /* articles to the external */
X                                /* command specified int the*/
X                                /* rkive.cf file.           */
X#define ONLY_ARCHIVE_NAME 6	/* Archive as "elm/part03"  */
X
X#define MAXMATCHLEN   10000   /* Length for Match-expression. */
X
X
X/*
X** patch handling type defines 
X**
X** These defines are used to determine which type of 
X** method the administrator has requested for the the
X** handling of patches received in the newsgroup.
X**
X*/
X
X#define HISTORICAL   0    	/* Archive as normally done.        */
X#define PACKAGE      1    	/* Archive patches in the directory */
X                                /* containing the initial posting.  */
X
Xstruct group_archive {
X    int owner;                  /* owner id of the archive files     */
X    int group;                  /* group id of the archive files     */
X    int modes;                  /* modes of the stored archive files */
X    int type;                   /* Type of archiving to be used.     */
X				/*        0 = Archive-Name           */
X                                /*        1 = Volume-Issue           */
X                                /*        2 = Article-Number         */
X                                /*        3 = Chronological          */
X                                /*        4 = Comp-Archives          */
X                                /*        5 = External-Command       */
X    int patch_type;             /* Method of handling patches.       */
X                                /*        0 = Historical             */
X                                /*        1 = Package                */
X    char ng_name[MAXNAMLEN];    /* Newsgroup to be archived.         */
X    char ng_path[MAXNAMLEN];    /* Path to archive's base directory. */
X    char location[MAXNAMLEN];	/* Path to archive's base directory. */
X    char arc_done[MAXNAMLEN];	/* Archive's .archived already file  */
X    char mail_list[BUFSIZ];	/* List of users to mail when new    */
X				/* members are added to the archive. */
X    char logfile[MAXNAMLEN];	/* Path to archive specific log file */
X    char index[MAXNAMLEN]; 	/* Path to archive specific index.   */
X    char patchlog[MAXNAMLEN];	/* Path to archive's patches log.    */
X    char logformat[BUFSIZ];	/* Format of the logfile entry.      */
X    char indformat[BUFSIZ];	/* Format of the index entry.        */
X    char compress[MAXNAMLEN];	/* Command line to use to compress   */
X				/* new archive members, optional.    */
X    char arch_command[MAXNAMLEN]; /* Command line to use to archive  */
X                              	/* the articles in the newsgroup.    */
X    char checkhash[MAXNAMLEN];	/* Command line to use to test       */
X				/* articles for transit damage.      */
X    char match[MAXMATCHLEN];    /* Match-expression                  */
X#ifdef NNTP
X    char nntp[MAXNAMLEN];	/* Name of system with nntp server   */
X#endif /*NNTP*/
X};
END_OF_FILE
if test 9824 -ne `wc -c <'rkive/rkive.h'`; then
    echo shar: \"'rkive/rkive.h'\" unpacked with wrong size!
fi
# end of 'rkive/rkive.h'
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
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.