Commit | Line | Data |
---|---|---|
3013fe88 NW |
1 | /* zip.c -- compress files to the gzip or pkzip format |
2 | * Copyright (C) 1992-1993 Jean-loup Gailly | |
3 | * This is free software; you can redistribute it and/or modify it under the | |
4 | * terms of the GNU General Public License, see the file COPYING. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
caed0dfe | 8 | static char rcsid[] = "$Id: zip.c,v 0.17 1993/06/10 13:29:25 jloup Exp $"; |
3013fe88 NW |
9 | #endif |
10 | ||
11 | #include <ctype.h> | |
3013fe88 NW |
12 | #include <sys/types.h> |
13 | ||
14 | #include "tailor.h" | |
15 | #include "gzip.h" | |
16 | #include "crypt.h" | |
17 | ||
18 | #ifdef HAVE_UNISTD_H | |
19 | # include <unistd.h> | |
20 | #endif | |
21 | #ifndef NO_FCNTL_H | |
22 | # include <fcntl.h> | |
23 | #endif | |
24 | ||
25 | local ulg crc; /* crc on uncompressed file data */ | |
26 | long header_bytes; /* number of bytes in gzip header */ | |
27 | ||
28 | /* =========================================================================== | |
29 | * Deflate in to out. | |
30 | * IN assertions: the input and output buffers are cleared. | |
31 | * The variables time_stamp and save_orig_name are initialized. | |
32 | */ | |
33 | int zip(in, out) | |
34 | int in, out; /* input and output file descriptors */ | |
35 | { | |
36 | uch flags = 0; /* general purpose bit flags */ | |
37 | ush attr = 0; /* ascii/binary flag */ | |
38 | ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ | |
39 | ||
40 | ifd = in; | |
41 | ofd = out; | |
42 | outcnt = 0; | |
43 | ||
44 | /* Write the header to the gzip file. See algorithm.doc for the format */ | |
45 | ||
46 | method = DEFLATED; | |
47 | put_byte(GZIP_MAGIC[0]); /* magic header */ | |
48 | put_byte(GZIP_MAGIC[1]); | |
49 | put_byte(DEFLATED); /* compression method */ | |
50 | ||
51 | if (save_orig_name) { | |
52 | flags |= ORIG_NAME; | |
53 | } | |
54 | put_byte(flags); /* general flags */ | |
55 | put_long(time_stamp); | |
56 | ||
57 | /* Write deflated file to zip file */ | |
58 | crc = updcrc(0, 0); | |
59 | ||
60 | bi_init(out); | |
61 | ct_init(&attr, &method); | |
62 | lm_init(level, &deflate_flags); | |
63 | ||
64 | put_byte((uch)deflate_flags); /* extra flags */ | |
65 | put_byte(OS_CODE); /* OS identifier */ | |
66 | ||
67 | if (save_orig_name) { | |
68 | char *p = basename(ifname); /* Don't save the directory part. */ | |
69 | do { | |
70 | put_char(*p); | |
71 | } while (*p++); | |
72 | } | |
73 | header_bytes = (long)outcnt; | |
74 | ||
75 | (void)deflate(); | |
76 | ||
77 | #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO) | |
78 | /* Check input size (but not in VMS -- variable record lengths mess it up) | |
79 | * and not on MSDOS -- diet in TSR mode reports an incorrect file size) | |
80 | */ | |
81 | if (ifile_size != -1L && isize != (ulg)ifile_size) { | |
82 | Trace((stderr, " actual=%ld, read=%ld ", ifile_size, isize)); | |
83 | fprintf(stderr, "%s: %s: file size changed while zipping\n", | |
84 | progname, ifname); | |
85 | } | |
86 | #endif | |
87 | ||
88 | /* Write the crc and uncompressed size */ | |
89 | put_long(crc); | |
90 | put_long(isize); | |
91 | header_bytes += 2*sizeof(long); | |
92 | ||
93 | flush_outbuf(); | |
94 | return OK; | |
95 | } | |
96 | ||
97 | ||
98 | /* =========================================================================== | |
99 | * Read a new buffer from the current input file, perform end-of-line | |
100 | * translation, and update the crc and input file size. | |
101 | * IN assertion: size >= 2 (for end-of-line translation) | |
102 | */ | |
103 | int file_read(buf, size) | |
104 | char *buf; | |
105 | unsigned size; | |
106 | { | |
107 | unsigned len; | |
108 | ||
109 | Assert(insize == 0, "inbuf not empty"); | |
110 | ||
111 | len = read(ifd, buf, size); | |
112 | if (len == (unsigned)(-1) || len == 0) return (int)len; | |
113 | ||
114 | crc = updcrc((uch*)buf, len); | |
115 | isize += (ulg)len; | |
116 | return (int)len; | |
117 | } |