[net.sources] arc.shar.02

stu@jpusa1.UUCP (Stu Heiss) (09/30/86)

#! /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:
#	Makefile
#	arc.c
#	arc.h
#	arcadd.c
#	arccode.c
#	arccvt.c
#	arcdel.c
#	arcext.c
#	arcio.c
# This archive created: Tue Sep 30 11:44:14 1986
# By:	stu (JPUSA - Chicago, IL)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "x - 'Makefile'"
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOFMakefile > 'Makefile'
X# Makefile for arc and xarc.  Doesn't do marc at present.
X# common src
XSRC=arcadd.c arccode.c arccvt.c arcdel.c arcio.c arclst.c arclzw.c arcmatch.c arcpack.c arcrun.c arcsq.c arcsvc.c arctst.c arcunp.c arcusq.c
X
X# common obj
XOBJ=arcadd.o arccode.o arccvt.o arcdel.o arcio.o arclst.o arclzw.o arcmatch.o arcpack.o arcrun.o arcsq.o arcsvc.o arctst.o arcunp.o arcusq.o
X
X# for unix
XUSRC=arcunix.c tm_to_time.c
XUOBJ=arcunix.o tm_to_time.o
X
X# for dos
XDSRC=arcdir.c arcdos.c
XDOBJ=arcdir.o arcdos.o
X
X# choose one pair
XSRCS=$(SRC) $(USRC)
XOBJS=$(OBJ) $(UOBJ)
X# SRCS=$(SRC) $(DSRC)
X# OBJS=$(OBJ) $(DOBJ)
X
XHEADERS=arc.h arcs.h
X
XAOBJ=$(OBJS) arc.o aarcext.o
XXOBJ=$(OBJS) xarc.o xarcext.o
X
XCFLAGS=-DSYS5 -O
X
XSHAR=shar -c -p X
X
Xarc:	$(AOBJ)
X	cc -o arc $(AOBJ)
X
Xaarcext.o:	arcext.c
X	cc $(CFLAGS) -c -DARC arcext.c
X	mv arcext.o aarcext.o
X
Xxarc:	$(XOBJ)
X	cc -o xarc $(XOBJ)
X
Xxarcext.o:	arcext.c
X	cc $(CFLAGS) -c -DXARC arcext.c
X	mv arcext.o xarcext.o
X
Xshar:
X	cat README > arc.shar.01
X	$(SHAR) Makefile arc.c arc.h arcadd.c arccode.c arccvt.c arcdel.c arcext.c arcio.c > arc.shar.02
X	$(SHAR) arclst.c arclzw.c arcmatch.c arcpack.c arcrun.c arcs.h > arc.shar.03
X	$(SHAR) arcsq.c arcsvc.c arctst.c arcunix.c arcunp.c arcusq.c marc.c tm_to_time.c xarc.c > arc.shar.04
SHAR_EOFMakefile
if test 1248 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 1248 characters)'
fi
fi
echo shar: "x - 'arc.c'"
if test -f 'arc.c'
then
	echo shar: "will not over-write existing file 'arc.c'"
