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
77 Copyright (C) 2004 Free Software Foundation, Inc.
79 This program is free software; you can redistribute it and/or
80 modify it under the terms of the GNU General Public License
81 as published by the Free Software Foundation; either version 2
82 of the License, or (at your option) any later version.
84 This program is distributed in the hope that it will be useful,
85 but WITHOUT ANY WARRANTY; without even the implied warranty of
86 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87 GNU General Public License for more details.
89 You should have received a copy of the GNU General Public License
90 along with this program; if not, write to the Free Software
91 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
108 #include <sys/types.h>
111 #include "pushback.h"
112 #include "compress.h"
115 int write_data (int, void *, size_t, struct zipentry
*);
118 extern off_t end_of_entries
;
122 void init_compression(){
124 memset(&zs
, 0, sizeof(z_stream
));
130 /* Why -MAX_WBITS? zlib has an undocumented feature, where if the windowbits
131 parameter is negative, it omits the zlib header, which seems to kill
132 any other zip/unzip program. This caused me SO much pain.. */
133 if(deflateInit2(&zs
, Z_DEFAULT_COMPRESSION
, Z_DEFLATED
, -MAX_WBITS
,
134 9, Z_DEFAULT_STRATEGY
) != Z_OK
){
136 fprintf(stderr
, "Error initializing deflation!\n");
142 write_data (int fd
, void *buf
, size_t len
,
143 struct zipentry
*ze
__attribute__((unused
)))
145 #ifdef WITH_SHIFT_DOWN
146 struct zipentry
*next
= NULL
;
147 off_t here
= lseek (fd
, 0, SEEK_CUR
);
149 * If we are updating and there is not enough space before the next
150 * entry, expand the file.
154 next
= ze
->next_entry
;
155 if (next
&& here
+ len
>= next
->offset
)
157 if (shift_down (fd
, next
->offset
, (here
+ len
) - next
->offset
, next
))
159 perror ("can't expand file");
164 #endif /* WITH_SHIFT_DOWN */
166 return write (fd
, buf
, len
);
169 int compress_file(int in_fd
, int out_fd
, struct zipentry
*ze
,
170 struct zipentry
*existing
)
173 Bytef out_buff
[RDSZ
];
174 unsigned int rdamt
, wramt
;
175 unsigned long tr
= 0;
181 zs
.next_in
= in_buff
;
183 zs
.next_out
= out_buff
;
184 zs
.avail_out
= (uInt
)RDSZ
;
186 ze
->crc
= crc32(0L, Z_NULL
, 0);
190 /* If deflate is out of input, fill the input buffer for it */
191 if(zs
.avail_in
== 0 && zs
.avail_out
> 0){
192 if((rtval
= read(in_fd
, in_buff
, RDSZ
)) == 0)
202 /* compute the CRC while we're at it */
203 ze
->crc
= crc32(ze
->crc
, in_buff
, rdamt
);
205 /* update the total amount read sofar */
208 zs
.next_in
= in_buff
;
212 /* deflate the data */
213 if(deflate(&zs
, 0) != Z_OK
){
214 fprintf(stderr
, "Error deflating! %s:%d\n", __FILE__
, __LINE__
);
218 /* If the output buffer is full, dump it to disk */
219 if(zs
.avail_out
== 0){
221 if (write_data (out_fd
, out_buff
, RDSZ
, existing
) != RDSZ
)
227 /* clear the output buffer */
228 zs
.next_out
= out_buff
;
229 zs
.avail_out
= (uInt
)RDSZ
;
234 /* If we have any data waiting in the buffer after we're done with the file
236 if(zs
.avail_out
< RDSZ
){
238 wramt
= RDSZ
- zs
.avail_out
;
240 if (write_data (out_fd
, out_buff
, wramt
, existing
) != (int)wramt
)
245 /* clear the output buffer */
246 zs
.next_out
= out_buff
;
247 zs
.avail_out
= (uInt
)RDSZ
;
251 /* finish deflation. This purges zlib's internal data buffers */
252 while(deflate(&zs
, Z_FINISH
) == Z_OK
){
253 wramt
= RDSZ
- zs
.avail_out
;
255 if (write_data (out_fd
, out_buff
, wramt
, existing
) != (int)wramt
)
261 zs
.next_out
= out_buff
;
262 zs
.avail_out
= (uInt
)RDSZ
;
265 /* If there's any data left in the buffer, write it out */
266 if(zs
.avail_out
!= RDSZ
){
267 wramt
= RDSZ
- zs
.avail_out
;
269 if (write_data (out_fd
, out_buff
, wramt
, existing
) != (int)wramt
)
276 /* update fastjar's entry information */
277 ze
->usize
= (ub4
)zs
.total_in
;
278 ze
->csize
= (ub4
)zs
.total_out
;
280 /* Reset the deflation for the next time around */
281 if(deflateReset(&zs
) != Z_OK
){
282 fprintf(stderr
, "Error resetting deflation\n");
289 void end_compression(){
292 /* Oddly enough, zlib always returns Z_DATA_ERROR if you specify no
293 zlib header. Go fig. */
294 if((rtval
= deflateEnd(&zs
)) != Z_OK
&& rtval
!= Z_DATA_ERROR
){
295 fprintf(stderr
, "Error calling deflateEnd\n");
296 fprintf(stderr
, "error: (%d) %s\n", rtval
, zs
.msg
);
302 void init_inflation(){
304 memset(&zs
, 0, sizeof(z_stream
));
310 if(inflateInit2(&zs
, -15) != Z_OK
){
311 fprintf(stderr
, "Error initializing deflation!\n");
317 int inflate_file(pb_file
*pbf
, int out_fd
, struct zipentry
*ze
){
319 Bytef out_buff
[RDSZ
];
326 crc
= crc32(crc
, NULL
, 0); /* initialize crc */
328 /* loop until we've consumed all the compressed data */
331 if(zs
.avail_in
== 0){
332 if((rdamt
= pb_read(pbf
, in_buff
, RDSZ
)) == 0)
334 else if((int)rdamt
< 0){
340 printf("%d bytes read\n", rdamt
);
343 zs
.next_in
= in_buff
;
347 zs
.next_out
= out_buff
;
350 if((rtval
= inflate(&zs
, 0)) != Z_OK
){
351 if(rtval
== Z_STREAM_END
){
353 printf("end of stream\n");
355 if(zs
.avail_out
!= RDSZ
){
356 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
359 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
360 (int)(RDSZ
- zs
.avail_out
)){
368 fprintf(stderr
, "Error inflating file! (%d)\n", rtval
);
372 if(zs
.avail_out
!= RDSZ
){
373 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
376 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
377 (int)(RDSZ
- zs
.avail_out
)){
381 zs
.next_out
= out_buff
;
387 printf("done inflating\n");
391 printf("%d bytes left over\n", zs
.avail_in
);
395 printf("CRC is %x\n", crc
);
400 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
402 ze
->usize
= zs
.total_out
;
409 Function name: report_str_error
410 args: val Error code returned from zlib.
411 purpose: Put out an error message corresponding to error code returned from zlib.
412 Be suitably cryptic seeing I don't really know exactly what these errors mean.
415 static void report_str_error(int val
) {
420 fprintf(stderr
, "Need a dictionary?\n");
423 fprintf(stderr
, "Z_DATA_ERROR\n");
426 fprintf(stderr
, "Z_STREAM_ERROR\n");
429 fprintf(stderr
, "Z_MEM_ERROR\n");
432 fprintf(stderr
, "Z_BUF_ERROR\n");
437 fprintf(stderr
, "Unknown behavior from inflate\n");
443 Function name: ez_inflate_str
444 args: pbf Pointer to pushback handle for file.
445 csize Compressed size of embedded file.
446 usize Uncompressed size of embedded file.
447 purpose: Read in and decompress the contents of an embedded file and store it in a
449 returns: Byte array of uncompressed embedded file.
452 static Bytef
*ez_inflate_str(pb_file
*pbf
, ub4 csize
, ub4 usize
) {
457 if((zs
.next_in
= in_buff
= (Bytef
*) malloc(csize
))) {
458 if((zs
.next_out
= out_buff
= (Bytef
*) malloc(usize
+ 1))) {
459 if((rdamt
= pb_read(pbf
, zs
.next_in
, csize
)) == csize
) {
461 zs
.avail_out
= usize
;
462 report_str_error(inflate(&zs
, 0));
465 out_buff
[usize
] = '\0';
468 fprintf(stderr
, "Read failed on input file.\n");
469 fprintf(stderr
, "Tried to read %u but read %u instead.\n", csize
, rdamt
);
476 fprintf(stderr
, "Malloc of out_buff failed.\n");
477 fprintf(stderr
, "Error: %s\n", strerror(errno
));
483 fprintf(stderr
, "Malloc of in_buff failed.\n");
484 fprintf(stderr
, "Error: %s\n", strerror(errno
));
492 Function name: hrd_inflate_str
493 args: pbf Pointer to pushback handle for file.
494 csize Pointer to compressed size of embedded file.
495 usize Pointer to uncompressed size of embedded file.
496 purpose: Read and decompress an embedded file into a string. Set csize and usize
497 accordingly. This function does the reading for us in the case there is not size
498 information in the header for the embedded file.
499 returns: Byte array of the contents of the embedded file.
502 static Bytef
*hrd_inflate_str(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
513 while(zret
!= Z_STREAM_END
&& (rdamt
= pb_read(pbf
, in_buff
, RDSZ
)))
517 zs
.next_in
= in_buff
;
519 if((tmp
= (Bytef
*) realloc(out_buff
, (RDSZ
* i
) + 1))) {
521 zs
.next_out
= &(out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
]);
522 zs
.avail_out
+= RDSZ
;
526 fprintf(stderr
, "Realloc of out_buff failed.\n");
527 fprintf(stderr
, "Error: %s\n", strerror(errno
));
530 } while((zret
= inflate(&zs
, 0)) == Z_OK
);
531 report_str_error(zret
);
533 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
535 out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
] = '\0';
536 *usize
= zs
.total_out
;
537 *csize
= zs
.total_in
;
545 Function name: inflate_string
546 args: pbf Pointer to pushback handle for file.
547 csize Pointer to compressed size of embedded file. May be 0 if not set.
548 usize Pointer to uncompressed size of embedded file. May be 0 if not set.
549 purpose: Decide the easiest (in computer terms) methos of decompressing this embedded
551 returns: Pointer to a string containing the decompressed contents of the embedded file.
552 If csize and usize are not set set them to correct numbers.
555 Bytef
*inflate_string(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
558 if(*csize
&& *usize
) ret_buf
= ez_inflate_str(pbf
, *csize
, *usize
);
559 else ret_buf
= hrd_inflate_str(pbf
, csize
, usize
);