home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / archivers / arcppc / src / rcs / arcunp.c,v < prev    next >
Text File  |  1998-04-23  |  9KB  |  458 lines

  1. head     1.7;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    hyc:1.7; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.7
  10. date     88.06.18.03.12.36;  author hyc;  state Exp;
  11. branches ;
  12. next     1.6;
  13.  
  14. 1.6
  15. date     88.06.07.03.16.00;  author hyc;  state Exp;
  16. branches ;
  17. next     1.5;
  18.  
  19. 1.5
  20. date     88.06.02.16.27.42;  author hyc;  state Exp;
  21. branches ;
  22. next     1.4;
  23.  
  24. 1.4
  25. date     88.06.01.19.57.21;  author hyc;  state Exp;
  26. branches ;
  27. next     1.3;
  28.  
  29. 1.3
  30. date     88.06.01.16.40.15;  author hyc;  state Exp;
  31. branches ;
  32. next     1.2;
  33.  
  34. 1.2
  35. date     88.06.01.16.39.12;  author hyc;  state Exp;
  36. branches ;
  37. next     1.1;
  38.  
  39. 1.1
  40. date     88.04.11.18.42.39;  author hyc;  state Exp;
  41. branches ;
  42. next     ;
  43.  
  44.  
  45. desc
  46. @@
  47.  
  48.  
  49. 1.7
  50. log
  51. @Ooops. Omitted a putc for DOS systems. Shame, shame.
  52. @
  53. text
  54. @/*
  55.  * $Header: arcunp.c,v 1.6 88/06/07 03:16:00 hyc Locked $
  56.  */
  57.  
  58. /*
  59.  * ARC - Archive utility - ARCUNP
  60.  * 
  61.  * Version 3.17, created on 02/13/86 at 10:20:08
  62.  * 
  63.  * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  64.  * 
  65.  * By:  Thom Henderson
  66.  * 
  67.  * Description: This file contains the routines used to expand a file when
  68.  * taking it out of an archive.
  69.  * 
  70.  * Language: Computer Innovations Optimizing C86
  71.  */
  72. #include <stdio.h>
  73. #include "arc.h"
  74. #if    MTS
  75. #include <ctype.h>
  76. #endif
  77.  
  78. void    setcode(), init_usq(), init_ucr(), decomp(), sqdecomp();
  79. void    abort(), putc_tst();
  80. int    getc_usq(), getc_ucr(), addcrc();
  81.  
  82. /* stuff for repeat unpacking */
  83.  
  84. #define DLE 0x90        /* repeat byte flag */
  85.  
  86. static int      state;        /* repeat unpacking state */
  87.  
  88. /* repeat unpacking states */
  89.  
  90. #define NOHIST 0        /* no relevant history */
  91. #define INREP 1            /* sending a repeated value */
  92.  
  93. static short    crcval;        /* CRC check value */
  94. static long     size;        /* bytes to read */
  95. #if    !DOS
  96. static int    gotcr;        /* got a carriage return? */
  97. #endif
  98.  
  99. int
  100. unpack(f, t, hdr)        /* unpack an archive entry */
  101.     FILE           *f, *t;    /* source, destination */
  102.     struct heads   *hdr;    /* pointer to file header data */
  103. {
  104.     int             c;    /* one char of stream */
  105.     void            putc_unp();
  106.     void            putc_ncr();
  107.     int             getc_unp();
  108.  
  109.     /* setups common to all methods */
  110. #if    !DOS
  111.     gotcr = 0;
  112. #endif
  113.     crcval = 0;        /* reset CRC check value */
  114.     size = hdr->size;    /* set input byte counter */
  115.     state = NOHIST;        /* initial repeat unpacking state */
  116.     setcode();        /* set up for decoding */
  117.  
  118.     /* use whatever method is appropriate */
  119.  
  120.     switch (hdrver) {    /* choose proper unpack method */
  121.     case 1:        /* standard packing */
  122.     case 2:
  123.         while ((c = getc_unp(f)) != EOF)
  124.             putc_unp((char) c, t);
  125.         break;
  126.  
  127.     case 3:        /* non-repeat packing */
  128.         while ((c = getc_unp(f)) != EOF)
  129.             putc_ncr((unsigned char) c, t);
  130.         break;
  131.  
  132.     case 4:        /* Huffman squeezing */
  133.         init_usq(f);
  134.         while ((c = getc_usq(f)) != EOF)
  135.             putc_ncr((unsigned char) c, t);
  136.         break;
  137.  
  138.     case 5:        /* Lempel-Zev compression */
  139.         init_ucr(0);
  140.         while ((c = getc_ucr(f)) != EOF)
  141.             putc_unp((char) c, t);
  142.         break;
  143.  
  144.     case 6:        /* Lempel-Zev plus non-repeat */
  145.         init_ucr(0);
  146.         while ((c = getc_ucr(f)) != EOF)
  147.             putc_ncr((unsigned char) c, t);
  148.         break;
  149.  
  150.     case 7:        /* L-Z plus ncr with new hash */
  151.         init_ucr(1);
  152.         while ((c = getc_ucr(f)) != EOF)
  153.             putc_ncr((unsigned char) c, t);
  154.         break;
  155.  
  156.     case 8:        /* dynamic Lempel-Zev */
  157.         decomp(f, t);
  158.         break;
  159.  
  160.     case 9:        /* Squashing */
  161.         sqdecomp(f, t);
  162.         break;
  163.  
  164.     default:        /* unknown method */
  165.         if (warn) {
  166.             printf("I don't know how to unpack file %s\n", hdr->name);
  167.             printf("I think you need a newer version of ARC\n");
  168.             nerrs++;
  169.         }
  170.         fseek(f, hdr->size, 1);    /* skip over bad file */
  171.         return 1;    /* note defective file */
  172.     }
  173.  
  174.     /* cleanups common to all methods */
  175.  
  176.     if (crcval != hdr->crc) {
  177.         if (warn || kludge) {
  178.             printf("WARNING: File %s fails CRC check\n", hdr->name);
  179.             nerrs++;
  180.         }
  181.         return 1;    /* note defective file */
  182.     }
  183.     return 0;        /* file is okay */
  184. }
  185.  
  186. /*
  187.  * This routine is used to put bytes in the output file.  It also performs
  188.  * various housekeeping functions, such as maintaining the CRC check value.
  189.  */
  190.  
  191. void
  192. putc_unp(c, t)            /* output an unpacked byte */
  193.     char            c;    /* byte to output */
  194.     FILE           *t;    /* file to output to */
  195. {
  196.     crcval = addcrc(crcval, c);    /* update the CRC check value */
  197. #if    MTS
  198.     if (!image)
  199.         atoe(&c, 1);
  200. #endif
  201. #if    DOS
  202.     putc_tst(c, t);
  203. #else
  204.     if (image)
  205.         putc_tst(c, t);
  206.     else {
  207.         if (gotcr) {
  208.             gotcr = 0;
  209.             if (c != '\n')
  210.                 putc_tst('\r', t);
  211.         }
  212.         if (c == '\r')
  213.             gotcr = 1;
  214.         else
  215.             putc_tst(c, t);
  216.     }
  217. #endif
  218. }
  219.  
  220. /*
  221.  * This routine is used to decode non-repeat compression.  Bytes are passed
  222.  * one at a time in coded format, and are written out uncoded. The data is
  223.  * stored normally, except that runs of more than two characters are
  224.  * represented as:
  225.  * 
  226.  * <char> <DLE> <count>
  227.  * 
  228.  * With a special case that a count of zero indicates a DLE as data, not as a
  229.  * repeat marker.
  230.  */
  231.  
  232. void
  233. putc_ncr(c, t)            /* put NCR coded bytes */
  234.     unsigned char   c;    /* next byte of stream */
  235.     FILE           *t;    /* file to receive data */
  236. {
  237.     static int      lastc;    /* last character seen */
  238.  
  239.     switch (state) {    /* action depends on our state */
  240.     case NOHIST:        /* no previous history */
  241.         if (c == DLE)    /* if starting a series */
  242.             state = INREP;    /* then remember it next time */
  243.         else
  244.             putc_unp(lastc = c, t);    /* else nothing unusual */
  245.         return;
  246.  
  247.     case INREP:        /* in a repeat */
  248.         if (c)        /* if count is nonzero */
  249.             while (--c)    /* then repeatedly ... */
  250.                 putc_unp(lastc, t);    /* ... output the byte */
  251.         else
  252.             putc_unp(DLE, t);    /* else output DLE as data */
  253.         state = NOHIST;    /* back to no history */
  254.         return;
  255.  
  256.     default:
  257.         abort("Bad NCR unpacking state (%d)", state);
  258.     }
  259. }
  260.  
  261. /*
  262.  * This routine provides low-level byte input from an archive.  This routine
  263.  * MUST be used, as end-of-file is simulated at the end of the archive entry.
  264.  */
  265.  
  266. int
  267. getc_unp(f)            /* get a byte from an archive */
  268.     FILE           *f;    /* archive file to read */
  269. {
  270.     register int    xx;
  271.     unsigned char        code();
  272.  
  273.     if (!size)        /* if no data left */
  274.         return EOF;    /* then pretend end of file */
  275.  
  276.     size--;            /* deduct from input counter */
  277.     xx = getc(f);
  278.     return code(xx);    /* and return next decoded byte */
  279. }
  280. @
  281.  
  282.  
  283. 1.6
  284. log
  285. @Dang. Forgot some brackets.
  286. @
  287. text
  288. @d2 1
  289. a2 1
  290.  * $Header: arcunp.c,v 1.5 88/06/02 16:27:42 hyc Locked $
  291. d148 3
  292. a150 1
  293. #if    !DOS
  294. @
  295.  
  296.  
  297. 1.5
  298. log
  299. @Minor fixes & speedups
  300. @
  301. text
  302. @d2 1
  303. a2 1
  304.  * $Header: arcunp.c,v 1.4 88/06/01 19:57:21 hyc Locked $
  305. d151 1
  306. a151 1
  307.     else
  308. d161 1
  309. @
  310.  
  311.  
  312. 1.4
  313. log
  314. @Changed compilation conditionals
  315. @
  316. text
  317. @d2 1
  318. a2 1
  319.  * $Header: arcunp.c,v 1.3 88/06/01 16:40:15 hyc Locked $
  320. d42 3
  321. d57 3
  322. a59 1
  323.  
  324. a142 3
  325. #if    !DOS
  326.     static int    cr=0;    /* have we seen a CR? */
  327. #endif
  328. d152 8
  329. a159 2
  330.         if (cr && (c != '\n')) {
  331.             putc_tst('\r', t);
  332. a160 3
  333.             cr = 0;
  334.         } else if (c == '\r')
  335.             cr = 1;
  336. @
  337.  
  338.  
  339. 1.3
  340. log
  341. @Merge Atari ST code
  342. @
  343. text
  344. @d2 1
  345. a2 1
  346.  * $Header: arcunp.c,v 1.2 88/06/01 16:39:12 hyc Locked $
  347. d21 1
  348. a21 1
  349. #ifdef MTS
  350. d138 3
  351. d142 1
  352. a142 1
  353. #ifdef    MTS
  354. d146 10
  355. a155 2
  356. #ifndef DOS
  357.     if ((c != '\r') || image)
  358. a156 1
  359.         putc_tst(c, t);
  360. @
  361.  
  362.  
  363. 1.2
  364. log
  365. @Fix declarations
  366. @
  367. text
  368. @d2 1
  369. a2 1
  370.  * $Header: arcunp.c,v 1.4 88/04/19 01:40:31 hyc Exp $
  371. d143 1
  372. a143 1
  373. #ifndef MSDOS
  374. @
  375.  
  376.  
  377. 1.1
  378. log
  379. @Initial revision
  380. @
  381. text
  382. @d2 1
  383. a2 21
  384.  * $Log:    arcunp.c,v $
  385.  * Revision 1.3  87/12/20  03:10:14  hyc
  386.  * Ah hah! The value fgetc was returning was getting sign extended!
  387.  * Thus, 0xff was indistinguishable from EOF, causing the premature
  388.  * termination... The solution is to use getc, which doesn't do this
  389.  * (on the Apollos, anyway...)
  390.  * 
  391.  * Note that I could *not* duplicate this behavior in a 5 liner...?
  392.  * 
  393.  * Revision 1.2  87/12/19  04:11:22  hyc
  394.  * Move image mode code around from MTS only to non-MSDOS.
  395.  * 
  396.  * Revision 1.1  87/12/19  04:06:39  hyc
  397.  * Initial revision
  398.  * 
  399.  * Revision 1.3  87/08/13  17:06:08  hyc
  400.  * Run thru indent, fixed some signed vs. unsigned problems
  401.  * with bp <-> buf, and inbuf and localbuf...
  402.  *  Revision 1.2  87/07/21  09:28:31  hyc *** empty
  403.  * log message ***
  404.  * 
  405. d21 3
  406. d25 4
  407. d33 1
  408. a33 1
  409. static INT      state;        /* repeat unpacking state */
  410. d40 2
  411. a41 2
  412. static INT      crcval;        /* CRC check value */
  413. static LONG     size;        /* bytes to read */
  414. d43 1
  415. a43 1
  416. INT
  417. d48 4
  418. a51 4
  419.     INT             c;    /* one char of stream */
  420.     INT             putc_unp();
  421.     INT             putc_ncr();
  422.     INT             getc_unp();
  423. d66 1
  424. a66 1
  425.             putc_unp(c, t);
  426. d71 1
  427. a71 1
  428.             putc_ncr(c, t);
  429. d77 1
  430. a77 1
  431.             putc_ncr(c, t);
  432. d83 1
  433. a83 1
  434.             putc_unp(c, t);
  435. d89 1
  436. a89 1
  437.             putc_ncr(c, t);
  438. d95 1
  439. a95 1
  440.             putc_ncr(c, t);
  441. d102 4
  442. d133 1
  443. a133 1
  444. static          INT
  445. d161 1
  446. a161 1
  447. INT
  448. d166 1
  449. a166 1
  450.     static INT      lastc;    /* last character seen */
  451. d195 1
  452. a195 1
  453. INT
  454. d199 3
  455. a201 1
  456.     register INT    xx;
  457. @
  458.