else
sed 's/^X//' << \SHAR_EOFarc.c > 'arc.c'
X#define MAIN
X/*  ARC - Archive utility
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
X#if unix
Xchar *Progname;
X#endif
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 *getenv();                   /* environment searcher */
X    int n;                             /* argument index */
X
X    if(num<3)
X    {    printf("ARC - Archive utility, %s\n",VERSION);
X         printf("(C) COPYRIGHT 1985,86 by System Enhancement Associates;");
X         printf(" ALL RIGHTS RESERVED\n\n");
X#if 0
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#endif 0
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 = getenv("ARCTEMP")))
X         arctemp = getenv("TEMP");
X
X    /* avoid any case problems with arguments */
X
X#if unix
X    Progname = arg[0];
X    upper(arg[1]);
X#else
X    for(n=1; n<num; n++)               /* for each argument */
X         upper(arg[n]);                /* convert it to uppercase */
X#endif
X
X    /* create archive names, supplying defaults */
X
X    makefnam(arg[2],".ARC",arcname);
X#if unix
X    makefnam(arcname,".$$$",newname);
X#else
X    makefnam(arcname,".$$$$",newname);
X#endif
X    makefnam(arcname,".BAK",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_EOFarc.c
if test 9133 -ne "`wc -c < 'arc.c'`"
then
	echo shar: "error transmitting 'arc.c'" '(should have been 9133 characters)'
fi
fi
echo shar: "x - 'arc.h'"
if test -f 'arc.h'
then
	echo shar: "will not over-write existing file 'arc.h'"
else
sed 's/^X//' << \SHAR_EOFarc.h > 'arc.h'
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#ifdef SYS5
X#define index strchr
X#define rindex strrchr
X#endif SYS5
X
X#if unix
X#define alloc xalloc
X#define realloc xrealloc
X#if m68000
Xtypedef long int int32_t;
Xtypedef short int int16_t;
Xtypedef unsigned short int uint16_t;
X#else	/* not m68000 */
Xput apropriate typedefs here
X#endif m68000
X#else	/* not unix, assume C86 */
Xtypedef long int int32_t;
Xtypedef int int16_t;
Xtypedef unsigned int uint16_t;
X#endif unix
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#include "arcs.h"
X
X#ifndef MAIN
X#define EXTERN extern
XEXTERN char VERSION[];
X#else
X#define EXTERN /**/
XEXTERN char VERSION[] = "Version 5.12 created on 02/05/86 at 22:22:01";
X#endif MAIN
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 */
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 */
X
SHAR_EOFarc.h
if test 2434 -ne "`wc -c < 'arc.h'`"
then
	echo shar: "error transmitting 'arc.h'" '(should have been 2434 characters)'
fi
fi
echo shar: "x - 'arcadd.c'"
if test -f 'arcadd.c'
then
	echo shar: "will not over-write existing file 'arcadd.c'"
else
sed 's/^X//' << \SHAR_EOFarcadd.c > 'arcadd.c'
X/*  ARC - Archive utility - ARCADD
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 *alloc(), *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	      if(path == NULL)
X	      path = (char **)alloc(nfiles*sizeof(char **));
X	      else
X	      path = (char **)realloc((char *)path,nfiles*sizeof(char **));
X	      if(name == NULL)
X	      name = (char **)alloc(nfiles*sizeof(char **));
X	      else
X	      name = (char **)realloc((char *)name,nfiles*sizeof(char **));
X              strcpy(i,d);             /* put name in path */
X              path[nfiles-1] = alloc(strlen(buf)+1);
X              strcpy(path[nfiles-1],buf);
X              name[nfiles-1] = d;      /* save name */
X
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         }
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,"r")))
X    {    if(warn)
X         {    printf("Cannot read file: %s\n",path);
X              nerrs++;
X         }
X         return;
X    }
X
X#if unix
X    upper(name);
X#endif
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#if unix
X    getstamp(path,&nhdr.date,&nhdr.time);
X#else
X    getstamp(f,&nhdr.date,&nhdr.time);
X#endif
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_EOFarcadd.c
if test 10681 -ne "`wc -c < 'arcadd.c'`"
then
	echo shar: "error transmitting 'arcadd.c'" '(should have been 10681 characters)'
fi
fi
echo shar: "x - 'arccode.c'"
if test -f 'arccode.c'
then
	echo shar: "will not over-write existing file 'arccode.c'"
