home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / COMPRESS / ARC520S.ZIP / ARCIO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-10-23  |  6.5 KB  |  187 lines

  1. /*  ARC - Archive utility - ARCIO
  2.  
  3.     Version 2.49, created on 07/25/86 at 16:44:23
  4.  
  5. (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  6.  
  7.     By:  Thom Henderson
  8.  
  9.     Description:
  10.          This file contains the file I/O routines used to manipulate
  11.          an archive.
  12.  
  13.     Language:
  14.          Computer Innovations Optimizing C86
  15. */
  16. #include <stdio.h>
  17. #include "arc.h"
  18.  
  19. int readhdr(hdr,f)                     /* read a header from an archive */
  20. struct heads *hdr;                     /* storage for header */
  21. FILE *f;                               /* archive to read header from */
  22. {
  23.     char name[13];                 /* filename buffer */
  24.     int try = 0;                       /* retry counter */
  25.     static int first = 1;              /* true only on first read */
  26.  
  27.     if(!f)                             /* if archive didn't open */
  28.          return 0;                     /* then pretend it's the end */
  29.     if(feof(f))                        /* if no more data */
  30.          return 0;                     /* then signal end of archive */
  31.  
  32.     if(fgetc(f)!=26)             /* check archive validity */
  33.     {    if(warn)
  34.          {    printf("An entry in %s has a bad header.",arcname);
  35.               nerrs++;
  36.          }
  37.  
  38.          while(!feof(f))
  39.          {    try++;
  40.               if(fgetc(f)==26)
  41.               {    ungetc(hdrver=fgetc(f),f);
  42.                    if(hdrver>=0 && hdrver<=8)
  43.                         break;
  44.               }
  45.          }
  46.  
  47.          if(feof(f) && first)
  48.               abort("%s is not an archive",arcname);
  49.  
  50.          if(warn)
  51.               printf("  %d bytes skipped.\n",try);
  52.  
  53.          if(feof(f))
  54.               return 0;
  55.     }
  56.  
  57.     hdrver = fgetc(f);                 /* get header version */
  58.     if(hdrver<0)
  59.          abort("Invalid header in archive %s",arcname);
  60.     if(hdrver==0)
  61.          return 0;                     /* note our end of archive marker */
  62.     if(hdrver>8)
  63.     {    fread(name,sizeof(char),13,f);
  64.          printf("I don't know how to handle file %s in archive %s\n",
  65.               name,arcname);
  66.          printf("I think you need a newer version of ARC.\n");
  67.          exit(1);
  68.     }
  69.  
  70.     /* amount to read depends on header type */
  71.  
  72.     if(hdrver==1)                      /* old style is shorter */
  73.     {    fread(hdr,sizeof(struct heads)-sizeof(long int),1,f);
  74.          hdrver = 2;                   /* convert header to new format */
  75.          hdr->length = hdr->size;      /* size is same when not packed */
  76.     }
  77.     else fread(hdr,sizeof(struct heads),1,f);
  78.  
  79.     if(hdr->date>olddate
  80.     ||(hdr->date==olddate && hdr->time>oldtime))
  81.     {    olddate = hdr->date;
  82.          oldtime = hdr->time;
  83.     }
  84.  
  85.     first = 0; return 1;               /* we read something */
  86. }
  87.  
  88. writehdr(hdr,f)                        /* write a header to an archive */
  89. struct heads *hdr;                     /* header to write */
  90. FILE *f;                               /* archive to write to */
  91. {
  92.     fputc(26,f);                 /* write out the mark of ARC */
  93.     fputc(hdrver,f);                   /* write out the header version */
  94.     if(!hdrver)                        /* if that's the end */
  95.          return;                       /* then write no more */
  96.     fwrite(hdr,sizeof(struct heads),1,f);
  97.  
  98.     /* note the newest file for updating the archive timestamp */
  99.  
  100.     if(hdr->date>arcdate
  101.     ||(hdr->date==arcdate && hdr->time>arctime))
  102.     {    arcdate = hdr->date;
  103.          arctime = hdr->time;
  104.     }
  105. }
  106.  
  107. putc_tst(c,t)                          /* put a character, with tests */
  108. char c;                                /* character to output */
  109. FILE *t;                               /* file to write to */
  110. {
  111.     if(t)
  112.          if(fputc(c,t)==EOF)
  113.               abort("Write fail (disk full?)");
  114. }
  115.  
  116. /*  NOTE:  The filecopy() function is used to move large numbers of bytes
  117.     from one file to another.  This particular version has been modified
  118.     to improve performance in Computer Innovations C86 version 2.3 in the
  119.     small memory model.  It may not work as expected with other compilers
  120.     or libraries, or indeed with different versions of the CI-C86 compiler
  121.     and library, or with the same version in a different memory model.
  122.  
  123.     The following is a functional equivalent to the filecopy() routine that
  124.     should work properly on any system using any compiler, albeit at
  125.     the cost of reduced performance:
  126.  
  127.          filecopy(f,t,size)
  128.          FILE *f, *t;
  129.          long size;
  130.          {
  131.              while(size--)
  132.                   putc_tst(fgetc(f),t);
  133.          }
  134. */
  135.  
  136. #include <fileio2.h>
  137.  
  138. filecopy(f,t,size)                     /* bulk file copier */
  139. FILE *f, *t;                           /* files from and to */
  140. long size;                             /* bytes to copy */
  141. {
  142.     char *buf;                         /* buffer pointer */
  143.     char *alloc();                     /* buffer allocator */
  144.     unsigned int bufl;                 /* buffer length */
  145.     unsigned int coreleft();           /* space available reporter */
  146.     unsigned int cpy;                  /* bytes being copied */
  147.     long floc, tloc, fseek();          /* file pointers, setter */
  148.     struct regval reg;                 /* registers for DOS calls */
  149.  
  150.     if((bufl=coreleft())<1000)         /* see how much space we have */
  151.          abort("Out of memory");
  152.     bufl -= 1000;                      /* fudge factor for overhead */
  153.     if(bufl>60000)
  154.          bufl = 60000;                 /* avoid choking alloc() */
  155.     if(bufl>size)
  156.          bufl = size;                  /* avoid wasting space */
  157.     buf = alloc(bufl);                 /* allocate our buffer */
  158.  
  159.     floc = fseek(f,0L,1);              /* reset I/O system */
  160.     tloc = fseek(t,0L,1);
  161.  
  162.     segread(®.si);                  /* set segment registers for DOS */
  163.  
  164.     while(size>0)                      /* while more to copy */
  165.     {    reg.ax = 0x3F00;              /* read from handle */
  166.          reg.bx = filehand(f);
  167.          reg.cx = bufl<size? bufl:size;/* amount to read */
  168.          reg.dx = buf;
  169.          if(sysint21(®,®)&1)
  170.               abort("Read fail");
  171.  
  172.          cpy = reg.ax;                 /* amount actually read */
  173.          reg.ax = 0x4000;              /* write to handle */
  174.          reg.bx = filehand(t);
  175.          reg.cx = cpy;
  176.          reg.dx = buf;
  177.          sysint21(®,®);
  178.  
  179.          if(reg.ax!=cpy)
  180.               abort("Write fail (disk full?)");
  181.  
  182.          size -= (long)cpy;
  183.     }
  184.  
  185.     free(buf);                         /* all done with buffer */
  186. }
  187.