home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-21 | 54.4 KB | 1,815 lines |
- Newsgroups: comp.sources.misc
- From: kirsch@usasoc.soc.mil (David Kirschbaum)
- Subject: v23i095: zip - Portable zip v1.0, Part08/09
- Message-ID: <1991Oct21.042237.8253@sparky.imd.sterling.com>
- X-Md4-Signature: bc22c8cab548726210a525d01abcccad
- Date: Mon, 21 Oct 1991 04:22:37 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
- Posting-number: Volume 23, Issue 95
- Archive-name: zip/part08
- Environment: UNIX, Minix, MSDOS, OS/2, VMS
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: im_bits.c im_lm.asm implode.c implode.h makefile.os2
- # ship.def zip.h zipnote.c
- # Wrapped by kent@sparky on Sun Oct 20 22:58:56 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 8 (of 9)."'
- if test -f 'im_bits.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'im_bits.c'\"
- else
- echo shar: Extracting \"'im_bits.c'\" \(4743 characters\)
- sed "s/^X//" >'im_bits.c' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * im_bits.c by Richard B. Wales & Jean-loup Gailly.
- X *
- X * PURPOSE
- X *
- X * Output variable-length bit strings.
- X *
- X * DISCUSSION
- X *
- X * The PKZIP "imploded" file format interprets compressed file data
- X * as a sequence of bits. Multi-bit strings in the file may cross
- X * byte boundaries without restriction.
- X *
- X * The first bit of each byte is the low-order bit.
- X *
- X * The routines in this file allow a variable-length bit value to
- X * be output right-to-left (useful for literal values). For
- X * left-to-right output (useful for code strings from the tree routines),
- X * the bits must have been reversed first with bi_reverse().
- X *
- X * INTERFACE
- X *
- X * ImpErr bi_init (FILE *fp)
- X * Initialize the bit string routines and specify the output
- X * file to be written to in subsequent calls.
- X *
- X * ImpErr bi_rlout (int value, int length)
- X * Write out a bit string, taking the source bits right to
- X * left.
- X *
- X * int bi_reverse (int value, int length)
- X * Reverse the bits of a bit string, taking the source bits left to
- X * right and emitting them right to left.
- X *
- X * ImpErr bi_windup (void)
- X * Write out any remaining bits in an incomplete byte.
- X */
- X
- X
- X#include "implode.h"
- X
- X
- X/***********************************************************************
- X *
- X * Local data used by the "bit string" routines.
- X */
- X
- X
- X/* Current file stream pointer. */
- Xlocal FILE * bi_fp;
- X
- Xlocal unsigned short bi_buf;
- X/* Output buffer. bits are inserted starting at the bottom (least significant
- X * bits).
- X */
- X
- X#define Buf_size (8 * 2*sizeof(char))
- X/* Number of bits used within bi_buf. (bi_buf might be implemented on
- X * more than 16 bits on some systems.)
- X */
- X
- Xlocal int bi_valid; /* number of valid bits in bi_buf */
- X/* All bits above the last valid bit are always zero.
- X */
- X
- X/* Output a 16 bit value to the bit stream, lower (oldest) byte first */
- X#define PUTSHORT(w) \
- X{ (void) zputc ((char)((w) & 0xff), bi_fp); \
- X (void) zputc ((char)((US_INT)(w) >> 8), bi_fp); \
- X if (ferror (bi_fp)) return IM_IOERR; \
- X}
- X
- X/* Output an 8 bit value to the bit stream, bits right to left */
- X#define PUTBYTE(w) \
- X{ (void) zputc ((char)((w) & 0xff), bi_fp); \
- X if (ferror (bi_fp)) return IM_IOERR; \
- X}
- X
- X/***********************************************************************
- X *
- X * Initialize the bit string routines.
- X */
- X
- XImpErr
- Xbi_init (fp)
- X FILE *fp;
- X{ if (fp == NULL)
- X { fprintf (stderr, "\nError in bi_init: null file pointer");
- X return IM_LOGICERR;
- X }
- X bi_fp = fp;
- X bi_buf = 0;
- X bi_valid = 0;
- X return IM_OK;
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Output bits from right to left.
- X */
- X
- XImpErr
- Xbi_rlout (value, length)
- X int value;
- X int length; /* must be <= 16 */
- X{
- X /* Send value on length bits. If not enough room in bi_buf, use
- X * (valid) bits from bi_buf and (16 - bi_valid) bits from value, leaving
- X * (width - (16-bi_valid)) unused bits in value.
- X */
- X if (bi_valid > Buf_size - length) {
- X bi_buf |= (value << bi_valid);
- X PUTSHORT(bi_buf);
- X bi_buf = (unsigned short)value >> (Buf_size - bi_valid);
- X bi_valid += length - Buf_size;
- X } else {
- X bi_buf |= value << bi_valid;
- X bi_valid += length;
- X }
- X#ifdef IMPDEBUG
- X fprintf (stderr, " / ");
- X while (length-- > 0)
- X {
- X putc ((value & 1) ? '1' : '0', stderr);
- X value >>= 1;
- X }
- X#endif /* IMPDEBUG */
- X return IM_OK;
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Reverse the bits of a bit string, taking the source bits left to
- X * right (starting at 2^15) and emitting them right to left.
- X */
- X
- Xint
- Xbi_reverse (value, length)
- X int value;
- X int length;
- X{
- X int result = 0;
- X unsigned short lbit = 0x8000;
- X unsigned short rbit = 1;
- X while (length-- > 0) {
- X if (value & lbit) result |= rbit;
- X lbit >>= 1, rbit <<= 1;
- X }
- X return result;
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Flush any remaining bits.
- X */
- X
- XImpErr
- Xbi_windup ()
- X{
- X if (bi_valid > 8) {
- X PUTSHORT(bi_buf);
- X } else if (bi_valid > 0) {
- X PUTBYTE(bi_buf);
- X }
- X bi_buf = 0;
- X bi_valid = 0;
- X return IM_OK;
- X}
- X
- X
- X/**********************************************************************/
- END_OF_FILE
- if test 4743 -ne `wc -c <'im_bits.c'`; then
- echo shar: \"'im_bits.c'\" unpacked with wrong size!
- fi
- # end of 'im_bits.c'
- fi
- if test -f 'im_lm.asm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'im_lm.asm'\"
- else
- echo shar: Extracting \"'im_lm.asm'\" \(9944 characters\)
- sed "s/^X//" >'im_lm.asm' <<'END_OF_FILE'
- X;
- X; Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X; Permission is granted to any individual or institution to use, copy, or
- X; redistribute this software so long as all of the original files are included
- X; unmodified, that it is not sold for profit, and that this copyright notice
- X; is retained.
- X;
- X
- X; im_lm.asm by Jean-loup Gailly.
- X
- X;im_lm.asm, optimized version of longest_match() and lm_process() in im_lmat.c
- X; Must be assembled with masm -ml. To be used only with C small model or
- X; compact model. This file is only optional. If you don't have masm, use the
- X; C version (add -DNO_ASM to CFLAGS in makefile.dos and remove im_lm.obj
- X; from OBJI).
- X;
- X; Turbo C 2.0 does not support static allocation of far data in
- X; the small model. So TC 2.0 users must assemble this with:
- X; tasm -ml -DDYN_ALLOC im_lm;
- X; OS/2 users must assemble this with -DOS2 -ml. To simplify the code,
- X; the option -DDYN_ALLOC is not supported for OS/2.
- X name im_lm
- X
- Xifndef DYN_ALLOC
- X extrn _prev : word
- X extrn _next : word
- X prev equ _prev
- X next equ _next
- Xload_es_prev macro
- X mov cx,seg _prev
- X mov es,cx
- Xendm
- Xload_ds_next macro
- X mov si,seg _next
- X mov ds,si
- Xendm
- Xendif
- X
- X_BSS segment word public 'BSS'
- X extrn _window : byte
- X extrn _match_length : word
- X extrn _start_length : word
- X extrn _strstart : word
- X extrn _strsize : word
- X extrn _ins_h : word
- X extrn _h_shift : byte
- X extrn _checkpoint : word
- X extrn _bufsize : word
- X extrn _max_chain_length : word
- X extrn _min_match_length : word
- Xifdef DYN_ALLOC
- X extrn _prev : word
- X extrn _next : word
- X prev equ 0 ; offset normalized to zero (except for OS/2)
- X next equ 0 ; offset normalized to zero (except for OS/2)
- Xload_es_prev macro
- X mov es,_prev[2] ; warning: the offset should be added under OS/2
- Xendm
- Xload_ds_next macro
- X mov ds,_next[2] ; warning: the offset should be added under OS/2
- Xendm
- Xendif
- X cur_best dw 1 dup(?) ; best match within longest_match
- X_BSS ends
- X
- XDGROUP group _BSS
- X
- X_TEXT segment word public 'CODE'
- X assume cs: _TEXT, ds: DGROUP, ss: DGROUP
- X
- X extrn _write_match : near
- X
- X BSZ equ 4096 ; keep consistent with tailor.h
- X WSIZE equ 8192 ; keep consistent with im_lmat.c
- X NIL equ (WSIZE+BSZ)
- X MAX_DIST equ NIL
- X MAX_LENGTH equ 320 ; keep consistent with im_lmat.c
- X HASH_MASK equ 16383 ; (1<<14)-1
- X
- X; Process a block of characters already inserted in the window
- X; IN assertion: count > 0
- X public _lm_process
- X_lm_process proc near
- X push bp
- X mov bp,sp
- X push di
- X push si
- X
- X count equ word ptr [bp+4]
- X; delete_point equ ax
- X; ins_h equ bx
- X; h_shift equ cl
- X; count equ dx
- X; cur_match equ si
- X; strstart equ di
- X; min_match_length equ bp
- X
- X mov dx,count
- X mov bx,_ins_h
- X mov di,_strstart
- X lea ax,[di+MAX_LENGTH-1]
- X sub ax,_bufsize
- X jae del_ok
- X add ax,MAX_DIST
- Xdel_ok: shl ax,1 ;delete_point as word index
- X load_es_prev
- X mov cl,_h_shift
- X load_ds_next
- X assume ds: nothing
- X jmp short insert
- X
- Xstart_overflow:
- X sub di,di ;strstart = 0
- X sub ss:_checkpoint,MAX_DIST
- X jmp short check_count
- Xdel_overflow:
- X mov ax,-2 ;delete_point = 0
- Xmain_loop:
- X add ax,2 ;delete_point++ (word index)
- X cmp ax,2*MAX_DIST
- X je del_overflow
- X xchg ax,si ;si=2*delete_point
- X mov bp,next[si]
- X shl bp,1
- X mov es:prev[bp],NIL
- X xchg ax,si ;ax=2*delete_point
- X
- X inc di ;strstart++
- X cmp di,MAX_DIST
- X je start_overflow
- Xcheck_count:
- X dec dx ;count--
- X jz end_proc_ok
- Xinsert:
- X shl bx,cl ;ins_h <<= h_shift
- X mov bp,ss:_min_match_length
- X xor bl,_window[di+bp-1] ;ins_h ^= window[s+min_match_length-1]
- X and bx,HASH_MASK
- X add bx,MAX_DIST+1
- X shl bx,1 ;word index
- X mov si,es:prev[bx] ;cur_match = match_head[ins_h]
- X mov es:prev[bx],di ;prev[ins_h+MAX_DIST+1] = strstart
- X shr bx,1 ;bx = ins_h + MAX_DIST + 1
- X shl di,1 ;di = strstart as word index
- X mov next[di],bx
- X sub bx,MAX_DIST+1 ;bx = ins_h
- X mov es:prev[di],si ;prev[s] = cur_match
- X shr di,1 ;di = strstart
- X shl si,1
- X mov next[si],di ;next[cur_match] = strstart
- X cmp di,ss:_checkpoint
- X jne main_loop
- X
- X push ax
- X push bx
- X push dx
- X mov ax,ss
- X mov ds,ax
- X assume ds: DGROUP
- X mov _match_length,0
- X mov _strstart,di
- X shr si,1 ;si = cur_match
- X cmp si,NIL ;cur_match == NIL ?
- X je call_write
- X call _longest_match ;returns best_match in si
- Xcall_write:
- X push _match_length
- X push si ;best_match or NIL
- X call _write_match
- X add sp,4
- X pop dx
- X pop bx
- X or al,al
- X jnz failure
- X pop ax
- X load_es_prev
- X mov cl,_h_shift
- X load_ds_next
- X assume ds: nothing
- X jmp main_loop
- Xend_proc_ok:
- X mov ax,ss
- X mov ds,ax
- X assume ds: DGROUP
- X sub ax,ax
- X mov _strstart,di
- Xend_proc:
- X mov _ins_h,bx
- X pop si
- X pop di
- X pop bp
- X ret
- Xfailure:
- X add sp,2 ;skip pushed ax
- X jmp short end_proc
- X
- X_lm_process endp
- X
- X; Find the longest match starting at the given string. Return its position
- X; and set its length in match_length. Matches shorter or equal to
- X; start_length are discarded, in which case match_length is unchanged
- X; and the result position is NIL.
- X; IN assertions: cur_match is the head of the hash chain for the current
- X; string (strstart) and is not NIL, start_length >= 1.
- X; registers: es points to the base of the prev array (preserved)
- X; si = cur_match and return value
- X; di = strstart
- X
- X; IPos longest_match(cur_match)
- X
- X public _longest_match
- X_longest_match proc near
- X
- X push bp
- X push di
- X
- X; match equ si
- X; scan equ di
- X; chain_count equ bp
- X; ma_length equ bx
- X
- X lea di,_window[di+2] ; di = window + strstart + 2
- X mov cur_best,NIL
- X mov bp,_max_chain_length ; chain_count = max_chain_length
- X mov bx,_start_length ; ma_length = start_length
- X mov ax,[bx+di-3] ; ax = scan[ma_length-1..ma_length]
- X mov cx,[di-2] ; cx = scan[0..1]
- X jmp short do_scan
- X
- X even ; align destination of branch
- Xlong_loop:
- X; at this point, di == scan+2, si = cur_match
- X mov ax,[bx+di-3] ; ax = scan[ma_length-1..ma_length]
- X mov cx,[di-2] ; cx = scan[0..1]
- Xshort_loop:
- X dec bp ; --chain_count
- X jz the_end
- X; at this point, di == scan+2, si = cur_match,
- X; ax = scan[ma_length-1..ma_length] and cx = scan[0..1]
- X shl si,1 ; cur_match as word index
- X mov si,es:prev[si] ; cur_match = prev[cur_match]
- X cmp si,NIL
- X je the_end
- Xdo_scan:
- X cmp ax,word ptr _window[bx+si-1] ; check match at ma_length-1
- X jne short_loop
- X cmp cx,word ptr _window[si] ; check min_match_length match
- X jne short_loop
- X mov dx,si ; dx = cur_match
- X lea si,_window[si+2] ; si = match
- X mov ax,di ; ax = scan+2
- X mov cx,ds
- X mov es,cx
- X mov cx,(MAX_LENGTH-2)/2 ; scan for at most MAX_LENGTH bytes
- X repe cmpsw ; loop until mismatch
- X load_es_prev ; reset es to address the prev array
- X mov cl,[di-2] ; mismatch on first or second byte?
- X sub cl,[si-2] ; dl = 0 if first bytes equal
- X xchg ax,di ; di = scan+2, ax = end of scan
- X sub ax,di ; ax = len
- X sub cl,1 ; set carry if cl == 0 (can't use DEC)
- X adc ax,0 ; ax = carry ? len+1 : len
- X mov si,dx ; si = cur_match
- X cmp ax,bx ; len > ma_length ?
- X jle long_loop
- X mov cur_best,si ; cur_best = cur_match
- X mov bx,ax ; bx = ma_length = len
- X cmp ax,_strsize ; len >= strsize ?
- X jle long_loop
- Xthe_end:
- X cmp bx,_start_length ; ma_length > start_length ?
- X jle return
- X mov _match_length,bx ; match_length = ma_length
- Xreturn:
- X mov si,cur_best ; result = cur_best
- X pop di
- X pop bp
- X ret
- X
- X_longest_match endp
- X
- X_TEXT ends
- Xend
- END_OF_FILE
- if test 9944 -ne `wc -c <'im_lm.asm'`; then
- echo shar: \"'im_lm.asm'\" unpacked with wrong size!
- fi
- # end of 'im_lm.asm'
- fi
- if test -f 'implode.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'implode.c'\"
- else
- echo shar: Extracting \"'implode.c'\" \(8838 characters\)
- sed "s/^X//" >'implode.c' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * implode.c by Richard B. Wales.
- X *
- X * PURPOSE
- X *
- X * Compress an input file using the ZIP "implosion" method.
- X *
- X * DISCUSSION
- X *
- X * The "implosion" algorithm is a composite of (1) OPM/L compres-
- X * sion within a sliding window, and (2) variable-length binary
- X * encoding of various parts of the OPM/L output.
- X *
- X * For a detailed treatment of OPM/L compression, see the source
- X * file "im_lmat.c".
- X *
- X * For a detailed treatment of variable-length binary encoding,
- X * see the source file "im_ctree.c".
- X *
- X * Since Pass Two (binary encoding) depends on a statistical anal-
- X * ysis of the entire output of Pass One (OPM/L compression), the
- X * Pass One output is saved in a temporary file and re-read for
- X * Pass Two. Implosion is thus a two-pass algorithm.
- X *
- X * An outline of the algorithm follows:
- X *
- X * (1) The entire input file is read and compressed via the OPM/L
- X * technique. The OPM/L output is saved in a temporary file.
- X *
- X * (2) The compressed info from (1) is analyzed, and various fre-
- X * quency counts are tallied.
- X *
- X * (3) Based on the frequency counts, a decision is made as to
- X * whether or not the "literal" characters (those not matched
- X * in earlier parts of the input) should be represented via a
- X * binary code tree or left "as is". If there are not very
- X * many literal characters, or if their frequency distribution
- X * is fairly even, the number of bits saved through coding may
- X * be exceeded by the amount of info which must be included to
- X * describe the tree.
- X *
- X * (4) The temporary file from (1) is re-read. The information is
- X * further compressed via the binary code trees, and the result
- X * is sent to the ZIP output file.
- X *
- X * REFERENCES
- X *
- X * APPNOTE.TXT documentation file in PKZIP 1.10 distribution.
- X *
- X * See also references in the "im_lmat.c" and "im_ctree.c" source
- X * files.
- X *
- X * INTERFACE
- X *
- X * int imp_setup (long filesize, int pack_level)
- X * Initialize the "implode" routines for a new file.
- X *
- X * int imp_p1 (char *buf, int count)
- X * Process "count" input characters pointed to by "buf". This
- X * routine is called as many times as needed to process the
- X * entire input file. There is no upper limit on "count".
- X *
- X * int imp_size (long *size, char *opts)
- X * Terminate processing of the input file, and return the com-
- X * pressed size ("size") and implosion option flags ("opts").
- X *
- X * int imp_p2 (FILE *outfp)
- X * Output the entire compressed file -- including S-F trees and
- X * data -- to the ZIP output file "outfp".
- X *
- X * int imp_clear (void)
- X * Clean up after processing and outputting a file. This rou-
- X * tine may be called at any time to abort further processing.
- X *
- X * All the above routines return zero if successful, or a non-zero
- X * value if there was an error.
- X */
- X
- X#include "implode.h"
- X#include "ziperr.h"
- X
- X
- X/***********************************************************************
- X *
- X * Error return codes for the main ZIP program.
- X * Most of these are in "ziperr.h".
- X */
- X
- X#define ZE_MAP(err) \
- X ( ((err) == IM_OK) ? ZE_OK \
- X : ((err) == IM_NOMEM) ? ZE_MEM \
- X : ((err) == IM_IOERR) ? ZE_TEMP \
- X : (fprintf(stderr,"\nZE_MAP(%d)",(err)), \
- X ZE_LOGIC))
- X
- X
- X/***********************************************************************
- X *
- X * State variable for the implosion routines.
- X */
- X
- X#define IMP_SETUP 0 /* need to do "imp_setup" */
- X#define IMP_P1 1 /* setup done, ready for Pass 1 */
- X#define IMP_P2 2 /* Pass 1 done, ready for Pass 2 */
- X#define IMP_CLEAR 3 /* Pass 2 done, ready for "imp_clear" */
- X
- Xlocal int imp_state = IMP_SETUP;
- X
- X
- X/***********************************************************************
- X *
- X * Global variables.
- X */
- X
- XFDATA fd;
- X
- X
- X/***********************************************************************
- X *
- X * Set up for performing implosion on a new file.
- X */
- X
- Xint
- Ximp_setup (filesize, pack_level)
- X long filesize; /* input file size */
- X int pack_level; /* 0 = best speed, 9 = best compression, other = default */
- X{
- X ImpErr retcode;
- X extern char *tempname();
- X
- X if (imp_state != IMP_SETUP)
- X { fprintf (stderr, "\nimp_setup called with wrong state %d",
- X imp_state);
- X return ZE_LOGIC;
- X }
- X imp_state = IMP_P1;
- X
- X /* Set up the initial parameters. Use an 8K window if the input
- X * file is greater than or equal to 5.5K, a 4K window otherwise.
- X */
- X fd.fd_bufsize = 8192;
- X if (filesize < 5632) fd.fd_bufsize = 4096;
- X
- X fd.fd_strsize = 320;
- X fd.fd_nbits = (fd.fd_bufsize == 4096) ? 6 : 7;
- X
- X /* Create a temporary file for the Pass One output. */
- X fd.fd_temp = topen ('I');
- X if (fd.fd_temp == NULL)
- X return ZE_MEM;
- X
- X /*
- X * Initialize the "longest match" routines.
- X * "ct_init" is called at this point because the "lm_input" routine
- X * (called in "imp_p1") calls the "ct_tally" routine.
- X */
- X retcode = lm_init (pack_level);
- X if (retcode != IM_OK) return ZE_MAP (retcode);
- X retcode = ct_init ();
- X return ZE_MAP (retcode);
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Feed characters to the implosion computation.
- X * This routine is called as many times as needed, until the entire
- X * input file has been processed.
- X */
- X
- Xint
- Ximp_p1 (buf, count)
- X char *buf; /* input characters */
- X int count; /* character count */
- X{ ImpErr retcode;
- X
- X if (imp_state != IMP_P1)
- X { fprintf (stderr, "\nimp_p1 called with wrong state %d",
- X imp_state);
- X return ZE_LOGIC;
- X }
- X
- X if (buf == NULL || count < 0)
- X { fprintf (stderr, "\nimp_p1 called with bad arguments");
- X return ZE_LOGIC;
- X }
- X retcode = lm_input ((U_CHAR *) buf, (U_INT) count);
- X return ZE_MAP (retcode);
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Terminate processing of input for this file, and determine the size
- X * this file will have if it is imploded. Also, find out whether two
- X * or three S-F trees will be used (needed for directory entries).
- X */
- X
- Xint
- Ximp_size (size, opts)
- X long *size; /* imploded size */
- X char *opts; /* implosion option info */
- X{ ImpErr retcode;
- X
- X if (imp_state != IMP_P1)
- X { fprintf (stderr, "\nimp_size called with wrong state %d",
- X imp_state);
- X return ZE_LOGIC;
- X }
- X imp_state = IMP_P2;
- X
- X if (size == NULL || opts == NULL)
- X { fprintf (stderr, "\nimp_size called with bad arguments");
- X return ZE_LOGIC;
- X }
- X retcode = lm_windup ();
- X if (retcode != IM_OK) return ZE_MAP (retcode);
- X retcode = ct_mktrees ();
- X if (retcode != IM_OK) return ZE_MAP (retcode);
- X *size = fd.fd_clen;
- X *opts = (char)(((fd.fd_bufsize == 8192) ? 0x02 : 0)
- X | ((fd.fd_method == LITERAL_TREE) ? 0x04 : 0));
- X return ZE_OK;
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Output the imploded version of the file (but not the file directory
- X * info) to the ZIP file.
- X */
- X
- Xint
- Ximp_p2 (outfp)
- X FILE *outfp; /* output (ZIP) file */
- X{ ImpErr retcode;
- X
- X if (imp_state != IMP_P2)
- X { fprintf (stderr, "\nimp_p2 called with wrong state %d",
- X imp_state);
- X return ZE_LOGIC;
- X }
- X imp_state = IMP_CLEAR;
- X
- X if (outfp == NULL)
- X { fprintf (stderr, "\nimp_p2 called with bad arguments");
- X return ZE_LOGIC;
- X }
- X retcode = ct_wrtrees (outfp);
- X if (retcode != IM_OK) return ZE_MAP (retcode);
- X retcode = ct_wrdata (outfp);
- X if (retcode != IM_OK) return ZE_MAP (retcode);
- X fflush (outfp);
- X if (ferror (outfp)) return ZE_TEMP;
- X return ZE_OK;
- X}
- X
- X
- X/***********************************************************************
- X *
- X * Clean up after doing an implosion.
- X * This routine may also be called at any time to abort an implosion.
- X */
- X
- Xint
- Ximp_clear ()
- X{ (void) lm_windup ();
- X if (fd.fd_temp != NULL)
- X (void) tclose (fd.fd_temp);
- X (void) ct_windup ();
- X imp_state = IMP_SETUP;
- X return ZE_OK;
- X}
- X
- X
- X/**********************************************************************/
- END_OF_FILE
- if test 8838 -ne `wc -c <'implode.c'`; then
- echo shar: \"'implode.c'\" unpacked with wrong size!
- fi
- # end of 'implode.c'
- fi
- if test -f 'implode.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'implode.h'\"
- else
- echo shar: Extracting \"'implode.h'\" \(4579 characters\)
- sed "s/^X//" >'implode.h' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * implode.h by Richard B. Wales.
- X */
- X
- X#include "crypt.h"
- X#include "tempf.h"
- X#include <errno.h>
- X
- X
- X/***********************************************************************
- X *
- X * Type definitions.
- X */
- X
- X
- Xtypedef long L_INT;
- Xtypedef int INT;
- Xtypedef short S_INT;
- X
- Xtypedef unsigned long UL_INT;
- Xtypedef unsigned int U_INT;
- Xtypedef unsigned short US_INT;
- X
- Xtypedef unsigned char U_CHAR;
- X
- Xtypedef unsigned long CRC;
- X
- X#define VOID void
- X
- X#define local static /* More meaningful outside functions */
- X/* #define local */
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- X/* Error return codes. */
- Xtypedef
- Xenum
- X { IM_OK, /* all OK */
- X IM_EOF, /* end of file on input */
- X IM_IOERR, /* I/O error */
- X IM_BADARG, /* invalid procedure argument */
- X IM_NOMEM, /* out of memory */
- X IM_LOGICERR, /* logic error */
- X IM_NOCTBLS /* no more code tables */
- X }
- X ImpErr;
- X
- X/* The different possible compression methods. */
- Xtypedef
- Xenum
- X { NO_LITERAL_TREE, /* use only two trees */
- X LITERAL_TREE /* use all three trees */
- X }
- X Method;
- X
- X/* File data structure. */
- Xtypedef
- Xstruct fdata
- X { L_INT fd_len; /* # of bytes in file */
- X L_INT fd_clen; /* compressed length */
- X tFILE *fd_temp; /* temporary file stream pointer */
- X U_INT fd_bufsize; /* size of sliding dictionary */
- X U_INT fd_strsize; /* max string match length */
- X U_INT fd_nbits; /* # distance bits to write literally */
- X Method fd_method; /* compression method */
- X }
- X FDATA;
- X
- X/* Data structure for string matches. */
- Xtypedef
- Xstruct match
- X { S_INT ma_dist; /* distance back into buffer */
- X union {
- X US_INT ma_length; /* length of matched string */
- X U_CHAR ma_litc[2]; /* literal characters matched */
- X } l;
- X /* l is ma_litc if ma_dist <= 0. If ma_dist < 0, the length is
- X * 2 and the distance is -ma_dist.
- X */
- X }
- X MATCH;
- X
- X
- X/***********************************************************************
- X *
- X * External variable declarations.
- X */
- X
- Xextern FDATA fd; /* file data */
- X#ifndef MSDOS
- Xextern int errno; /* system error code */
- X#endif /* MSDOS */
- X
- Xextern MATCH *ma_buf; /* match info buffer */
- X#define MA_BUFSIZE 512
- X/* MA_BUFSIZE must be such that
- X * 256*sizeof(TRDATA) <= MA_BUFSIZE*sizeof(MATCH)
- X * since the same buffer is used for both purposes at different times.
- X */
- X
- X/***********************************************************************
- X *
- X * External procedure declarations.
- X */
- X
- X
- X#ifdef MODERN
- X#include <string.h>
- X#else
- Xvoidp *malloc();
- Xchar *strcpy();
- Xchar *strcat();
- X#endif /* MODERN */
- X
- X
- X/***********************************************************************
- X *
- X * Routines in "im_lmat.c" source file.
- X */
- X
- X
- XImpErr lm_init
- X OF ((int pack_level));
- X
- XImpErr lm_input
- X OF ((U_CHAR *block, U_INT count));
- X
- XImpErr lm_windup
- X OF ((void));
- X
- X
- X/***********************************************************************
- X *
- X * Routines in "im_ctree.c" source file.
- X */
- X
- XImpErr ct_init
- X OF ((void));
- X
- XImpErr ct_tally
- X OF ((MATCH *ma));
- X
- XImpErr ct_mktrees
- X OF ((void));
- X
- XImpErr ct_wrtrees
- X OF ((FILE *outfp));
- X
- XImpErr ct_wrdata
- X OF ((FILE *outfp));
- X
- XImpErr ct_windup
- X OF ((void));
- X
- X
- X/***********************************************************************
- X *
- X * Routines in "im_bits.c" source file.
- X */
- X
- XImpErr bi_init
- X OF ((FILE *fp));
- X
- XImpErr bi_rlout
- X OF ((int value, int length));
- X
- Xint bi_reverse
- X OF ((int value, int length));
- X
- XImpErr bi_windup
- X OF ((void));
- X
- X
- X/***********************************************************************
- X *
- X * Routines in "implode.c" source file.
- X */
- X
- Xint imp_setup
- X OF ((long filesize, int pack_level));
- X
- Xint imp_p1
- X OF ((char *buf, int count));
- X
- Xint imp_size
- X OF ((long *size, char *opts));
- X
- Xint imp_p2
- X OF ((FILE *outfp));
- X
- Xint imp_clear
- X OF ((void));
- X
- X
- X/**********************************************************************/
- END_OF_FILE
- if test 4579 -ne `wc -c <'implode.h'`; then
- echo shar: \"'implode.h'\" unpacked with wrong size!
- fi
- # end of 'implode.h'
- fi
- if test -f 'makefile.os2' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makefile.os2'\"
- else
- echo shar: Extracting \"'makefile.os2'\" \(3393 characters\)
- sed "s/^X//" >'makefile.os2' <<'END_OF_FILE'
- X# Makefile for Zip, ZipNote, ZipSplit, and Ship
- X# for Microsoft C 6.00 and MASM 6.00 under OS/2.
- X
- X# To use, enter "nmake -f makefile.os2".
- X
- X# The resulting programs can be used under OS/2 protected
- X# and real mode as well as under MS-DOS!
- X# A larger stack has to be used for OS/2 because system calls
- X# use more stack than under DOS, 8k is recommended by Microsoft.
- X
- X# Note that __STDC__ has to be defined explicitly with C 6.00 when -Ze
- X# is given, because Microsoft disables __STDC__ when their extensions
- X# are enabled. This is different to the C 5.10 behaviour.
- X
- X# If you do not have masm, then add -DNO_ASM to CFLAGS and remove
- X# im_lm.obj from OBJI
- X
- XMODEL=-AC
- X# change this to -AS to use the small model
- XDEFINES=-D__STDC__ -DOS2 -DEXPORT
- X
- X# Loop optimization -Ol with C 6.00A is sometimes not safe.
- X# Use it only for time-critical modules.
- X
- XCC=cl -nologo
- XCFLAGS=$(MODEL) -W1 -Zep1 -J -G2s -Ocegit $(DEFINES)
- XXFLAGS=-Oxaz
- XLDFLAGS=$(MODEL) -Lp -F 2000
- XAS=ml -nologo
- XAFLAGS=-W2 -Zm -Cp $(DEFINES)
- X
- X# For protect-mode only programs use rem
- XSTRIP=bind -nologo
- X# STRIP=rem
- X
- X# variables
- X# remove im_lm.obj in OBJI if you do not have masm
- XOBJZ = zip.obj zipfile.obj zipup.obj fileio.obj util.obj tempf.obj \
- X shrink.obj globals.obj dir_os2.obj
- XOBJI = implode.obj im_lmat.obj im_ctree.obj im_bits.obj im_lm.obj
- X
- XOBJN = zipnote.obj zipfile_.obj zipup_.obj fileio_.obj globals.obj
- XOBJS = zipsplit.obj zipfile_.obj zipup_.obj fileio_.obj globals.obj
- X
- Xzips: zip.exe zipnote.exe zipsplit.exe ship.exe
- X
- Xzip.obj: zip.h ziperr.h tailor.h revision.h zip.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xzipfile.obj: zip.h ziperr.h tailor.h zipfile.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xzipup.obj: zip.h ziperr.h tailor.h revision.h zipup.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xfileio.obj: zip.h ziperr.h tailor.h fileio.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xutil.obj: zip.h ziperr.h tailor.h util.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xtempf.obj: tempf.h tailor.h tempf.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xshrink.obj: zip.h ziperr.h tempf.h tailor.h shrink.c
- X $(CC) -c $(CFLAGS) $(XFLAGS) $*.c
- X
- Xglobals.obj: zip.h ziperr.h tailor.h globals.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xdir_os2.obj: dir_os2.c dir_os2.h
- X $(CC) -c $(CFLAGS) dir_os2.c
- X
- Xzipnote.obj: zip.h ziperr.h tailor.h revision.h zipnote.c
- X $(CC) -c $(CFLAGS) $*.c
- X
- Xzipsplit.obj: zipsplit.c zip.h ziperr.h tailor.h revision.h
- X $(CC) -c $(CFLAGS) $*.c
- X
- Ximplode.obj: implode.h crypt.h ziperr.h tempf.h tailor.h implode.c
- X $(CC) -c $(CFLAGS) $(XFLAGS) $*.c
- X
- Xim_lmat.obj: implode.h crypt.h ziperr.h tempf.h tailor.h im_lmat.c
- X $(CC) -c $(CFLAGS) $(XFLAGS) $*.c
- X
- Xim_lm.obj: im_lm.asm
- X $(AS) -c $(AFLAGS) $*.asm
- X# masm -ml -t -DOS2 im_lm.asm; # use this for 5.10
- X
- Xim_ctree.obj: implode.h crypt.h ziperr.h tempf.h tailor.h im_ctree.c
- X $(CC) -c $(CFLAGS) $(XFLAGS) $*.c
- X
- Xim_bits.obj: implode.h crypt.h ziperr.h tempf.h tailor.h im_bits.c
- X $(CC) -c $(CFLAGS) $(XFLAGS) $*.c
- X
- Xzipfile_.obj: zipfile.c zip.h
- X $(CC) -c $(CFLAGS) -DUTIL -Fo$@ zipfile.c
- X
- Xzipup_.obj: zipup.c zip.h
- X $(CC) -c $(CFLAGS) -DUTIL -Fo$@ zipup.c
- X
- Xfileio_.obj: fileio.c zip.h
- X $(CC) -c $(CFLAGS) -DUTIL -Fo$@ fileio.c
- X
- Xzip.exe: $(OBJZ) $(OBJI) zip.def
- X $(CC) $(LDFLAGS) $** -o $@
- X $(STRIP) $@ -n DOSQFSATTACH
- X
- Xzipnote.exe: $(OBJN) zip.def
- X $(CC) $(LDFLAGS) $** -o $@
- X $(STRIP) $@
- X
- Xzipsplit.exe: $(OBJS) zip.def
- X $(CC) $(LDFLAGS) $** -o $@
- X $(STRIP) $@
- X
- Xship.exe: ship.c ship.def
- X $(CC) $(CFLAGS) $(LDFLAGS) $** -o $@
- X $(STRIP) $@
- END_OF_FILE
- if test 3393 -ne `wc -c <'makefile.os2'`; then
- echo shar: \"'makefile.os2'\" unpacked with wrong size!
- fi
- # end of 'makefile.os2'
- fi
- if test -f 'ship.def' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ship.def'\"
- else
- echo shar: Extracting \"'ship.def'\" \(74 characters\)
- sed "s/^X//" >'ship.def' <<'END_OF_FILE'
- XNAME WINDOWCOMPAT NEWFILES
- XDESCRIPTION 'encode/split/mail & decode files'
- END_OF_FILE
- if test 74 -ne `wc -c <'ship.def'`; then
- echo shar: \"'ship.def'\" unpacked with wrong size!
- fi
- # end of 'ship.def'
- fi
- if test -f 'zip.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'zip.h'\"
- else
- echo shar: Extracting \"'zip.h'\" \(8017 characters\)
- sed "s/^X//" >'zip.h' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * zip.h by Mark Adler.
- X */
- X
- X
- X/* Set up portability */
- X#include "tailor.h"
- X
- X/* Define malloc() and string functions */
- X#ifdef MODERN
- X# include <string.h>
- X#else /* !MODERN */
- X voidp *malloc();
- X char *getenv();
- X long atol();
- X char *strcpy();
- X char *strcat();
- X char *strchr();
- X char *strrchr();
- X# ifndef ZMEM
- X char *memset();
- X char *memcpy();
- X# endif /* !ZMEM */
- X#endif /* ?MODERN */
- X
- X
- X/* Define fseek() commands */
- X#ifndef SEEK_SET
- X# define SEEK_SET 0
- X#endif /* !SEEK_SET */
- X
- X#ifndef SEEK_CUR
- X# define SEEK_CUR 1
- X#endif /* !SEEK_CUR */
- X
- X
- X/* Forget FILENAME_MAX (incorrectly = 14 on some System V) */
- X#ifdef MSDOS
- X# define FNMAX 256
- X#else /* !MSDOS */
- X# define FNMAX 1024
- X#endif /* ?MSDOS */
- X
- X
- X/* Types centralized here for easy modification */
- X#define local static /* More meaningful outside functions */
- Xtypedef unsigned char uch; /* unsigned 8-bit value */
- Xtypedef unsigned short ush; /* unsigned 16-bit value */
- Xtypedef unsigned long ulg; /* unsigned 32-bit value */
- X
- X
- X/* Lengths of headers after signatures in bytes */
- X#define LOCHEAD 26
- X#define CENHEAD 42
- X#define ENDHEAD 18
- X
- X
- X/* Structures for in-memory file information */
- Xstruct zlist {
- X /* See central header in zipfile.c for what vem..off are */
- X ush vem, ver, flg, how;
- X ulg tim, crc, siz, len;
- X extent nam, ext, cext, com; /* offset of ext must be >= LOCHEAD */
- X ush dsk, att, lflg; /* offset of lflg must be >= LOCHEAD */
- X ulg atx, off;
- X char *name; /* File name in zip file */
- X char *extra; /* Extra field (set only if ext != 0) */
- X char *cextra; /* Extra in central (set only if cext != 0) */
- X char *comment; /* Comment (set only if com != 0) */
- X char *zname; /* Name for new zip file header */
- X int mark; /* Marker for files to operate on */
- X int trash; /* Marker for files to delete */
- X struct zlist far *nxt; /* Pointer to next header in list */
- X};
- Xstruct flist {
- X char *name; /* Pointer to zero-delimited name */
- X char *zname; /* Name used for zip file headers */
- X struct flist far * far *lst; /* Pointer to link pointing here */
- X struct flist far *nxt; /* Link to next name */
- X};
- X
- X
- X/* Error return codes and PERR macro */
- X#include "ziperr.h"
- X
- X
- X/* Public globals */
- Xextern char errbuf[]; /* Handy place to build error messages */
- Xextern int recurse; /* Recurse into directories encountered */
- Xextern int pathput; /* Store path with name */
- X#define BEST -1 /* Use best method */
- X#define STORE 0 /* Store method */
- X#define SHRINK 1 /* Use shrink or store only */
- X#define IMPLODE 6 /* Use implode or store only */
- Xextern int method; /* Restriction on compression method */
- Xextern int dosify; /* Make new entries look like MSDOS */
- Xextern char *special; /* Don't compress special suffixes */
- Xextern int verbose; /* Report oddities in zip file structure */
- Xextern int level; /* Compression level */
- X#ifdef VMS
- X extern int vmsver; /* Append VMS version number to file names */
- X#endif /* VMS */
- Xextern int linkput; /* Store symbolic links as such */
- Xextern int noisy; /* False for quiet operation */
- Xextern char *key; /* Scramble password or NULL */
- Xextern char *tempath; /* Path for temporary files */
- Xextern char *zipfile; /* New or existing zip archive (zip file) */
- Xextern ulg zipbeg; /* Starting offset of zip structures */
- Xextern ulg cenbeg; /* Starting offset of central directory */
- Xextern struct zlist far *zfiles;/* Pointer to list of files in zip file */
- Xextern extent zcount; /* Number of files in zip file */
- Xextern extent zcomlen; /* Length of zip file comment */
- Xextern char *zcomment; /* Zip file comment (not zero-terminated) */
- Xextern struct zlist far **zsort;/* List of files sorted by name */
- Xextern struct flist far *found; /* List of names found */
- Xextern struct flist far * far *fnxt; /* Where to put next in found list */
- Xextern extent fcount; /* Count of names in found list */
- Xextern int shract; /* Shrink active */
- Xextern int impact; /* Implosion active */
- X
- X
- X/* Diagnostic function */
- X#ifdef DEBUG
- X# define diag(where) fprintf(stderr, "zip diagnostic: %s\n", where)
- X#else /* !DEBUG */
- X# define diag(where)
- X#endif /* ?DEBUG */
- X
- X
- X/* Public function prototypes */
- X
- X /* in zip.c, zipcloak.c, or zipsplit.c */
- Xvoid warn OF((char *, char *));
- X
- X /* in zipup.c */
- Xint zipcopy OF((struct zlist far *, FILE *, FILE *));
- X#ifndef UTIL
- X int percent OF((ulg, ulg));
- X int zipup OF((struct zlist far *, FILE *));
- X#endif /* !UTIL */
- X
- X /* in zipfile.c */
- X#ifndef UTIL
- X struct zlist far *zsearch OF((char *));
- X int trash OF((void));
- X#endif /* !UTIL */
- Xchar *ziptyp OF((char *));
- Xint readzipfile OF((void));
- Xint putlocal OF((struct zlist far *, FILE *));
- Xint putcentral OF((struct zlist far *, FILE *));
- Xint putend OF((int, ulg, ulg, extent, char *, FILE *));
- X
- X /* in fileio.c */
- X#ifndef UTIL
- X# ifdef MSDOS
- X int wild OF((char *));
- X# endif /* MSDOS */
- X char *getnam OF((char *));
- X struct flist far *fexpel OF((struct flist far *));
- X char *in2ex OF((char *));
- X int exclude OF((void));
- X int procname OF((char *));
- X void stamp OF((char *, ulg));
- X ulg dostime OF((int, int, int, int, int, int));
- X ulg filetime OF((char *, ulg *, long *));
- X int issymlnk OF((ulg a));
- X# ifdef S_IFLNK
- X# define rdsymlnk(p,b,n) readlink(p,b,n)
- X extern int readlink OF((char *, char *, int));
- X# else /* !S_IFLNK */
- X# define rdsymlnk(p,b,n) (0)
- X# endif /* !S_IFLNK */
- X int deletedir OF((char *));
- X#endif /* !UTIL */
- Xint destroy OF((char *));
- Xint replace OF((char *, char *));
- Xint getfileattr OF((char *));
- Xint setfileattr OF((char *, int));
- Xchar *tempname OF((int));
- Xint fcopy OF((FILE *, FILE *, ulg));
- X#ifndef EXPORT
- X# ifndef MSVMS
- X void echoff OF((int));
- X void echon OF((void));
- X# endif /* !MSVMS */
- X char *getp OF((char *, char *, int));
- X#endif /* !EXPORT */
- X#ifdef ZMEM
- X char *memset OF((char *, int, unsigned int));
- X char *memcpy OF((char *, char *, unsigned int));
- X int memcmp OF((char *, char *, unsigned int));
- X#endif /* ZMEM */
- X
- X /* in crypt.c */
- X#ifdef EXPORT
- X# define zfwrite fwrite
- X#else /* !EXPORT */
- X void crypthead OF((char *, ulg, FILE *));
- X# ifdef UTIL
- X int zipcloak OF ((struct zlist far *, FILE *, FILE *, char *));
- X int zipbare OF ((struct zlist far *, FILE *, FILE *, char *));
- X# else /* !UTIL */
- X int zfwrite OF((voidp *, extent, extent, FILE *));
- X int zfputc OF((int, FILE *));
- X# endif /* ?UTIL */
- X#endif /* ?EXPORT */
- X
- X /* in util.c */
- Xchar *isshexp OF((char *));
- Xint shmatch OF((char *, char *));
- X#ifdef MSDOS
- X int dosmatch OF((char *, char *));
- X#endif /* MSDOS */
- Xvoidp far **search OF((voidp *, voidp far **, extent,
- X int (*)(voidp *, voidp far *)));
- Xulg crc32 OF((ulg, int));
- Xulg updcrc OF((char *, extent));
- X
- X /* in shrink.c */
- X#ifndef UTIL
- X int shr_setup OF((void));
- X int shr_p1 OF((uch *, extent));
- X int shr_size OF((ulg *));
- X int shr_p2 OF((FILE *));
- X int shr_clear OF((void));
- X
- X /* in implode.c */
- X# ifndef NOIMPLODE
- X int imp_setup OF((long, int));
- X int imp_p1 OF((char *, int));
- X int imp_size OF((ulg *, uch *));
- X int imp_p2 OF((FILE *));
- X int imp_clear OF((void));
- X# endif /* !NOIMPLODE */
- X#endif /* !UTIL */
- X
- X
- X/* end of zip.h */
- END_OF_FILE
- if test 8017 -ne `wc -c <'zip.h'`; then
- echo shar: \"'zip.h'\" unpacked with wrong size!
- fi
- # end of 'zip.h'
- fi
- if test -f 'zipnote.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'zipnote.c'\"
- else
- echo shar: Extracting \"'zipnote.c'\" \(9810 characters\)
- sed "s/^X//" >'zipnote.c' <<'END_OF_FILE'
- X/*
- X
- X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
- X Permission is granted to any individual or institution to use, copy, or
- X redistribute this software so long as all of the original files are included
- X unmodified, that it is not sold for profit, and that this copyright notice
- X is retained.
- X
- X*/
- X
- X/*
- X * zipnote.c by Mark Adler.
- X */
- X
- X#define UTIL
- X#include "revision.h"
- X#include "zip.h"
- X#include <signal.h>
- X
- X
- X/* Character to mark zip entry names in the comment file */
- X#define MARK '@'
- X
- X/* Temporary zip file name and file pointer */
- Xlocal char *tempzip;
- Xlocal FILE *tempzf;
- X
- X
- X/* Local functions */
- X#ifdef PROTO
- X local void err(int, char *);
- X local void handler(int);
- X local void license(void);
- X local void help(void);
- X local void putclean(char *);
- X local int catalloc(char * far *, char *);
- X void main(int, char **);
- X#endif /* PROTO */
- X
- X
- X
- Xlocal void err(c, h)
- Xint c; /* error code from the ZE_ class */
- Xchar *h; /* message about how it happened */
- X/* Issue a message for the error, clean up files and memory, and exit. */
- X{
- X if (PERR(c))
- X perror("zipnote error");
- X fprintf(stderr, "zipnote error: %s (%s)\n", errors[c-1], h);
- X if (tempzf != NULL)
- X fclose(tempzf);
- X if (tempzip != NULL)
- X {
- X destroy(tempzip);
- X free((voidp *)tempzip);
- X }
- X if (zipfile != NULL)
- X free((voidp *)zipfile);
- X#ifdef VMS
- X exit(0);
- X#else /* !VMS */
- X exit(c);
- X#endif /* ?VMS */
- X}
- X
- X
- Xlocal void handler(s)
- Xint s; /* signal number (ignored) */
- X/* Upon getting a user interrupt, abort cleanly using err(). */
- X{
- X#ifndef MSDOS
- X putc('\n', stderr);
- X#endif /* !MSDOS */
- X err(ZE_ABORT, "aborting");
- X s++; /* keep some compilers happy */
- X}
- X
- X
- Xvoid warn(a, b)
- Xchar *a, *b; /* message strings juxtaposed in output */
- X/* Print a warning message to stderr and return. */
- X{
- X fprintf(stderr, "zipnote warning: %s%s\n", a, b);
- X}
- X
- X
- Xlocal void license()
- X/* Print license information to stdout. */
- X{
- X extent i; /* counter for copyright array */
- X
- X for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
- X puts(copyright[i]);
- X for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
- X puts(disclaimer[i]);
- X}
- X
- X
- Xlocal void help()
- X/* Print help (along with license info) to stdout. */
- X{
- X extent i; /* counter for help array */
- X
- X /* help array */
- X static char *text[] = {
- X"",
- X"ZipNote %d.%d (%s)",
- X"Usage: zipnote [-w] [-b path] zipfile",
- X" the default action is to write the comments in zipfile to stdout",
- X" -w write the zipfile comments from stdin",
- X" -b use \"path\" for the temporary zip file",
- X" -h show this help -l show software license",
- X"",
- X"Example:",
- X#ifdef VMS
- X" define/user sys$output foo.tmp",
- X" zipnote foo.zip",
- X" edit foo.tmp",
- X" ... then you edit the comments, save, and exit ...",
- X" define/user sys$input foo.tmp",
- X" zipnote -w foo.zip"
- X#else /* !VMS */
- X" zipnote foo.zip > foo.tmp",
- X" ed foo.tmp",
- X" ... then you edit the comments, save, and exit ...",
- X" zipnote -w foo.zip < foo.tmp"
- X#endif /* ?VMS */
- X };
- X
- X for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
- X puts(copyright[i]);
- X for (i = 0; i < sizeof(text)/sizeof(char *); i++)
- X {
- X printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
- X putchar('\n');
- X }
- X}
- X
- X
- Xlocal void putclean(s)
- Xchar *s; /* string to write to stdout */
- X/* Write the string s to stdout, filtering out control characters that are
- X not tab or newline (mainly to remove carriage returns), and prefix MARK's
- X and backslashes with a backslash. Also, terminate with a newline if
- X needed. */
- X{
- X int c; /* next character in string */
- X int e; /* last character written */
- X
- X e = '\n'; /* if empty, write nothing */
- X while ((c = *s++) != 0)
- X {
- X if (c == MARK || c == '\\')
- X putchar('\\');
- X if (c >= ' ' || c == '\t' || c == '\n')
- X putchar(e = c);
- X }
- X if (e != '\n')
- X putchar('\n');
- X}
- X
- X
- Xlocal int catalloc(a, s)
- Xchar * far *a; /* pointer to a pointer to a malloc'ed string */
- Xchar *s; /* string to concatenate on a */
- X/* Concatentate the string s to the malloc'ed string pointed to by a.
- X Preprocess s by removing backslash escape characters. */
- X{
- X char *p; /* temporary pointer */
- X char *q; /* temporary pointer */
- X
- X for (p = q = s; *q; *p++ = *q++)
- X if (*q == '\\' && *(q+1))
- X q++;
- X *p = 0;
- X if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL)
- X return ZE_MEM;
- X strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s);
- X free((voidp *)*a);
- X *a = p;
- X return ZE_OK;
- X}
- X
- X
- Xvoid main(argc, argv)
- Xint argc; /* number of tokens in command line */
- Xchar **argv; /* command line tokens */
- X/* Write the comments in the zipfile to stdout, or read them from stdin. */
- X{
- X char a[FNMAX+1]; /* input line buffer */
- X ulg c; /* start of central directory */
- X int k; /* next argument type */
- X char *q; /* steps through option arguments */
- X int r; /* arg counter, temporary variable */
- X ulg s; /* length of central directory */
- X int t; /* attributes of zip file */
- X int w; /* true if updating zip file from stdin */
- X FILE *x, *y; /* input and output zip files */
- X struct zlist far *z; /* steps through zfiles linked list */
- X
- X
- X /* If no args, show help */
- X if (argc == 1)
- X {
- X help();
- X exit(0);
- X }
- X
- X /* Go through args */
- X zipfile = tempzip = NULL;
- X tempzf = NULL;
- X signal(SIGINT, handler);
- X signal(SIGTERM, handler);
- X k = w = 0;
- X for (r = 1; r < argc; r++)
- X if (*argv[r] == '-')
- X if (argv[r][1])
- X for (q = argv[r]+1; *q; q++)
- X switch(*q)
- X {
- X case 'b': /* Specify path for temporary file */
- X if (k)
- X err(ZE_PARMS, "use -b before zip file name");
- X else
- X k = 1; /* Next non-option is path */
- X break;
- X case 'h': /* Show help */
- X help(); exit(0);
- X case 'l': /* Show copyright and disclaimer */
- X license(); exit(0);
- X case 'w':
- X w = 1; break;
- X default:
- X err(ZE_PARMS, "unknown option");
- X }
- X else
- X err(ZE_PARMS, "zip file cannot be stdin");
- X else
- X if (k == 0)
- X if (zipfile == NULL)
- X {
- X if ((zipfile = ziptyp(argv[r])) == NULL)
- X err(ZE_MEM, "was processing arguments");
- X }
- X else
- X err(ZE_PARMS, "can only specify one zip file");
- X else
- X {
- X tempath = argv[r];
- X k = 0;
- X }
- X if (zipfile == NULL)
- X err(ZE_PARMS, "need to specify zip file");
- X
- X /* Read zip file */
- X if ((r = readzipfile()) != ZE_OK)
- X err(r, zipfile);
- X if (zfiles == NULL)
- X err(ZE_NAME, zipfile);
- X
- X /* Put comments to stdout, if not -u */
- X if (!w)
- X {
- X for (z = zfiles; z != NULL; z = z->nxt)
- X {
- X printf("%c %s\n", MARK, z->zname);
- X if (z->com)
- X putclean(z->comment);
- X putchar(MARK); putchar('\n');
- X }
- X putchar(MARK); putchar('\n');
- X if (zcomlen)
- X putclean(zcomment);
- X exit(ZE_OK);
- X }
- X
- X /* If updating comments, make sure zip file is writeable */
- X if ((x = fopen(zipfile, "a")) == NULL)
- X err(ZE_CREAT, zipfile);
- X fclose(x);
- X t = getfileattr(zipfile);
- X
- X /* Process stdin, replacing comments */
- X for (z = zfiles; z != NULL; z = z->nxt)
- X {
- X if (gets(a) == NULL || a[0] != MARK || a[1] != ' ' ||
- X strcmp(a + 2, z->zname))
- X err(ZE_NOTE, "missing entry name");
- X if (z->com)
- X free((voidp *)z->comment);
- X z->comment = malloc(1); *(z->comment) = 0;
- X while (gets(a) != NULL && *a != MARK)
- X if ((r = catalloc(&(z->comment), a)) != ZE_OK)
- X err(r, "was building new comments");
- X if (a[1])
- X err(ZE_NOTE, "missing comment end line");
- X z->com = strlen(z->comment);
- X }
- X if (gets(a) == NULL || a[0] != MARK || a[1])
- X err(ZE_NOTE, "missing zip file comment marker line");
- X zcomment = malloc(1); *zcomment = 0;
- X while (gets(a) != NULL)
- X if ((r = catalloc(&zcomment, a)) != ZE_OK)
- X err(r, "was building new comments");
- X zcomlen = strlen(zcomment);
- X
- X /* Open output zip file for writing */
- X if ((tempzf = y = fopen(tempzip = tempname('Z'), FOPW)) == NULL)
- X err(ZE_TEMP, tempzip);
- X
- X /* Open input zip file again, copy preamble if any */
- X if ((x = fopen(zipfile, FOPR)) == NULL)
- X err(ZE_NAME, zipfile);
- X if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
- X err(r, r == ZE_TEMP ? tempzip : zipfile);
- X
- X /* Go through local entries, copying them over as is */
- X for (z = zfiles; z != NULL; z = z->nxt)
- X if ((r = zipcopy(z, x, y)) != ZE_OK)
- X err(r, "was copying an entry");
- X fclose(x);
- X
- X /* Write central directory and end of central directory with new comments */
- X if ((c = ftell(y)) == -1L) /* get start of central */
- X err(ZE_TEMP, tempzip);
- X for (z = zfiles; z != NULL; z = z->nxt)
- X if ((r = putcentral(z, y)) != ZE_OK)
- X err(r, tempzip);
- X if ((s = ftell(y)) == -1L) /* get end of central */
- X err(ZE_TEMP, tempzip);
- X s -= c; /* compute length of central */
- X if ((r = putend((int)zcount, s, c, zcomlen, zcomment, y)) != ZE_OK)
- X err(r, tempzip);
- X tempzf = NULL;
- X if (fclose(y))
- X err(ZE_TEMP, tempzip);
- X if ((r = replace(zipfile, tempzip)) != ZE_OK)
- X {
- X warn("new zip file left as: ", tempzip);
- X free((voidp *)tempzip);
- X tempzip = NULL;
- X err(r, "was replacing the original zip file");
- X }
- X free((voidp *)tempzip);
- X tempzip = NULL;
- X setfileattr(zipfile, t);
- X free((voidp *)zipfile);
- X zipfile = NULL;
- X
- X /* Done! */
- X exit(ZE_OK);
- X}
- END_OF_FILE
- if test 9810 -ne `wc -c <'zipnote.c'`; then
- echo shar: \"'zipnote.c'\" unpacked with wrong size!
- fi
- # end of 'zipnote.c'
- fi
- echo shar: End of archive 8 \(of 9\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-