home *** CD-ROM | disk | FTP | other *** search
- /* ARC - Archive utility - ARCIO
-
- Version 2.49, created on 07/25/86 at 16:44:23
-
- (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 <stdio.h>
- #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[13]; /* 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)!=26) /* check archive validity */
- { if(warn)
- { printf("An entry in %s has a bad header.",arcname);
- nerrs++;
- }
-
- while(!feof(f))
- { try++;
- if(fgetc(f)==26)
- { ungetc(hdrver=fgetc(f),f);
- if(hdrver>=0 && hdrver<=8)
- 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>8)
- { fread(name,sizeof(char),13,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(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 */
- {
- fputc(26,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 */
- 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 */
- char c; /* character to output */
- FILE *t; /* file to write to */
- {
- if(t)
- if(fputc(c,t)==EOF)
- abort("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(fgetc(f),t);
- }
- */
-
- #include <fileio2.h>
-
- filecopy(f,t,size) /* bulk file copier */
- FILE *f, *t; /* files from and to */
- long size; /* bytes to copy */
- {
- char *buf; /* buffer pointer */
- char *alloc(); /* buffer allocator */
- unsigned int bufl; /* buffer length */
- unsigned int coreleft(); /* space available reporter */
- unsigned int cpy; /* bytes being copied */
- long floc, tloc, fseek(); /* file pointers, setter */
- struct regval reg; /* registers for DOS calls */
-
- if((bufl=coreleft())<1000) /* see how much space we have */
- abort("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 */
- buf = alloc(bufl); /* allocate our buffer */
-
- floc = fseek(f,0L,1); /* reset I/O system */
- tloc = fseek(t,0L,1);
-
- segread(®.si); /* set segment registers for DOS */
-
- while(size>0) /* while more to copy */
- { reg.ax = 0x3F00; /* read from handle */
- reg.bx = filehand(f);
- reg.cx = bufl<size? bufl:size;/* amount to read */
- reg.dx = buf;
- if(sysint21(®,®)&1)
- abort("Read fail");
-
- cpy = reg.ax; /* amount actually read */
- reg.ax = 0x4000; /* write to handle */
- reg.bx = filehand(t);
- reg.cx = cpy;
- reg.dx = buf;
- sysint21(®,®);
-
- if(reg.ax!=cpy)
- abort("Write fail (disk full?)");
-
- size -= (long)cpy;
- }
-
- free(buf); /* all done with buffer */
- }
-