/* ARC - Archive utility - ARCDOS Version 1.43, created on 11/09/85 at 22:24:44 (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED By: Thom Henderson Description: This file contains certain DOS level routines that assist in doing fancy things with an archive, primarily reading and setting the date and time last modified. These are, by nature, system dependant functions. But they are also, by nature, very expendable. Language: Computer Innovations Optimizing C86 */ #include #include "arc.h" #include "fileio2.h" /* needed for filehand */ getstamp(f,date,time) /* get a file's date/time stamp */ FILE *f; /* file to get stamp from */ unsigned int *date, *time; /* storage for the stamp */ { struct {int ax,bx,cx,dx,si,di,ds,es;} reg; reg.ax = 0x5700; /* get date/time */ reg.bx = filehand(f); /* file handle */ if(sysint21(®,®)&1) /* DOS call */ printf("Get timestamp fail (%d)\n",reg.ax); *date = reg.dx; /* save date/time */ *time = reg.cx; } setstamp(f,date,time) /* set a file's date/time stamp */ FILE *f; /* file to set stamp on */ unsigned int date, time; /* desired date, time */ { struct {int ax,bx,cx,dx,si,di,ds,es;} reg; fflush(f); /* force any pending output */ reg.ax = 0x5701; /* set date/time */ reg.bx = filehand(f); /* file handle */ reg.cx = time; /* desired time */ reg.dx = date; /* desired date */ if(sysint21(®,®)&1) /* DOS call */ printf("Set timestamp fail (%d)\n",reg.ax); } static int filehand(stream) /* find handle on a file */ struct bufstr *stream; /* file to grab onto */ { return stream->bufhand; /* return DOS 2.0 file handle */ } /* ARC - Archive utility - ARCDIR Version 1.02, created on 02/04/86 at 01:36:09 (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED By: Thom Henderson Description: This file contains the dir() routine used when adding files to an archive. It is an adaptation of the CI-C86 library function filedir(). It differes in that it returns the file names one by one, instead of all at once. Language: Computer Innovations Optimizing C86 */ #include #include static struct { char dummy[21]; /* reserved for dos */ unsigned char attribute; /* returned attribute */ unsigned time; unsigned date; long size; /* size of file */ unsigned char fn[13]; /* string containing the filename */ } ff_area; char *dir(filename) /* get files, one by one */ char *filename; /* template, or NULL */ { struct { int ax,bx,cx,dx,si,di,ds,es; } reg; char *result; static int first = 1; /* true only on first call */ #ifdef _C86_BIG reg.ds = ((unsigned long)filename) >> 16; #else segread(®.si); /* get ds value */ #endif if(filename) /* if filename is given */ { reg.dx = filename; /* then use it */ reg.ax = 0x4e00; /* and search for first */ } else if(first) /* if no name and first call */ return NULL; /* then not much we can do */ else reg.ax = 0x4f00; /* else search for next */ first = 0; /* no longer first time */ reg.cx = 0; /* set search modes */ bdos(0x1a,&ff_area); /* set the transfer address */ if(sysint21(®,®)&1) return NULL; /* no more files */ result = malloc(strlen(ff_area.fn)+1); strcpy(result,ff_area.fn); /* save name of file */ return result; } rempath(nargs,arg) /* remove paths from filenames */ int nargs; /* number of names */ char *arg[]; /* pointers to names */ { char *i; /* string index, reverse indexer */ int n; /* index */ for(n=0; n #include "arc.h" runarc(num,arg) /* run file from archive */ int num; /* number of arguments */ char *arg[]; /* pointers to arguments */ { struct heads hdr; /* file header */ int run; /* true to run current file */ int did[MAXARG]; /* true when argument was used */ int n; /* index */ char *makefnam(); /* filename fixer */ char buf[STRLEN]; /* filename buffer */ for(n=0; nname,buf); if(!strcmp(buf,"$ARCTEMP.BAS")) strcpy(sys,"BASICA $ARCTEMP"); else if(!strcmp(buf,"$ARCTEMP.BAT") || !strcmp(buf,"$ARCTEMP.COM") || !strcmp(buf,"$ARCTEMP.EXE")) strcpy(sys,"$ARCTEMP"); else { if(warn) { printf("File %s is not a .BAS, .BAT, .COM, or .EXE\n", hdr->name); nerrs++; } fseek(arc,hdr->size,1); /* skip this file */ return; } if(!(tmp = opnfilwr(buf))) fatal("Unable to create temporary file %s",buf); if(note) printf("Invoking file: %s\n",hdr->name); dir = getcwd(NULL, 0); /* see where we are */ unpack(arc,tmp,hdr); /* unpack the entry */ fclose(tmp); /* release the file */ system(sys); /* try to invoke it */ chdir(dir); free(dir); /* return to whence we started */ if(remove(buf) && warn) { printf("Cannot unsave temporary file %s\n",buf); nerrs++; } } /* ARC - Archive utility - ARCIO Version 2.50, created on 04/22/87 at 13:25:20 Copyright 1989 Lawrence J. Jones; All Rights Reserved (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED By: Thom Henderson Description: This file contains the file I/O routines used to manipulate an archive. Language: Computer Innovations Optimizing C86 */ #include #include #include "arc.h" int readhdr(hdr,f) /* read a header from an archive */ struct heads *hdr; /* storage for header */ FILE *f; /* archive to read header from */ { char name[FNLEN]; /* filename buffer */ int try = 0; /* retry counter */ static int first = 1; /* true only on first read */ if(!f) /* if archive didn't open */ return 0; /* then pretend it's the end */ if(feof(f)) /* if no more data */ return 0; /* then signal end of archive */ if(getc(f)!=ARCMARK) /* check archive validity */ { if(warn) { printf("An entry in %s has a bad header.",arcname); nerrs++; } while(!feof(f)) { try++; if(getc(f)==ARCMARK) { ungetc(hdrver=getc(f),f); if(hdrver>=0 && hdrver<=ARCVER) break; } } if(feof(f) && first) fatal("%s is not an archive",arcname); if(changing && warn) fatal("%s is corrupted -- changes disallowed",arcname); if(warn) printf(" %d bytes skipped.\n",try); if(feof(f)) return 0; } hdrver = getc(f); /* get header version */ if(hdrver<0) fatal("Invalid header in archive %s",arcname); if(hdrver==0) return 0; /* note our end of archive marker */ if(hdrver>ARCVER) { fread(name,sizeof(char),FNLEN,f); printf("I don't know how to handle file %s in archive %s\n", name,arcname); printf("I think you need a newer version of ARC.\n"); exit(EXIT_FAILURE); } /* amount to read depends on header type */ if(hdrver==1) /* old style is shorter */ { fread(hdr,sizeof(struct heads)-sizeof(long int),1,f); hdrver = 2; /* convert header to new format */ hdr->length = hdr->size; /* size is same when not packed */ } else fread(hdr,sizeof(struct heads),1,f); if(hdr->date>olddate ||(hdr->date==olddate && hdr->time>oldtime)) { olddate = hdr->date; oldtime = hdr->time; } first = 0; return 1; /* we read something */ } writehdr(hdr,f) /* write a header to an archive */ struct heads *hdr; /* header to write */ FILE *f; /* archive to write to */ { putc(ARCMARK,f); /* write out the mark of ARC */ putc(hdrver,f); /* write out the header version */ if(!hdrver) /* if that's the end */ return; /* then write no more */ fwrite(hdr,sizeof(struct heads),1,f); /* note the newest file for updating the archive timestamp */ if(hdr->date>arcdate ||(hdr->date==arcdate && hdr->time>arctime)) { arcdate = hdr->date; arctime = hdr->time; } } putc_tst(c,t) /* put a character, with tests */ int c; /* character to output */ FILE *t; /* file to write to */ { if(t) if(putc(c,t)==EOF) fatal("Write fail (disk full?)"); } /* NOTE: The filecopy() function is used to move large numbers of bytes from one file to another. This particular version has been modified to improve performance in Computer Innovations C86 version 2.3 in the small memory model. It may not work as expected with other compilers or libraries, or indeed with different versions of the CI-C86 compiler and library, or with the same version in a different memory model. The following is a functional equivalent to the filecopy() routine that should work properly on any system using any compiler, albeit at the cost of reduced performance: filecopy(f,t,size) FILE *f, *t; long size; { while(size--) putc_tst(getc(f),t); } */ filecopy(f,t,size) /* bulk file copier */ FILE *f, *t; /* files from and to */ long size; /* bytes to copy */ { char *buf; /* buffer pointer */ unsigned int bufl; /* buffer length */ unsigned int cpy; /* bytes being copied */ long floc, tloc; /* file pointers, setter */ if((bufl=coreleft())<1000) /* see how much space we have */ fatal("Out of memory"); bufl -= 1000; /* fudge factor for overhead */ if(bufl>60000) bufl = 60000; /* avoid choking alloc() */ if(bufl>size) bufl = size; /* avoid wasting space */ while (!(buf = malloc(bufl))) /* allocate our buffer */ { if ((bufl >>= 1) == 0) fatal("Out of memory"); } floc = fseek(f,0L,1); /* reset I/O system */ tloc = fseek(t,0L,1); while(size>0) /* while more to copy */ { cpy = fread(buf, 1, bufl, f); if(cpy == 0) fatal("Read fail"); if(fwrite(buf, 1, cpy, t) != cpy) fatal("Write fail (disk full?)"); size -= (long)cpy; } free(buf); /* all done with buffer */ }