1 /*
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
56
57 #else // Have ZLIB
58
59 #include <zlib.h>
60
61 inline uint jar::get_crc32(uint c, uchar *ptr, uint len) { return crc32(c, ptr, len); }
62
63 #endif // End of ZLIB
64
65 #ifdef _BIG_ENDIAN
66 #define SWAP_BYTES(a) \
67 ((((a) << 8) & 0xff00) | 0x00ff) & (((a) >> 8) | 0xff00)
68 #else
69 #define SWAP_BYTES(a) (a)
70 #endif
71
72 #define GET_INT_LO(a) \
73 SWAP_BYTES(a & 0xFFFF)
74
75 #define GET_INT_HI(a) \
76 SWAP_BYTES((a >> 16) & 0xFFFF);
77
78
79 void jar::init(unpacker* u_) {
80 BYTES_OF(*this).clear();
81 u = u_;
82 u->jarout = this;
83 }
84
85 // Write data to the ZIP output stream.
86 void jar::write_data(void* buff, int len) {
87 while (len > 0) {
88 int rc = (int)fwrite(buff, 1, len, jarfp);
89 if (rc <= 0) {
90 fprintf(u->errstrm, "Error: write on output file failed err=%d\n",errno);
91 exit(1); // Called only from the native standalone unpacker
92 }
93 output_file_offset += rc;
94 buff = ((char *)buff) + rc;
95 len -= rc;
96 }
97 }
98
99 void jar::add_to_jar_directory(const char* fname, bool store, int modtime,
100 int len, int clen, uLong crc) {
101 uint fname_length = (uint)strlen(fname);
102 ushort header[23];
103 if (modtime == 0) modtime = default_modtime;
104 uLong dostime = get_dostime(modtime);
105
106 header[0] = (ushort)SWAP_BYTES(0x4B50);
107 header[1] = (ushort)SWAP_BYTES(0x0201);
108 header[2] = (ushort)SWAP_BYTES(0xA);
109
110 // required version
111 header[3] = (ushort)SWAP_BYTES(0xA);
112
113 // flags 02 = maximum sub-compression flag
114 header[4] = ( store ) ? 0x0 : SWAP_BYTES(0x2);
115
116 // Compression method 8=deflate.
117 header[5] = ( store ) ? 0x0 : SWAP_BYTES(0x08);
118
119 // Last modified date and time.
120 header[6] = (ushort)GET_INT_LO(dostime);
121 header[7] = (ushort)GET_INT_HI(dostime);
122
123 // CRC
124 header[8] = (ushort)GET_INT_LO(crc);
125 header[9] = (ushort)GET_INT_HI(crc);
126
127 // Compressed length:
128 header[10] = (ushort)GET_INT_LO(clen);
129 header[11] = (ushort)GET_INT_HI(clen);
130
131 // Uncompressed length.
132 header[12] = (ushort)GET_INT_LO(len);
133 header[13] = (ushort)GET_INT_HI(len);
134
135 // Filename length
136 header[14] = (ushort)SWAP_BYTES(fname_length);
137 // So called "extra field" length.
138 header[15] = 0;
139 // So called "comment" length.
140 header[16] = 0;
141 // Disk number start
142 header[17] = 0;
143 // File flags => binary
144 header[18] = 0;
145 // More file flags
146 header[19] = 0;
147 header[20] = 0;
148 // Offset within ZIP file.
149 header[21] = (ushort)GET_INT_LO(output_file_offset);
150 header[22] = (ushort)GET_INT_HI(output_file_offset);
151
152 // Copy the whole thing into the central directory.
153 central_directory.append(header, sizeof(header));
154
155 // Copy the fname to the header.
156 central_directory.append(fname, fname_length);
157
158 central_directory_count++;
159 }
160
161 void jar::write_jar_header(const char* fname, bool store, int modtime,
162 int len, int clen, uint crc) {
163 uint fname_length = (uint)strlen(fname);
164 ushort header[15];
165 if (modtime == 0) modtime = default_modtime;
166 uLong dostime = get_dostime(modtime);
167
168 // ZIP LOC magic.
169 header[0] = (ushort)SWAP_BYTES(0x4B50);
170 header[1] = (ushort)SWAP_BYTES(0x0403);
171
172 // Version
173 header[2] = (ushort)SWAP_BYTES(0xA);
174
175 // flags 02 = maximum sub-compression flag
176 header[3] = ( store ) ? 0x0 : SWAP_BYTES(0x2);
177
178 // Compression method = deflate
179 header[4] = ( store ) ? 0x0 : SWAP_BYTES(0x08);
180
181 // Last modified date and time.
182 header[5] = (ushort)GET_INT_LO(dostime);
183 header[6] = (ushort)GET_INT_HI(dostime);
184
185 // CRC
186 header[7] = (ushort)GET_INT_LO(crc);
187 header[8] = (ushort)GET_INT_HI(crc);
188
189 // Compressed length:
190 header[9] = (ushort)GET_INT_LO(clen);
191 header[10] = (ushort)GET_INT_HI(clen);
192
193 // Uncompressed length.
194 header[11] = (ushort)GET_INT_LO(len);
195 header[12] = (ushort)GET_INT_HI(len);
196
197 // Filename length
198 header[13] = (ushort)SWAP_BYTES(fname_length);
199 // So called "extra field" length.
200 header[14] = 0;
201
202 // Write the LOC header to the output file.
203 write_data(header, (int)sizeof(header));
204
205 // Copy the fname to the header.
206 write_data((char*)fname, (int)fname_length);
207 }
208
209 static const char marker_comment[] = ZIP_ARCHIVE_MARKER_COMMENT;
210
211 void jar::write_central_directory() {
212 bytes mc; mc.set(marker_comment);
213
214 ushort header[11];
215
216 // Create the End of Central Directory structure.
217 header[0] = (ushort)SWAP_BYTES(0x4B50);
218 header[1] = (ushort)SWAP_BYTES(0x0605);
219 // disk numbers
220 header[2] = 0;
221 header[3] = 0;
222 // Number of entries in central directory.
223 header[4] = (ushort)SWAP_BYTES(central_directory_count);
224 header[5] = (ushort)SWAP_BYTES(central_directory_count);
225 // Size of the central directory}
226 header[6] = (ushort)GET_INT_LO((int)central_directory.size());
227 header[7] = (ushort)GET_INT_HI((int)central_directory.size());
228 // Offset of central directory within disk.
229 header[8] = (ushort)GET_INT_LO(output_file_offset);
230 header[9] = (ushort)GET_INT_HI(output_file_offset);
231 // zipfile comment length;
232 header [10] = (ushort)SWAP_BYTES((int)mc.len);
233
234 // Write the central directory.
235 PRINTCR((2, "Central directory at %d\n", output_file_offset));
236 write_data(central_directory.b);
237
238 // Write the End of Central Directory structure.
239 PRINTCR((2, "end-of-directory at %d\n", output_file_offset));
240 write_data(header, (int)sizeof(header));
241
242 PRINTCR((2, "writing zip comment\n"));
243 // Write the comment.
244 write_data(mc);
245 }
246
247 // Public API
248
249 // Open a Jar file and initialize.
250 void jar::openJarFile(const char* fname) {
251 if (!jarfp) {
252 PRINTCR((1, "jar::openJarFile: opening %s\n",fname));
253 jarfp = fopen(fname, "wb");
254 if (!jarfp) {
255 fprintf(u->errstrm, "Error: Could not open jar file: %s\n",fname);
256 exit(3); // Called only from the native standalone unpacker
257 }
269 if (head.len != 0)
270 crc = get_crc32(crc, (uchar *)head.ptr, (uint)head.len);
271 if (tail.len != 0)
272 crc = get_crc32(crc, (uchar *)tail.ptr, (uint)tail.len);
273
274 bool deflate = (deflate_hint && len > 0);
275
276 if (deflate) {
277 if (deflate_bytes(head, tail) == false) {
278 PRINTCR((2, "Reverting to store fn=%s\t%d -> %d\n",
279 fname, len, deflated.size()));
280 deflate = false;
281 }
282 }
283 clen = (int)((deflate) ? deflated.size() : len);
284 add_to_jar_directory(fname, !deflate, modtime, len, clen, crc);
285 write_jar_header( fname, !deflate, modtime, len, clen, crc);
286
287 if (deflate) {
288 write_data(deflated.b);
289 } else {
290 write_data(head);
291 write_data(tail);
292 }
293 }
294
295 // Add a ZIP entry for a directory name no data
296 void jar::addDirectoryToJarFile(const char* dir_name) {
297 bool store = true;
298 add_to_jar_directory((const char*)dir_name, store, default_modtime, 0, 0, 0);
299 write_jar_header( (const char*)dir_name, store, default_modtime, 0, 0, 0);
300 }
301
302 // Write out the central directory and close the jar file.
303 void jar::closeJarFile(bool central) {
304 if (jarfp) {
305 fflush(jarfp);
306 if (central) write_central_directory();
307 fflush(jarfp);
308 fclose(jarfp);
351 return dostime_cache;
352 }
353
354
355
356 #ifndef NO_ZLIB
357
358 /* Returns true on success, and will set the clen to the compressed
359 length, the caller should verify if true and clen less than the
360 input data
361 */
362 bool jar::deflate_bytes(bytes& head, bytes& tail) {
363 int len = (int)(head.len + tail.len);
364
365 z_stream zs;
366 BYTES_OF(zs).clear();
367
368 // NOTE: the window size should always be -MAX_WBITS normally -15.
369 // unzip/zipup.c and java/Deflater.c
370
371 int error = deflateInit2(&zs, Z_BEST_COMPRESSION, Z_DEFLATED,
372 -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
373 if (error != Z_OK) {
374 switch (error) {
375 case Z_MEM_ERROR:
376 PRINTCR((2, "Error: deflate error : Out of memory \n"));
377 break;
378 case Z_STREAM_ERROR:
379 PRINTCR((2,"Error: deflate error : Invalid compression level \n"));
380 break;
381 case Z_VERSION_ERROR:
382 PRINTCR((2,"Error: deflate error : Invalid version\n"));
383 break;
384 default:
385 PRINTCR((2,"Error: Internal deflate error error = %d\n", error));
386 }
387 return false;
388 }
389
390 deflated.empty();
391 zs.next_out = (uchar*) deflated.grow(add_size(len, (len/2)));
397 bytes* first = &head;
398 bytes* last = &tail;
399 if (last->len == 0) {
400 first = null;
401 last = &head;
402 } else if (first->len == 0) {
403 first = null;
404 }
405
406 if (first != null && error == Z_OK) {
407 zs.next_in = (uchar*) first->ptr;
408 zs.avail_in = (int)first->len;
409 error = deflate(&zs, Z_NO_FLUSH);
410 }
411 if (error == Z_OK) {
412 zs.next_in = (uchar*) last->ptr;
413 zs.avail_in = (int)last->len;
414 error = deflate(&zs, Z_FINISH);
415 }
416 if (error == Z_STREAM_END) {
417 if (len > (int)zs.total_out ) {
418 PRINTCR((2, "deflate compressed data %d -> %d\n", len, zs.total_out));
419 deflated.b.len = zs.total_out;
420 deflateEnd(&zs);
421 return true;
422 }
423 PRINTCR((2, "deflate expanded data %d -> %d\n", len, zs.total_out));
424 deflateEnd(&zs);
425 return false;
426 }
427
428 deflateEnd(&zs);
429 PRINTCR((2, "Error: deflate error deflate did not finish error=%d\n",error));
430 return false;
431 }
432
433 // Callback for fetching data from a GZIP input stream
434 static jlong read_input_via_gzip(unpacker* u,
435 void* buf, jlong minlen, jlong maxlen) {
436 assert(minlen <= maxlen); // don't talk nonsense
437 jlong numread = 0;
|
1 /*
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
56
57 #else // Have ZLIB
58
59 #include <zlib.h>
60
61 inline uint jar::get_crc32(uint c, uchar *ptr, uint len) { return crc32(c, ptr, len); }
62
63 #endif // End of ZLIB
64
65 #ifdef _BIG_ENDIAN
66 #define SWAP_BYTES(a) \
67 ((((a) << 8) & 0xff00) | 0x00ff) & (((a) >> 8) | 0xff00)
68 #else
69 #define SWAP_BYTES(a) (a)
70 #endif
71
72 #define GET_INT_LO(a) \
73 SWAP_BYTES(a & 0xFFFF)
74
75 #define GET_INT_HI(a) \
76 SWAP_BYTES((a >> 16) & 0xFFFF)
77
78 static const ushort jarmagic[2] = { SWAP_BYTES(0xCAFE), 0 };
79
80 void jar::init(unpacker* u_) {
81 BYTES_OF(*this).clear();
82 u = u_;
83 u->jarout = this;
84 }
85
86 // Write data to the ZIP output stream.
87 void jar::write_data(void* buff, int len) {
88 while (len > 0) {
89 int rc = (int)fwrite(buff, 1, len, jarfp);
90 if (rc <= 0) {
91 fprintf(u->errstrm, "Error: write on output file failed err=%d\n",errno);
92 exit(1); // Called only from the native standalone unpacker
93 }
94 output_file_offset += rc;
95 buff = ((char *)buff) + rc;
96 len -= rc;
97 }
98 }
99
100 void jar::add_to_jar_directory(const char* fname, bool store, int modtime,
101 int len, int clen, uLong crc) {
102 uint fname_length = (uint)strlen(fname);
103 ushort header[23];
104 if (modtime == 0) modtime = default_modtime;
105 uLong dostime = get_dostime(modtime);
106
107 header[0] = (ushort)SWAP_BYTES(0x4B50);
108 header[1] = (ushort)SWAP_BYTES(0x0201);
109 header[2] = (ushort)SWAP_BYTES(( store ) ? 0x0A : 0x14);
110
111 // required version
112 header[3] = (ushort)SWAP_BYTES(( store ) ? 0x0A : 0x14);
113
114 // Flags - UTF-8 compression and separating crc and sizes
115 // into separate headers for deflated file
116 header[4] = ( store ) ? SWAP_BYTES(0x0800) : 0x0808;
117
118 // Compression method 8=deflate.
119 header[5] = ( store ) ? 0x0 : SWAP_BYTES(0x08);
120
121 // Last modified date and time.
122 header[6] = (ushort)GET_INT_LO(dostime);
123 header[7] = (ushort)GET_INT_HI(dostime);
124
125 // CRC
126 header[8] = (ushort)GET_INT_LO(crc);
127 header[9] = (ushort)GET_INT_HI(crc);
128
129 // Compressed length:
130 header[10] = (ushort)GET_INT_LO(clen);
131 header[11] = (ushort)GET_INT_HI(clen);
132
133 // Uncompressed length.
134 header[12] = (ushort)GET_INT_LO(len);
135 header[13] = (ushort)GET_INT_HI(len);
136
137 // Filename length
138 header[14] = (ushort)SWAP_BYTES(fname_length);
139 // So called "extra field" length.
140 // If it's the first record we must add JAR magic sequence
141 header[15] = ( central_directory_count ) ? 0 : (ushort)SWAP_BYTES(4);
142 // So called "comment" length.
143 header[16] = 0;
144 // Disk number start
145 header[17] = 0;
146 // File flags => binary
147 header[18] = 0;
148 // More file flags
149 header[19] = 0;
150 header[20] = 0;
151 // Offset within ZIP file.
152 header[21] = (ushort)GET_INT_LO(output_file_offset);
153 header[22] = (ushort)GET_INT_HI(output_file_offset);
154
155 // Copy the whole thing into the central directory.
156 central_directory.append(header, sizeof(header));
157
158 // Copy the fname to the header.
159 central_directory.append(fname, fname_length);
160
161 // Add jar magic for the first record
162 if (central_directory_count == 0) {
163 central_directory.append((void *)jarmagic, sizeof(jarmagic));
164 }
165
166 central_directory_count++;
167 }
168
169 void jar::write_jar_header(const char* fname, bool store, int modtime,
170 int len, int clen, uint crc) {
171 uint fname_length = (uint)strlen(fname);
172 ushort header[15];
173 if (modtime == 0) modtime = default_modtime;
174 uLong dostime = get_dostime(modtime);
175
176 // ZIP LOC magic.
177 header[0] = (ushort)SWAP_BYTES(0x4B50);
178 header[1] = (ushort)SWAP_BYTES(0x0403);
179
180 // Version
181 header[2] = (ushort)SWAP_BYTES(( store ) ? 0x0A : 0x14);
182
183 // General purpose flags - same as in the Central Directory
184 header[3] = ( store ) ? SWAP_BYTES(0x0800) : 0x0808;
185
186 // Compression method = deflate
187 header[4] = ( store ) ? 0x0 : SWAP_BYTES(0x08);
188
189 // Last modified date and time.
190 header[5] = (ushort)GET_INT_LO(dostime);
191 header[6] = (ushort)GET_INT_HI(dostime);
192
193 // CRC, 0 if deflated, will come separately in extra header
194 header[7] = ( store ) ? (ushort)GET_INT_LO(crc) : 0;
195 header[8] = ( store ) ? (ushort)GET_INT_HI(crc) : 0;
196
197 // Compressed length, 0 if deflated
198 header[9] = ( store ) ? (ushort)GET_INT_LO(clen) : 0;
199 header[10] = ( store ) ? (ushort)GET_INT_HI(clen) : 0;
200
201 // Uncompressed length, 0 if deflated
202 header[11] = ( store ) ? (ushort)GET_INT_LO(len) : 0;
203 header[12] = ( store ) ? (ushort)GET_INT_HI(len) : 0;
204
205 // Filename length
206 header[13] = (ushort)SWAP_BYTES(fname_length);
207 // So called "extra field" length.
208 header[14] = ( central_directory_count - 1 ) ? 0 : (ushort)SWAP_BYTES(4);
209
210 // Write the LOC header to the output file.
211 write_data(header, (int)sizeof(header));
212
213 // Copy the fname to the header.
214 write_data((char*)fname, (int)fname_length);
215
216 if (central_directory_count == 1) {
217 // Write JAR magic sequence
218 write_data((void *)jarmagic, (int)sizeof(jarmagic));
219 }
220 }
221
222 void jar::write_jar_extra(int len, int clen, uint crc) {
223 ushort header[8];
224 // Extra field signature
225 header[0] = (ushort)SWAP_BYTES(0x4B50);
226 header[1] = (ushort)SWAP_BYTES(0x0807);
227 // CRC
228 header[2] = (ushort)GET_INT_LO(crc);
229 header[3] = (ushort)GET_INT_HI(crc);
230 // Compressed length
231 header[4] = (ushort)GET_INT_LO(clen);
232 header[5] = (ushort)GET_INT_HI(clen);
233 // Uncompressed length
234 header[6] = (ushort)GET_INT_LO(len);
235 header[7] = (ushort)GET_INT_HI(len);
236
237 write_data(header, sizeof(header));
238 }
239
240 static const char marker_comment[] = ZIP_ARCHIVE_MARKER_COMMENT;
241
242 void jar::write_central_directory() {
243 bytes mc; mc.set(marker_comment);
244
245 ushort header[11];
246 ushort header64[38];
247
248 // Create the End of Central Directory structure.
249 header[0] = (ushort)SWAP_BYTES(0x4B50);
250 header[1] = (ushort)SWAP_BYTES(0x0605);
251 // disk numbers
252 header[2] = 0;
253 header[3] = 0;
254 // Number of entries in central directory.
255 header[4] = ( central_directory_count >= 0xffff ) ? 0xffff : (ushort)SWAP_BYTES(central_directory_count);
256 header[5] = ( central_directory_count >= 0xffff ) ? 0xffff : (ushort)SWAP_BYTES(central_directory_count);
257 // Size of the central directory}
258 header[6] = (ushort)GET_INT_LO((int)central_directory.size());
259 header[7] = (ushort)GET_INT_HI((int)central_directory.size());
260 // Offset of central directory within disk.
261 header[8] = (ushort)GET_INT_LO(output_file_offset);
262 header[9] = (ushort)GET_INT_HI(output_file_offset);
263 // zipfile comment length;
264 header[10] = (ushort)SWAP_BYTES((int)mc.len);
265
266 // Write the central directory.
267 PRINTCR((2, "Central directory at %d\n", output_file_offset));
268 write_data(central_directory.b);
269
270 // If number of records exceeds the 0xFFFF we need to prepend extended
271 // Zip64 End of Central Directory record and its locator to the old
272 // style ECD record
273 if (central_directory_count > 0xFFFF) {
274 // Zip64 END signature
275 header64[0] = (ushort)SWAP_BYTES(0x4B50);
276 header64[1] = (ushort)0x0606;
277 // Size of header (long)
278 header64[2] = (ushort)SWAP_BYTES(44);;
279 header64[3] = 0;
280 header64[4] = 0;
281 header64[5] = 0;
282 // Version produced and required (short)
283 header64[6] = (ushort)SWAP_BYTES(45);
284 header64[7] = (ushort)SWAP_BYTES(45);
285 // Current disk number (int)
286 header64[8] = 0;
287 header64[9] = 0;
288 // Central directory start disk (int)
289 header64[10] = 0;
290 header64[11] = 0;
291 // Count of records on disk (long)
292 header64[12] = (ushort)GET_INT_LO(central_directory_count);
293 header64[13] = (ushort)GET_INT_HI(central_directory_count);
294 header64[14] = 0;
295 header64[15] = 0;
296 // Count of records totally (long)
297 header64[16] = (ushort)GET_INT_LO(central_directory_count);
298 header64[17] = (ushort)GET_INT_HI(central_directory_count);
299 header64[18] = 0;
300 header64[19] = 0;
301 // Length of the central directory (long)
302 header64[20] = header[6];
303 header64[21] = header[7];
304 header64[22] = 0;
305 header64[23] = 0;
306 // Offset of central directory (long)
307 header64[24] = header[8];
308 header64[25] = header[9];
309 header64[26] = 0;
310 header64[27] = 0;
311 // Zip64 end of central directory locator
312 // Locator signature
313 header64[28] = (ushort)SWAP_BYTES(0x4B50);
314 header64[29] = (ushort)SWAP_BYTES(0x0706);
315 // Start disk number (int)
316 header64[30] = 0;
317 header64[31] = 0;
318 // Offset of zip64 END record (long)
319 header64[32] = (ushort)GET_INT_LO(output_file_offset);
320 header64[33] = (ushort)GET_INT_HI(output_file_offset);
321 header64[34] = 0;
322 header64[35] = 0;
323 // Total number of disks (int)
324 header64[36] = (ushort)SWAP_BYTES(1);
325 header64[37] = 0;
326 write_data(header64, (int)sizeof(header64));
327 }
328
329 // Write the End of Central Directory structure.
330 PRINTCR((2, "end-of-directory at %d\n", output_file_offset));
331 write_data(header, (int)sizeof(header));
332
333 PRINTCR((2, "writing zip comment\n"));
334 // Write the comment.
335 write_data(mc);
336 }
337
338 // Public API
339
340 // Open a Jar file and initialize.
341 void jar::openJarFile(const char* fname) {
342 if (!jarfp) {
343 PRINTCR((1, "jar::openJarFile: opening %s\n",fname));
344 jarfp = fopen(fname, "wb");
345 if (!jarfp) {
346 fprintf(u->errstrm, "Error: Could not open jar file: %s\n",fname);
347 exit(3); // Called only from the native standalone unpacker
348 }
360 if (head.len != 0)
361 crc = get_crc32(crc, (uchar *)head.ptr, (uint)head.len);
362 if (tail.len != 0)
363 crc = get_crc32(crc, (uchar *)tail.ptr, (uint)tail.len);
364
365 bool deflate = (deflate_hint && len > 0);
366
367 if (deflate) {
368 if (deflate_bytes(head, tail) == false) {
369 PRINTCR((2, "Reverting to store fn=%s\t%d -> %d\n",
370 fname, len, deflated.size()));
371 deflate = false;
372 }
373 }
374 clen = (int)((deflate) ? deflated.size() : len);
375 add_to_jar_directory(fname, !deflate, modtime, len, clen, crc);
376 write_jar_header( fname, !deflate, modtime, len, clen, crc);
377
378 if (deflate) {
379 write_data(deflated.b);
380 // Write deflated information in extra header
381 write_jar_extra(len, clen, crc);
382 } else {
383 write_data(head);
384 write_data(tail);
385 }
386 }
387
388 // Add a ZIP entry for a directory name no data
389 void jar::addDirectoryToJarFile(const char* dir_name) {
390 bool store = true;
391 add_to_jar_directory((const char*)dir_name, store, default_modtime, 0, 0, 0);
392 write_jar_header( (const char*)dir_name, store, default_modtime, 0, 0, 0);
393 }
394
395 // Write out the central directory and close the jar file.
396 void jar::closeJarFile(bool central) {
397 if (jarfp) {
398 fflush(jarfp);
399 if (central) write_central_directory();
400 fflush(jarfp);
401 fclose(jarfp);
444 return dostime_cache;
445 }
446
447
448
449 #ifndef NO_ZLIB
450
451 /* Returns true on success, and will set the clen to the compressed
452 length, the caller should verify if true and clen less than the
453 input data
454 */
455 bool jar::deflate_bytes(bytes& head, bytes& tail) {
456 int len = (int)(head.len + tail.len);
457
458 z_stream zs;
459 BYTES_OF(zs).clear();
460
461 // NOTE: the window size should always be -MAX_WBITS normally -15.
462 // unzip/zipup.c and java/Deflater.c
463
464 int error = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
465 -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
466 if (error != Z_OK) {
467 switch (error) {
468 case Z_MEM_ERROR:
469 PRINTCR((2, "Error: deflate error : Out of memory \n"));
470 break;
471 case Z_STREAM_ERROR:
472 PRINTCR((2,"Error: deflate error : Invalid compression level \n"));
473 break;
474 case Z_VERSION_ERROR:
475 PRINTCR((2,"Error: deflate error : Invalid version\n"));
476 break;
477 default:
478 PRINTCR((2,"Error: Internal deflate error error = %d\n", error));
479 }
480 return false;
481 }
482
483 deflated.empty();
484 zs.next_out = (uchar*) deflated.grow(add_size(len, (len/2)));
490 bytes* first = &head;
491 bytes* last = &tail;
492 if (last->len == 0) {
493 first = null;
494 last = &head;
495 } else if (first->len == 0) {
496 first = null;
497 }
498
499 if (first != null && error == Z_OK) {
500 zs.next_in = (uchar*) first->ptr;
501 zs.avail_in = (int)first->len;
502 error = deflate(&zs, Z_NO_FLUSH);
503 }
504 if (error == Z_OK) {
505 zs.next_in = (uchar*) last->ptr;
506 zs.avail_in = (int)last->len;
507 error = deflate(&zs, Z_FINISH);
508 }
509 if (error == Z_STREAM_END) {
510 if ((int)zs.total_out > 0) {
511 // Even if compressed size is bigger than uncompressed, write it
512 PRINTCR((2, "deflate compressed data %d -> %d\n", len, zs.total_out));
513 deflated.b.len = zs.total_out;
514 deflateEnd(&zs);
515 return true;
516 }
517 PRINTCR((2, "deflate expanded data %d -> %d\n", len, zs.total_out));
518 deflateEnd(&zs);
519 return false;
520 }
521
522 deflateEnd(&zs);
523 PRINTCR((2, "Error: deflate error deflate did not finish error=%d\n",error));
524 return false;
525 }
526
527 // Callback for fetching data from a GZIP input stream
528 static jlong read_input_via_gzip(unpacker* u,
529 void* buf, jlong minlen, jlong maxlen) {
530 assert(minlen <= maxlen); // don't talk nonsense
531 jlong numread = 0;
|