/* ------------------------------------------------------------------------ */
#include "lha.h"
+static long reading_size;
+
/* ------------------------------------------------------------------------ */
int
encode_lzhuf(infp, outfp, size, original_size_var, packed_size_var,
char *hdr_method;
{
static int method = -1;
+ unsigned int crc;
if (method < 0) {
method = compress_method;
interface.outfile = outfp;
interface.original = size;
start_indicator(name, size, "Freezing", 1 << dicbit);
- encode(&interface);
+ crc = encode(&interface);
*packed_size_var = interface.packed;
*original_size_var = interface.original;
} else {
- copyfile(infp, outfp, size, 1);
+ copyfile(infp, outfp, size, 0, &crc);
*packed_size_var = *original_size_var = size;
}
memcpy(hdr_method, "-lh -", 5);
reading_size = 0L;
}
/* ------------------------------------------------------------------------ */
+#ifdef NEED_INCREMENTAL_INDICATOR
+void
+put_indicator(count)
+ long int count;
+{
+ reading_size += count;
+ if (!quiet && indicator_threshold) {
+ while (reading_size > indicator_count) {
+ putchar('o');
+ fflush(stdout);
+ indicator_count += indicator_threshold;
+ }
+ }
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
void
finish_indicator2(name, msg, pcnt)
char *name;
#endif
fflush(stdout);
}
+
/* ------------------------------------------------------------------------ */
void
finish_indicator(name, msg)
#include "lha.h"
/* ------------------------------------------------------------------------ */
-static unsigned short crctable[UCHAR_MAX + 1];
static unsigned char subbitbuf, bitcount;
#ifdef EUC
static int putc_euc_cache;
}
/* ------------------------------------------------------------------------ */
-#ifdef NEED_INCREMENTAL_INDICATOR
-static void
-put_indicator(count)
- long int count;
-{
- if (!quiet && indicator_threshold) {
- while (count > indicator_count) {
- putchar('o');
- fflush(stdout);
- indicator_count += indicator_threshold;
- }
- }
-}
-#endif
-
-/* ------------------------------------------------------------------------ */
-unsigned short
-calccrc(p, n)
+unsigned int
+calccrc(crc, p, n)
+ unsigned int crc;
unsigned char *p;
unsigned int n;
{
- reading_size += n;
-#ifdef NEED_INCREMENTAL_INDICATOR
- put_indicator(reading_size);
-#endif
while (n-- > 0)
- UPDATE_CRC(*p++);
+ crc = UPDATE_CRC(crc, *p++);
return crc;
}
/* ------------------------------------------------------------------------ */
int
-fread_crc(p, n, fp)
+fread_crc(crcp, p, n, fp)
+ unsigned int *crcp;
unsigned char *p;
int n;
FILE *fp;
else
n = fread(p, 1, n, fp);
- calccrc(p, n);
+ *crcp = calccrc(*crcp, p, n);
+#ifdef NEED_INCREMENTAL_INDICATOR
+ put_indicator(n);
+#endif
return n;
}
/* ------------------------------------------------------------------------ */
void
-fwrite_crc(p, n, fp)
+fwrite_crc(crcp, p, n, fp)
+ unsigned int *crcp;
unsigned char *p;
int n;
FILE *fp;
{
- calccrc(p, n);
+ *crcp = calccrc(*crcp, p, n);
+#ifdef NEED_INCREMENTAL_INDICATOR
+ put_indicator(n);
+#endif
if (verify_mode)
return;
return cnt;
}
-/* ------------------------------------------------------------------------ */
-unsigned short
-calc_header_crc(p, n) /* Thanks T.Okamoto */
- unsigned char *p;
- unsigned int n;
-{
- crc = 0;
- while (n-- > 0)
- UPDATE_CRC(*p++);
- return crc;
-}
/* Local Variables: */
/* tab-width : 4 */
/* End: */
char *name;
int method;
{
+ unsigned int crc;
+
interface.method = method;
interface.dicbit = 13; /* method + 8; -lh5- */
interface.infile = infp;
case LARC4_METHOD_NUM:
start_indicator(name, original_size
,verify_mode ? "Testing " : "Melting ", 2048);
- copyfile(infp, (verify_mode ? NULL : outfp), original_size, 2);
+ copyfile(infp, (verify_mode ? NULL : outfp), original_size, 2, &crc);
break;
case LARC_METHOD_NUM: /* -lzs- */
interface.dicbit = 11;
start_indicator(name, original_size
,verify_mode ? "Testing " : "Melting "
,1 << interface.dicbit);
- decode(&interface);
+ crc = decode(&interface);
break;
case LZHUFF1_METHOD_NUM: /* -lh1- */
case LZHUFF4_METHOD_NUM: /* -lh4- */
start_indicator(name, original_size
,verify_mode ? "Testing " : "Melting "
,1 << interface.dicbit);
- decode(&interface);
+ crc = decode(&interface);
break;
case LZHUFF6_METHOD_NUM: /* -lh6- */ /* Added N.Watazaki (^_^) */
#ifdef SUPPORT_LH7
start_indicator(name, original_size
,verify_mode ? "Testing " : "Melting "
,1 << interface.dicbit);
- decode(&interface);
+ crc = decode(&interface);
}
finish_indicator(name, verify_mode ? "Tested " : "Melted ");
#endif
/* ------------------------------------------------------------------------ */
-static unsigned short
+static int
get_word()
{
int b0, b1;
- unsigned short w;
+ int w;
#if DUMP_HEADER
printf("%02d %2d: ", get_ptr - start_ptr, 2);
* size field is 4 bytes
*/
static long
-get_extended_header(fp, hdr, header_size)
+get_extended_header(fp, hdr, header_size, hcrc)
FILE *fp;
LzHeader *hdr;
long header_size;
+ unsigned int *hcrc;
{
char data[LZHEADER_STORAGE];
int name_length;
error("Invalid header (LHa file ?)");
return -1;
}
+
ext_type = get_byte();
switch (ext_type) {
case 0:
/* header crc (CRC-16) */
- skip_bytes(header_size - n); /* FIXME: ignored? */
+ hdr->header_crc = get_word();
+ *--get_ptr = 0; /* clear buffer for CRC calculation. */
+ *--get_ptr = 0;
+ skip_bytes(header_size - n);
break;
case 1:
/* filename */
}
next:
+ if (hcrc)
+ *hcrc = calccrc(*hcrc, data, header_size);
+
if (hdr->size_field_length == 2)
whole_size += header_size = get_word();
else
if (extend_size > 0)
skip_bytes(extend_size);
+ hdr->header_size += 2;
return TRUE;
}
skip_bytes(dummy); /* skip old style extend header */
extend_size = get_word();
- extend_size = get_extended_header(fp, hdr, extend_size);
+ extend_size = get_extended_header(fp, hdr, extend_size, 0);
if (extend_size == -1)
return FALSE;
/* the `packed_size' field contains the extended header size. */
/* the `header_size' field does not. */
hdr->packed_size -= extend_size;
- hdr->header_size += extend_size;
+ hdr->header_size += extend_size + 2;
return TRUE;
}
{
int header_size, extend_size;
int padding;
+ unsigned int hcrc;
hdr->size_field_length = 2; /* in bytes */
hdr->header_size = header_size = get_word();
hdr->extend_type = get_byte();
extend_size = get_word();
- extend_size = get_extended_header(fp, hdr, extend_size);
+ INITIALIZE_CRC(hcrc);
+ hcrc = calccrc(hcrc, data, get_ptr - data);
+
+ extend_size = get_extended_header(fp, hdr, extend_size, &hcrc);
if (extend_size == -1)
return FALSE;
padding = header_size - 26 - extend_size;
while (padding--) /* padding should be 0 or 1 */
- fgetc(fp);
+ hcrc = UPDATE_CRC(hcrc, fgetc(fp));
- /* FIXME: no collate the header CRC */
+ if (hdr->header_crc != hcrc)
+ error("header CRC error");
return TRUE;
}
{
long header_size, extend_size;
int padding;
+ unsigned int hcrc;
hdr->size_field_length = get_word();
hdr->header_size = header_size = get_longword();
extend_size = get_longword();
- extend_size = get_extended_header(fp, hdr, extend_size);
+ INITIALIZE_CRC(hcrc);
+ hcrc = calccrc(hcrc, data, get_ptr - data);
+
+ extend_size = get_extended_header(fp, hdr, extend_size, &hcrc);
if (extend_size == -1)
return FALSE;
padding = header_size - 32 - extend_size;
- while (padding--) /* padding should be 0 */
- fgetc(fp);
+ while (padding--) /* padding should be 0 */
+ hcrc = UPDATE_CRC(hcrc, fgetc(fp));
- /* FIXME: no collate the header CRC */
+ if (hdr->header_crc != hcrc)
+ error("header CRC error");
return TRUE;
}
int header_size;
char *extend_header_top;
char *headercrc_ptr;
- unsigned short hcrc;
+ unsigned int hcrc;
basename = strrchr(pathname, LHA_PATHSEP);
if (basename) {
put_word(header_size);
/* put hader CRC in extended header */
- hcrc = calc_header_crc(data, (unsigned int) header_size);
+ INITIALIZE_CRC(hcrc);
+ hcrc = calccrc(hcrc, data, (unsigned int) header_size);
setup_put(headercrc_ptr);
put_word(hcrc);
unsigned char attribute;
unsigned char header_level;
char name[FILENAME_LENGTH];
- unsigned short crc;
- boolean has_crc;
+ unsigned int crc; /* file CRC */
+ boolean has_crc; /* file CRC */
+ unsigned int header_crc; /* header CRC */
unsigned char extend_type;
unsigned char minor_version;
EXTERN int archive_file_gid;
EXTERN struct interfacing interface;
-/* EXTERN unsigned short crc; */ /* 1996.8.13 t.okamoto */
EXTERN int noconvertcase; /* 2000.10.6 */
/* crcio.c */
EXTERN FILE *infile, *outfile;
-EXTERN unsigned short crc, bitbuf;
+EXTERN unsigned short bitbuf;
+EXTERN unsigned int crctable[UCHAR_MAX + 1];
EXTERN int dispflg;
-EXTERN long reading_size;
/* from dhuf.c */
EXTERN unsigned int n_max;
/* from crcio.c */
#define CRCPOLY 0xA001 /* CRC-16 (x^16+x^15+x^2+1) */
-#define UPDATE_CRC(c) crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
+#define INITIALIZE_CRC(crc) ((crc) = 0)
+#define UPDATE_CRC(crc, c) \
+ (crctable[((crc) ^ (c)) & 0xFF] ^ ((crc) >> CHAR_BIT))
/* dhuf.c */
#define N_CHAR (256 + 60 - THRESHOLD + 1)
oafp = xfopen(temporary_name, READ_BINARY);
reading_filename = temporary_name;
- copyfile(oafp, nafp, new_archive_size, 0);
+ copyfile(oafp, nafp, new_archive_size, 0, 0);
if (nafp != stdout)
fclose(nafp);
fclose(oafp);
LzHeader *hdr;
{
if (noexec) {
- fseek(oafp, (long) (hdr->header_size + 2) + hdr->packed_size, SEEK_CUR);
+ fseek(oafp, hdr->header_size + hdr->packed_size, SEEK_CUR);
}
else {
reading_filename = archive_name;
writing_filename = temporary_name;
- if (hdr->header_level != 2) {
- copyfile(oafp, nafp,
- (long) (hdr->header_size + 2) + hdr->packed_size, 0);
- } else {
- copyfile(oafp, nafp,
- (long) (hdr->header_size) + hdr->packed_size, 0);
- }
+ copyfile(oafp, nafp, hdr->header_size + hdr->packed_size, 0, 0);
}
}
/* ¼½ñ¤ò DICSIZ ʬ Á°¤Ë¤º¤é¤¹ */
-static void update()
+static unsigned int
+update(crc)
+ unsigned int crc;
{
unsigned int i, j;
long n;
}
}
#endif
- n = fread_crc(&text[(unsigned)(txtsiz - dicsiz)],
+ n = fread_crc(&crc, &text[(unsigned)(txtsiz - dicsiz)],
(unsigned)dicsiz, infile);
remainder += n;
j = prev[i];
prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
}
+
+ return crc;
}
/* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
-static void get_next()
+static unsigned int
+get_next(crc)
+ unsigned int crc;
{
remainder--;
if (++pos >= txtsiz - maxmatch) {
- update();
+ crc = update(crc);
#ifdef DEBUG
noslide = 0;
#endif
}
hval = ((hval << 5) ^ text[pos + 2]) & (unsigned)(HSHSIZ - 1);
+
+ return crc;
}
-void encode(interface)
-struct interfacing *interface;
+unsigned int
+encode(interface)
+ struct interfacing *interface;
{
int lastmatchlen;
unsigned int lastmatchoffset;
+ unsigned int crc;
#ifdef DEBUG
unsigned int addr;
outfile = interface->outfile;
origsize = interface->original;
compsize = count = 0L;
- crc = unpackable = 0;
+ unpackable = 0;
+
+ INITIALIZE_CRC(crc);
/* encode_alloc(); */ /* allocate_memory(); */
init_slide();
encode_set.encode_start();
memset(&text[0], ' ', (long)TXTSIZ);
- remainder = fread_crc(&text[dicsiz], txtsiz-dicsiz, infile);
+ remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
encoded_origsize = remainder;
matchlen = THRESHOLD - 1;
while (remainder > 0 && ! unpackable) {
lastmatchlen = matchlen; lastmatchoffset = pos - matchpos - 1;
--matchlen;
- get_next(); match_insert();
+ crc = get_next(crc); match_insert();
if (matchlen > remainder) matchlen = remainder;
if (matchlen > lastmatchlen || lastmatchlen < THRESHOLD) {
encode_set.output(text[pos - 1], 0);
}
#endif
while (--lastmatchlen > 0) {
- get_next(); insert();
+ crc = get_next(crc); insert();
count++;
}
- get_next();
+ crc = get_next(crc);
matchlen = THRESHOLD - 1;
match_insert();
if (matchlen > remainder) matchlen = remainder;
interface->packed = compsize;
interface->original = encoded_origsize;
+
+ return crc;
}
/* ------------------------------------------------------------------------ */
-void
+unsigned int
decode(interface)
struct interfacing *interface;
{
unsigned int i, j, k, c;
unsigned int dicsiz1, offset;
unsigned char *dtext;
-
+ unsigned int crc;
#ifdef DEBUG
fout = fopen("de", "wt");
compsize = interface->packed;
decode_set = decode_define[interface->method - 1];
- crc = 0;
+ INITIALIZE_CRC(crc);
prev_char = -1;
dicsiz = 1L << dicbit;
dtext = (unsigned char *)xmalloc(dicsiz);
#endif
dtext[loc++] = c;
if (loc == dicsiz) {
- fwrite_crc(dtext, dicsiz, outfile);
+ fwrite_crc(&crc, dtext, dicsiz, outfile);
loc = 0;
}
count++;
#endif
dtext[loc++] = c;
if (loc == dicsiz) {
- fwrite_crc(dtext, dicsiz, outfile);
+ fwrite_crc(&crc, dtext, dicsiz, outfile);
loc = 0;
}
}
}
}
if (loc != 0) {
- fwrite_crc(dtext, loc, outfile);
+ fwrite_crc(&crc, dtext, loc, outfile);
}
free(dtext);
+ return crc;
}
/* Local Variables: */
#include <errno.h>
/* ------------------------------------------------------------------------ */
-extern unsigned short crc;
-extern int quiet;
-/* ------------------------------------------------------------------------ */
long
-copyfile(f1, f2, size, crc_flg) /* return: size of source file */
+copyfile(f1, f2, size, text_flg, crcp) /* return: size of source file */
FILE *f1;
FILE *f2;
long size;
- int crc_flg;/* 0: no crc, 1: crc check, 2: extract, 3:
- * append */
+ int text_flg; /* 0: binary, 1: read text, 2: write text */
+ unsigned int *crcp;
{
unsigned short xsize;
char *buf;
long rsize = 0;
+ if (!text_mode)
+ text_flg = 0;
+
buf = (char *)xmalloc(BUFFERSIZE);
- crc = 0;
- if ((crc_flg == 2 || crc_flg) && text_mode)
+ if (crcp)
+ INITIALIZE_CRC(*crcp);
+ if (text_flg)
init_code_cache();
while (size > 0) {
/* read */
- if (crc_flg == 3 && text_mode) {
+ if (text_flg & 1) {
xsize = fread_txt(buf, BUFFERSIZE, f1);
if (xsize == 0)
break;
if (fread(buf, 1, xsize, f1) != xsize) {
fatal_error("file read error");
}
+ size -= xsize;
}
/* write */
if (f2) {
- if (crc_flg == 2 && text_mode) {
+ if (text_flg & 2) {
if (fwrite_txt(buf, xsize, f2)) {
fatal_error("file write error");
}
}
}
/* calculate crc */
- if (crc_flg) {
- calccrc(buf, xsize);
+ if (crcp) {
+ *crcp = calccrc(*crcp, buf, xsize);
+#ifdef NEED_INCREMENTAL_INDICATOR
+ put_indicator(xsize);
+#endif
}
rsize += xsize;
- if (crc_flg != 3 || !text_mode)
- size -= xsize;
}
free(buf);
return rsize;
long *write_size_var;
{
int save_quiet;
+ unsigned int crc;
save_quiet = quiet;
quiet = 1;
- size = copyfile(ifp, ofp, size, 3);
+ size = copyfile(ifp, ofp, size, 1, &crc);
*original_size_var = *write_size_var = size;
quiet = save_quiet;
return crc;