ARC for BSD4.2 (part 1 of 5)

turner at imagen.UUCP turner at imagen.UUCP
Tue Aug 5 08:39:09 AEST 1986


This is my hacked version of the arc program that was posted to the net, I
have modified it to run under Unix BSD4.2. if you want it to run under 
SVR2 you probably will have to change the opendir, scandir, and closedir
calls, I don't really know System 5. IMPORTANT: this is a BETA test version
i doubt severly that there are no bugs, please report any that you find to me.

1) I don't have a PC handy so i have no idea if it still works on the PC; to
	compile it for the PC edit arc.h and arcs.c and change the #defines,
	the define ST is for the Atari 520ST and with luck that will be done
	shortly. If you compile it for the PC you will need the routines for 
	opendir etc. that are in shar part 5, otherwise you can ignore that 
	shar file.
2) the Makefile is configured to compile for debugging (-g) (shows ya what 
	kind of faith i have in my code (:-)
3) everything seems to work for both arc files created on the PC and on BSD4.2
	with the exception of the t (test) option which gives strange results,
	i suspect the problem is in the code not the archive
4) there is one bug that i know of, if you archive a 0 length file, arc will
	blow up (floating point exception) when you try to extract it; the
	question is should the check happen when you add the file, extract
	it, or should if create a 0 length file ? you decide.
5) send flames etc. to me, because of the way postnews works here my signature
	will probably be at the end of each shar file, if not its:
----
Name:	James M. Turner
Mail:	Imagen Corp. 2650 San Tomas Expressway, P.O. Box 58101
        Santa Clara, CA 95052-8101
AT&T:	(408) 986-9400
UUCP:	...{decvax,ucbvax}!decwrl!imagen!turner
CompuServe: 76327,1575
GEnie     : D-ARCANGEL
----

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	arc.h
#	arcm.h
#	arcs.h
#	arc.c
#	arcadd.c
#	arccode.c
#	arccvt.c
#	arcdel.c
#	arcdir.c
#	arcdos.c
#	Makefile
# This archive created: Mon Aug  4 14:42:58 1986
# By:	D'arc Angel (The Houses of the Holy)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'arc.h'" '(2153 characters)'
if test -f 'arc.h'
then
	echo shar: "will not over-write existing file 'arc.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'arc.h'
	X/*
	X * $Header: arc.h,v 1.2 86/07/15 07:52:34 turner Exp $
	X */
	X
	X/*
	X * $Log:	arc.h,v $
	X * Revision 1.2  86/07/15  07:52:34  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:01:23  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X#define	ST	0	/* Atari 520ST or 1040 		 */
	X#define BSD	1	/* BSD4.2 on a vax		 */
	X#define MSDOS	0	/* MSDOS on an IBM PC or Wannabe */
	X
	X#if ST
	X#define EXTERN
	X#define INT short
	X#endif
	X
	X#if BSD
	X#include <ctype.h>	/* for isupper etc.                  */
	X#define EXTERN
	X#define INT short
	X#define envfind getenv
	X#endif
	X
	X#if MSDOS
	X#define EXTERN extern
	X#define INT int
	X#endif
	X
	X/*
	X * added macro def's in C format 6/26/86 jmt 
	X */
	X#include "arcm.h"
	X
	X/*  ARC - Archive utility - ARC Header
	X
	X    Version 2.14, created on 02/03/86 at 22:48:29
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description: 
	X         This is the header file for the ARC archive utility.  It defines
	X         global parameters and the references to the external data.
	X
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X */
	X
	X#include "arcs.h"
	X
	XEXTERN INT keepbak;             /* true if saving the old archive */
	XEXTERN INT warn;                /* true to print warnings */
	XEXTERN INT note;                /* true to print comments */
	XEXTERN INT bose;                /* true to be verbose */
	XEXTERN INT nocomp;              /* true to suppress compression */
	XEXTERN INT kludge;              /* kludge flag */
	XEXTERN char *arctemp;        /* arc temp file prefix */
	XEXTERN char *password;       /* encryption password pointer */
	XEXTERN INT nerrs;               /* number of errors encountered */
	X
	XEXTERN char hdrver;                      /* header version */
	X
	XEXTERN FILE *arc;                        /* the old archive */
	XEXTERN FILE *new;                        /* the new archive */
	X
	XEXTERN char arcname[100];           /* storage for archive name */
	XEXTERN char bakname[100];           /* storage for backup copy name */
	XEXTERN char newname[100];           /* storage for new archive name */
	XEXTERN unsigned INT arcdate;    /* archive date stamp */
	XEXTERN unsigned INT arctime;    /* archive time stamp */
SHAR_EOF
if test 2153 -ne "`wc -c < 'arc.h'`"
then
	echo shar: "error transmitting 'arc.h'" '(should have been 2153 characters)'
fi
fi
echo shar: "extracting 'arcm.h'" '(695 characters)'
if test -f 'arcm.h'
then
	echo shar: "will not over-write existing file 'arcm.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcm.h'
	X/*
	X * $Header: arcm.h,v 1.2 86/07/15 07:53:40 turner Exp $
	X */
	X
	X/*
	X * $Log:	arcm.h,v $
	X * Revision 1.2  86/07/15  07:53:40  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:01:25  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*
	X *
	X * ARC archive utility - standard MACRO insert file.
	X *
	X * parameters:
	X *
	X */
	X
	X#define ARCMARK 26 /*                   special archive marker        */
	X#define ARCVER 8   /*                   archive header version code   */
	X#define STRLEN 100 /*                   system standard string length */
	X#define FNLEN 13   /*                   file name length              */
	X#define MAXARG 25  /*                   maximum number of arguments   */
	X
	X#define ARC 1
	X#define XARC 0
SHAR_EOF
if test 695 -ne "`wc -c < 'arcm.h'`"
then
	echo shar: "error transmitting 'arcm.h'" '(should have been 695 characters)'
fi
fi
echo shar: "extracting 'arcs.h'" '(1965 characters)'
if test -f 'arcs.h'
then
	echo shar: "will not over-write existing file 'arcs.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcs.h'
	X/*
	X * $Header: arcs.h,v 1.2 86/07/15 07:54:02 turner Exp $
	X */
	X
	X/*
	X * $Log:	arcs.h,v $
	X * Revision 1.2  86/07/15  07:54:02  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:01:27  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - Archive file header format
	X
	X    Version 2.12, created on 12/17/85 at 14:40:26
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file defines the format of an archive file header, excluding
	X         the archive marker and the header version number.
	X
	X         Each entry in an archive begins with a one byte archive marker,
	X         which is set to 26.  The marker is followed by a one byte
	X         header type code, from zero to 7.
	X
	X         If the header type code is zero, then it is an end marker, and
	X         no more data should be read from the archive.
	X
	X         If the header type code is in the range 2 to 7, then it is
	X         followed by a standard archive header, which is defined below.
	X
	X         If the header type code is one, then it is followed by an older
	X         format archive header.  The older format header does not contain
	X         the true length.  A header should be read for a length of
	X         sizeof(struct heads)-sizeof(long).  Then set length equal to size
	X         and change the header version to 2.
	X
	X    Programming note:
	X         The crc value given in the header is based on the unpacked data.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X
	Xstruct heads                           /* archive entry header format */
	X{   char name[13];                 /* file name */
	X    long size;                         /* size of file, in bytes */
	X    unsigned INT date;                 /* creation date */
	X    unsigned INT time;                 /* creation time */
	X INT crc;                           /* cyclic redundancy check */
	X    long length;                       /* true file length */
	X}   ;
