author | ksrini |
Tue, 07 May 2013 13:37:03 -0700 | |
changeset 20797 | bb3ea44a7875 |
parent 5506 | 202f599c92aa |
child 21299 | b4e7e588552d |
child 21278 | ef8a3a2a72f2 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
20797 | 2 |
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 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 |
* |
|
5506 | 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 |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
/** |
|
27 |
* Note: Lifted from uncrunch.c from jdk sources |
|
28 |
*/ |
|
29 |
#include <stdio.h> |
|
30 |
#include <string.h> |
|
31 |
#include <errno.h> |
|
32 |
#include <time.h> |
|
33 |
||
34 |
#include <stdlib.h> |
|
35 |
||
36 |
#ifndef _MSC_VER |
|
37 |
#include <strings.h> |
|
38 |
#endif |
|
39 |
||
40 |
#include "defines.h" |
|
41 |
#include "bytes.h" |
|
42 |
#include "utils.h" |
|
43 |
||
44 |
#include "constants.h" |
|
45 |
#include "unpack.h" |
|
46 |
||
47 |
#include "zip.h" |
|
48 |
||
49 |
#ifdef NO_ZLIB |
|
50 |
||
51 |
inline bool jar::deflate_bytes(bytes& head, bytes& tail) { |
|
52 |
return false; |
|
53 |
} |
|
54 |
inline uint jar::get_crc32(uint c, uchar *ptr, uint len) { return 0; } |
|
55 |
#define Z_NULL NULL |
|
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 sparc |
|
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) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
88 |
int rc = (int)fwrite(buff, 1, len, jarfp); |
2 | 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) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
101 |
uint fname_length = (uint)strlen(fname); |
2 | 102 |
ushort header[23]; |
103 |
if (modtime == 0) modtime = default_modtime; |
|
104 |
uLong dostime = get_dostime(modtime); |
|
105 |
||
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
106 |
header[0] = (ushort)SWAP_BYTES(0x4B50); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
107 |
header[1] = (ushort)SWAP_BYTES(0x0201); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
108 |
header[2] = (ushort)SWAP_BYTES(0xA); |
2 | 109 |
|
110 |
// required version |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
111 |
header[3] = (ushort)SWAP_BYTES(0xA); |
2 | 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. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
120 |
header[6] = (ushort)GET_INT_LO(dostime); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
121 |
header[7] = (ushort)GET_INT_HI(dostime); |
2 | 122 |
|
123 |
// CRC |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
124 |
header[8] = (ushort)GET_INT_LO(crc); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
125 |
header[9] = (ushort)GET_INT_HI(crc); |
2 | 126 |
|
127 |
// Compressed length: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
128 |
header[10] = (ushort)GET_INT_LO(clen); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
129 |
header[11] = (ushort)GET_INT_HI(clen); |
2 | 130 |
|
131 |
// Uncompressed length. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
132 |
header[12] = (ushort)GET_INT_LO(len); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
133 |
header[13] = (ushort)GET_INT_HI(len); |
2 | 134 |
|
135 |
// Filename length |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
136 |
header[14] = (ushort)SWAP_BYTES(fname_length); |
2 | 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. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
149 |
header[21] = (ushort)GET_INT_LO(output_file_offset); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
150 |
header[22] = (ushort)GET_INT_HI(output_file_offset); |
2 | 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) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
163 |
uint fname_length = (uint)strlen(fname); |
2 | 164 |
ushort header[15]; |
165 |
if (modtime == 0) modtime = default_modtime; |
|
166 |
uLong dostime = get_dostime(modtime); |
|
167 |
||
168 |
// ZIP LOC magic. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
169 |
header[0] = (ushort)SWAP_BYTES(0x4B50); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
170 |
header[1] = (ushort)SWAP_BYTES(0x0403); |
2 | 171 |
|
172 |
// Version |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
173 |
header[2] = (ushort)SWAP_BYTES(0xA); |
2 | 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. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
182 |
header[5] = (ushort)GET_INT_LO(dostime); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
183 |
header[6] = (ushort)GET_INT_HI(dostime); |
2 | 184 |
|
185 |
// CRC |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
186 |
header[7] = (ushort)GET_INT_LO(crc); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
187 |
header[8] = (ushort)GET_INT_HI(crc); |
2 | 188 |
|
189 |
// Compressed length: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
190 |
header[9] = (ushort)GET_INT_LO(clen); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
191 |
header[10] = (ushort)GET_INT_HI(clen); |
2 | 192 |
|
193 |
// Uncompressed length. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
194 |
header[11] = (ushort)GET_INT_LO(len); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
195 |
header[12] = (ushort)GET_INT_HI(len); |
2 | 196 |
|
197 |
// Filename length |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
198 |
header[13] = (ushort)SWAP_BYTES(fname_length); |
2 | 199 |
// So called "extra field" length. |
200 |
header[14] = 0; |
|
201 |
||
202 |
// Write the LOC header to the output file. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
203 |
write_data(header, (int)sizeof(header)); |
2 | 204 |
|
205 |
// Copy the fname to the header. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
206 |
write_data((char*)fname, (int)fname_length); |
2 | 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. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
217 |
header[0] = (ushort)SWAP_BYTES(0x4B50); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
218 |
header[1] = (ushort)SWAP_BYTES(0x0605); |
2 | 219 |
// disk numbers |
220 |
header[2] = 0; |
|
221 |
header[3] = 0; |
|
222 |
// Number of entries in central directory. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
223 |
header[4] = (ushort)SWAP_BYTES(central_directory_count); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
224 |
header[5] = (ushort)SWAP_BYTES(central_directory_count); |
2 | 225 |
// Size of the central directory} |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
226 |
header[6] = (ushort)GET_INT_LO((int)central_directory.size()); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
227 |
header[7] = (ushort)GET_INT_HI((int)central_directory.size()); |
2 | 228 |
// Offset of central directory within disk. |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
229 |
header[8] = (ushort)GET_INT_LO(output_file_offset); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
230 |
header[9] = (ushort)GET_INT_HI(output_file_offset); |
2 | 231 |
// zipfile comment length; |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
232 |
header [10] = (ushort)SWAP_BYTES((int)mc.len); |
2 | 233 |
|
234 |
// Write the central directory. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
235 |
PRINTCR((2, "Central directory at %d\n", output_file_offset)); |
2 | 236 |
write_data(central_directory.b); |
237 |
||
238 |
// Write the End of Central Directory structure. |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
239 |
PRINTCR((2, "end-of-directory at %d\n", output_file_offset)); |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
240 |
write_data(header, (int)sizeof(header)); |
2 | 241 |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
242 |
PRINTCR((2, "writing zip comment\n")); |
2 | 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) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
252 |
PRINTCR((1, "jar::openJarFile: opening %s\n",fname)); |
2 | 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 |
} |
|
258 |
} |
|
259 |
} |
|
260 |
||
261 |
// Add a ZIP entry and copy the file data |
|
262 |
void jar::addJarEntry(const char* fname, |
|
263 |
bool deflate_hint, int modtime, |
|
264 |
bytes& head, bytes& tail) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
265 |
int len = (int)(head.len + tail.len); |
2 | 266 |
int clen = 0; |
267 |
||
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
268 |
uint crc = get_crc32(0,Z_NULL,0); |
2 | 269 |
if (head.len != 0) |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
270 |
crc = get_crc32(crc, (uchar *)head.ptr, (uint)head.len); |
2 | 271 |
if (tail.len != 0) |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
272 |
crc = get_crc32(crc, (uchar *)tail.ptr, (uint)tail.len); |
2 | 273 |
|
274 |
bool deflate = (deflate_hint && len > 0); |
|
275 |
||
276 |
if (deflate) { |
|
277 |
if (deflate_bytes(head, tail) == false) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
278 |
PRINTCR((2, "Reverting to store fn=%s\t%d -> %d\n", |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
279 |
fname, len, deflated.size())); |
2 | 280 |
deflate = false; |
281 |
} |
|
282 |
} |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
283 |
clen = (int)((deflate) ? deflated.size() : len); |
2 | 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); |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
309 |
PRINTCR((2, "jar::closeJarFile:closed jar-file\n")); |
2 | 310 |
} |
311 |
reset(); |
|
312 |
} |
|
313 |
||
314 |
/* Convert the date y/n/d and time h:m:s to a four byte DOS date and |
|
315 |
* time (date in high two bytes, time in low two bytes allowing magnitude |
|
316 |
* comparison). |
|
317 |
*/ |
|
318 |
inline |
|
319 |
uLong jar::dostime(int y, int n, int d, int h, int m, int s) { |
|
320 |
return y < 1980 ? dostime(1980, 1, 1, 0, 0, 0) : |
|
321 |
(((uLong)y - 1980) << 25) | ((uLong)n << 21) | ((uLong)d << 16) | |
|
322 |
((uLong)h << 11) | ((uLong)m << 5) | ((uLong)s >> 1); |
|
323 |
} |
|
324 |
||
325 |
#ifdef _REENTRANT // solaris |
|
326 |
extern "C" struct tm *gmtime_r(const time_t *, struct tm *); |
|
327 |
#else |
|
328 |
#define gmtime_r(t, s) gmtime(t) |
|
329 |
#endif |
|
330 |
/* |
|
331 |
* Return the Unix time in DOS format |
|
332 |
*/ |
|
333 |
uLong jar::get_dostime(int modtime) { |
|
334 |
// see defines.h |
|
335 |
if (modtime != 0 && modtime == modtime_cache) |
|
336 |
return dostime_cache; |
|
337 |
if (modtime != 0 && default_modtime == 0) |
|
338 |
default_modtime = modtime; // catch a reasonable default |
|
339 |
time_t t = modtime; |
|
340 |
struct tm sbuf; |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
341 |
(void)memset((void*)&sbuf,0, sizeof(sbuf)); |
2 | 342 |
struct tm* s = gmtime_r(&t, &sbuf); |
20797 | 343 |
if (s == NULL) { |
344 |
fprintf(u->errstrm, "Error: gmtime failure, invalid input archive\n"); |
|
345 |
exit(2); |
|
346 |
} |
|
2 | 347 |
modtime_cache = modtime; |
348 |
dostime_cache = dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, |
|
349 |
s->tm_hour, s->tm_min, s->tm_sec); |
|
350 |
//printf("modtime %d => %d\n", modtime_cache, dostime_cache); |
|
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) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
363 |
int len = (int)(head.len + tail.len); |
2 | 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: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
376 |
PRINTCR((2, "Error: deflate error : Out of memory \n")); |
2 | 377 |
break; |
378 |
case Z_STREAM_ERROR: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
379 |
PRINTCR((2,"Error: deflate error : Invalid compression level \n")); |
2 | 380 |
break; |
381 |
case Z_VERSION_ERROR: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
382 |
PRINTCR((2,"Error: deflate error : Invalid version\n")); |
2 | 383 |
break; |
384 |
default: |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
385 |
PRINTCR((2,"Error: Internal deflate error error = %d\n", error)); |
2 | 386 |
} |
387 |
return false; |
|
388 |
} |
|
389 |
||
390 |
deflated.empty(); |
|
20797 | 391 |
zs.next_out = (uchar*) deflated.grow(add_size(len, (len/2))); |
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
392 |
zs.avail_out = (int)deflated.size(); |
2 | 393 |
|
394 |
zs.next_in = (uchar*)head.ptr; |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
395 |
zs.avail_in = (int)head.len; |
2 | 396 |
|
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; |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
408 |
zs.avail_in = (int)first->len; |
2 | 409 |
error = deflate(&zs, Z_NO_FLUSH); |
410 |
} |
|
411 |
if (error == Z_OK) { |
|
412 |
zs.next_in = (uchar*) last->ptr; |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
413 |
zs.avail_in = (int)last->len; |
2 | 414 |
error = deflate(&zs, Z_FINISH); |
415 |
} |
|
416 |
if (error == Z_STREAM_END) { |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
417 |
if (len > (int)zs.total_out ) { |
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
418 |
PRINTCR((2, "deflate compressed data %d -> %d\n", len, zs.total_out)); |
2 | 419 |
deflated.b.len = zs.total_out; |
420 |
deflateEnd(&zs); |
|
421 |
return true; |
|
422 |
} |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
423 |
PRINTCR((2, "deflate expanded data %d -> %d\n", len, zs.total_out)); |
2 | 424 |
deflateEnd(&zs); |
425 |
return false; |
|
426 |
} |
|
427 |
||
428 |
deflateEnd(&zs); |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
429 |
PRINTCR((2, "Error: deflate error deflate did not finish error=%d\n",error)); |
2 | 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; |
|
438 |
char* bufptr = (char*) buf; |
|
439 |
char* inbuf = u->gzin->inbuf; |
|
440 |
size_t inbuflen = sizeof(u->gzin->inbuf); |
|
441 |
unpacker::read_input_fn_t read_gzin_fn = |
|
442 |
(unpacker::read_input_fn_t) u->gzin->read_input_fn; |
|
443 |
z_stream& zs = *(z_stream*) u->gzin->zstream; |
|
444 |
while (numread < minlen) { |
|
445 |
int readlen = (1 << 16); // pretty arbitrary |
|
446 |
if (readlen > (maxlen - numread)) |
|
447 |
readlen = (int)(maxlen - numread); |
|
448 |
zs.next_out = (uchar*) bufptr; |
|
449 |
zs.avail_out = readlen; |
|
450 |
if (zs.avail_in == 0) { |
|
451 |
zs.avail_in = (int) read_gzin_fn(u, inbuf, 1, inbuflen); |
|
452 |
zs.next_in = (uchar*) inbuf; |
|
453 |
} |
|
454 |
int error = inflate(&zs, Z_NO_FLUSH); |
|
455 |
if (error != Z_OK && error != Z_STREAM_END) { |
|
456 |
u->abort("error inflating input"); |
|
457 |
break; |
|
458 |
} |
|
459 |
int nr = readlen - zs.avail_out; |
|
460 |
numread += nr; |
|
461 |
bufptr += nr; |
|
462 |
assert(numread <= maxlen); |
|
463 |
if (error == Z_STREAM_END) { |
|
464 |
enum { TRAILER_LEN = 8 }; |
|
465 |
// skip 8-byte trailer |
|
466 |
if (zs.avail_in >= TRAILER_LEN) { |
|
467 |
zs.avail_in -= TRAILER_LEN; |
|
468 |
} else { |
|
469 |
// Bug: 5023768,we read past the TRAILER_LEN to see if there is |
|
470 |
// any extraneous data, as we dont support concatenated .gz |
|
471 |
// files just yet. |
|
472 |
int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen); |
|
473 |
zs.avail_in += extra - TRAILER_LEN; |
|
474 |
} |
|
475 |
// %%% should check final CRC and length here |
|
476 |
// %%% should check for concatenated *.gz files here |
|
477 |
if (zs.avail_in > 0) |
|
478 |
u->abort("garbage after end of deflated input stream"); |
|
479 |
// pop this filter off: |
|
480 |
u->gzin->free(); |
|
481 |
break; |
|
482 |
} |
|
483 |
} |
|
484 |
||
485 |
//fprintf(u->errstrm, "readInputFn(%d,%d) => %d (gunzip)\n", |
|
486 |
// (int)minlen, (int)maxlen, (int)numread); |
|
487 |
return numread; |
|
488 |
} |
|
489 |
||
490 |
void gunzip::init(unpacker* u_) { |
|
491 |
BYTES_OF(*this).clear(); |
|
492 |
u = u_; |
|
493 |
assert(u->gzin == null); // once only, please |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
494 |
read_input_fn = (void*)u->read_input_fn; |
2 | 495 |
zstream = NEW(z_stream, 1); |
496 |
u->gzin = this; |
|
497 |
u->read_input_fn = read_input_via_gzip; |
|
498 |
} |
|
499 |
||
500 |
void gunzip::start(int magic) { |
|
501 |
assert((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC); |
|
502 |
int gz_flg = (magic & 0xFF); // keep "flg", discard other 3 bytes |
|
503 |
enum { |
|
504 |
FHCRC = (1<<1), |
|
505 |
FEXTRA = (1<<2), |
|
506 |
FNAME = (1<<3), |
|
507 |
FCOMMENT = (1<<4) |
|
508 |
}; |
|
509 |
char gz_mtime[4]; |
|
510 |
char gz_xfl[1]; |
|
511 |
char gz_os[1]; |
|
512 |
char gz_extra_len[2]; |
|
513 |
char gz_hcrc[2]; |
|
514 |
char gz_ignore; |
|
515 |
// do not save extra, name, comment |
|
516 |
read_fixed_field(gz_mtime, sizeof(gz_mtime)); |
|
517 |
read_fixed_field(gz_xfl, sizeof(gz_xfl)); |
|
518 |
read_fixed_field(gz_os, sizeof(gz_os)); |
|
519 |
if (gz_flg & FEXTRA) { |
|
520 |
read_fixed_field(gz_extra_len, sizeof(gz_extra_len)); |
|
521 |
int extra_len = gz_extra_len[0] & 0xFF; |
|
522 |
extra_len += (gz_extra_len[1] & 0xFF) << 8; |
|
523 |
for (; extra_len > 0; extra_len--) { |
|
524 |
read_fixed_field(&gz_ignore, 1); |
|
525 |
} |
|
526 |
} |
|
527 |
int null_terms = 0; |
|
528 |
if (gz_flg & FNAME) null_terms++; |
|
529 |
if (gz_flg & FCOMMENT) null_terms++; |
|
530 |
for (; null_terms; null_terms--) { |
|
531 |
for (;;) { |
|
532 |
gz_ignore = 0; |
|
533 |
read_fixed_field(&gz_ignore, 1); |
|
534 |
if (gz_ignore == 0) break; |
|
535 |
} |
|
536 |
} |
|
537 |
if (gz_flg & FHCRC) |
|
538 |
read_fixed_field(gz_hcrc, sizeof(gz_hcrc)); |
|
539 |
||
540 |
if (aborting()) return; |
|
541 |
||
542 |
// now the input stream is ready to read into the inflater |
|
543 |
int error = inflateInit2((z_stream*) zstream, -MAX_WBITS); |
|
544 |
if (error != Z_OK) { abort("cannot create input"); return; } |
|
545 |
} |
|
546 |
||
547 |
void gunzip::free() { |
|
548 |
assert(u->gzin == this); |
|
549 |
u->gzin = null; |
|
550 |
u->read_input_fn = (unpacker::read_input_fn_t) this->read_input_fn; |
|
551 |
inflateEnd((z_stream*) zstream); |
|
552 |
mtrace('f', zstream, 0); |
|
553 |
::free(zstream); |
|
554 |
zstream = null; |
|
555 |
mtrace('f', this, 0); |
|
556 |
::free(this); |
|
557 |
} |
|
558 |
||
559 |
void gunzip::read_fixed_field(char* buf, size_t buflen) { |
|
560 |
if (aborting()) return; |
|
561 |
jlong nr = ((unpacker::read_input_fn_t)read_input_fn) |
|
562 |
(u, buf, buflen, buflen); |
|
1082
53833ff90c45
6496269: Many warnings generated from com/sun/java/util/jar/pack/*.cpp when compiled on Linux
ohair
parents:
2
diff
changeset
|
563 |
if ((size_t)nr != buflen) |
2 | 564 |
u->abort("short stream header"); |
565 |
} |
|
566 |
||
567 |
#else // NO_ZLIB |
|
568 |
||
569 |
void gunzip::free() { |
|
570 |
} |
|
571 |
||
572 |
#endif // NO_ZLIB |