home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / unix / arcunx11 / arc.sh1 / arcio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-01  |  5.4 KB  |  167 lines

  1. /*
  2.  *    arcio.c    1.1
  3.  *
  4.  *    Author: Thom Henderson
  5.  *    Original System V port: Mike Stump
  6.  *    Enhancements, Bug fixes, and cleanup: Chris Seaman
  7.  *    Date: Fri Mar 20 09:57:02 1987
  8.  *    Last Mod.    3/21/87
  9.  *
  10.  */
  11.  
  12. /*
  13.  * ARC - Archive utility - ARCIO
  14.  * 
  15.  * Version 2.30, created on 02/03/86 at 22:56:00
  16.  * 
  17.  * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  18.  * 
  19.  *     Description:
  20.  *          This file contains the file I/O routines used to manipulate
  21.  *          an archive.
  22.  */
  23.  
  24. #include "arc.h"
  25.  
  26. INT readhdr(hdr,f)                     /* read a header from an archive */
  27. struct heads *hdr;                     /* storage for header */
  28. FILE *f;                               /* archive to read header from */
  29. {
  30.     INT i;                             /* misc. variables */
  31.     int fnlen = (ibmpc) ? FNLEN2 : FNLEN1; /* file name length */
  32.     unsigned char dummy[30];           /* dummy array for header storage */
  33.     char name[FNLEN1];                 /* filename buffer */
  34.     INT try = 0;                       /* retry counter */
  35.     static INT first = 1;              /* true only on first read */
  36.  
  37.     if (!f)                            /* if archive didn't open */
  38.         return(0);                     /* then pretend it's the end */
  39.     if (feof(f))                       /* if no more data */
  40.         return(0);                     /* then signal end of archive */
  41.  
  42.     if (fgetc(f)!=ARCMARK)             /* check archive validity */
  43.     {
  44.         if (warn)
  45.         {
  46.             printf("An entry in %s has a bad header.\n",arcname);
  47.             nerrs++;
  48.         }
  49.  
  50.         while (!feof(f))
  51.         {
  52.             try++;
  53.             if (fgetc(f)==ARCMARK)
  54.             {
  55.                 ungetc(hdrver=fgetc(f),f);
  56.                 if (hdrver>=0 && hdrver<=ARCVER)
  57.                     break;
  58.             }
  59.         }
  60.  
  61.         if (feof(f) && first)
  62.             abort("%s is not an archive",arcname);
  63.  
  64.         if (warn)
  65.             printf("  %d bytes skipped.\n",try);
  66.  
  67.         if (feof(f))
  68.             return(0);
  69.     }
  70.  
  71.     hdrver = fgetc(f);                 /* get header version */
  72.     if (hdrver<0)
  73.         abort("Invalid header in archive %s",arcname);
  74.     if (hdrver==0)
  75.         return(0);                     /* note our end of archive marker */
  76.     if (hdrver>ARCVER)
  77.     {
  78.         fread(name,sizeof(char),fnlen,f);
  79.         printf("I don't know how to handle file %s in archive %s\n",
  80.             name,arcname);
  81.         printf("I think you need a newer version of ARC.\n");
  82.         abort("Archive error");
  83.     }
  84.  
  85.     /* amount to read depends on header type */
  86.  
  87.     if (hdrver==1)                     /* old style is shorter */
  88.     {
  89.         fread(hdr,sizeof(struct heads)-sizeof(long),1,f);
  90.         hdrver = 2;                    /* convert header to new format */
  91.         hdr->length = hdr->size;       /* size is same when not packed */
  92.     }
  93.     else
  94.     {
  95.         fread(dummy,fnlen+14,1,f);
  96.  
  97.         for (i=0;i<FNLEN1;hdr->name[i]='\0',i++);
  98.         for (i=0;i<fnlen;hdr->name[i]=dummy[i],i++);
  99.         hdr->size = (long)((dummy[fnlen+3]<<24) + (dummy[fnlen+2]<<16)
  100.             + (dummy[fnlen+1]<<8) + dummy[fnlen]);
  101.         hdr->date = (short)((dummy[fnlen+5]<<8) + dummy[fnlen+4]);
  102.         hdr->time = (short)((dummy[fnlen+7]<<8) + dummy[fnlen+6]);
  103.         hdr->crc  = (short)((dummy[fnlen+9]<<8) + dummy[fnlen+8]);
  104.         hdr->length = (long)((dummy[fnlen+13]<<24) + (dummy[fnlen+12]<<16)
  105.             + (dummy[fnlen+11]<<8) + dummy[fnlen+10]);
  106.     }
  107.  
  108.     first = 0;
  109.     return(1);                         /* we read something */
  110. }
  111.  
  112. INT writehdr(hdr,f)                    /* write a header to an archive */
  113. struct heads *hdr;                     /* header to write */
  114. FILE *f;                               /* archive to write to */
  115. {
  116.     int i;
  117.     int fnlen = (ibmpc) ? FNLEN2 : FNLEN1; /* file name length */
  118.  
  119.     fputc(ARCMARK,f);                  /* write out the mark of ARC */
  120.     fputc(hdrver,f);                   /* write out the header version */
  121.     if (!hdrver)                       /* if that's the end */
  122.         return;                        /* then write no more */
  123.  
  124.     for (i = strlen(hdr->name);i < fnlen;i++)
  125.         hdr->name[i] = '\0';
  126.  
  127.     fwrite(hdr->name,1,fnlen,f);
  128.     fputc(hdr->size&255,f);         fputc((hdr->size>>8)&255,f);
  129.     fputc((hdr->size>>16)&255,f);   fputc((hdr->size>>24)&255,f);
  130.     fputc(hdr->date&255,f);         fputc((hdr->date>>8)&255,f);
  131.     fputc(hdr->time&255,f);         fputc((hdr->time>>8)&255,f);
  132.     fputc(hdr->crc&255,f);          fputc((hdr->crc>>8)&255,f);
  133.     fputc(hdr->length&255,f);       fputc((hdr->length>>8)&255,f);
  134.     fputc((hdr->length>>16)&255,f); fputc((hdr->length>>24)&255,f);
  135.  
  136.     /* note the newest file for updating the archive timestamp */
  137.  
  138.     if (hdr->date>arcdate ||
  139.        (hdr->date==arcdate && hdr->time>arctime))
  140.     {
  141.         arcdate = hdr->date;
  142.         arctime = hdr->time;
  143.     }
  144. }
  145.  
  146. INT filecopy(f,t,size)                 /* bulk file copier */
  147. FILE *f, *t;                           /* from, to */
  148. long size;                             /* number of bytes */
  149. {
  150.     INT putc_tst();
  151.  
  152.     while (size--)                     /* while more bytes to move */
  153.         putc_tst(fgetc(f),t);
  154. }
  155.  
  156. INT putc_tst(c,t)                      /* put a character, with tests */
  157. char c;                                /* character to output */
  158. FILE *t;                               /* file to write to */
  159. {
  160.     if (t)
  161.         if (fputc(c,t)==EOF)
  162.         {
  163.             perror("system error:");
  164.             abort("Write failed");
  165.         }
  166. }
  167.