/* ARC - Archive utility - ARCIO (C) COPYRIGHT 1985 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 "arc.h" #if unix extern urdhdr(); extern urdohdr(); extern uwrhdr(); #endif 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(fgetc(f)!=ARCMARK) /* check archive validity */ { if(warn) { printf("An entry in %s has a bad header.",arcname); nerrs++; } while(!feof(f)) { try++; if(fgetc(f)==ARCMARK) { ungetc(hdrver=fgetc(f),f); if(hdrver>=0 && hdrver<=ARCVER) break; } } if(feof(f) && first) abort("%s is not an archive",arcname); if(warn) printf(" %d bytes skipped.\n",try); if(feof(f)) return 0; } hdrver = fgetc(f); /* get header version */ if(hdrver<0) abort("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(1); } /* amount to read depends on header type */ #if unix if(hdrver==1) /* old style is shorter */ { urdohdr(hdr,f); hdrver = 2; /* convert header to new format */ hdr->length = hdr->size; /* size is same when not packed */ } else urdhdr(hdr,f); #else 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); #endif 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 */ { fputc(ARCMARK,f); /* write out the mark of ARC */ fputc(hdrver,f); /* write out the header version */ if(!hdrver) /* if that's the end */ return; /* then write no more */ #if unix uwrhdr(hdr,f); #else fwrite(hdr,sizeof(struct heads),1,f); #endif /* 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; } } filecopy(f,t,size) /* bulk file copier */ FILE *f, *t; /* from, to */ long size; /* number of bytes */ { int len; /* length of a given copy */ while(size--) /* while more bytes to move */ putc_tst(fgetc(f),t); } putc_tst(c,t) /* put a character, with tests */ char c; /* character to output */ FILE *t; /* file to write to */ { if(t) if(fputc(c,t)==EOF) abort("Write fail (disk full?)"); }