SHAR_EOF
if test 1965 -ne "`wc -c < 'arcs.h'`"
then
	echo shar: "error transmitting 'arcs.h'" '(should have been 1965 characters)'
fi
fi
echo shar: "extracting 'arc.c'" '(9644 characters)'
if test -f 'arc.c'
then
	echo shar: "will not over-write existing file 'arc.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arc.c'
	Xstatic char *RCSid = "$Header: arc.c,v 1.2 86/07/15 07:52:04 turner Exp $";
	X
	X/*
	X * $Log:	arc.c,v $
	X * Revision 1.2  86/07/15  07:52:04  turner
	X * first working version for the vax
	X * 
	X * Revision 1.1  86/06/26  14:59:15  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =5.12), created on $tag(
	XTED_DATE DB =02/05/86) at $tag(
	XTED_TIME DB =22:22:01))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This program is a general archive utility, and is used to maintain
	X         an archive of files.  An "archive" is a single file that combines
	X         many files, reducing storage space and allowing multiple files to
	X         be handled as one.
	X
	X    Instructions:
	X         Run this program with no arguments for complete instructions.
	X
	X    Programming notes:
	X         ARC Version 2 differs from version 1 in that archive entries
	X         are automatically compressed when they are added to the archive,
	X         making a separate compression step unecessary.  The nature of the
	X         compression is indicated by the header version number placed in
	X         each archive entry, as follows:
	X
	X         1 = Old style, no compression
	X         2 = New style, no compression
	X         3 = Compression of repeated characters only
	X         4 = Compression of repeated characters plus Huffman SQueezing
	X         5 = Lempel-Zev packing of repeated strings (old style)
	X         6 = Lempel-Zev packing of repeated strings (new style)
	X         7 = Lempel-Zev Williams packing with improved has function
	X         8 = Dynamic Lempel-Zev packing with adaptive reset
	X
	X         Type 5, Lempel-Zev packing, was added as of version 4.0
	X
	X         Type 6 is Lempel-Zev packing where runs of repeated characters
	X         have been collapsed, and was added as of version 4.1
	X
	X         Type 7 is a variation of Lempel-Zev using a different hash
	X         function which yields speed improvements of 20-25%, and was
	X         added as of version 4.6
	X
	X         Type 8 is a different implementation of Lempel-Zev, using a
	X         variable code size and an adaptive block reset, and was added
	X         as of version 5.0
	X
	X         Verion 4.3 introduced a temporary file for holding the result
	X         of the first crunch pass, thus speeding up crunching.
	X
	X         Version 4.4 introduced the ARCTEMP environment string, so that
	X         the temporary crunch file may be placed on a ramdisk.  Also
	X         added was the distinction bewteen Adding a file in all cases,
	X         and Updating a file only if the disk file is newer than the
	X         corresponding archive entry.
	X
	X         The compression method to use is determined when the file is
	X         added, based on whichever method yields the smallest result.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xmain(num,arg)                          /* system entry point */
	Xint num;                               /* number of arguments */
	Xchar *arg[];                           /* pointers to arguments */
	X{
	X    char opt = 0;                      /* selected action */
	X    char *a;                           /* option pointer */
	X    char *makefnam();                  /* filename fixup routine */
	X    char *upper();                     /* case conversion routine */
	X    char *index();                     /* string index utility */
	X    char *envfind();                   /* environment searcher */
	X int n;                             /* argument index */
	X
	X    if(num<3)
	X    {    printf("ARC - Archive utility, $version\n");
	X         printf("(C) COPYRIGHT 1985,86 by System Enhancement Associates;");
	X         printf(" ALL RIGHTS RESERVED\n\n");
	X         printf("Please refer all inquiries to:\n\n");
	X         printf("       System Enhancement Associates\n");
	X         printf("       21 New Street, Wayne NJ 07470\n\n");
	X         printf("You may copy and distribute this program freely,");
	X         printf(" provided that:\n");
	X         printf("    1)   No fee is charged for such copying and");
	X         printf(" distribution, and\n");
	X         printf("    2)   It is distributed ONLY in its original,");
	X         printf(" unmodified state.\n\n");
	X         printf("If you like this program, and find it of use, then your");
	X         printf(" contribution will\n");
	X         printf("be appreciated.  You may not use this product in a");
	X         printf(" commercial environment\n");
	X         printf("or a governmental organization without paying a license");
	X         printf(" fee of $35.  Site\n");
	X         printf("licenses and commercial distribution licenses are");
	X         printf(" available.  A program\n");
	X         printf("disk and printed documentation are available for $50.\n");
	X         printf("\nIf you fail to abide by the terms of this license, ");
	X         printf(" then your conscience\n");
	X         printf("will haunt you for the rest of your life.\n\n");
	X         printf("Usage: ARC {amufdxerplvtc}[bswn][g<password>]");
	X         printf(" <archive> [<filename> . . .]\n");
	X         printf("Where:   a   = add files to archive\n");
	X         printf("         m   = move files to archive\n");
	X         printf("         u   = update files in archive\n");
	X         printf("         f   = freshen files in archive\n");
	X         printf("         d   = delete files from archive\n");
	X         printf("         x,e = extract files from archive\n");
	X         printf("         r   = run files from archive\n");
	X         printf("         p   = copy files from archive to");
	X         printf(" standard output\n");
	X         printf("         l   = list files in archive\n");
	X         printf("         v   = verbose listing of files in archive\n");
	X         printf("         t   = test archive integrity\n");
	X         printf("         c   = convert entry to new packing method\n");
	X         printf("         b   = retain backup copy of archive\n");
	X         printf("         s   = suppress compression (store only)\n");
	X         printf("         w   = suppress warning messages\n");
	X         printf("         n   = suppress notes and comments\n");
	X         printf("         g   = Encrypt/decrypt archive entry\n");
	X         printf("\nPlease refer to the program documentation for");
	X         printf(" complete instructions.\n");
	X         return 1;
	X    }
	X
	X    /* see where temp files go */
	X
	X    if(!(arctemp = envfind("ARCTEMP")))
	X         arctemp = envfind("TEMP");
	X
	X#if MSDOS 
	X    /* avoid any case problems with arguments */
	X
	X    for(n=1; n<num; n++)               /* for each argument */
	X         upper(arg[n]);                /* convert it to uppercase */
	X#endif
	X#if BSD | ST
	X    /* avoid any case problems with command options */
	X
	X         upper(arg[1]);                /* convert it to uppercase */
	X#endif
	X
	X    /* create archive names, supplying defaults */
	X
	X#if MSDOS
	X    makefnam(arg[2],".ARC",arcname);
	X#endif
	X#if BSD | ST
	X    makefnam(arg[2],".arc",arcname);
	X#endif
	X    makefnam(".$$$$",arcname,newname);
	X    makefnam(".BAK",arcname,bakname);
	X
	X    /* now scan the command and see what we are to do */
	X
	X    for(a=arg[1]; *a; a++)             /* scan the option flags */
	X    {    if(index("AMUFDXEPLVTCR",*a)) /* if a known command */
	X         {    if(opt)                  /* do we have one yet? */
	X                   abort("Cannot mix %c and %c",opt,*a);
	X              opt = *a;                /* else remember it */
	X         }
	X
	X         else if(*a=='B')              /* retain backup copy */
	X              keepbak = 1;
	X
	X         else if(*a=='W')              /* suppress warnings */
	X              warn = 0;
	X
	X         else if(*a=='N')              /* suppress notes and comments */
	X              note = 0;
	X
	X         else if(*a=='G')              /* garble */
	X         {    password = a+1;
	X              while(*a)
	X                   a++;
	X              a--;
	X         }
	X
	X         else if(*a=='S')              /* storage kludge */
	X              nocomp = 1;
	X
	X         else if(*a=='K')              /* special kludge */
	X              kludge = 1;
	X
	X         else if(*a=='-' || *a=='/')   /* UNIX and PC-DOS option markers */
	X              ;
	X
	X         else abort("%c is an unknown command",*a);
	X    }
	X
	X    if(!opt)
	X         abort("I have nothing to do!");
	X
	X    /* act on whatever action command was given */
	X
	X    switch(opt)                        /* action depends on command */
	X    {
	X    case 'A':                          /* Add */
	X    case 'M':                          /* Move */
	X    case 'U':                          /* Update */
	X    case 'F':                          /* Freshen */
	X         addarc(num-3,&arg[3],(opt=='M'),(opt=='U'),(opt=='F'));
	X         break;
	X
	X    case 'D':                          /* Delete */
	X         delarc(num-3,&arg[3]);
	X         break;
	X
	X    case 'E':                          /* Extract */
	X    case 'X':                          /* eXtract */
	X    case 'P':                          /* Print */
	X         extarc(num-3,&arg[3],(opt=='P'));
	X         break;
	X
	X    case 'V':                          /* Verbose list */
	X         bose = 1;
	X    case 'L':                          /* List */
	X         lstarc(num-3,&arg[3]);
	X         break;
	X
	X    case 'T':                          /* Test */
	X         tstarc();
	X         break;
	X
	X    case 'C':                          /* Convert */
	X         cvtarc(num-3,&arg[3]);
	X         break;
	X
	X    case 'R':                          /* Run */
	X         runarc(num-3,&arg[3]);
	X         break;
	X
	X    default:
	X         abort("I don't know how to do %c yet!",opt);
	X    }
	X
	X    return nerrs;
	X}
