home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / OS2LHX.LZH / LHPROC.C < prev    next >
C/C++ Source or Header  |  1989-04-15  |  6KB  |  258 lines

  1. /* LHPROC.C -- Test/List/Extract routine for LHX
  2.  *
  3.  * version 1.0 by Mark Armbrust, 15 April 1985   (IRS? Just say NO!)
  4.  *
  5.  * The code in this module is public domain -- do whatever you want with it */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <dos.h>
  10. #include <conio.h>
  11. #include <ctype.h>
  12.  
  13. #include "lhx.h"
  14.  
  15. /* private functions */
  16.  
  17. PRIVATE int      ProcessData (FILE *, unsigned long, unsigned int, FILE *);
  18. PRIVATE int      ProcessCompData (FILE *, unsigned long, unsigned long,
  19.                                  unsigned int, FILE *);
  20.  
  21. /* private data */
  22.  
  23. PRIVATE char month[16][4] = {"0??","Jan","Feb","Mar","Apr","May","Jun","Jul",
  24.                              "Aug","Sep","Oct","Nov","Dec","13?","14?","15?"};
  25.  
  26.  
  27. PUBLIC int    Process    (arcfile, filenames)
  28.  
  29. FILE            *    arcfile;
  30. struct fname    *    filenames;
  31. {
  32. struct lzhdir        header;
  33. unsigned char        sum;
  34. char                temp[100];
  35. unsigned            errors, i;
  36. unsigned long        next_hdr;
  37. FILE            *    file;
  38. char            *    p;
  39. char            *    q;
  40.  
  41.  
  42. switch (mode & MODES) {
  43.     case TEST:
  44.         printf ("\nTesting archive %s\n", name);
  45.         break;
  46.     case LIST:
  47.         printf ("\nListing archive %s\n", name);
  48.         break;
  49.     case EXTRACT:
  50.         printf ("\nExtracting archive %s\n", name);
  51.         break;
  52.     }
  53.  
  54. errors = 0;
  55.  
  56. if (header_start != -1)
  57.     fseek (arcfile, header_start, SEEK_SET);
  58.  
  59. while ( ! feof (arcfile) ) {
  60.     header.header_len = (char) fgetc (arcfile);
  61.     if (feof (arcfile) )
  62.         break;
  63.     if ( header_start == -1 && header.header_len == 0)
  64.         continue;
  65.  
  66.     if ( header_start == -1 && (header.header_len < 21 || header.header_len > 98)) {
  67.         printf ("  invalid file header -- skipping remainder of file\n");
  68.         ++errors;
  69.         break;
  70.         }
  71.  
  72.     if (header.header_len > 98)
  73.         header.header_len = 98;
  74.  
  75.     if ( ! fread (&header.header_sum, header.header_len + 1, 1, arcfile) &&
  76.              header_start == -1) {
  77.         printf ("  unexpected eof\n");
  78.         ++errors;
  79.         break;
  80.         }
  81.  
  82.     i = header.name_len;
  83.     if (i > header.header_len - 22)
  84.         i = header.header_len - 22;
  85.     strncpy (temp, header.filename, i);
  86.     temp[i] = '\0';
  87.  
  88.     next_hdr = ftell (arcfile) + header.data_size;
  89.  
  90.     if (file_name[0] || MatchAny (temp, filenames)) {
  91.  
  92.         for (sum=0, i=0; i<header.header_len; ++i)
  93.             sum += ((char *)&header)[i+2];
  94.  
  95.         header.file_CRC = *((int *)&header.filename[header.name_len]);
  96.  
  97.         if (mode & LIST) {
  98.             printf ("%c %c%cr%c%c%8ld /%8ld  %2d %3s %.2d  %.2d:%.2d:%.2d   %s\n",
  99.                     (header.header_sum == sum) ? ' ' : '?',
  100.                     (header.file_attr & _A_SYSTEM) ? 's' : '-',
  101.                     (header.file_attr & _A_HIDDEN) ? 'h' : '-',
  102.                     (header.file_attr & _A_RDONLY) ? '-' : 'w',
  103.                     (header.file_attr & _A_ARCH) ? '-' : 'a',
  104.                     header.file_size,
  105.                     header.data_size,
  106.                     header.file_date & 0x001F,
  107.                     month[(header.file_date & 0x01E0) >> 5],
  108.                     (((header.file_date & 0xFE00) >> 9) + 80) % 100,
  109.                     (header.file_time & 0xF800) >> 11,
  110.                     (header.file_time & 0x07E0) >> 5,
  111.                     (header.file_time & 0x001F) << 1,
  112.                     temp);
  113.             }
  114.         else {
  115.             if (file_name[0])
  116.                 printf ("  %s -- ", file_name);
  117.             else
  118.                 printf ("  %s -- ", temp);
  119.  
  120.             if ((mode & TEST) && header.header_sum != sum) {
  121.                 printf ("bad file header, ");
  122.                 ++errors;
  123.                 }
  124.  
  125.             if (mode & TEST)
  126.                 file = 0;
  127.             else {
  128.                 p = temp;
  129.                 if (q = strrchr (p, '\\')) p = q + 1;
  130.                 if (q = strrchr (p, '/')) p = q + 1;
  131.  
  132.                 if (file_name[0])
  133.                     p = file_name;
  134.  
  135.                 if ( file = fopen (p, "r")) {
  136.                     fclose (file);
  137.                     do {
  138.                         fprintf (stderr, "\nfile exists; overwrite (y/n)? \007");
  139.                         i = getche();
  140.                         fprintf (stderr, "\n");
  141.                         if ( (i=toupper(i)) == 'N')
  142.                             goto NEXT_FILE;
  143.                         }
  144.                     while (i != 'Y');
  145.                     }
  146.  
  147.                 if ( ! (file = fopen (p, "wb")) ) {
  148.                     printf ("could not create file '%s'\n", p);
  149.                     goto NEXT_FILE;
  150.                     }
  151.                 }
  152.  
  153.             if (file_start != -1)
  154.                 fseek (arcfile, file_start, SEEK_SET);
  155.             if (file_size != -1)
  156.                 header.data_size = header.file_size = file_size;
  157.  
  158.             if (file_type == 0 || strncmp (header.method, "-lh0-", 5) == 0)
  159.                 errors += ProcessData (arcfile, header.file_size, header.file_CRC, file);
  160.             else if (file_type == 1 || strncmp (header.method, "-lh1-", 5) == 0)
  161.                 errors += ProcessCompData (arcfile, header.data_size, header.file_size,
  162.                                         header.file_CRC, file);
  163.             else {
  164.                 printf ("unknown compression method -- file skipped\n");
  165.                 ++errors;
  166.                 }
  167.             if (file)
  168.                 fclose (file);
  169.             }
  170.         }
  171. NEXT_FILE:
  172.     if (file_start != -1)                /* if we had to tell it where the data starts,    */
  173.         fseek (arcfile, -1L, SEEK_CUR);    /* assume the next header immediatly follows.    */
  174.     else
  175.         fseek (arcfile, next_hdr, SEEK_SET);
  176.  
  177.     header_start = -1;
  178.     file_start = -1;
  179.     file_size = -1;
  180.     file_type = -1;
  181.  
  182.     if (file_name[0])
  183.         break;
  184.     }
  185. if ((mode & TEST) || errors)
  186.     printf ("%d error%s detected\n", errors, (errors==1)?"":"s");
  187. return (errors);
  188. }
  189.  
  190.  
  191.  
  192. PRIVATE int      ProcessData (arcfile, data_size, file_CRC, file)
  193.  
  194. FILE            *    arcfile;
  195. unsigned long        data_size;
  196. unsigned int          file_CRC;
  197. FILE            *    file;
  198. {
  199. int      count;
  200.  
  201. crccode = 0;
  202. while (data_size) {
  203.     if (data_size < BUFF_LEN)
  204.         count = (int) data_size;
  205.     else
  206.         count = BUFF_LEN;
  207.  
  208.     if ( ! fread (buffer, count, 1, arcfile) ) {
  209.         printf ("unexpected eof\n");
  210.         return 1;
  211.         }
  212.  
  213.     addbfcrc (buffer, count);
  214.  
  215.     if (file)
  216.         if ( ! fwrite (buffer, count, 1, file) ) {
  217.             printf ("write error; disk full?\n");
  218.             return 1;
  219.             }
  220.  
  221.     data_size -= count;
  222.     }
  223.  
  224. if (crccode == file_CRC) {
  225.     printf ("%s OK\n", (mode&TEST) ? "data" : "extracted");
  226.     return 0;
  227.     }
  228. printf ("%s CRC error\n", (mode&TEST) ? "data" : "extracted with");
  229. return 1;
  230. }
  231.  
  232.  
  233.  
  234. PRIVATE int      ProcessCompData (arcfile, data_size, file_size, file_CRC, file)
  235.  
  236. FILE            *    arcfile;
  237. unsigned long        data_size;
  238. unsigned long         file_size;
  239. unsigned int          file_CRC;
  240. FILE            *    file;
  241. {
  242.  
  243. crccode = 0;
  244. textsize = file_size;
  245. infile = arcfile;
  246. outfile = file;
  247.  
  248. Decode ();
  249.  
  250. if (crccode == file_CRC) {
  251.     printf ("%s OK\n", (mode&TEST) ? "data" : "extracted");
  252.     return 0;
  253.     }
  254. printf ("%s CRC error\n", (mode&TEST) ? "data" : "extracted with");
  255. return 1;
  256. }
  257.  
  258.