1 /* $Id: compress.c,v 1.2 2000/12/14 18:45:35 ghazi Exp $
4 Revision 1.2 2000/12/14 18:45:35 ghazi
7 * compress.c: Include stdlib.h and compress.h.
9 (report_str_error): Make static.
10 (ez_inflate_str): Delete unused variable. Add parens in if-stmt.
11 (hrd_inflate_str): Likewise.
13 * compress.h (init_compression, end_compression, init_inflation,
14 end_inflation): Prototype void arguments.
16 * dostime.c (rcsid): Delete.
18 * jargrep.c: Include ctype.h, stdlib.h, zlib.h and compress.h.
19 Make functions static. Cast ctype function argument to `unsigned
20 char'. Add parens in if-stmts. Constify.
21 (Usage): Change into a macro.
22 (jargrep): Remove unused parameter.
24 * jartool.c: Constify. Add parens in if-stmts. Align
25 signed/unsigned char pointers in functions calls using casts.
27 (list_jar): Fix printf format specifier.
28 (usage): Chop long string into bits. Reformat.
30 * pushback.c (rcsid): Delete.
32 Revision 1.1 2000/12/09 03:08:23 apbianco
33 2000-12-08 Alexandre Petit-Bianco <apbianco@cygnus.com>
37 Revision 1.7 2000/09/13 14:02:02 cory
38 Reformatted some of the code to more closly match the layout of the orriginal
41 Revision 1.6 2000/09/12 22:29:36 cory
42 Jargrep now seems to do what I want it to do. Performs properly on Linux x86,
43 will test some other platforms later.
45 Revision 1.1.1.1 1999/12/06 03:09:16 toast
50 Revision 1.7 1999/05/10 08:50:05 burnsbr
51 *** empty log message ***
53 Revision 1.6 1999/05/10 08:38:44 burnsbr
54 *** empty log message ***
56 Revision 1.5 1999/05/10 08:30:29 burnsbr
59 Revision 1.4 1999/04/27 10:03:33 burnsbr
60 added configure support
62 Revision 1.3 1999/04/26 02:35:32 burnsbr
63 compression now works.. yahoo
65 Revision 1.2 1999/04/23 12:01:59 burnsbr
68 Revision 1.1 1999/04/23 11:58:25 burnsbr
75 compress.c - code for handling deflation
76 Copyright (C) 1999 Bryan Burns
78 This program is free software; you can redistribute it and/or
79 modify it under the terms of the GNU General Public License
80 as published by the Free Software Foundation; either version 2
81 of the License, or (at your option) any later version.
83 This program is distributed in the hope that it will be useful,
84 but WITHOUT ANY WARRANTY; without even the implied warranty of
85 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86 GNU General Public License for more details.
88 You should have received a copy of the GNU General Public License
89 along with this program; if not, write to the Free Software
90 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
107 #include <sys/types.h>
110 #include "pushback.h"
111 #include "compress.h"
117 void init_compression(){
119 memset(&zs
, 0, sizeof(z_stream
));
125 /* Why -MAX_WBITS? zlib has an undocumented feature, where if the windowbits
126 parameter is negative, it omits the zlib header, which seems to kill
127 any other zip/unzip program. This caused me SO much pain.. */
128 if(deflateInit2(&zs
, Z_DEFAULT_COMPRESSION
, Z_DEFLATED
, -MAX_WBITS
,
129 9, Z_DEFAULT_STRATEGY
) != Z_OK
){
131 fprintf(stderr
, "Error initializing deflation!\n");
136 int compress_file(int in_fd
, int out_fd
, struct zipentry
*ze
){
138 Bytef out_buff
[RDSZ
];
139 unsigned int rdamt
, wramt
;
140 unsigned long tr
= 0;
146 zs
.next_in
= in_buff
;
148 zs
.next_out
= out_buff
;
149 zs
.avail_out
= (uInt
)RDSZ
;
151 ze
->crc
= crc32(0L, Z_NULL
, 0);
155 /* If deflate is out of input, fill the input buffer for it */
156 if(zs
.avail_in
== 0 && zs
.avail_out
> 0){
157 if((rtval
= read(in_fd
, in_buff
, RDSZ
)) == 0)
167 /* compute the CRC while we're at it */
168 ze
->crc
= crc32(ze
->crc
, in_buff
, rdamt
);
170 /* update the total amount read sofar */
173 zs
.next_in
= in_buff
;
177 /* deflate the data */
178 if(deflate(&zs
, 0) != Z_OK
){
179 fprintf(stderr
, "Error deflating! %s:%d\n", __FILE__
, __LINE__
);
183 /* If the output buffer is full, dump it to disk */
184 if(zs
.avail_out
== 0){
186 if(write(out_fd
, out_buff
, RDSZ
) != RDSZ
){
191 /* clear the output buffer */
192 zs
.next_out
= out_buff
;
193 zs
.avail_out
= (uInt
)RDSZ
;
198 /* If we have any data waiting in the buffer after we're done with the file
200 if(zs
.avail_out
< RDSZ
){
202 wramt
= RDSZ
- zs
.avail_out
;
204 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
208 /* clear the output buffer */
209 zs
.next_out
= out_buff
;
210 zs
.avail_out
= (uInt
)RDSZ
;
214 /* finish deflation. This purges zlib's internal data buffers */
215 while(deflate(&zs
, Z_FINISH
) == Z_OK
){
216 wramt
= RDSZ
- zs
.avail_out
;
218 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
223 zs
.next_out
= out_buff
;
224 zs
.avail_out
= (uInt
)RDSZ
;
227 /* If there's any data left in the buffer, write it out */
228 if(zs
.avail_out
!= RDSZ
){
229 wramt
= RDSZ
- zs
.avail_out
;
231 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
237 /* update fastjar's entry information */
238 ze
->usize
= (ub4
)zs
.total_in
;
239 ze
->csize
= (ub4
)zs
.total_out
;
241 /* Reset the deflation for the next time around */
242 if(deflateReset(&zs
) != Z_OK
){
243 fprintf(stderr
, "Error resetting deflation\n");
250 void end_compression(){
253 /* Oddly enough, zlib always returns Z_DATA_ERROR if you specify no
254 zlib header. Go fig. */
255 if((rtval
= deflateEnd(&zs
)) != Z_OK
&& rtval
!= Z_DATA_ERROR
){
256 fprintf(stderr
, "Error calling deflateEnd\n");
257 fprintf(stderr
, "error: (%d) %s\n", rtval
, zs
.msg
);
263 void init_inflation(){
265 memset(&zs
, 0, sizeof(z_stream
));
271 if(inflateInit2(&zs
, -15) != Z_OK
){
272 fprintf(stderr
, "Error initializing deflation!\n");
278 int inflate_file(pb_file
*pbf
, int out_fd
, struct zipentry
*ze
){
280 Bytef out_buff
[RDSZ
];
287 crc
= crc32(crc
, NULL
, 0); /* initialize crc */
289 /* loop until we've consumed all the compressed data */
292 if(zs
.avail_in
== 0){
293 if((rdamt
= pb_read(pbf
, in_buff
, RDSZ
)) == 0)
295 else if((int)rdamt
< 0){
301 printf("%d bytes read\n", rdamt
);
304 zs
.next_in
= in_buff
;
308 zs
.next_out
= out_buff
;
311 if((rtval
= inflate(&zs
, 0)) != Z_OK
){
312 if(rtval
== Z_STREAM_END
){
314 printf("end of stream\n");
316 if(zs
.avail_out
!= RDSZ
){
317 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
320 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
321 (int)(RDSZ
- zs
.avail_out
)){
329 fprintf(stderr
, "Error inflating file! (%d)\n", rtval
);
333 if(zs
.avail_out
!= RDSZ
){
334 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
337 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
338 (int)(RDSZ
- zs
.avail_out
)){
342 zs
.next_out
= out_buff
;
348 printf("done inflating\n");
352 printf("%d bytes left over\n", zs
.avail_in
);
356 printf("CRC is %x\n", crc
);
361 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
363 ze
->usize
= zs
.total_out
;
370 Function name: report_str_error
371 args: val Error code returned from zlib.
372 purpose: Put out an error message corresponding to error code returned from zlib.
373 Be suitably cryptic seeing I don't really know exactly what these errors mean.
376 static void report_str_error(int val
) {
381 fprintf(stderr
, "Need a dictionary?\n");
384 fprintf(stderr
, "Z_DATA_ERROR\n");
387 fprintf(stderr
, "Z_STREAM_ERROR\n");
390 fprintf(stderr
, "Z_MEM_ERROR\n");
393 fprintf(stderr
, "Z_BUF_ERROR\n");
398 fprintf(stderr
, "Unknown behavior from inflate\n");
404 Function name: ez_inflate_str
405 args: pbf Pointer to pushback handle for file.
406 csize Compressed size of embedded file.
407 usize Uncompressed size of embedded file.
408 purpose: Read in and decompress the contents of an embedded file and store it in a
410 returns: Byte array of uncompressed embedded file.
413 static Bytef
*ez_inflate_str(pb_file
*pbf
, ub4 csize
, ub4 usize
) {
418 if((zs
.next_in
= in_buff
= (Bytef
*) malloc(csize
))) {
419 if((zs
.next_out
= out_buff
= (Bytef
*) malloc(usize
+ 1))) {
420 if((rdamt
= pb_read(pbf
, zs
.next_in
, csize
)) == csize
) {
422 zs
.avail_out
= usize
;
423 report_str_error(inflate(&zs
, 0));
426 out_buff
[usize
] = '\0';
429 fprintf(stderr
, "Read failed on input file.\n");
430 fprintf(stderr
, "Tried to read %u but read %u instead.\n", csize
, rdamt
);
437 fprintf(stderr
, "Malloc of out_buff failed.\n");
438 fprintf(stderr
, "Error: %s\n", strerror(errno
));
444 fprintf(stderr
, "Malloc of in_buff failed.\n");
445 fprintf(stderr
, "Error: %s\n", strerror(errno
));
453 Function name: hrd_inflate_str
454 args: pbf Pointer to pushback handle for file.
455 csize Pointer to compressed size of embedded file.
456 usize Pointer to uncompressed size of embedded file.
457 purpose: Read and decompress an embedded file into a string. Set csize and usize
458 accordingly. This function does the reading for us in the case there is not size
459 information in the header for the embedded file.
460 returns: Byte array of the contents of the embedded file.
463 static Bytef
*hrd_inflate_str(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
474 while(zret
!= Z_STREAM_END
&& (rdamt
= pb_read(pbf
, in_buff
, RDSZ
)))
478 zs
.next_in
= in_buff
;
480 if((tmp
= (Bytef
*) realloc(out_buff
, (RDSZ
* i
) + 1))) {
482 zs
.next_out
= &(out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
]);
483 zs
.avail_out
+= RDSZ
;
487 fprintf(stderr
, "Realloc of out_buff failed.\n");
488 fprintf(stderr
, "Error: %s\n", strerror(errno
));
491 } while((zret
= inflate(&zs
, 0)) == Z_OK
);
492 report_str_error(zret
);
494 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
496 out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
] = '\0';
497 *usize
= zs
.total_out
;
498 *csize
= zs
.total_in
;
506 Function name: inflate_string
507 args: pbf Pointer to pushback handle for file.
508 csize Pointer to compressed size of embedded file. May be 0 if not set.
509 usize Pointer to uncompressed size of embedded file. May be 0 if not set.
510 purpose: Decide the easiest (in computer terms) methos of decompressing this embedded
512 returns: Pointer to a string containing the decompressed contents of the embedded file.
513 If csize and usize are not set set them to correct numbers.
516 Bytef
*inflate_string(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
519 if(*csize
&& *usize
) ret_buf
= ez_inflate_str(pbf
, *csize
, *usize
);
520 else ret_buf
= hrd_inflate_str(pbf
, csize
, usize
);