home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 28
/
amigaformatcd28.iso
/
-seriously_amiga-
/
archivers
/
arcppc
/
src
/
rcs
/
arcunp.c,v
< prev
next >
Wrap
Text File
|
1998-04-23
|
9KB
|
458 lines
head 1.7;
branch ;
access ;
symbols ;
locks hyc:1.7; strict;
comment @ * @;
1.7
date 88.06.18.03.12.36; author hyc; state Exp;
branches ;
next 1.6;
1.6
date 88.06.07.03.16.00; author hyc; state Exp;
branches ;
next 1.5;
1.5
date 88.06.02.16.27.42; author hyc; state Exp;
branches ;
next 1.4;
1.4
date 88.06.01.19.57.21; author hyc; state Exp;
branches ;
next 1.3;
1.3
date 88.06.01.16.40.15; author hyc; state Exp;
branches ;
next 1.2;
1.2
date 88.06.01.16.39.12; author hyc; state Exp;
branches ;
next 1.1;
1.1
date 88.04.11.18.42.39; author hyc; state Exp;
branches ;
next ;
desc
@@
1.7
log
@Ooops. Omitted a putc for DOS systems. Shame, shame.
@
text
@/*
* $Header: arcunp.c,v 1.6 88/06/07 03:16:00 hyc Locked $
*/
/*
* ARC - Archive utility - ARCUNP
*
* Version 3.17, created on 02/13/86 at 10:20:08
*
* (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
*
* By: Thom Henderson
*
* Description: This file contains the routines used to expand a file when
* taking it out of an archive.
*
* Language: Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include "arc.h"
#if MTS
#include <ctype.h>
#endif
void setcode(), init_usq(), init_ucr(), decomp(), sqdecomp();
void abort(), putc_tst();
int getc_usq(), getc_ucr(), addcrc();
/* stuff for repeat unpacking */
#define DLE 0x90 /* repeat byte flag */
static int state; /* repeat unpacking state */
/* repeat unpacking states */
#define NOHIST 0 /* no relevant history */
#define INREP 1 /* sending a repeated value */
static short crcval; /* CRC check value */
static long size; /* bytes to read */
#if !DOS
static int gotcr; /* got a carriage return? */
#endif
int
unpack(f, t, hdr) /* unpack an archive entry */
FILE *f, *t; /* source, destination */
struct heads *hdr; /* pointer to file header data */
{
int c; /* one char of stream */
void putc_unp();
void putc_ncr();
int getc_unp();
/* setups common to all methods */
#if !DOS
gotcr = 0;
#endif
crcval = 0; /* reset CRC check value */
size = hdr->size; /* set input byte counter */
state = NOHIST; /* initial repeat unpacking state */
setcode(); /* set up for decoding */
/* use whatever method is appropriate */
switch (hdrver) { /* choose proper unpack method */
case 1: /* standard packing */
case 2:
while ((c = getc_unp(f)) != EOF)
putc_unp((char) c, t);
break;
case 3: /* non-repeat packing */
while ((c = getc_unp(f)) != EOF)
putc_ncr((unsigned char) c, t);
break;
case 4: /* Huffman squeezing */
init_usq(f);
while ((c = getc_usq(f)) != EOF)
putc_ncr((unsigned char) c, t);
break;
case 5: /* Lempel-Zev compression */
init_ucr(0);
while ((c = getc_ucr(f)) != EOF)
putc_unp((char) c, t);
break;
case 6: /* Lempel-Zev plus non-repeat */
init_ucr(0);
while ((c = getc_ucr(f)) != EOF)
putc_ncr((unsigned char) c, t);
break;
case 7: /* L-Z plus ncr with new hash */
init_ucr(1);
while ((c = getc_ucr(f)) != EOF)
putc_ncr((unsigned char) c, t);
break;
case 8: /* dynamic Lempel-Zev */
decomp(f, t);
break;
case 9: /* Squashing */
sqdecomp(f, t);
break;
default: /* unknown method */
if (warn) {
printf("I don't know how to unpack file %s\n", hdr->name);
printf("I think you need a newer version of ARC\n");
nerrs++;
}
fseek(f, hdr->size, 1); /* skip over bad file */
return 1; /* note defective file */
}
/* cleanups common to all methods */
if (crcval != hdr->crc) {
if (warn || kludge) {
printf("WARNING: File %s fails CRC check\n", hdr->name);
nerrs++;
}
return 1; /* note defective file */
}
return 0; /* file is okay */
}
/*
* This routine is used to put bytes in the output file. It also performs
* various housekeeping functions, such as maintaining the CRC check value.
*/
void
putc_unp(c, t) /* output an unpacked byte */
char c; /* byte to output */
FILE *t; /* file to output to */
{
crcval = addcrc(crcval, c); /* update the CRC check value */
#if MTS
if (!image)
atoe(&c, 1);
#endif
#if DOS
putc_tst(c, t);
#else
if (image)
putc_tst(c, t);
else {
if (gotcr) {
gotcr = 0;
if (c != '\n')
putc_tst('\r', t);
}
if (c == '\r')
gotcr = 1;
else
putc_tst(c, t);
}
#endif
}
/*
* This routine is used to decode non-repeat compression. Bytes are passed
* one at a time in coded format, and are written out uncoded. The data is
* stored normally, except that runs of more than two characters are
* represented as:
*
* <char> <DLE> <count>
*
* With a special case that a count of zero indicates a DLE as data, not as a
* repeat marker.
*/
void
putc_ncr(c, t) /* put NCR coded bytes */
unsigned char c; /* next byte of stream */
FILE *t; /* file to receive data */
{
static int lastc; /* last character seen */
switch (state) { /* action depends on our state */
case NOHIST: /* no previous history */
if (c == DLE) /* if starting a series */
state = INREP; /* then remember it next time */
else
putc_unp(lastc = c, t); /* else nothing unusual */
return;
case INREP: /* in a repeat */
if (c) /* if count is nonzero */
while (--c) /* then repeatedly ... */
putc_unp(lastc, t); /* ... output the byte */
else
putc_unp(DLE, t); /* else output DLE as data */
state = NOHIST; /* back to no history */
return;
default:
abort("Bad NCR unpacking state (%d)", state);
}
}
/*
* This routine provides low-level byte input from an archive. This routine
* MUST be used, as end-of-file is simulated at the end of the archive entry.
*/
int
getc_unp(f) /* get a byte from an archive */
FILE *f; /* archive file to read */
{
register int xx;
unsigned char code();
if (!size) /* if no data left */
return EOF; /* then pretend end of file */
size--; /* deduct from input counter */
xx = getc(f);
return code(xx); /* and return next decoded byte */
}
@
1.6
log
@Dang. Forgot some brackets.
@
text
@d2 1
a2 1
* $Header: arcunp.c,v 1.5 88/06/02 16:27:42 hyc Locked $
d148 3
a150 1
#if !DOS
@
1.5
log
@Minor fixes & speedups
@
text
@d2 1
a2 1
* $Header: arcunp.c,v 1.4 88/06/01 19:57:21 hyc Locked $
d151 1
a151 1
else
d161 1
@
1.4
log
@Changed compilation conditionals
@
text
@d2 1
a2 1
* $Header: arcunp.c,v 1.3 88/06/01 16:40:15 hyc Locked $
d42 3
d57 3
a59 1
a142 3
#if !DOS
static int cr=0; /* have we seen a CR? */
#endif
d152 8
a159 2
if (cr && (c != '\n')) {
putc_tst('\r', t);
a160 3
cr = 0;
} else if (c == '\r')
cr = 1;
@
1.3
log
@Merge Atari ST code
@
text
@d2 1
a2 1
* $Header: arcunp.c,v 1.2 88/06/01 16:39:12 hyc Locked $
d21 1
a21 1
#ifdef MTS
d138 3
d142 1
a142 1
#ifdef MTS
d146 10
a155 2
#ifndef DOS
if ((c != '\r') || image)
a156 1
putc_tst(c, t);
@
1.2
log
@Fix declarations
@
text
@d2 1
a2 1
* $Header: arcunp.c,v 1.4 88/04/19 01:40:31 hyc Exp $
d143 1
a143 1
#ifndef MSDOS
@
1.1
log
@Initial revision
@
text
@d2 1
a2 21
* $Log: arcunp.c,v $
* Revision 1.3 87/12/20 03:10:14 hyc
* Ah hah! The value fgetc was returning was getting sign extended!
* Thus, 0xff was indistinguishable from EOF, causing the premature
* termination... The solution is to use getc, which doesn't do this
* (on the Apollos, anyway...)
*
* Note that I could *not* duplicate this behavior in a 5 liner...?
*
* Revision 1.2 87/12/19 04:11:22 hyc
* Move image mode code around from MTS only to non-MSDOS.
*
* Revision 1.1 87/12/19 04:06:39 hyc
* Initial revision
*
* Revision 1.3 87/08/13 17:06:08 hyc
* Run thru indent, fixed some signed vs. unsigned problems
* with bp <-> buf, and inbuf and localbuf...
* Revision 1.2 87/07/21 09:28:31 hyc *** empty
* log message ***
*
d21 3
d25 4
d33 1
a33 1
static INT state; /* repeat unpacking state */
d40 2
a41 2
static INT crcval; /* CRC check value */
static LONG size; /* bytes to read */
d43 1
a43 1
INT
d48 4
a51 4
INT c; /* one char of stream */
INT putc_unp();
INT putc_ncr();
INT getc_unp();
d66 1
a66 1
putc_unp(c, t);
d71 1
a71 1
putc_ncr(c, t);
d77 1
a77 1
putc_ncr(c, t);
d83 1
a83 1
putc_unp(c, t);
d89 1
a89 1
putc_ncr(c, t);
d95 1
a95 1
putc_ncr(c, t);
d102 4
d133 1
a133 1
static INT
d161 1
a161 1
INT
d166 1
a166 1
static INT lastc; /* last character seen */
d195 1
a195 1
INT
d199 3
a201 1
register INT xx;
@