148
static void write_zip_data_desc(unsigned long size,
149
unsigned long compressed_size,
152
struct zip_data_desc trailer;
154
copy_le32(trailer.magic, 0x08074b50);
155
copy_le32(trailer.crc32, crc);
156
copy_le32(trailer.compressed_size, compressed_size);
157
copy_le32(trailer.size, size);
158
write_or_die(1, &trailer, ZIP_DATA_DESC_SIZE);
161
static void set_zip_dir_data_desc(struct zip_dir_header *header,
163
unsigned long compressed_size,
166
copy_le32(header->crc32, crc);
167
copy_le32(header->compressed_size, compressed_size);
168
copy_le32(header->size, size);
171
static void set_zip_header_data_desc(struct zip_local_header *header,
173
unsigned long compressed_size,
176
copy_le32(header->crc32, crc);
177
copy_le32(header->compressed_size, compressed_size);
178
copy_le32(header->size, size);
181
static int has_only_ascii(const char *s)
192
#define STREAM_BUFFER_SIZE (1024 * 16)
123
194
static int write_zip_entry(struct archiver_args *args,
124
const unsigned char *sha1, const char *path, size_t pathlen,
125
unsigned int mode, void *buffer, unsigned long size)
195
const unsigned char *sha1,
196
const char *path, size_t pathlen,
127
199
struct zip_local_header header;
128
200
struct zip_dir_header dirent;
201
struct zip_extra_mtime extra;
129
202
unsigned long attr2;
130
203
unsigned long compressed_size;
131
unsigned long uncompressed_size;
132
204
unsigned long crc;
133
205
unsigned long direntsize;
135
207
unsigned char *out;
136
208
void *deflated = NULL;
210
struct git_istream *stream = NULL;
211
unsigned long flags = 0;
138
214
crc = crc32(0, NULL, 0);
216
if (!has_only_ascii(path)) {
220
warning("Path is not valid UTF-8: %s", path);
140
223
if (pathlen > 0xffff) {
141
224
return error("path too long (%d chars, SHA1: %s): %s",
142
225
(int)pathlen, sha1_to_hex(sha1), path);
149
uncompressed_size = 0;
150
233
compressed_size = 0;
151
236
} else if (S_ISREG(mode) || S_ISLNK(mode)) {
237
enum object_type type = sha1_object_info(sha1, &size);
153
240
attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
154
241
(mode & 0111) ? ((mode) << 16) : 0;
155
if (S_ISREG(mode) && args->compression_level != 0)
242
if (S_ISREG(mode) && args->compression_level != 0 && size > 0)
157
crc = crc32(crc, buffer, size);
159
uncompressed_size = size;
160
compressed_size = size;
245
if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
246
size > big_file_threshold) {
247
stream = open_istream(sha1, &type, &size, NULL);
249
return error("cannot stream blob %s",
254
buffer = sha1_file_to_archive(args, path, sha1, mode,
257
return error("cannot read %s",
259
crc = crc32(crc, buffer, size);
262
compressed_size = (method == 0) ? size : 0;
162
264
return error("unsupported file mode: 0%o (SHA1: %s)", mode,
163
265
sha1_to_hex(sha1));
167
deflated = zlib_deflate(buffer, size, args->compression_level,
169
if (deflated && compressed_size - 6 < size) {
170
/* ZLIB --> raw compressed data (see RFC 1950) */
171
/* CMF and FLG ... */
172
out = (unsigned char *)deflated + 2;
173
compressed_size -= 6; /* ... and ADLER32 */
268
if (buffer && method == 8) {
269
out = deflated = zlib_deflate_raw(buffer, size,
270
args->compression_level,
272
if (!out || compressed_size >= size) {
176
275
compressed_size = size;
279
copy_le16(extra.magic, 0x5455);
280
copy_le16(extra.extra_size, ZIP_EXTRA_MTIME_PAYLOAD_SIZE);
281
extra.flags[0] = 1; /* just mtime */
282
copy_le32(extra.mtime, args->time);
180
284
/* make sure we have enough free space in the dictionary */
181
direntsize = ZIP_DIR_HEADER_SIZE + pathlen;
285
direntsize = ZIP_DIR_HEADER_SIZE + pathlen + ZIP_EXTRA_MTIME_SIZE;
182
286
while (zip_dir_size < zip_dir_offset + direntsize) {
183
287
zip_dir_size += ZIP_DIRECTORY_MIN_SIZE;
184
288
zip_dir = xrealloc(zip_dir, zip_dir_size);
188
292
copy_le16(dirent.creator_version,
189
293
S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0);
190
294
copy_le16(dirent.version, 10);
191
copy_le16(dirent.flags, 0);
295
copy_le16(dirent.flags, flags);
192
296
copy_le16(dirent.compression_method, method);
193
297
copy_le16(dirent.mtime, zip_time);
194
298
copy_le16(dirent.mdate, zip_date);
195
copy_le32(dirent.crc32, crc);
196
copy_le32(dirent.compressed_size, compressed_size);
197
copy_le32(dirent.size, uncompressed_size);
299
set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
198
300
copy_le16(dirent.filename_length, pathlen);
199
copy_le16(dirent.extra_length, 0);
301
copy_le16(dirent.extra_length, ZIP_EXTRA_MTIME_SIZE);
200
302
copy_le16(dirent.comment_length, 0);
201
303
copy_le16(dirent.disk, 0);
202
304
copy_le16(dirent.attr1, 0);
203
305
copy_le32(dirent.attr2, attr2);
204
306
copy_le32(dirent.offset, zip_offset);
205
memcpy(zip_dir + zip_dir_offset, &dirent, ZIP_DIR_HEADER_SIZE);
206
zip_dir_offset += ZIP_DIR_HEADER_SIZE;
207
memcpy(zip_dir + zip_dir_offset, path, pathlen);
208
zip_dir_offset += pathlen;
211
308
copy_le32(header.magic, 0x04034b50);
212
309
copy_le16(header.version, 10);
213
copy_le16(header.flags, 0);
310
copy_le16(header.flags, flags);
214
311
copy_le16(header.compression_method, method);
215
312
copy_le16(header.mtime, zip_time);
216
313
copy_le16(header.mdate, zip_date);
217
copy_le32(header.crc32, crc);
218
copy_le32(header.compressed_size, compressed_size);
219
copy_le32(header.size, uncompressed_size);
314
set_zip_header_data_desc(&header, size, compressed_size, crc);
220
315
copy_le16(header.filename_length, pathlen);
221
copy_le16(header.extra_length, 0);
316
copy_le16(header.extra_length, ZIP_EXTRA_MTIME_SIZE);
222
317
write_or_die(1, &header, ZIP_LOCAL_HEADER_SIZE);
223
318
zip_offset += ZIP_LOCAL_HEADER_SIZE;
224
319
write_or_die(1, path, pathlen);
225
320
zip_offset += pathlen;
226
if (compressed_size > 0) {
321
write_or_die(1, &extra, ZIP_EXTRA_MTIME_SIZE);
322
zip_offset += ZIP_EXTRA_MTIME_SIZE;
323
if (stream && method == 0) {
324
unsigned char buf[STREAM_BUFFER_SIZE];
328
readlen = read_istream(stream, buf, sizeof(buf));
331
crc = crc32(crc, buf, readlen);
332
write_or_die(1, buf, readlen);
334
close_istream(stream);
338
compressed_size = size;
339
zip_offset += compressed_size;
341
write_zip_data_desc(size, compressed_size, crc);
342
zip_offset += ZIP_DATA_DESC_SIZE;
344
set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
345
} else if (stream && method == 8) {
346
unsigned char buf[STREAM_BUFFER_SIZE];
351
unsigned char compressed[STREAM_BUFFER_SIZE * 2];
353
memset(&zstream, 0, sizeof(zstream));
354
git_deflate_init_raw(&zstream, args->compression_level);
357
zstream.next_out = compressed;
358
zstream.avail_out = sizeof(compressed);
361
readlen = read_istream(stream, buf, sizeof(buf));
364
crc = crc32(crc, buf, readlen);
366
zstream.next_in = buf;
367
zstream.avail_in = readlen;
368
result = git_deflate(&zstream, 0);
370
die("deflate error (%d)", result);
371
out_len = zstream.next_out - compressed;
374
write_or_die(1, compressed, out_len);
375
compressed_size += out_len;
376
zstream.next_out = compressed;
377
zstream.avail_out = sizeof(compressed);
381
close_istream(stream);
385
zstream.next_in = buf;
386
zstream.avail_in = 0;
387
result = git_deflate(&zstream, Z_FINISH);
388
if (result != Z_STREAM_END)
389
die("deflate error (%d)", result);
391
git_deflate_end(&zstream);
392
out_len = zstream.next_out - compressed;
393
write_or_die(1, compressed, out_len);
394
compressed_size += out_len;
395
zip_offset += compressed_size;
397
write_zip_data_desc(size, compressed_size, crc);
398
zip_offset += ZIP_DATA_DESC_SIZE;
400
set_zip_dir_data_desc(&dirent, size, compressed_size, crc);
401
} else if (compressed_size > 0) {
227
402
write_or_die(1, out, compressed_size);
228
403
zip_offset += compressed_size;
409
memcpy(zip_dir + zip_dir_offset, &dirent, ZIP_DIR_HEADER_SIZE);
410
zip_dir_offset += ZIP_DIR_HEADER_SIZE;
411
memcpy(zip_dir + zip_dir_offset, path, pathlen);
412
zip_dir_offset += pathlen;
413
memcpy(zip_dir + zip_dir_offset, &extra, ZIP_EXTRA_MTIME_SIZE);
414
zip_dir_offset += ZIP_EXTRA_MTIME_SIZE;