SHAR_EOF
if test 9644 -ne "`wc -c < 'arc.c'`"
then
	echo shar: "error transmitting 'arc.c'" '(should have been 9644 characters)'
fi
fi
echo shar: "extracting 'arcadd.c'" '(10835 characters)'
if test -f 'arcadd.c'
then
	echo shar: "will not over-write existing file 'arcadd.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcadd.c'
	Xstatic char *RCSid = "$Header: arcadd.c,v 1.2 86/07/15 07:52:37 turner Exp $";
	X
	X/*
	X * $Log:	arcadd.c,v $
	X * Revision 1.2  86/07/15  07:52:37  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  14:59:37  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCADD
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =3.39), created on $tag(
	XTED_DATE DB =02/05/86) at $tag(
	XTED_TIME DB =22:21:53))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to add files to an archive.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xaddarc(num,arg,move,update,fresh)      /* add files to archive */
	Xint num;                               /* number of arguments */
	Xchar *arg[];                           /* pointers to arguments */
	Xint move;                              /* true if moving file */
	Xint update;                            /* true if updating */
	Xint fresh;                             /* true if freshening */
	X{
	X    char *d, *dir();                   /* directory junk */
	X    char buf[STRLEN];                 /* pathname buffer */
	X    char **path = NULL;                /* pointer to pointers to paths */
	X    char **name = NULL;                /* pointer to pointers to names */
	X int nfiles = 0;                    /* number of files in lists */
	X int notemp;                        /* true until a template works */
	X int nowork = 1;                    /* true until files are added */
	X    char *i, *rindex();                /* string indexing junk */
	X    char *malloc(), *realloc();         /* memory allocators */
	X int m, n;                          /* indices */
	X    unsigned int coreleft();           /* remaining memory reporter */
	X
	X    if(num<1)                          /* if no files named */
	X    {    num = 1;                      /* then fake one */
	X         arg[0] = "*.*";               /* add everything */
	X    }
	X
	X    for(n=0; n<num; n++)               /* for each template supplied */
	X    {    strcpy(buf,arg[n]);           /* get ready to fix path */
	X         if(!(i=rindex(buf,'\\')))
	X              if(!(i=rindex(buf,'/')))
	X                   if(!(i=rindex(buf,':')))
	X                        i = buf-1;
	X         i++;                          /* pointer to where name goes */
	X
	X         notemp = 1;                   /* reset files flag */
	X         for(d=dir(arg[n],0); *d; d=dir(NULL,0))
	X         {    notemp = 0;              /* template is giving results */
	X              nfiles++;                /* add each matching file */
	X              path = (char **)realloc(path,nfiles*sizeof(char **));
	X              name = (char **)realloc(name,nfiles*sizeof(char **));
	X              strcpy(i,d);             /* put name in path */
	X              path[nfiles-1] = malloc(strlen(buf)+1);
	X              strcpy(path[nfiles-1],buf);
	X              name[nfiles-1] = d;      /* save name */
	X
	X#if MSDOS
	X              if(coreleft()<5120)
	X              {    nfiles = addbunch(nfiles,path,name,move,update,fresh);
	X                   nowork = nowork && !nfiles;
	X                   while(nfiles)
	X                   {    free(path[--nfiles]);
	X                        free(name[nfiles]);
	X                   }
	X                   free(path); free(name);
	X                   path = name = NULL;
	X              }
	X#endif
	X         }
	X         if(notemp && warn)
	X              printf("No files match: %s\n",arg[n]);
	X    }
	X
	X    if(nfiles)
	X    {    nfiles = addbunch(nfiles,path,name,move,update,fresh);
	X         nowork = nowork && !nfiles;
	X         while(nfiles)
	X         {    free(path[--nfiles]);
	X              free(name[nfiles]);
	X         }
	X         free(path); free(name);
	X    }
	X
	X    if(nowork && warn)
	X         printf("No files were added.\n");
	X}
	X
	Xint addbunch(nfiles,path,name,move,update,fresh) /* add a bunch of files */
	Xint nfiles;                            /* number of files to add */
	Xchar **path;                           /* pointers to pathnames */
	Xchar **name;                           /* pointers to filenames */
	Xint move;                              /* true if moving file */
	Xint update;                            /* true if updating */
	Xint fresh;                             /* true if freshening */
	X{
	X    char buf[STRLEN];                 /* pathname buffer */
	X int m, n;                          /* indices */
	X    char *d;                           /* swap pointer */
	X    struct heads hdr;                  /* file header data storage */
	X
	X    for(n=0; n<nfiles-1; n++)          /* sort the list of names */
	X    {    for(m=n+1; m<nfiles; m++)
	X         {    if(strcmp(name[n],name[m])>0)
	X              {    d = path[n];
	X                   path[n] = path[m];
	X                   path[m] = d;
	X                   d = name[n];
	X                   name[n] = name[m];
	X                   name[m] = d;
	X              }
	X         }
	X    }
	X
	X    for(n=0; n<nfiles-1; )             /* consolidate the list of names */
	X    {    if(!strcmp(path[n],path[n+1]) /* if duplicate names */
	X         || !strcmp(path[n],arcname)   /* or this archive */
	X         || !strcmp(path[n],newname)   /* or the new version */
	X         || !strcmp(path[n],bakname))  /* or its backup */
	X         {    free(path[n]);           /* then forget the file */
	X              free(name[n]);
	X              for(m=n; m<nfiles-1; m++)
	X              {    path[m] = path[m+1];
	X                   name[m] = name[m+1];
	X              }
	X              nfiles--;
	X         }
	X         else n++;                     /* else test the next one */
	X    }
	X
	X    if(!strcmp(path[n],arcname)        /* special check for last file */
	X    || !strcmp(path[n],newname)        /* courtesy of Rick Moore */
	X    || !strcmp(path[n],bakname))
	X    {    free(path[n]);
	X         free(name[n]);
	X         nfiles--;
	X    }
	X
	X    if(!nfiles)                        /* make sure we got some */
	X         return 0;
	X
	X    for(n=0; n<nfiles-1; n++)          /* watch out for duplicate names */
	X         if(!strcmp(name[n],name[n+1]))
	X              abort("Duplicate filenames:\n  %s\n  %s",path[n],path[n+1]);
	X
	X    openarc(1);                        /* open archive for changes */
	X
	X    for(n=0; n<nfiles; n++)            /* add each file in the list */
	X         addfile(path[n],name[n],update,fresh);
	X
	X    /* now we must copy over all files that follow our additions */
	X
	X    while(readhdr(&hdr,arc))           /* while more entries to copy */
	X    {    writehdr(&hdr,new);
	X         filecopy(arc,new,hdr.size);
	X    }
	X    hdrver = 0;                        /* archive EOF type */
	X    writehdr(&hdr,new);                /* write out our end marker */
	X    closearc(1);                       /* close archive after changes */
	X
	X    if(move)                           /* if this was a move */
	X    {    for(n=0; n<nfiles; n++)       /* then delete each file added */
	X         {    if(unlink(path[n]) && warn)
	X              {    printf("Cannot unsave %s\n",path[n]);
	X                   nerrs++;
	X              }
	X         }
	X    }
	X
	X    return nfiles;                     /* say how many were added */
	X}
	X
	Xstatic addfile(path,name,update,fresh) /* add named file to archive */
	Xchar *path;                            /* path name of file to add */
	Xchar *name;                            /* name of file to add */
	Xint update;                            /* true if updating */
	Xint fresh;                             /* true if freshening */
	X{
	X    struct heads nhdr;                 /* data regarding the new file */
	X    struct heads ohdr;                 /* data regarding an old file */
	X    FILE *f, *fopen();                 /* file to add, opener */
	X    long starts, ftell();              /* file locations */
	X int c;                             /* one char of file */
	X int upd = 0;                       /* true if replacing an entry */
	X
	X    if(!(f=fopen(path,"rb")))
	X    {    if(warn)
	X         {    printf("Cannot read file: %s\n",path);
	X              nerrs++;
	X         }
	X         return;
	X    }
	X
	X    strcpy(nhdr.name,name);            /* save name */
	X    nhdr.size = 0;                     /* clear out size storage */
	X    nhdr.crc = 0;                      /* clear out CRC check storage */
	X    getstamp(f,&nhdr.date,&nhdr.time);
	X
	X    /* position archive to spot for new file */
	X
	X    if(arc)                            /* if adding to existing archive */
	X    {    starts = ftell(arc);          /* where are we? */
	X         while(readhdr(&ohdr,arc))     /* while more files to check */
	X         {    if(!strcmp(ohdr.name,nhdr.name))
	X              {    upd = 1;            /* replace existing entry */
	X                   if(update || fresh) /* if updating or freshening */
	X                   {    if(nhdr.date<ohdr.date
	X                        || (nhdr.date==ohdr.date && nhdr.time<=ohdr.time))
	X                        {    fseek(arc,starts,0);
	X                             fclose(f);
	X                             return;   /* skip if not newer */
	X                        }
	X                   }
	X              }
	X
	X              if(strcmp(ohdr.name,nhdr.name)>=0)
	X                   break;              /* found our spot */
	X
	X              writehdr(&ohdr,new);     /* entry preceeds update; keep it */
	X              filecopy(arc,new,ohdr.size);
	X              starts = ftell(arc);     /* now where are we? */
	X         }
	X
	X         if(upd)                       /* if an update */
	X         {    if(note)
	X                   printf("Updating file: %-12s  ",name);
	X              fseek(arc,ohdr.size,1);
	X         }
	X         else if(fresh)                /* else if freshening */
	X         {    fseek(arc,starts,0);     /* then do not add files */
	X              fclose(f);
	X              return;
	X         }
	X         else                          /* else adding a new file */
	X         {    if(note)
	X                   printf("Adding file:   %-12s  ",name);
	X              fseek(arc,starts,0);     /* reset for next time */
	X         }
	X    }
	X
	X    else                               /* no existing archive */
	X    {    if(fresh)                     /* cannot freshen nothing */
	X         {    fclose(f);
	X              return;
	X         }
	X         else if(note)                 /* else adding a file */
	X              printf("Adding file:   %-12s  ",name);
	X    }
	X
	X    starts = ftell(new);               /* note where header goes */
	X    hdrver = ARCVER;                  /* anything but end marker */
	X    writehdr(&nhdr,new);               /* write out header skeleton */
	X    pack(f,new,&nhdr);                 /* pack file into archive */
	X    fseek(new,starts,0);               /* move back to header skeleton */
	X    writehdr(&nhdr,new);               /* write out real header */
	X    fseek(new,nhdr.size,1);            /* skip over data to next header */
	X    fclose(f);                         /* all done with the file */
	X}
