ewilts%Ins.MRC.AdhocNet.CA%Stasis.MRC.AdhocNet.CA%UNCAEDU.@CORNELLC.CCS.CORNELL.EDU.BITNET (Ed Wilts) (06/24/88)
$Part05: $ File_is="ARCEXT.C" $ Check_Sum_is=890573280 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X/* X$define(arc,$ifdef(xarc,off,on))# macro switch for ARC only code X$define(xarc,$ifdef(xarc,on,off))# macro switch for XARC only code X */ X/* ARC - Archive utility - ARCEXT X X$define(tag,$$segment(@1,$$index(@1,=)+1))# X$define(version,Version $tag( XTED_VERSION DB =2.18), created on $tag( XTED_DATE DB =02/03/86) at $tag( XTED_TIME DB =22:55:19))# 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 extract files from X an archive. X X Language: X Computer Innovations Optimizing C86 X*/ X#include <stdio.h> X#include "arc.h" X#if ARC`009`009`009`009`009/* $emit($arc)# */ XINT extarc(num,arg,prt) /* extract files from archive */ XINT num; /* number of arguments */ Xchar *arg[]; /* pointers to arguments */ XINT prt; /* true if printing */ X#endif`009`009`009`009`009/* $emit($xarc)# */ X#if XARC XINT extarc() /* extract files from archive */ X#endif`009`009`009`009`009/* $emit(on)# */ X{ X struct heads hdr; /* file header */ X#if ARC`009`009`009`009`009/* $emit($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, *malloc(); /* name pointer list, allocator */ X INT n; /* index */ X INT extfile(); X X#if MSDOS X name = malloc(num*sizeof(char *)); /* get storage for name pointers */ X#endif X#if BSD V name = (char **)malloc(num*sizeof(char *)); /* get storage for name pointe Xrs */ X#endif 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`009`009`009`009`009/* $emit(on)# */ X X openarc(0); /* open archive for reading */ X X#if ARC`009`009`009`009`009/* $emit($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`009`009`009`009`009/* $emit($xarc)# */ X#if XARC X while(readhdr(&hdr,arc)) /* extract all files */ X extfile(&hdr); X#endif`009`009`009`009`009/* $emit(on)# */ X X closearc(0); /* close archive after reading */ X#if ARC`009`009`009`009`009/* $emit($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`009`009`009`009`009/* $emit(on)# */ X} X X#if ARC`009`009`009`009`009/* $emit($arc)# */ Xstatic INT 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#endif`009`009`009`009`009/* $emit($xarc)# */ X#if XARC Xstatic INT extfile(hdr) /* extract a file */ X#endif`009`009`009`009`009/* $emit(on)# */ X`009`009`009/* $define(use,$ife($arc,on,fix,hdr->name))# */ X#if ARC X#define USE fix X#else X#define USE hdr->name X#endif X X{ X FILE *f, *fopen(); /* extracted file, opener */ X char buf[STRLEN]; /* input buffer */ X#if ARC`009`009`009`009`009/* $emit($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 strcpy(i+1,hdr->name); /* replace template with name */ X#endif`009`009`009`009`009/* $emit(on)# */ 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 setstamp(f,hdr->date,hdr->time); /* set the proper date/time stamp */ X fclose(f); /* all done writing to file */ X} X $ GoSub Convert_File $ File_is="ARCIO.C" $ Check_Sum_is=322898887 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY Xstatic char *RCSid = "$Header: arcio.c,v 1.2 86/07/15 07:53:11 turner Exp $"; X X/* X * $Log:`009arcio.c,v $ X * Hack-attack 1.3 86/12/20 01:23:45 wilhite@usceast.uucp X * `009Bludgeoned into submission for VAX 11/780 BSD4.2 X *`009(ugly code, but fewer core dumps) X * X * Revision 1.2 86/07/15 07:53:11 turner X * X * X * Revision 1.1 86/06/26 15:00:21 turner X * initial version X * X * X */ X X/* ARC - Archive utility - ARCIO X X$define(tag,$$segment(@1,$$index(@1,=)+1))# X$define(version,Version $tag( XTED_VERSION DB =2.30), created on $tag( XTED_DATE DB =02/03/86) at $tag( XTED_TIME DB =22:56:00))# 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 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 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#if BSD | ST X unsigned char dummy[28]; X`009INT i,j,k; X#endif 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.\n",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(hdrver==1) /* old style is shorter */ X { fread(hdr,sizeof(struct heads)-sizeof(long),1,f); X hdrver = 2; /* convert header to new format */ X hdr->length = hdr->size; /* size is same when not packed */ X } X else { X#if MSDOS X`009fread(hdr,sizeof(struct heads),1,f); X#endif X#if BSD | ST X`009fread(dummy,27,1,f); X X`009for(i=0;i<13;hdr->name[i]=dummy[i],i++); X`009hdr->size = (long)((dummy[16]<<24) + (dummy[15]<<16) + (dummy[14]<<8) X`009 + dummy[13]); X`009hdr->date = (short)((dummy[18]<<8) + dummy[17]); X`009hdr->time = (short)((dummy[20]<<8) + dummy[19]); X`009hdr->crc = (short)((dummy[22]<<8) + dummy[21]); X`009hdr->length = (long)((dummy[26]<<24) + (dummy[25]<<16) X`009 + (dummy[24]<<8) + dummy[23]); X#endif X } X X first = 0; return 1; /* we read something */ X} X XINT writehdr(hdr,f) /* write a header to an archive */ Xstruct heads *hdr; /* header to write */ XFILE *f; /* archive to write to */ X{ X unsigned char dummy[28]; 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 MSDOS X fwrite(hdr,sizeof(struct heads),1,f); X#endif X#if BSD | ST X/* X * put out the hdr in the brain damaged unaligned half back *sswards X * way HAL does it X */ X fwrite(hdr->name,1,13,f); X fwrite(&hdr->size,sizeof(long),1,f); X fwrite(&hdr->date,sizeof(INT),1,f); X fwrite(&hdr->time,sizeof(INT),1,f); X fwrite(&hdr->crc ,sizeof(INT),1,f); X fwrite(&hdr->length,sizeof(long),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 XINT filecopy(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 INT putc_tst(); X X while(size--) /* while more bytes to move */ X putc_tst(fgetc(f),t); X} X XINT putc_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 MSDOS | ST X if(fputc(c,t)==EOF) X abort("Write fail (disk full?)"); X#endif X#if BSD X/* X * for reasons beyond me BSD unix returns EOF X */ X`009fputc(c,t); X#endif X} X $ GoSub Convert_File $ Goto Part06