else
sed 's/^X//' << \SHAR_EOFarccode.c > 'arccode.c'
X/*  ARC - Archive utility - ARCCODE
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_EOFarccode.c
if test 1340 -ne "`wc -c < 'arccode.c'`"
then
	echo shar: "error transmitting 'arccode.c'" '(should have been 1340 characters)'
fi
fi
echo shar: "x - 'arccvt.c'"
if test -f 'arccvt.c'
then
	echo shar: "will not over-write existing file 'arccvt.c'"
else
sed 's/^X//' << \SHAR_EOFarccvt.c > 'arccvt.c'
X/*  ARC - Archive utility - ARCCVT
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,"w+")))
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_EOFarccvt.c
if test 4025 -ne "`wc -c < 'arccvt.c'`"
then
	echo shar: "error transmitting 'arccvt.c'" '(should have been 4025 characters)'
fi
fi
echo shar: "x - 'arcdel.c'"
if test -f 'arcdel.c'
then
	echo shar: "will not over-write existing file 'arcdel.c'"
else
sed 's/^X//' << \SHAR_EOFarcdel.c > 'arcdel.c'
X/*  ARC - Archive utility - ARCDEL
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_EOFarcdel.c
if test 2489 -ne "`wc -c < 'arcdel.c'`"
then
	echo shar: "error transmitting 'arcdel.c'" '(should have been 2489 characters)'
fi
fi
echo shar: "x - 'arcext.c'"
if test -f 'arcext.c'
then
	echo shar: "will not over-write existing file 'arcext.c'"
else
sed 's/^X//' << \SHAR_EOFarcext.c > 'arcext.c'
X/*  ARC - Archive utility - ARCEXT
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 extract files from
X         an archive.
X
X    Language:
X         Computer Innovations Optimizing C86
X*/
X#include <stdio.h>
X#include "arc.h"
X
X#ifdef ARC
Xextarc(num,arg,prt)                    /* extract files from archive */
Xint num;                               /* number of arguments */
Xchar *arg[];                           /* pointers to arguments */
Xint prt;                               /* true if printing */
X#endif ARC
X#ifdef XARC
Xextarc()                               /* extract files from archive */
X#endif XARC
X{
X    struct heads hdr;                  /* file header */
X#ifdef ARC
X    int save;                          /* true to save current file */
X    int did[MAXARG];                  /* true when argument was used */
X    char *i, *rindex();                /* string index */
X    char **name, *alloc();             /* name pointer list, allocator */
X    int n;                             /* index */
X
X    name = (char **)alloc(num*sizeof(char *));  /* get storage for name pointers */
X
X    for(n=0; n<num; n++)               /* for each argument */
X    {    did[n] = 0;                   /* reset usage flag */
X         if(!(i=rindex(arg[n],'\\')))  /* find start of name */
X              if(!(i=rindex(arg[n],'/')))
X                   if(!(i=rindex(arg[n],':')))
X                        i = arg[n]-1;
X         name[n] = i+1;
X    }
X
X#endif ARC
X
X    openarc(0);                        /* open archive for reading */
X
X#ifdef ARC
X    if(num)                            /* if files were named */
X    {    while(readhdr(&hdr,arc))      /* while more files to check */
X         {    save = 0;                /* reset save flag */
X              for(n=0; n<num; n++)     /* for each template given */
X              {    if(match(hdr.name,name[n]))
X                   {    save = 1;      /* turn on save flag */
X                        did[n] = 1;    /* turn on usage flag */
X                        break;         /* stop looking */
X                   }
X              }
X
X              if(save)                 /* extract if desired, else skip */
X                   extfile(&hdr,arg[n],prt);
X              else fseek(arc,hdr.size,1);
X         }
X    }
X
X    else while(readhdr(&hdr,arc))      /* else extract all files */
X         extfile(&hdr,"",prt);
X#endif ARC
X#ifdef XARC
X    while(readhdr(&hdr,arc))           /* extract all files */
X         extfile(&hdr);
X#endif XARC
X
X    closearc(0);                       /* close archive after reading */
X#ifdef ARC
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    free(name);
X#endif ARC
X}
X
X#ifdef ARC
Xstatic extfile(hdr,path,prt)           /* extract a file */
Xstruct heads *hdr;                     /* pointer to header data */
Xchar *path;                            /* pointer to path name */
Xint prt;                               /* true if printing */
X#define USE fix
X#endif ARC
X#ifdef XARC
Xstatic extfile(hdr)                    /* extract a file */
X#define USE hdr->name
X#endif XARC
X{
X    FILE *f, *fopen();                 /* extracted file, opener */
X    char buf[STRLEN];                 /* input buffer */
X#ifdef ARC
X    char fix[STRLEN];                 /* fixed name buffer */
X    char *i, *rindex();                /* string index */
X
X    if(prt)                            /* printing is much easier */
X    {    unpack(arc,stdout,hdr);       /* unpack file from archive */
X         printf("\f");                 /* eject the form */
X         return;                       /* see? I told you! */
X    }
X
X    strcpy(fix,path);                  /* note path name template */
X    if(!(i=rindex(fix,'\\')))          /* find start of name */
X         if(!(i=rindex(fix,'/')))
X              if(!(i=rindex(fix,':')))
X                   i = fix-1;
X#if unix
X    lower(hdr->name);
X#endif
X    strcpy(i+1,hdr->name);             /* replace template with name */
X#endif ARC
X#ifdef XARC
X#if unix
X    lower(hdr->name);
X#endif
X#endif XARC
X
X    if(note)
X         printf("Extracting file: %s\n",USE);
X
X    if(warn)
X    {    if(f=fopen(USE,"r"))        /* see if it exists */
X         {    fclose(f);
X              printf("WARNING: File %s already exists!",USE);
X              while(1)
X              {    printf("  Overwrite it (y/n)? ");
X                   fgets(buf,STRLEN,stdin);
X                   *buf = toupper(*buf);
X                   if(*buf=='Y' || *buf=='N')
X                        break;
X              }
X              if(*buf=='N')
X              {    printf("%s not extracted.\n",USE);
X                   fseek(arc,hdr->size,1);
X                   return;
X              }
X         }
X    }
X
X    if(!(f=fopen(USE,"w")))
X    {    if(warn)
X         {    printf("Cannot create %s\n",USE);
X              nerrs++;
X         }
X         fseek(arc,hdr->size,1);
X         return;
X    }
X
X    /* now unpack the file */
X
X    unpack(arc,f,hdr);                 /* unpack file from archive */
X#if unix
X    fclose(f);                         /* all done writing to file */
X    setstamp(USE,hdr->date,hdr->time);   /* set the proper date/time stamp */
X#else
X    setstamp(f,hdr->date,hdr->time);   /* set the proper date/time stamp */
X    fclose(f);                         /* all done writing to file */
X#endif
X}
SHAR_EOFarcext.c
if test 5535 -ne "`wc -c < 'arcext.c'`"
then
	echo shar: "error transmitting 'arcext.c'" '(should have been 5535 characters)'