SHAR_EOF
if test 10835 -ne "`wc -c < 'arcadd.c'`"
then
	echo shar: "error transmitting 'arcadd.c'" '(should have been 10835 characters)'
fi
fi
echo shar: "extracting 'arccode.c'" '(1724 characters)'
if test -f 'arccode.c'
then
	echo shar: "will not over-write existing file 'arccode.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arccode.c'
	Xstatic char *RCSid = "$Header: arccode.c,v 1.1 86/06/26 14:59:53 turner Exp $";
	X
	X/*
	X * $Log:	arccode.c,v $
	X * Revision 1.1  86/06/26  14:59:53  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCCODE
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =1.02), created on $tag(
	XTED_DATE DB =01/20/86) at $tag(
	XTED_TIME DB =13:33:35))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to encrypt and decrypt
	X         data in an archive.  The encryption method is nothing fancy,
	X         being just a routine XOR, but it is used on the packed data,
	X         and uses a variable length key.  The end result is something
	X         that is in theory crackable, but I'd hate to try it.  It should
	X         be more than sufficient for casual use.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xstatic char *p;                        /* password pointer */
	X
	Xsetcode()                              /* get set for encoding/decoding */
	X{
	X    p = password;                      /* reset password pointer */
	X}
	X
	Xint code(c)                            /* encode some character */
	Xint c;                                 /* character to encode */
	X{
	X    if(p)                              /* if password is in use */
	X    {    if(!*p)                       /* if we reached the end */
	X              p = password;            /* then wrap back to the start */
	X         return c^*p++;                /* very simple here */
	X    }
	X    else return c;                     /* else no encryption */
	X}
