home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / MACUNPACK / pit.c < prev    next >
C/C++ Source or Header  |  1995-09-18  |  6KB  |  286 lines

  1. #include "macunpack.h"
  2. #ifdef PIT
  3. #include "../fileio/wrfile.h"
  4. #include "../fileio/fileglob.h"
  5. #include "../fileio/kind.h"
  6. #include "globals.h"
  7. #include "pit.h"
  8. #include "../fileio/machdr.h"
  9. #include "crc.h"
  10. #include "../util/masks.h"
  11. #include "../util/util.h"
  12. #include "huffman.h"
  13.  
  14. extern void read_tree();
  15. extern void de_huffman();
  16. extern void set_huffman();
  17.  
  18. static int pit_filehdr();
  19. static void pit_wrfile();
  20. static void pit_nocomp();
  21. static void pit_huffman();
  22.  
  23. void pit()
  24. {
  25.     struct pit_header filehdr;
  26.     char pithdr[4];
  27.     int decode, synced, ch;
  28.     unsigned long data_crc, crc;
  29.  
  30.     updcrc = binhex_updcrc;
  31.     crcinit = binhex_crcinit;
  32.     set_huffman(HUFF_BE);
  33.     synced = 0;
  34.     while(1) {
  35.     if(!synced) {
  36.         if(fread(pithdr, 1, 4, infp) != 4) {
  37.         (void)fprintf(stderr, "Premature EOF\n");
  38. #ifdef SCAN
  39.         do_error("macunpack: Premature EOF");
  40. #endif /* SCAN */
  41.         exit(1);
  42.         }
  43.     }
  44.     synced = 0;
  45.     if(strncmp(pithdr, "PEnd", 4) == 0) {
  46.         break;
  47.     }
  48.     if(strncmp(pithdr, "PMa", 3) != 0) {
  49.         (void)fprintf(stderr, "File contains non PackIt info %.4s\n",
  50.             pithdr);
  51. #ifdef SCAN
  52.         do_error("macunpack: File contains non PackIt info");
  53. #endif /* SCAN */
  54.         exit(1);
  55.     }
  56.     switch(pithdr[3]) {
  57.     case 'g':
  58.     case '4':
  59.         break;
  60.     case '5':
  61.     case '6':
  62.         if(pithdr[3] == '6') {
  63.         (void)fprintf(stderr, "DES-");
  64.         }
  65.         (void)fprintf(stderr, "Encrypted file found, trying to sync");
  66.         while(!synced) {
  67.         ch = getb(infp);
  68.         if(ch == 'P') {
  69.             pithdr[0] = ch;
  70.             pithdr[1] = ch = getb(infp);
  71.             if(ch == 'M') {
  72.             pithdr[2] = ch = getb(infp);
  73.             if(ch == 'a') {
  74.                 pithdr[3] = ch = getb(infp);
  75.                 if((ch >= '4' && ch <= '6') || ch == 'g') {
  76.                 synced = 1;
  77.                 }
  78.             }
  79.             } else if(ch == 'E') {
  80.             pithdr[2] = ch = getb(infp);
  81.             if(ch == 'n') {
  82.                 pithdr[3] = ch = getb(infp);
  83.                 if(ch == 'd') {
  84.                 synced = 1;
  85.                 }
  86.             }
  87.             }
  88.             if(!synced) {
  89.             (void)ungetc(ch, infp);
  90.             }
  91.         }
  92.         }
  93.         (void)fprintf(stderr, ", done.\n");
  94. #ifdef SCAN
  95.         do_idf("", PROTECTED);
  96. #endif /* SCAN */
  97.         continue;
  98.     default:
  99.         (void)fprintf(stderr, "File contains non PackIt info %.4s\n",
  100.             pithdr);
  101. #ifdef SCAN
  102.         do_error("macunpack: File contains non PackIt info");
  103. #endif /* SCAN */
  104.         exit(1);
  105.     }
  106.     bytes_read = 0;
  107.     if(pithdr[3] == '4') {
  108.         read_tree();
  109.         decode = huffman;
  110.     } else {
  111.         decode = nocomp;
  112.     }
  113.     if(pit_filehdr(&filehdr, decode) == -1) {
  114.         (void)fprintf(stderr, "Can't read file header\n");
  115. #ifdef SCAN
  116.         do_error("macunpack: Can't read file header");
  117. #endif /* SCAN */
  118.         exit(1);
  119.     }
  120.     bytes_written = filehdr.rlen + filehdr.dlen;
  121.     start_info(info, filehdr.rlen, filehdr.dlen);
  122.     start_data();
  123.     pit_wrfile(filehdr.dlen, decode);
  124.     data_crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.dlen);
  125.     start_rsrc();
  126.     pit_wrfile(filehdr.rlen, decode);
  127.     data_crc = (*updcrc)(data_crc, out_buffer, filehdr.rlen);
  128.     if(decode == nocomp) {
  129.         crc = getb(infp);
  130.         crc = (crc << 8) | getb(infp);
  131.     } else {
  132.         crc = (getihuffbyte() & BYTEMASK) |
  133.           ((getihuffbyte() & BYTEMASK) << 8);
  134.     }
  135.     if(crc != data_crc) {
  136.         (void)fprintf(stderr,
  137.             "CRC error in file: need 0x%04x, got 0x%04x\n",
  138.             (int)crc, (int)data_crc);
  139. #ifdef SCAN
  140.         do_error("macunpack: CRC error in file");
  141. #endif /* SCAN */
  142.         exit(1);
  143.     }
  144.     if(verbose) {
  145.         if(decode == nocomp) {
  146.         (void)fprintf(stderr, "\tNo compression");
  147.         } else {
  148.         (void)fprintf(stderr, "\tHuffman compressed (%4.1f%%)",
  149.             100.0 * bytes_read / bytes_written);
  150.         }
  151.     }
  152.     if(write_it) {
  153.         end_file();
  154.     }
  155.     if(verbose) {
  156.         (void)fprintf(stderr, ".\n");
  157.     }
  158.     }
  159. }
  160.  
  161. static int pit_filehdr(f, compr)
  162. struct pit_header *f;
  163. int compr;
  164. {
  165.     register int i;
  166.     unsigned long crc;
  167.     int n;
  168.     char hdr[HDRBYTES];
  169.     char ftype[5], fauth[5];
  170.  
  171.     for(i = 0; i < INFOBYTES; i++)
  172.     info[i] = '\0';
  173.  
  174.     if(compr == huffman) {
  175.     for(i = 0; i < HDRBYTES; i++) {
  176.         hdr[i] = getihuffbyte();
  177.     }
  178.     } else {
  179.     if(fread(hdr, 1, HDRBYTES, infp) != HDRBYTES) {
  180.         return -1;
  181.     }
  182.     }
  183.     crc = INIT_CRC;
  184.     crc = (*updcrc)(crc, hdr, HDRBYTES - 2);
  185.  
  186.     f->hdrCRC = get2(hdr + H_HDRCRC);
  187.     if(f->hdrCRC != crc) {
  188.     (void)fprintf(stderr,
  189.         "\tHeader CRC mismatch: got 0x%04x, need 0x%04x\n",
  190.         f->hdrCRC & WORDMASK, (int)crc);
  191.     return -1;
  192.     }
  193.  
  194.     n = hdr[H_NLENOFF] & BYTEMASK;
  195.     if(n > H_NAMELEN) {
  196.     n = H_NAMELEN;
  197.     }
  198.     info[I_NAMEOFF] = n;
  199.     copy(info + I_NAMEOFF + 1, hdr + H_NAMEOFF, n);
  200.     transname(hdr + H_NAMEOFF, text, n);
  201.     text[n] = '\0';
  202.  
  203.     f->rlen = get4(hdr + H_RLENOFF);
  204.     f->dlen = get4(hdr + H_DLENOFF);
  205.  
  206.     write_it = 1;
  207.     if(list) {
  208.     transname(hdr + H_TYPEOFF, ftype, 4);
  209.     transname(hdr + H_AUTHOFF, fauth, 4);
  210.     do_indent(indent);
  211.     (void)fprintf(stderr,
  212.         "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
  213.         text, ftype, fauth, (long)f->dlen, (long)f->rlen);
  214.     if(info_only) {
  215.         write_it = 0;
  216.     }
  217.     if(query) {
  218.         write_it = do_query();
  219.     } else {
  220.         (void)fputc('\n', stderr);
  221.     }
  222.     }
  223.  
  224.  
  225.     if(write_it) {
  226.     define_name(text);
  227.  
  228.     copy(info + I_TYPEOFF, hdr + H_TYPEOFF, 4);
  229.     copy(info + I_AUTHOFF, hdr + H_AUTHOFF, 4);
  230.     copy(info + I_FLAGOFF, hdr + H_FLAGOFF, 2);
  231.     copy(info + I_LOCKOFF, hdr + H_LOCKOFF, 2);
  232.     copy(info + I_DLENOFF, hdr + H_DLENOFF, 4);
  233.     copy(info + I_RLENOFF, hdr + H_RLENOFF, 4);
  234.     copy(info + I_CTIMOFF, hdr + H_CTIMOFF, 4);
  235.     copy(info + I_MTIMOFF, hdr + H_MTIMOFF, 4);
  236.     }
  237.     return 1;
  238. }
  239.  
  240. static void pit_wrfile(bytes, type)
  241. unsigned long bytes;
  242. int type;
  243. {
  244.     if(bytes == 0) {
  245.     return;
  246.     }
  247.     switch(type) {
  248.     case nocomp:
  249.     pit_nocomp(bytes);
  250.     break;
  251.     case huffman:
  252.     pit_huffman(bytes);
  253.     }
  254. }
  255.  
  256. /*---------------------------------------------------------------------------*/
  257. /*    No compression                                 */
  258. /*---------------------------------------------------------------------------*/
  259. static void pit_nocomp(ibytes)
  260. unsigned long ibytes;
  261. {
  262.     int n;
  263.  
  264.     n = fread(out_buffer, 1, (int)ibytes, infp);
  265.     if(n != ibytes) {
  266.     (void)fprintf(stderr, "Premature EOF\n");
  267. #ifdef SCAN
  268.     do_error("macunpack: Premature EOF");
  269. #endif /* SCAN */
  270.     exit(1);
  271.     }
  272. }
  273.  
  274. /*---------------------------------------------------------------------------*/
  275. /*    Huffman compression                             */
  276. /*---------------------------------------------------------------------------*/
  277. static void pit_huffman(obytes)
  278. unsigned long obytes;
  279. {
  280.     de_huffman(obytes);
  281. }
  282. #else /* PIT */
  283. int pit; /* keep lint and some compilers happy */
  284. #endif /* PIT */
  285.  
  286.