home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm68k / arc68k.arc / ARCIO.C < prev    next >
Text File  |  1987-11-27  |  7KB  |  241 lines

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