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}