SHAR_EOF
if test 1724 -ne "`wc -c < 'arccode.c'`"
then
	echo shar: "error transmitting 'arccode.c'" '(should have been 1724 characters)'
fi
fi
echo shar: "extracting 'arccvt.c'" '(4450 characters)'
if test -f 'arccvt.c'
then
	echo shar: "will not over-write existing file 'arccvt.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arccvt.c'
	Xstatic char *RCSid = "$Header: arccvt.c,v 1.2 86/07/15 07:52:46 turner Exp $";
	X
	X/*
	X * $Log:	arccvt.c,v $
	X * Revision 1.2  86/07/15  07:52:46  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  14:59:56  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCCVT
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =1.16), created on $tag(
	XTED_DATE DB =02/03/86) at $tag(
	XTED_TIME DB =22:53:02))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to convert archives to use
	X         newer file storage methods.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xstatic char tempname[STRLEN];         /* temp file name */
	X
	Xcvtarc(num,arg)                        /* convert archive */
	Xint num;                               /* number of arguments */
	Xchar *arg[];                           /* pointers to arguments */
	X{
	X    struct heads hdr;                  /* file header */
	X int cvt;                           /* true to convert current file */
	X int did[MAXARG];                  /* true when argument was used */
	X int n;                             /* index */
	X    char *makefnam();                  /* filename fixer */
	X    FILE *fopen();                     /* file opener */
	X
	X    if(arctemp)                   /* use temp area if specified */
	X         sprintf(tempname,"%s$ARCTEMP.CVT",arctemp);
	X    else makefnam("$ARCTEMP.CVT",arcname,tempname);
	X
	X    openarc(1);                        /* open archive for changes */
	X
	X    for(n=0; n<num; n++)               /* for each argument */
	X         did[n] = 0;                   /* reset usage flag */
	X    rempath(num,arg);                  /* strip off paths */
	X
	X    if(num)                            /* if files were named */
	X    {    while(readhdr(&hdr,arc))      /* while more files to check */
	X         {    cvt = 0;                 /* reset convert flag */
	X              for(n=0; n<num; n++)     /* for each template given */
	X              {    if(match(hdr.name,arg[n]))
	X                   {    cvt = 1;       /* turn on convert flag */
	X                        did[n] = 1;    /* turn on usage flag */
	X                        break;         /* stop looking */
	X                   }
	X              }
	X
	X              if(cvt)                  /* if converting this one */
	X                   cvtfile(&hdr);      /* then do it */
	X              else                     /* else just copy it */
	X              {    writehdr(&hdr,new);
	X                   filecopy(arc,new,hdr.size);
	X              }
	X         }
	X    }
	X
	X    else while(readhdr(&hdr,arc))      /* else convert all files */
	X         cvtfile(&hdr);
	X
	X    hdrver = 0;                        /* archive EOF type */
	X    writehdr(&hdr,new);                /* write out our end marker */
	X    closearc(1);                       /* close archive after changes */
	X
	X    if(note)
	X    {    for(n=0; n<num; n++)          /* report unused args */
	X         {    if(!did[n])
	X              {    printf("File not found: %s\n",arg[n]);
	X                   nerrs++;
	X              }
	X         }
	X    }
	X}
	X
	Xstatic cvtfile(hdr)                    /* convert a file */
	Xstruct heads *hdr;                     /* pointer to header data */
	X{
	X    long starts, ftell();              /* where the file goes */
	X    FILE *tmp, *fopen();               /* temporary file */
	X
	X    if(!(tmp=fopen(tempname,"wrb")))
	X         abort("Unable to create temporary file %s",tempname);
	X
	X    if(note)
	X         printf("Converting file: %-12s   reading, ",hdr->name);
	X
	X    unpack(arc,tmp,hdr);               /* unpack the entry */
	X    fseek(tmp,0L,0);                   /* reset temp for reading */
	X
	X    starts = ftell(new);               /* note where header goes */
	X    hdrver = ARCVER;                  /* anything but end marker */
	X    writehdr(hdr,new);                 /* write out header skeleton */
	X    pack(tmp,new,hdr);                 /* pack file into archive */
	X    fseek(new,starts,0);               /* move back to header skeleton */
	X    writehdr(hdr,new);                 /* write out real header */
	X    fseek(new,hdr->size,1);            /* skip over data to next header */
	X    fclose(tmp);                       /* all done with the file */
	X    if(unlink(tempname) && warn)
	X    {    printf("Cannot unsave %s\n",tempname);
	X         nerrs++;
	X    }
	X}