fi
fi
echo shar: "x - 'arcio.c'"
if test -f 'arcio.c'
then
	echo shar: "will not over-write existing file 'arcio.c'"
else
sed 's/^X//' << \SHAR_EOFarcio.c > 'arcio.c'
X/*  ARC - Archive utility - ARCIO
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 file I/O routines used to manipulate
X         an archive.
X
X    Language:
X         Computer Innovations Optimizing C86
X*/
X#include <stdio.h>
X#include "arc.h"
X#if unix
Xextern urdhdr();
Xextern urdohdr();
Xextern uwrhdr();
X#endif
X
Xint readhdr(hdr,f)                     /* read a header from an archive */
Xstruct heads *hdr;                     /* storage for header */
XFILE *f;                               /* archive to read header from */
X{
X    char name[FNLEN];                 /* filename buffer */
X    int try = 0;                       /* retry counter */
X    static int first = 1;              /* true only on first read */
X
X    if(!f)                             /* if archive didn't open */
X         return 0;                     /* then pretend it's the end */
X    if(feof(f))                        /* if no more data */
X         return 0;                     /* then signal end of archive */
X
X    if(fgetc(f)!=ARCMARK)             /* check archive validity */
X    {    if(warn)
X         {    printf("An entry in %s has a bad header.",arcname);
X              nerrs++;
X         }
X
X         while(!feof(f))
X         {    try++;
X              if(fgetc(f)==ARCMARK)
X              {    ungetc(hdrver=fgetc(f),f);
X                   if(hdrver>=0 && hdrver<=ARCVER)
X                        break;
X              }
X         }
X
X         if(feof(f) && first)
X              abort("%s is not an archive",arcname);
X
X         if(warn)
X              printf("  %d bytes skipped.\n",try);
X
X         if(feof(f))
X              return 0;
X    }
X
X    hdrver = fgetc(f);                 /* get header version */
X    if(hdrver<0)
X         abort("Invalid header in archive %s",arcname);
X    if(hdrver==0)
X         return 0;                     /* note our end of archive marker */
X    if(hdrver>ARCVER)
X    {    fread(name,sizeof(char),FNLEN,f);
X         printf("I don't know how to handle file %s in archive %s\n",
X              name,arcname);
X         printf("I think you need a newer version of ARC.\n");
X         exit(1);
X    }
X
X    /* amount to read depends on header type */
X
X#if unix
X    if(hdrver==1)                      /* old style is shorter */
X    {
X	 urdohdr(hdr,f);
X         hdrver = 2;                   /* convert header to new format */
X         hdr->length = hdr->size;      /* size is same when not packed */
X    }
X    else urdhdr(hdr,f);
X#else
X    if(hdrver==1)                      /* old style is shorter */
X    {    fread(hdr,sizeof(struct heads)-sizeof(long int),1,f);
X         hdrver = 2;                   /* convert header to new format */
X         hdr->length = hdr->size;      /* size is same when not packed */
X    }
X    else fread(hdr,sizeof(struct heads),1,f);
X#endif
X
X    first = 0; return 1;               /* we read something */
X}
X
Xwritehdr(hdr,f)                        /* write a header to an archive */
Xstruct heads *hdr;                     /* header to write */
XFILE *f;                               /* archive to write to */
X{
X    fputc(ARCMARK,f);                 /* write out the mark of ARC */
X    fputc(hdrver,f);                   /* write out the header version */
X    if(!hdrver)                        /* if that's the end */
X         return;                       /* then write no more */
X#if unix
X    uwrhdr(hdr,f);
X#else
X    fwrite(hdr,sizeof(struct heads),1,f);
X#endif
X
X    /* note the newest file for updating the archive timestamp */
X
X    if(hdr->date>arcdate
X    ||(hdr->date==arcdate && hdr->time>arctime))
X    {    arcdate = hdr->date;
X         arctime = hdr->time;
X    }
X}
X
Xfilecopy(f,t,size)                     /* bulk file copier */
XFILE *f, *t;                           /* from, to */
Xlong size;                             /* number of bytes */
X{
X    int len;                           /* length of a given copy */
X
X    while(size--)                      /* while more bytes to move */
X         putc_tst(fgetc(f),t);
X}
X
Xputc_tst(c,t)                          /* put a character, with tests */
Xchar c;                                /* character to output */
XFILE *t;                               /* file to write to */
X{
X    if(t)
X         if(fputc(c,t)==EOF)
X              abort("Write fail (disk full?)");
X}
SHAR_EOFarcio.c
if test 4343 -ne "`wc -c < 'arcio.c'`"
then
	echo shar: "error transmitting 'arcio.c'" '(should have been 4343 characters)'
fi
fi
exit 0
#	End of shell archive
-- 
Stu Heiss {ihnp4!jpusa1!stu}