2 * Copyright (c) 2006 Rene Scharfe
13 static unsigned char *zip_dir
;
14 static unsigned int zip_dir_size
;
16 static unsigned int zip_offset
;
17 static unsigned int zip_dir_offset
;
18 static unsigned int zip_dir_entries
;
20 #define ZIP_DIRECTORY_MIN_SIZE (1024 * 1024)
21 #define ZIP_STREAM (1 << 3)
22 #define ZIP_UTF8 (1 << 11)
24 struct zip_local_header
{
25 unsigned char magic
[4];
26 unsigned char version
[2];
27 unsigned char flags
[2];
28 unsigned char compression_method
[2];
29 unsigned char mtime
[2];
30 unsigned char mdate
[2];
31 unsigned char crc32
[4];
32 unsigned char compressed_size
[4];
33 unsigned char size
[4];
34 unsigned char filename_length
[2];
35 unsigned char extra_length
[2];
36 unsigned char _end
[1];
39 struct zip_data_desc
{
40 unsigned char magic
[4];
41 unsigned char crc32
[4];
42 unsigned char compressed_size
[4];
43 unsigned char size
[4];
44 unsigned char _end
[1];
47 struct zip_dir_header
{
48 unsigned char magic
[4];
49 unsigned char creator_version
[2];
50 unsigned char version
[2];
51 unsigned char flags
[2];
52 unsigned char compression_method
[2];
53 unsigned char mtime
[2];
54 unsigned char mdate
[2];
55 unsigned char crc32
[4];
56 unsigned char compressed_size
[4];
57 unsigned char size
[4];
58 unsigned char filename_length
[2];
59 unsigned char extra_length
[2];
60 unsigned char comment_length
[2];
61 unsigned char disk
[2];
62 unsigned char attr1
[2];
63 unsigned char attr2
[4];
64 unsigned char offset
[4];
65 unsigned char _end
[1];
68 struct zip_dir_trailer
{
69 unsigned char magic
[4];
70 unsigned char disk
[2];
71 unsigned char directory_start_disk
[2];
72 unsigned char entries_on_this_disk
[2];
73 unsigned char entries
[2];
74 unsigned char size
[4];
75 unsigned char offset
[4];
76 unsigned char comment_length
[2];
77 unsigned char _end
[1];
81 * On ARM, padding is added at the end of the struct, so a simple
82 * sizeof(struct ...) reports two bytes more than the payload size
83 * we're interested in.
85 #define ZIP_LOCAL_HEADER_SIZE offsetof(struct zip_local_header, _end)
86 #define ZIP_DATA_DESC_SIZE offsetof(struct zip_data_desc, _end)
87 #define ZIP_DIR_HEADER_SIZE offsetof(struct zip_dir_header, _end)
88 #define ZIP_DIR_TRAILER_SIZE offsetof(struct zip_dir_trailer, _end)
90 static void copy_le16(unsigned char *dest
, unsigned int n
)
93 dest
[1] = 0xff & (n
>> 010);
96 static void copy_le32(unsigned char *dest
, unsigned int n
)
99 dest
[1] = 0xff & (n
>> 010);
100 dest
[2] = 0xff & (n
>> 020);
101 dest
[3] = 0xff & (n
>> 030);
104 static void *zlib_deflate(void *data
, unsigned long size
,
105 int compression_level
, unsigned long *compressed_size
)
108 unsigned long maxsize
;
112 memset(&stream
, 0, sizeof(stream
));
113 git_deflate_init(&stream
, compression_level
);
114 maxsize
= git_deflate_bound(&stream
, size
);
115 buffer
= xmalloc(maxsize
);
117 stream
.next_in
= data
;
118 stream
.avail_in
= size
;
119 stream
.next_out
= buffer
;
120 stream
.avail_out
= maxsize
;
123 result
= git_deflate(&stream
, Z_FINISH
);
124 } while (result
== Z_OK
);
126 if (result
!= Z_STREAM_END
) {
131 git_deflate_end(&stream
);
132 *compressed_size
= stream
.total_out
;
137 static void write_zip_data_desc(unsigned long size
,
138 unsigned long compressed_size
,
141 struct zip_data_desc trailer
;
143 copy_le32(trailer
.magic
, 0x08074b50);
144 copy_le32(trailer
.crc32
, crc
);
145 copy_le32(trailer
.compressed_size
, compressed_size
);
146 copy_le32(trailer
.size
, size
);
147 write_or_die(1, &trailer
, ZIP_DATA_DESC_SIZE
);
150 static void set_zip_dir_data_desc(struct zip_dir_header
*header
,
152 unsigned long compressed_size
,
155 copy_le32(header
->crc32
, crc
);
156 copy_le32(header
->compressed_size
, compressed_size
);
157 copy_le32(header
->size
, size
);
160 static void set_zip_header_data_desc(struct zip_local_header
*header
,
162 unsigned long compressed_size
,
165 copy_le32(header
->crc32
, crc
);
166 copy_le32(header
->compressed_size
, compressed_size
);
167 copy_le32(header
->size
, size
);
170 #define STREAM_BUFFER_SIZE (1024 * 16)
172 static int write_zip_entry(struct archiver_args
*args
,
173 const unsigned char *sha1
,
174 const char *path
, size_t pathlen
,
177 struct zip_local_header header
;
178 struct zip_dir_header dirent
;
179 unsigned int creator_version
= 0;
180 unsigned long attr2
= 0;
181 unsigned long compressed_size
;
183 unsigned long direntsize
;
186 void *deflated
= NULL
;
188 struct git_istream
*stream
= NULL
;
189 unsigned long flags
= 0;
192 crc
= crc32(0, NULL
, 0);
194 if (has_non_ascii(path
)) {
198 warning("Path is not valid UTF-8: %s", path
);
201 if (pathlen
> 0xffff) {
202 return error("path too long (%d chars, SHA1: %s): %s",
203 (int)pathlen
, sha1_to_hex(sha1
), path
);
206 if (S_ISDIR(mode
) || S_ISGITLINK(mode
)) {
214 } else if (S_ISREG(mode
) || S_ISLNK(mode
)) {
215 enum object_type type
= sha1_object_info(sha1
, &size
);
218 if (S_ISREG(mode
) && args
->compression_level
!= 0 && size
> 0)
220 if (S_ISLNK(mode
) || (mode
& 0111) || (flags
& ZIP_UTF8
)) {
221 creator_version
= 0x033f;
227 compressed_size
= size
;
229 if (S_ISREG(mode
) && type
== OBJ_BLOB
&& !args
->convert
&&
230 size
> big_file_threshold
) {
231 stream
= open_istream(sha1
, &type
, &size
, NULL
);
233 return error("cannot stream blob %s",
238 buffer
= sha1_file_to_archive(args
, path
, sha1
, mode
,
241 return error("cannot read %s",
243 crc
= crc32(crc
, buffer
, size
);
247 return error("unsupported file mode: 0%o (SHA1: %s)", mode
,
251 if (buffer
&& method
== 8) {
252 deflated
= zlib_deflate(buffer
, size
, args
->compression_level
,
254 if (deflated
&& compressed_size
- 6 < size
) {
255 /* ZLIB --> raw compressed data (see RFC 1950) */
256 /* CMF and FLG ... */
257 out
= (unsigned char *)deflated
+ 2;
258 compressed_size
-= 6; /* ... and ADLER32 */
261 compressed_size
= size
;
265 /* make sure we have enough free space in the dictionary */
266 direntsize
= ZIP_DIR_HEADER_SIZE
+ pathlen
;
267 while (zip_dir_size
< zip_dir_offset
+ direntsize
) {
268 zip_dir_size
+= ZIP_DIRECTORY_MIN_SIZE
;
269 zip_dir
= xrealloc(zip_dir
, zip_dir_size
);
272 copy_le32(dirent
.magic
, 0x02014b50);
273 copy_le16(dirent
.creator_version
, creator_version
);
274 copy_le16(dirent
.version
, 10);
275 copy_le16(dirent
.flags
, flags
);
276 copy_le16(dirent
.compression_method
, method
);
277 copy_le16(dirent
.mtime
, zip_time
);
278 copy_le16(dirent
.mdate
, zip_date
);
279 set_zip_dir_data_desc(&dirent
, size
, compressed_size
, crc
);
280 copy_le16(dirent
.filename_length
, pathlen
);
281 copy_le16(dirent
.extra_length
, 0);
282 copy_le16(dirent
.comment_length
, 0);
283 copy_le16(dirent
.disk
, 0);
284 copy_le16(dirent
.attr1
, 0);
285 copy_le32(dirent
.attr2
, attr2
);
286 copy_le32(dirent
.offset
, zip_offset
);
288 copy_le32(header
.magic
, 0x04034b50);
289 copy_le16(header
.version
, 10);
290 copy_le16(header
.flags
, flags
);
291 copy_le16(header
.compression_method
, method
);
292 copy_le16(header
.mtime
, zip_time
);
293 copy_le16(header
.mdate
, zip_date
);
294 if (flags
& ZIP_STREAM
)
295 set_zip_header_data_desc(&header
, 0, 0, 0);
297 set_zip_header_data_desc(&header
, size
, compressed_size
, crc
);
298 copy_le16(header
.filename_length
, pathlen
);
299 copy_le16(header
.extra_length
, 0);
300 write_or_die(1, &header
, ZIP_LOCAL_HEADER_SIZE
);
301 zip_offset
+= ZIP_LOCAL_HEADER_SIZE
;
302 write_or_die(1, path
, pathlen
);
303 zip_offset
+= pathlen
;
304 if (stream
&& method
== 0) {
305 unsigned char buf
[STREAM_BUFFER_SIZE
];
309 readlen
= read_istream(stream
, buf
, sizeof(buf
));
312 crc
= crc32(crc
, buf
, readlen
);
313 write_or_die(1, buf
, readlen
);
315 close_istream(stream
);
319 compressed_size
= size
;
320 zip_offset
+= compressed_size
;
322 write_zip_data_desc(size
, compressed_size
, crc
);
323 zip_offset
+= ZIP_DATA_DESC_SIZE
;
325 set_zip_dir_data_desc(&dirent
, size
, compressed_size
, crc
);
326 } else if (stream
&& method
== 8) {
327 unsigned char buf
[STREAM_BUFFER_SIZE
];
332 unsigned char compressed
[STREAM_BUFFER_SIZE
* 2];
334 memset(&zstream
, 0, sizeof(zstream
));
335 git_deflate_init(&zstream
, args
->compression_level
);
338 zstream
.next_out
= compressed
;
339 zstream
.avail_out
= sizeof(compressed
);
342 readlen
= read_istream(stream
, buf
, sizeof(buf
));
345 crc
= crc32(crc
, buf
, readlen
);
347 zstream
.next_in
= buf
;
348 zstream
.avail_in
= readlen
;
349 result
= git_deflate(&zstream
, 0);
351 die("deflate error (%d)", result
);
353 if (!compressed_size
)
355 out_len
= zstream
.next_out
- out
;
358 write_or_die(1, out
, out_len
);
359 compressed_size
+= out_len
;
360 zstream
.next_out
= compressed
;
361 zstream
.avail_out
= sizeof(compressed
);
365 close_istream(stream
);
369 zstream
.next_in
= buf
;
370 zstream
.avail_in
= 0;
371 result
= git_deflate(&zstream
, Z_FINISH
);
372 if (result
!= Z_STREAM_END
)
373 die("deflate error (%d)", result
);
375 git_deflate_end(&zstream
);
377 if (!compressed_size
)
379 out_len
= zstream
.next_out
- out
- 4;
380 write_or_die(1, out
, out_len
);
381 compressed_size
+= out_len
;
382 zip_offset
+= compressed_size
;
384 write_zip_data_desc(size
, compressed_size
, crc
);
385 zip_offset
+= ZIP_DATA_DESC_SIZE
;
387 set_zip_dir_data_desc(&dirent
, size
, compressed_size
, crc
);
388 } else if (compressed_size
> 0) {
389 write_or_die(1, out
, compressed_size
);
390 zip_offset
+= compressed_size
;
396 memcpy(zip_dir
+ zip_dir_offset
, &dirent
, ZIP_DIR_HEADER_SIZE
);
397 zip_dir_offset
+= ZIP_DIR_HEADER_SIZE
;
398 memcpy(zip_dir
+ zip_dir_offset
, path
, pathlen
);
399 zip_dir_offset
+= pathlen
;
405 static void write_zip_trailer(const unsigned char *sha1
)
407 struct zip_dir_trailer trailer
;
409 copy_le32(trailer
.magic
, 0x06054b50);
410 copy_le16(trailer
.disk
, 0);
411 copy_le16(trailer
.directory_start_disk
, 0);
412 copy_le16(trailer
.entries_on_this_disk
, zip_dir_entries
);
413 copy_le16(trailer
.entries
, zip_dir_entries
);
414 copy_le32(trailer
.size
, zip_dir_offset
);
415 copy_le32(trailer
.offset
, zip_offset
);
416 copy_le16(trailer
.comment_length
, sha1
? 40 : 0);
418 write_or_die(1, zip_dir
, zip_dir_offset
);
419 write_or_die(1, &trailer
, ZIP_DIR_TRAILER_SIZE
);
421 write_or_die(1, sha1_to_hex(sha1
), 40);
424 static void dos_time(time_t *time
, int *dos_date
, int *dos_time
)
426 struct tm
*t
= localtime(time
);
428 *dos_date
= t
->tm_mday
+ (t
->tm_mon
+ 1) * 32 +
429 (t
->tm_year
+ 1900 - 1980) * 512;
430 *dos_time
= t
->tm_sec
/ 2 + t
->tm_min
* 32 + t
->tm_hour
* 2048;
433 static int write_zip_archive(const struct archiver
*ar
,
434 struct archiver_args
*args
)
438 dos_time(&args
->time
, &zip_date
, &zip_time
);
440 zip_dir
= xmalloc(ZIP_DIRECTORY_MIN_SIZE
);
441 zip_dir_size
= ZIP_DIRECTORY_MIN_SIZE
;
443 err
= write_archive_entries(args
, write_zip_entry
);
445 write_zip_trailer(args
->commit_sha1
);
452 static struct archiver zip_archiver
= {
455 ARCHIVER_WANT_COMPRESSION_LEVELS
|ARCHIVER_REMOTE
458 void init_zip_archiver(void)
460 register_archiver(&zip_archiver
);