SHAR_EOF
if test 4450 -ne "`wc -c < 'arccvt.c'`"
then
	echo shar: "error transmitting 'arccvt.c'" '(should have been 4450 characters)'
fi
fi
echo shar: "extracting 'arcdel.c'" '(2914 characters)'
if test -f 'arcdel.c'
then
	echo shar: "will not over-write existing file 'arcdel.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcdel.c'
	Xstatic char *RCSid = "$Header: arcdel.c,v 1.2 86/07/15 07:52:53 turner Exp $";
	X
	X/*
	X * $Log:	arcdel.c,v $
	X * Revision 1.2  86/07/15  07:52:53  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:00:04  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCDEL
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =2.09), created on $tag(
	XTED_DATE DB =02/03/86) at $tag(
	XTED_TIME DB =22:53:27))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains the routines used to delete entries
	X         in an archive.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	Xdelarc(num,arg)                        /* remove files from archive */
	Xint num;                               /* number of arguments */
	Xchar *arg[];                           /* pointers to arguments */
	X{
	X    struct heads hdr;                  /* header data */
	X int del;                           /* true to delete a file */
	X int did[MAXARG];                  /* true when argument used */
	X int n;                             /* index */
	X
	X    if(!num)                           /* she must specify which */
	X         abort("You must tell me which files to delete!");
	X
	X    for(n=0; n<num; n++)               /* for each argument */
	X         did[n] = 0;                   /* reset usage flag */
	X    rempath(num,arg);                  /* strip off paths */
	X
	X    openarc(1);                        /* open archive for changes */
	X
	X    while(readhdr(&hdr,arc))           /* while more entries in archive */
	X    {    del = 0;                      /* reset delete flag */
	X         for(n=0; n<num; n++)          /* for each template given */
	X         {    if(match(hdr.name,arg[n]))
	X              {    del = 1;            /* turn on delete flag */
	X                   did[n] = 1;         /* turn on usage flag */
	X                   break;              /* stop looking */
	X              }
	X         }
	X
	X         if(del)                       /* skip over unwanted files */
	X         {    fseek(arc,hdr.size,1);
	X              if(note)
	X                   printf("Deleting file: %s\n",hdr.name);
	X         }
	X         else                          /* else copy over file data */
	X         {    writehdr(&hdr,new);      /* write out header and file */
	X              filecopy(arc,new,hdr.size);
	X         }
	X    }
	X
	X    hdrver = 0;                        /* special end of archive type */
	X    writehdr(&hdr,new);                /* write out archive end marker */
	X    closearc(1);                       /* close archive after changes */
	X
	X    if(note)
	X    {    for(n=0; n<num; n++)          /* report unused arguments */
	X         {    if(!did[n])
	X              {    printf("File not found: %s\n",arg[n]);
	X                   nerrs++;
	X              }
	X         }
	X    }
	X}
SHAR_EOF
if test 2914 -ne "`wc -c < 'arcdel.c'`"
then
	echo shar: "error transmitting 'arcdel.c'" '(should have been 2914 characters)'
