OSDN Git Service

* src/header.c (get_header_level2): check CRC value for reading
authorarai <arai@6a8cc165-1e22-0410-a132-eb4e3f353aba>
Sat, 10 Aug 2002 10:08:56 +0000 (10:08 +0000)
committerarai <arai@6a8cc165-1e22-0410-a132-eb4e3f353aba>
Sat, 10 Aug 2002 10:08:56 +0000 (10:08 +0000)
level 2 and 3 header.
(get_header_level3): ditto.
(get_extended_header): ditto.
(get_header_level0): set total header size to
`LzHeader.header_size' even if level 0 or 1 header is read.
(get_header_level1): ditto.

* src/append.c (encode_lzhuf): encode(), decode() and copyfile()
were changed.
(put_indicator): moved from crcio.c.

* src/crcio.c (put_indicator): moved to append.c.
(calccrc): generalized.
(fread_crc): changed interface.
(fwrite_crc): changed interface.
(calc_header_crc): removed. use calccrc() instead.

* src/extract.c (decode_lzhuf): copyfile() and decode() were changed.

* src/lha.h: hate global variable. `crc' is removed.
`reading_size' moved to append.c.

* src/lha_macro.h (INITIALIZE_CRC): newly added.
(UPDATE_CRC): no update in macro code.

* src/lhadd.c (temporary_to_new_archive_file): copyfile() was changed.

* src/lharc.c (copy_old_one): header size adjusting is done by
the get_header().

* src/slide.c (update): changed interface.
(get_next): ditto.
(encode): ditto.
(decode): ditto.

* src/util.c (copyfile): changed interface.

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/lha/lha/trunk@452 6a8cc165-1e22-0410-a132-eb4e3f353aba

src/append.c
src/crcio.c
src/extract.c
src/header.c
src/lha.h
src/lha_macro.h
src/lhadd.c
src/lharc.c
src/slide.c
src/util.c

index d404104..b67665e 100644 (file)
@@ -8,6 +8,8 @@
 /* ------------------------------------------------------------------------ */
 #include "lha.h"
 
+static long reading_size;
+
 /* ------------------------------------------------------------------------ */
 int
 encode_lzhuf(infp, outfp, size, original_size_var, packed_size_var,
@@ -21,6 +23,7 @@ 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;
@@ -35,11 +38,11 @@ encode_lzhuf(infp, outfp, size, original_size_var, packed_size_var,
                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);
@@ -96,6 +99,23 @@ start_indicator(name, size, msg, def_indicator_threshold)
        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;
@@ -114,6 +134,7 @@ finish_indicator2(name, msg, pcnt)
 #endif
        fflush(stdout);
 }
+
 /* ------------------------------------------------------------------------ */
 void
 finish_indicator(name, msg)
index e912af9..9f70d37 100644 (file)
@@ -9,7 +9,6 @@
 #include "lha.h"
 
 /* ------------------------------------------------------------------------ */
-static unsigned short crctable[UCHAR_MAX + 1];
 static unsigned char subbitbuf, bitcount;
 #ifdef EUC
 static int      putc_euc_cache;
@@ -34,33 +33,14 @@ make_crctable( /* void */ )
 }
 
 /* ------------------------------------------------------------------------ */
-#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;
 }
 
@@ -150,7 +130,8 @@ putbits(n, x)                       /* Write rightmost n bits of x */
 
 /* ------------------------------------------------------------------------ */
 int
-fread_crc(p, n, fp)
+fread_crc(crcp, p, n, fp)
+    unsigned int *crcp;
        unsigned char  *p;
        int             n;
        FILE           *fp;
@@ -160,18 +141,25 @@ fread_crc(p, n, 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;
 
@@ -341,17 +329,6 @@ fread_txt(p, n, fp)
        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: */
index 931308a..00b66bd 100644 (file)
@@ -17,6 +17,8 @@ decode_lzhuf(infp, outfp, original_size, packed_size, name, method)
        char           *name;
        int             method;
 {
+    unsigned int crc;
+
        interface.method = method;
        interface.dicbit = 13;  /* method + 8; -lh5- */
        interface.infile = infp;
@@ -29,14 +31,14 @@ decode_lzhuf(infp, outfp, original_size, packed_size, name, method)
        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- */
@@ -45,7 +47,7 @@ decode_lzhuf(infp, outfp, original_size, packed_size, name, method)
                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
@@ -57,7 +59,7 @@ decode_lzhuf(infp, outfp, original_size, packed_size, name, method)
                start_indicator(name, original_size
                                ,verify_mode ? "Testing " : "Melting "
                                ,1 << interface.dicbit);
-               decode(&interface);
+               crc = decode(&interface);
        }
        finish_indicator(name, verify_mode ? "Tested  " : "Melted  ");
 
index 2d283fb..e718272 100644 (file)
@@ -91,11 +91,11 @@ dump_skip_bytes(len)
 #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);
@@ -525,10 +525,11 @@ unix_to_generic_stamp(t)
  *    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;
@@ -555,11 +556,15 @@ get_extended_header(fp, hdr, header_size)
             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 */
@@ -619,6 +624,9 @@ get_extended_header(fp, hdr, header_size)
         }
 
     next:
+        if (hcrc)
+            *hcrc = calccrc(*hcrc, data, header_size);
+
         if (hdr->size_field_length == 2)
             whole_size += header_size = get_word();
         else
@@ -761,6 +769,7 @@ get_header_level0(fp, hdr, data)
     if (extend_size > 0)
         skip_bytes(extend_size);
 
+    hdr->header_size += 2;
     return TRUE;
 }
 
@@ -845,7 +854,7 @@ get_header_level1(fp, hdr, data)
         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;
 
@@ -853,7 +862,7 @@ get_header_level1(fp, hdr, data)
     /* 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;
 }
@@ -895,6 +904,7 @@ get_header_level2(fp, hdr, data)
 {
     int header_size, extend_size;
     int padding;
+    unsigned int hcrc;
 
     hdr->size_field_length = 2; /* in bytes */
     hdr->header_size = header_size = get_word();
@@ -921,15 +931,19 @@ get_header_level2(fp, hdr, data)
     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;
 }
@@ -969,6 +983,7 @@ get_header_level3(fp, hdr, data)
 {
     long header_size, extend_size;
     int padding;
+    unsigned int hcrc;
 
     hdr->size_field_length = get_word();
 
@@ -995,15 +1010,19 @@ get_header_level3(fp, hdr, data)
     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;
 }
@@ -1380,7 +1399,7 @@ write_header_level2(data, hdr, pathname)
     int header_size;
     char *extend_header_top;
     char *headercrc_ptr;
-    unsigned short hcrc;
+    unsigned int hcrc;
 
     basename = strrchr(pathname, LHA_PATHSEP);
     if (basename) {
@@ -1484,7 +1503,8 @@ write_header_level2(data, hdr, pathname)
     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);
 
index 61461eb..a7aa70e 100644 (file)
--- a/src/lha.h
+++ b/src/lha.h
@@ -211,8 +211,9 @@ typedef struct LzHeader {
        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;
 
@@ -292,7 +293,6 @@ EXTERN int      archive_file_mode;
 EXTERN int      archive_file_gid;
 
 EXTERN struct  interfacing interface;
-/* EXTERN unsigned short crc; */  /* 1996.8.13 t.okamoto */
 
 EXTERN int      noconvertcase; /* 2000.10.6 */
 
@@ -322,9 +322,9 @@ EXTERN long         indicator_threshold;
 
 /* 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;
index 26ac285..67dc6fb 100644 (file)
 
 /* 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)
index 5c3d9fb..29d3e6d 100644 (file)
@@ -346,7 +346,7 @@ temporary_to_new_archive_file(new_archive_size)
 
        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);
index bc2573f..891548d 100644 (file)
@@ -1149,18 +1149,12 @@ copy_old_one(oafp, nafp, hdr)
        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);
        }
 }
 
index 14cff86..9bcca6d 100644 (file)
@@ -165,7 +165,9 @@ static void init_slide()
 
 /* ¼­½ñ¤ò DICSIZ Ê¬ Á°¤Ë¤º¤é¤¹ */
 
-static void update()
+static unsigned int
+update(crc)
+    unsigned int crc;
 {
        unsigned int i, j;
        long n;
@@ -181,7 +183,7 @@ static void update()
                }
        }
 #endif
-       n = fread_crc(&text[(unsigned)(txtsiz - dicsiz)], 
+       n = fread_crc(&crc, &text[(unsigned)(txtsiz - dicsiz)], 
                                   (unsigned)dicsiz, infile);
 
        remainder += n;
@@ -197,6 +199,8 @@ static void update()
                j = prev[i];
                prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
        }
+
+    return crc;
 }
 
 
@@ -273,23 +277,29 @@ static void match_insert()
 
 /* ¥Ý¥¤¥ó¥¿¤ò¿Ê¤á¡¢¼­½ñ¤ò¹¹¿·¤·¡¢¥Ï¥Ã¥·¥åÃͤò¹¹¿·¤¹¤ë */
 
-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;
@@ -303,7 +313,9 @@ struct interfacing *interface;
        outfile = interface->outfile;
        origsize = interface->original;
        compsize = count = 0L;
-       crc = unpackable = 0;
+       unpackable = 0;
+
+    INITIALIZE_CRC(crc);
 
        /* encode_alloc(); */ /* allocate_memory(); */
        init_slide();  
@@ -311,7 +323,7 @@ struct interfacing *interface;
        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;
 
@@ -325,7 +337,7 @@ struct interfacing *interface;
        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);
@@ -354,10 +366,10 @@ struct interfacing *interface;
                        }
 #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;
@@ -367,17 +379,19 @@ struct interfacing *interface;
 
        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");
@@ -391,7 +405,7 @@ decode(interface)
        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);
@@ -409,7 +423,7 @@ decode(interface)
 #endif
                        dtext[loc++] = c;
                        if (loc == dicsiz) {
-                               fwrite_crc(dtext, dicsiz, outfile);
+                               fwrite_crc(&crc, dtext, dicsiz, outfile);
                                loc = 0;
                        }
                        count++;
@@ -429,7 +443,7 @@ decode(interface)
 #endif
                                dtext[loc++] = c;
                                if (loc == dicsiz) {
-                                       fwrite_crc(dtext, dicsiz, outfile);
+                                       fwrite_crc(&crc, dtext, dicsiz, outfile);
                                        loc = 0;
                                }
                        }
@@ -439,10 +453,11 @@ decode(interface)
                }
        }
        if (loc != 0) {
-               fwrite_crc(dtext, loc, outfile);
+               fwrite_crc(&crc, dtext, loc, outfile);
        }
 
        free(dtext);
+    return crc;
 }
 
 /* Local Variables: */
index da01caa..094d82e 100644 (file)
 #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;
@@ -50,10 +51,11 @@ copyfile(f1, f2, size, crc_flg)     /* return: size of source file */
                        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");
                                }
@@ -65,12 +67,13 @@ copyfile(f1, f2, size, crc_flg)     /* return: size of source file */
                        }
                }
                /* 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;
@@ -85,10 +88,11 @@ encode_stored_crc(ifp, ofp, size, original_size_var, write_size_var)
        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;