home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume32 / xbbs / part07 / bbscarc.c next >
C/C++ Source or Header  |  1992-09-08  |  5KB  |  177 lines

  1. #include "bbscdef.h"
  2.  
  3. struct heads {                /* archive entry header format */
  4.     char        name[13];    /* file name */
  5.     int        size;        /* size of file, in bytes */
  6.     unsigned short    date;        /* creation date */
  7.     unsigned short    time;        /* creation time */
  8.     unsigned short        crc;        /* cyclic redundancy check */
  9.     int        length;        /* true file length */
  10. };
  11.  
  12. #define ARCMARK        26    /* special archive marker */
  13. #define ARCVER        9    /* archive header version code */
  14. #define ARCFNLEN    13    /* file name length */
  15.  
  16. char    hdrver;            /* header version */
  17. FILE    *arc;            /* the old archive */
  18. FILE    *inps;
  19.  
  20. listarc(filename, port_id)
  21. char    *filename, *port_id;
  22. {
  23.     struct heads    hdr;            /* header data */
  24.     long        tnum, tlen, tsize;    /* totals */
  25.     strcpy(buf128, "/tmp/arclst.");
  26.     strcat(buf128, port_id);
  27.     inps = fopen(buf128, "w");
  28.  
  29.     strcpy(buf128, filename);
  30.  
  31.     fprintf(inps, "\nArchive:  %s\n\n", buf128);
  32.  
  33.     tnum = tlen = tsize = 0;    /* reset totals */
  34.  
  35.     fprintf(inps, "Name          Length    Stowage    SF   Size now  ");
  36.     fprintf(inps, "Date       Time    CRC\n");
  37.     fprintf(inps, "============  ========  ========  ====  ========  ");
  38.     fprintf(inps, "=========  ======  ====\n");
  39.     
  40.     if (!(arc = fopen(buf128, "rb"))) {    /* open archive for reading */
  41.         fprintf(inps, "Cannot read archive: %s\n", buf128);
  42.         return;
  43.     }
  44.  
  45.     while (readhdr(&hdr, arc)) {    /* else report on all files */
  46.         lstfile(&hdr);
  47.         tnum++;         /* update totals */
  48.         tlen += hdr.length;
  49.         tsize += hdr.size;
  50.         fseek(arc, hdr.size, 1);/* skip to next header */
  51.     }
  52.  
  53.     fclose(arc);            /* close archive after reading */
  54.  
  55.     fprintf(inps, "        ====  ========            ====  ========\n");
  56.     fprintf(inps, "Total %6ld  %8ld            %3ld%%  %8ld  \n\n",
  57.        tnum, tlen, tlen ? 100L - (100L * tsize) / tlen : 0, tsize);
  58.     fclose(inps);
  59. }
  60.  
  61. static lstfile(hdr)               /* tell about a file */
  62. struct heads *hdr;               /* pointer to header data */
  63. {
  64.     int    yr, mo, dy;               /* parts of a date */
  65.     int    hh, mm, ss;               /* parts of a time */
  66.  
  67.     static char    *mon[] = {           /* month abbreviations */
  68.         "Jan", "Feb", "Mar", "Apr",
  69.         "May", "Jun", "Jul", "Aug",
  70.         "Sep", "Oct", "Nov", "Dec"
  71.     };
  72.  
  73.     yr = (hdr -> date >> 9) & 0x7f;        /* dissect the date */
  74.     mo = (hdr -> date >> 5) & 0x0f;
  75.     dy = hdr -> date & 0x1f;
  76.  
  77.     hh = (hdr -> time >> 11) & 0x1f;    /* dissect the time */
  78.     mm = (hdr -> time >> 5) & 0x3f;
  79.     ss = (hdr -> time & 0x1f) * 2;
  80.  
  81.     fprintf(inps, "%-12s  %8ld  ", hdr -> name, hdr -> length);
  82.  
  83.     switch (hdrver) {
  84.     case 1:
  85.     case 2:
  86.         fprintf(inps, "   --   ");
  87.         break;
  88.     case 3:
  89.         fprintf(inps, " Packed ");
  90.         break;
  91.     case 4:
  92.         fprintf(inps, "Squeezed");
  93.         break;
  94.     case 5:
  95.     case 6:
  96.     case 7:
  97.         fprintf(inps, "crunched");
  98.         break;
  99.     case 8:
  100.         fprintf(inps, "Crunched");
  101.         break;
  102.     case 9: fprintf(inps, "Squashed");
  103.         break;
  104.     default:
  105.         fprintf(inps, "Unknown!");
  106.     }
  107.  
  108.     fprintf(inps, "  %3ld%%  %8ld  %2d %3s %02d  %2d:%02d%c  %04X\n",
  109.         100L - (100L * hdr -> size) / hdr -> length,
  110.         hdr -> size,
  111.         dy, mon[mo-1], (yr + 80) % 100,
  112.         (hh > 12 ? hh - 12 : hh), mm, (hh > 12 ? 'p' : 'a'), hdr -> crc);
  113. }
  114.  
  115. int readhdr(hdr, f)            /* read a header from an archive */
  116. struct heads    *hdr;            /* storage for header */
  117. FILE        *f;            /* archive to read header from */
  118. {
  119.     char        name[ARCFNLEN];    /* filename buffer */
  120.     int        try = 0;    /* retry counter */
  121.     static int    first = 1;    /* true only on first read */
  122.  
  123.     if (!f)                /* if archive didn't open */
  124.         return 0;        /* then pretend it's the end */
  125.     if (feof(f))            /* if no more data */
  126.         return 0;        /* then signal end of archive */
  127.  
  128.     if (fgetc(f) != ARCMARK) {    /* check archive validity */
  129.         fprintf(inps, "An entry in %s has a bad header.\n", buf128);
  130.  
  131.         while(!feof(f)) {
  132.             try++;
  133.             if (fgetc(f) == ARCMARK) {
  134.                 ungetc(hdrver = fgetc(f), f);
  135.                 if (hdrver >= 0 && hdrver <= ARCVER)
  136.                     break;
  137.             }
  138.         }
  139.  
  140.         if (feof(f) && first) {
  141.             fprintf(inps,"%s is not an archive.\n", buf128);
  142.             return 0;
  143.         }
  144.  
  145.         fprintf(inps, "  %d bytes skipped.\n", try);
  146.  
  147.         if (feof(f))
  148.             return 0;
  149.     }
  150.  
  151.     hdrver = fgetc(f);        /* get header version */
  152.     if (hdrver < 0) {
  153.         fprintf(inps, "Invalid header in archive %s\n", buf128);
  154.         return 0;
  155.     }
  156.     if (hdrver == 0)
  157.         return 0;        /* note our end of archive marker */
  158.     if (hdrver > ARCVER) {
  159.         fread(name, sizeof(char), ARCFNLEN, f);
  160.         fprintf(inps, "I don't know how to handle file %s in archive %s\n",
  161.            name, buf128);
  162.         fprintf(inps, "I think you need a newer version of ARC.\n");
  163.             return 0;
  164.     }
  165.  
  166.     /* amount to read depends on header type */
  167.  
  168.     if (hdrver == 1) {            /* old style is shorter */
  169.         fread(hdr, sizeof (struct heads) - sizeof (long int), 1, f);
  170.         hdrver = 2;                   /* convert header to new format */
  171.         hdr -> length = hdr -> size;    /* size is same when not packed */
  172.     } else
  173.         fread(hdr, sizeof (struct heads), 1, f);
  174.     first = 0;
  175.     return 1;                /* we read something */
  176. }
  177.