fi
fi
echo shar: "extracting 'arcdir.c'" '(8244 characters)'
if test -f 'arcdir.c'
then
	echo shar: "will not over-write existing file 'arcdir.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcdir.c'
	Xstatic char *RCSid = "$Header: arcdir.c,v 1.2 86/07/15 07:52:56 turner Exp $";
	X
	X/*
	X * $Log:	arcdir.c,v $
	X * Revision 1.2  86/07/15  07:52:56  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:00:12  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCDIR
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X
	X#if MSDOS
	X#include <dir.h>
	X#endif
	X
	X#if BSD
	X#include <sys/types.h>
	X#include <sys/dir.h>
	X#endif
	X
	Xchar *pattern;			      /* global so that fmatch can use them */
	Xint filemode;
	X
	Xchar *dir(filename,mode)               /* get files, one by one */
	Xchar *filename;                        /* template, or NULL */
	Xint mode;                              /* search mode bits */
	X{
	X	struct direct *(*namelist[]);
	X	int alphasort(), fmatch();
	X	static int num = 0,ii;
	X	char *result;
	X
	X	pattern = filename;
	X	filemode = mode;		/* set up globals for fmatch */
	X	if(num == 0) { /* first call */
	X		num = scandir(".", namelist, fmatch, alphasort);
	X		ii = 0;
	X	}
	X	if(ii >= num) { /* all out of files */
	X		if(num) /* there were some files found */
	X		    freedir(namelist);
	X		num = 0;
	X		return(NULL);
	X	}
	X	else {
	X		result = (char *)malloc(strlen((*namelist)[ii]->d_name)+1);
	X		strcpy(result,(*namelist)[ii++]->d_name);
	X		return(&result[0]);
	X	}
	X}
	X
	X
	X#define ASTERISK '*'		/* The '*' metacharacter */
	X#define QUESTION '?'		/* The '?' metacharacter */
	X#define LEFT_BRACKET '['	/* The '[' metacharacter */
	X#define RIGHT_BRACKET ']'	/* The ']' metacharacter */
	X
	X#define IS_OCTAL(ch) (ch >= '0' && ch <= '7')
	X
	Xtypedef int BOOLEAN;
	X#define VOID int
	X#define TRUE 1
	X#define FALSE 0
	X#define EOS '\000'
	X
	Xstatic BOOLEAN do_list ();
	Xstatic char nextch ();
	Xstatic VOID list_parse ();
	X
	X
	X/*
	X *  FUNCTION
	X *
	X *	match   test string for wildcard match
	X *
	X *  SYNOPSIS
	X *
	X *	BOOLEAN match (string, pattern)
	X *	register char *string;
	X *	register char *pattern;
	X *
	X *  DESCRIPTION
	X *
	X *	Test string for match using pattern.  The pattern may
	X *	contain the normal shell metacharacters for pattern
	X *	matching.  The '*' character matches any string,
	X *	including the null string.  The '?' character matches
	X *	any single character.  A list of characters enclosed
	X *	in '[' and ']' matches any character in the list.
	X *	If the first character following the beginning '['
	X *	is a '!' then any character not in the list is matched.
	X *
	X */
	X
	X
	X/*
	X *  PSEUDO CODE
	X *
	X *	Begin match
	X *	    Switch on type of pattern character
	X *		Case ASTERISK:
	X *		    Attempt to match asterisk
	X *		    Break
	X *		Case QUESTION MARK:
	X *		    Attempt to match question mark
	X *		    Break
	X *		Case EOS:
	X *		    Match is result of EOS on string test
	X *		    Break
	X *		Case default:
	X *		    If explicit match then
	X *			Match is result of submatch
	X *		    Else
	X *			Match is FALSE
	X *		    End if
	X *		    Break
	X *	    End switch
	X *	    Return result of match test
	X *	End match
	X *
	X */
	X
	Xstatic BOOLEAN match (string, pattern)
	Xregister char *string;
	Xregister char *pattern;
	X{
	X    register BOOLEAN ismatch;
	X
	X    ismatch = FALSE;
	X    switch (*pattern) {
	X	case ASTERISK:
	X	    pattern++;
	X	    do {
	X		ismatch = match (string, pattern);
	X	    } while (!ismatch && *string++ != EOS);
	X	    break;
	X	case QUESTION:
	X	    if (*string != EOS) {
	X		ismatch = match (++string, ++pattern);
	X	    }
	X	    break;
	X	case EOS:
	X	    if (*string == EOS) {
	X		ismatch = TRUE;
	X	    }
	X	    break;
	X	case LEFT_BRACKET:
	X	    if (*string != EOS) {
	X		ismatch = do_list (string, pattern);
	X	    }
	X	    break;
	X	default:
	X	    if (tolower(*string) == tolower(*pattern))
	X	    {
	X	    	string++;
	X	    	pattern++;
	X		ismatch = match (string, pattern);
	X	    } else {
	X		ismatch = FALSE;
	X	    }
	X	    break;
	X    }
	X    return (ismatch);
	X}
	X
	X
	X/*
	X *  FUNCTION
	X *
	X *	do_list    process a list and following substring
	X *
	X *  SYNOPSIS
	X *
	X *	static BOOLEAN do_list (string, pattern)
	X *	register char *string;
	X *	register char *pattern;
	X *
	X *  DESCRIPTION
	X *
	X *	Called when a list is found in the pattern.  Returns
	X *	TRUE if the current character matches the list and
	X *	the remaining substring matches the remaining pattern.
	X *
	X *	Returns FALSE if either the current character fails to
	X *	match the list or the list matches but the remaining
	X *	substring and subpattern's don't.
	X *
	X *  RESTRICTIONS
	X *
	X *	The mechanism used to match characters in an inclusive
	X *	pair (I.E. [a-d]) may not be portable to machines
	X *	in which the native character set is not ASCII.
	X *
	X *	The rules implemented here are:
	X *
	X *		(1)	The backslash character may be
	X *			used to quote any special character.
	X *			I.E.  "\]" and "\-" anywhere in list,
	X *			or "\!" at start of list.
	X *
	X *		(2)	The sequence \nnn becomes the character
	X *			given by nnn (in octal).
	X *
	X *		(3)	Any non-escaped ']' marks the end of list.
	X *
	X *		(4)	A list beginning with the special character
	X *			'!' matches any character NOT in list.
	X *			The '!' character is only special if it
	X *			is the first character in the list.
	X *
	X */
	X
	X
	X/*
	X *  PSEUDO CODE
	X *
	X *	Begin do_list
	X *	    Default result is no match
	X *	    Skip over the opening left bracket
	X *	    If the next pattern character is a '!' then
	X *		List match gives FALSE
	X *		Skip over the '!' character
	X *	    Else
	X *		List match gives TRUE
	X *	    End if
	X *	    While not at closing bracket or EOS
	X *		Get lower and upper bounds
	X *		If character in bounds then
	X *		    Result is same as sense flag.
	X *		    Skip over rest of list
	X *		End if
	X *	    End while
	X *	    If match found then
	X *		If not at end of pattern then
	X *		    Call match with rest of pattern
	X *		End if
	X *	    End if
	X *	    Return match result
	X *	End do_list
	X *
	X */
	X
	Xstatic BOOLEAN do_list (string, pattern)
	Xregister char *string;
	Xchar *pattern;
	X{
	X    register BOOLEAN ismatch;
	X    register BOOLEAN if_found;
	X    register BOOLEAN if_not_found;
	X    auto char lower;
	X    auto char upper;
	X
	X    pattern++;
	X    if (*pattern == '!') {
	X	if_found = FALSE;
	X	if_not_found = TRUE;
	X	pattern++;
	X    } else {
	X	if_found = TRUE;
	X	if_not_found = FALSE;
	X    }
	X    ismatch = if_not_found;
	X    while (*pattern != ']' && *pattern != EOS) {
	X	list_parse (&pattern, &lower, &upper);
	X	if (*string >= lower && *string <= upper) {
	X	    ismatch = if_found;
	X	    while (*pattern != ']' && *pattern != EOS) {pattern++;}
	X	}
	X    }
	X    if (*pattern++ != ']') {
	X	fprintf (stderr, "warning - character class error\n");
	X    } else {
	X	if (ismatch) {
	X	    ismatch = match (++string, pattern);
	X	}
	X    }
	X    return (ismatch);
	X}
	X
	X
	X/*
	X *  FUNCTION
	X *
	X *	list_parse    parse part of list into lower and upper bounds
	X *
	X *  SYNOPSIS
	X *
	X *	static VOID list_parse (patp, lowp, highp)
	X *	char **patp;
	X *	char *lowp;
	X *	char *highp;
	X *
	X *  DESCRIPTION
	X *
	X *	Given pointer to a pattern pointer (patp), pointer to
	X *	a place to store lower bound (lowp), and pointer to a
	X *	place to store upper bound (highp), parses part of
	X *	the list, updating the pattern pointer in the process.
	X *
	X *	For list characters which are not part of a range,
	X *	the lower and upper bounds are set to that character.
	X *
	X */
	X
	Xstatic VOID list_parse (patp, lowp, highp)
	Xchar **patp;
	Xchar *lowp;
	Xchar *highp;
	X{
	X    *lowp = nextch (patp);
	X    if (**patp == '-') {
	X	(*patp)++;
	X	*highp = nextch (patp);
	X    } else {
	X	*highp = *lowp;
	X    }
	X}
	X
	X
	X/*
	X *  FUNCTION
	X *
	X *	nextch    determine next character in a pattern
	X *
	X *  SYNOPSIS
	X *
	X *	static char nextch (patp)
	X *	char **patp;
	X *
	X *  DESCRIPTION
	X *
	X *	Given pointer to a pointer to a pattern, uses the pattern
	X *	pointer to determine the next character in the pattern,
	X *	subject to translation of backslash-char and backslash-octal
	X *	sequences.
	X *
	X *	The character pointer is updated to point at the next pattern
	X *	character to be processed.
	X *
	X */
	X
	Xstatic char nextch (patp)
	Xchar **patp;
	X{
	X    register char ch;
	X    register char chsum;
	X    register int count;
	X
	X    ch = *(*patp)++;
	X    if (ch == '\\') {
	X	ch = *(*patp)++;
	X	if (IS_OCTAL (ch)) {
	X	    chsum = 0;
	X	    for (count = 0; count < 3 && IS_OCTAL (ch); count++) {
	X		chsum *= 8;
	X		chsum += ch - '0';
	X		ch = *(*patp)++;
	X	    }
	X	    (*patp)--;
	X	    ch = chsum;
	X	}
	X    }
	X    return (ch);
	X}
	X
	X/*
	X *	Filename match - here, *.* matches everything
	X */
	X
	XBOOLEAN fmatch (direntry)
	Xstruct direct *direntry;
	X{
	X    char *ptr,*string;
	X
	X    string = direntry->d_name;
	X
	X    if(!strcmp(pattern, "") || !strcmp(pattern, "*.*"))
	X    	return(1);
	X    return(match(string, pattern));
	X}
SHAR_EOF
if test 8244 -ne "`wc -c < 'arcdir.c'`"
then
	echo shar: "error transmitting 'arcdir.c'" '(should have been 8244 characters)'
fi
fi
echo shar: "extracting 'arcdos.c'" '(3211 characters)'
if test -f 'arcdos.c'
then
	echo shar: "will not over-write existing file 'arcdos.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'arcdos.c'
	Xstatic char *RCSid = "$Header: arcdos.c,v 1.2 86/07/15 07:53:02 turner Exp $";
	X
	X/*
	X * $Log:	arcdos.c,v $
	X * Revision 1.2  86/07/15  07:53:02  turner
	X * 
	X * 
	X * Revision 1.1  86/06/26  15:00:15  turner
	X * initial version
	X * 
	X * 
	X */
	X
	X/*  ARC - Archive utility - ARCDOS
	X
	X$define(tag,$$segment(@1,$$index(@1,=)+1))#
	X$define(version,Version $tag(
	XTED_VERSION DB =1.43), created on $tag(
	XTED_DATE DB =11/09/85) at $tag(
	XTED_TIME DB =22:24:44))#
	X$undefine(tag)#
	X    $version
	X
	X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
	X
	X    By:  Thom Henderson
	X
	X    Description:
	X         This file contains certain DOS level routines that assist
	X         in doing fancy things with an archive, primarily reading and
	X         setting the date and time last modified.
	X
	X         These are, by nature, system dependant functions.  But they are
	X         also, by nature, very expendable.
	X
	X    Language:
	X         Computer Innovations Optimizing C86
	X*/
	X#include <stdio.h>
	X#include "arc.h"
	X#if MSDOS
	X#include "fileio2.h"                   /* needed for filehand */
	X#endif
	X#if BSD
	X#include <sys/types.h>
	X#include <sys/stat.h>
	X#endif
	X
	Xgetstamp(f,date,time)                  /* get a file's date/time stamp */
	XFILE *f;                               /* file to get stamp from */
	Xunsigned int *date, *time;             /* storage for the stamp */
	X{
	X#if MSDOS
	X    struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
	X
	X    reg.ax = 0x5700;                   /* get date/time */
	X    reg.bx = filehand(f);              /* file handle */
	X    if(sysint21(&reg,&reg)&1)          /* DOS call */
	X         printf("Get timestamp fail (%d)\n",reg.ax);
	X
	X    *date = reg.dx;                    /* save date/time */
	X    *time = reg.cx;
	X#endif
	X#if BSD
	X    struct stat *buf;
	X    int day,hr,min,sec,yr,imon;
	X    static char mon[4],*mons[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul",
	X					"Aug","Sep","Oct","Nov","Dec"};
	X
	X    buf = (struct stat *)malloc(sizeof(struct stat));
	X    fstat(f->_file,buf); 
	X/*
	X * assume the UGLY ibm format for date and time
	X */
	X    sscanf(ctime(&(buf->st_atime)),"%*4s%3s%d%d:%d:%d%d"
	X	,mon,&day,&hr,&min,&sec,&yr);
	X    for(imon = 0; imon < 12 && strcmp(mon,mons[imon]); imon++);
	X
	X    *date = (unsigned int)(((yr-1980)<<9)+((imon+1)<<5)+day);
	X    *time = (unsigned int)((hr<<11)+(min<<5)+sec/2);
	X#endif
	X}
	X
	Xsetstamp(f,date,time)                  /* set a file's date/time stamp */
	XFILE *f;                               /* file to set stamp on */
	Xunsigned int date, time;               /* desired date, time */
	X{
	X#if MSDOS
	X    struct {int ax,bx,cx,dx,si,di,ds,es;} reg;
	X
	X    fflush(f);                         /* force any pending output */
	X
	X    reg.ax = 0x5701;                   /* set date/time */
	X    reg.bx = filehand(f);              /* file handle */
	X    reg.cx = time;                     /* desired time */
	X    reg.dx = date;                     /* desired date */
	X    if(sysint21(&reg,&reg)&1)          /* DOS call */
	X         printf("Set timestamp fail (%d)\n",reg.ax);
	X#endif
	X}
	X
	Xstatic int filehand(stream)            /* find handle on a file */
	Xstruct bufstr *stream;                 /* file to grab onto */
	X{
	X#if MSDOS
	X    return stream->bufhand;            /* return DOS 2.0 file handle */
	X#endif
	X}
SHAR_EOF
if test 3211 -ne "`wc -c < 'arcdos.c'`"
then
	echo shar: "error transmitting 'arcdos.c'" '(should have been 3211 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(479 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	XCFLAGS = -g
	X#CFLAGS = -O
	X
	XOBJS = arc.o arcadd.o arccode.o arccvt.o arcdel.o arcdir.o \
	Xarcdos.o arcext.o arcio.o arclst.o arclzw.o arcmatch.o arcpack.o arcrun.o \
	Xarcs.o arcsq.o arcsvc.o arctst.o arcunp.o arcusq.o arcvax.o arcmisc.o
	X
	X
	XSRCS = arc.c arcadd.c arccode.c arccvt.c arcdel.c arcdir.c \
	Xarcdos.c arcext.c arcio.c arclst.c arclzw.c arcmatch.c arcpack.c arcrun.c \
	Xarcs.c arcsq.c arcsvc.c arctst.c arcunp.c arcusq.c arcvax.c arcmisc.c
	X
	Xarc:	${OBJS}
	X	cc  -g -o arc ${OBJS}
SHAR_EOF
if test 479 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 479 characters)'
fi
fi
exit 0
#	End of shell archive
-- 
----
	"I ain't gay, but there are sure times when i wish i could say
		that i wasn't straight"

Name:	James M. Turner
Mail:	Imagen Corp. 2650 San Tomas Expressway, P.O. Box 58101
        Santa Clara, CA 95052-8101
AT&T:	(408) 986-9400
UUCP:	...{decvax,ucbvax}!decwrl!imagen!turner
CompuServe: 76327,1575
GEnie     : D-ARCANGEL



More information about the Comp.sources.unix mailing list