Merge branch 'vendor/FLEX'
[dragonfly.git] / contrib / libarchive / libarchive / archive_write_set_format_zip.c
1 /*-
2  * Copyright (c) 2008 Anselm Strauss
3  * Copyright (c) 2009 Joerg Sonnenberger
4  * Copyright (c) 2011-2012 Michihiro NAKAJIMA
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*
29  * Development supported by Google Summer of Code 2008.
30  */
31
32 /*
33  * The current implementation is very limited:
34  *
35  *   - No encryption support.
36  *   - No ZIP64 support.
37  *   - No support for splitting and spanning.
38  *   - Only supports regular file and folder entries.
39  *
40  * Note that generally data in ZIP files is little-endian encoded,
41  * with some exceptions.
42  *
43  * TODO: Since Libarchive is generally 64bit oriented, but this implementation
44  * does not yet support sizes exceeding 32bit, it is highly fragile for
45  * big archives. This should change when ZIP64 is finally implemented, otherwise
46  * some serious checking has to be done.
47  *
48  */
49
50 #include "archive_platform.h"
51 __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
52
53 #ifdef HAVE_ERRNO_H
54 #include <errno.h>
55 #endif
56 #ifdef HAVE_LANGINFO_H
57 #include <langinfo.h>
58 #endif
59 #ifdef HAVE_STDLIB_H
60 #include <stdlib.h>
61 #endif
62 #ifdef HAVE_STRING_H
63 #include <string.h>
64 #endif
65 #ifdef HAVE_ZLIB_H
66 #include <zlib.h>
67 #endif
68
69 #include "archive.h"
70 #include "archive_endian.h"
71 #include "archive_entry.h"
72 #include "archive_entry_locale.h"
73 #include "archive_private.h"
74 #include "archive_write_private.h"
75
76 #ifndef HAVE_ZLIB_H
77 #include "archive_crc32.h"
78 #endif
79
80 #define ZIP_SIGNATURE_LOCAL_FILE_HEADER 0x04034b50
81 #define ZIP_SIGNATURE_DATA_DESCRIPTOR 0x08074b50
82 #define ZIP_SIGNATURE_FILE_HEADER 0x02014b50
83 #define ZIP_SIGNATURE_CENTRAL_DIRECTORY_END 0x06054b50
84 #define ZIP_SIGNATURE_EXTRA_TIMESTAMP 0x5455
85 #define ZIP_SIGNATURE_EXTRA_NEW_UNIX 0x7875
86 #define ZIP_VERSION_EXTRACT 0x0014 /* ZIP version 2.0 is needed. */
87 #define ZIP_VERSION_BY 0x0314 /* Made by UNIX, using ZIP version 2.0. */
88 #define ZIP_FLAGS 0x08 /* Flagging bit 3 (count from 0) for using data descriptor. */
89 #define ZIP_FLAGS_UTF8_NAME     (1 << 11)
90
91 enum compression {
92         COMPRESSION_STORE = 0
93 #ifdef HAVE_ZLIB_H
94         ,
95         COMPRESSION_DEFLATE = 8
96 #endif
97 };
98
99 static ssize_t archive_write_zip_data(struct archive_write *,
100                    const void *buff, size_t s);
101 static int archive_write_zip_close(struct archive_write *);
102 static int archive_write_zip_free(struct archive_write *);
103 static int archive_write_zip_finish_entry(struct archive_write *);
104 static int archive_write_zip_header(struct archive_write *,
105               struct archive_entry *);
106 static int archive_write_zip_options(struct archive_write *,
107               const char *, const char *);
108 static unsigned int dos_time(const time_t);
109 static size_t path_length(struct archive_entry *);
110 static int write_path(struct archive_entry *, struct archive_write *);
111
112 #define LOCAL_FILE_HEADER_SIGNATURE             0
113 #define LOCAL_FILE_HEADER_VERSION               4
114 #define LOCAL_FILE_HEADER_FLAGS                 6
115 #define LOCAL_FILE_HEADER_COMPRESSION           8
116 #define LOCAL_FILE_HEADER_TIMEDATE              10
117 #define LOCAL_FILE_HEADER_CRC32                 14
118 #define LOCAL_FILE_HEADER_COMPRESSED_SIZE       18
119 #define LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE     22
120 #define LOCAL_FILE_HEADER_FILENAME_LENGTH       26
121 #define LOCAL_FILE_HEADER_EXTRA_LENGTH          28
122 #define SIZE_LOCAL_FILE_HEADER                  30
123
124 #define FILE_HEADER_SIGNATURE                   0
125 #define FILE_HEADER_VERSION_BY                  4
126 #define FILE_HEADER_VERSION_EXTRACT             6
127 #define FILE_HEADER_FLAGS                       8
128 #define FILE_HEADER_COMPRESSION                 10
129 #define FILE_HEADER_TIMEDATE                    12
130 #define FILE_HEADER_CRC32                       16
131 #define FILE_HEADER_COMPRESSED_SIZE             20
132 #define FILE_HEADER_UNCOMPRESSED_SIZE           24
133 #define FILE_HEADER_FILENAME_LENGTH             28
134 #define FILE_HEADER_EXTRA_LENGTH                30
135 #define FILE_HEADER_COMMENT_LENGTH              32
136 #define FILE_HEADER_DISK_NUMBER                 34
137 #define FILE_HEADER_ATTRIBUTES_INTERNAL         36
138 #define FILE_HEADER_ATTRIBUTES_EXTERNAL         38
139 #define FILE_HEADER_OFFSET                      42
140 #define SIZE_FILE_HEADER                        46
141
142         /* Not mandatory, but recommended by specification. */
143 #define DATA_DESCRIPTOR_SIGNATURE               0
144 #define DATA_DESCRIPTOR_CRC32                   4
145 #define DATA_DESCRIPTOR_COMPRESSED_SIZE         8
146 #define DATA_DESCRIPTOR_UNCOMPRESSED_SIZE       12
147 #define SIZE_DATA_DESCRIPTOR                    16
148
149 #define EXTRA_DATA_LOCAL_TIME_ID                0
150 #define EXTRA_DATA_LOCAL_TIME_SIZE              2
151 #define EXTRA_DATA_LOCAL_TIME_FLAG              4
152 #define EXTRA_DATA_LOCAL_MTIME                  5
153 #define EXTRA_DATA_LOCAL_ATIME                  9
154 #define EXTRA_DATA_LOCAL_CTIME                  13
155 #define EXTRA_DATA_LOCAL_UNIX_ID                17
156 #define EXTRA_DATA_LOCAL_UNIX_SIZE              19
157 #define EXTRA_DATA_LOCAL_UNIX_VERSION           21
158 #define EXTRA_DATA_LOCAL_UNIX_UID_SIZE          22
159 #define EXTRA_DATA_LOCAL_UNIX_UID               23
160 #define EXTRA_DATA_LOCAL_UNIX_GID_SIZE          27
161 #define EXTRA_DATA_LOCAL_UNIX_GID               28
162 #define SIZE_EXTRA_DATA_LOCAL                   32
163
164 #define EXTRA_DATA_CENTRAL_TIME_ID              0
165 #define EXTRA_DATA_CENTRAL_TIME_SIZE            2
166 #define EXTRA_DATA_CENTRAL_TIME_FLAG            4
167 #define EXTRA_DATA_CENTRAL_MTIME                5
168 #define EXTRA_DATA_CENTRAL_UNIX_ID              9
169 #define EXTRA_DATA_CENTRAL_UNIX_SIZE            11
170 #define SIZE_EXTRA_DATA_CENTRAL                 13
171
172 #define CENTRAL_DIRECTORY_END_SIGNATURE         0
173 #define CENTRAL_DIRECTORY_END_DISK              4
174 #define CENTRAL_DIRECTORY_END_START_DISK        6
175 #define CENTRAL_DIRECTORY_END_ENTRIES_DISK      8
176 #define CENTRAL_DIRECTORY_END_ENTRIES           10
177 #define CENTRAL_DIRECTORY_END_SIZE              12
178 #define CENTRAL_DIRECTORY_END_OFFSET            16
179 #define CENTRAL_DIRECTORY_END_COMMENT_LENGTH    20
180 #define SIZE_CENTRAL_DIRECTORY_END              22
181
182 struct zip_file_header_link {
183         struct zip_file_header_link *next;
184         struct archive_entry *entry;
185         int64_t offset;
186         unsigned long crc32;
187         int64_t compressed_size;
188         enum compression compression;
189         int flags;
190 };
191
192 struct zip {
193         uint8_t data_descriptor[SIZE_DATA_DESCRIPTOR];
194         struct zip_file_header_link *central_directory;
195         struct zip_file_header_link *central_directory_end;
196         int64_t offset;
197         int64_t written_bytes;
198         int64_t remaining_data_bytes;
199         enum compression compression;
200         int flags;
201         struct archive_string_conv *opt_sconv;
202         struct archive_string_conv *sconv_default;
203         int     init_default_conversion;
204
205 #ifdef HAVE_ZLIB_H
206         z_stream stream;
207         size_t len_buf;
208         unsigned char *buf;
209 #endif
210 };
211
212 static int
213 archive_write_zip_options(struct archive_write *a, const char *key,
214     const char *val)
215 {
216         struct zip *zip = a->format_data;
217         int ret = ARCHIVE_FAILED;
218
219         if (strcmp(key, "compression") == 0) {
220                 if (val == NULL || val[0] == 0) {
221                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
222                             "%s: compression option needs a compression name",
223                             a->format_name);
224                 } else if (strcmp(val, "deflate") == 0) {
225 #ifdef HAVE_ZLIB_H
226                         zip->compression = COMPRESSION_DEFLATE;
227                         ret = ARCHIVE_OK;
228 #else
229                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
230                             "deflate compression not supported");
231 #endif
232                 } else if (strcmp(val, "store") == 0) {
233                         zip->compression = COMPRESSION_STORE;
234                         ret = ARCHIVE_OK;
235                 }
236                 return (ret);
237         } else if (strcmp(key, "hdrcharset")  == 0) {
238                 if (val == NULL || val[0] == 0) {
239                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
240                             "%s: hdrcharset option needs a character-set name",
241                             a->format_name);
242                 } else {
243                         zip->opt_sconv = archive_string_conversion_to_charset(
244                             &a->archive, val, 0);
245                         if (zip->opt_sconv != NULL)
246                                 ret = ARCHIVE_OK;
247                         else
248                                 ret = ARCHIVE_FATAL;
249                 }
250                 return (ret);
251         }
252
253         /* Note: The "warn" return is just to inform the options
254          * supervisor that we didn't handle it.  It will generate
255          * a suitable error if no one used this option. */
256         return (ARCHIVE_WARN);
257 }
258
259 int
260 archive_write_set_format_zip(struct archive *_a)
261 {
262         struct archive_write *a = (struct archive_write *)_a;
263         struct zip *zip;
264
265         archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
266             ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
267
268         /* If another format was already registered, unregister it. */
269         if (a->format_free != NULL)
270                 (a->format_free)(a);
271
272         zip = (struct zip *) calloc(1, sizeof(*zip));
273         if (zip == NULL) {
274                 archive_set_error(&a->archive, ENOMEM,
275                     "Can't allocate zip data");
276                 return (ARCHIVE_FATAL);
277         }
278         zip->central_directory = NULL;
279         zip->central_directory_end = NULL;
280         zip->offset = 0;
281         zip->written_bytes = 0;
282         zip->remaining_data_bytes = 0;
283
284 #ifdef HAVE_ZLIB_H
285         zip->compression = COMPRESSION_DEFLATE;
286         zip->len_buf = 65536;
287         zip->buf = malloc(zip->len_buf);
288         if (zip->buf == NULL) {
289                 free(zip);
290                 archive_set_error(&a->archive, ENOMEM,
291                     "Can't allocate compression buffer");
292                 return (ARCHIVE_FATAL);
293         }
294 #else
295         zip->compression = COMPRESSION_STORE;
296 #endif
297
298         a->format_data = zip;
299         a->format_name = "zip";
300         a->format_options = archive_write_zip_options;
301         a->format_write_header = archive_write_zip_header;
302         a->format_write_data = archive_write_zip_data;
303         a->format_finish_entry = archive_write_zip_finish_entry;
304         a->format_close = archive_write_zip_close;
305         a->format_free = archive_write_zip_free;
306         a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
307         a->archive.archive_format_name = "ZIP";
308
309         archive_le32enc(&zip->data_descriptor[DATA_DESCRIPTOR_SIGNATURE],
310             ZIP_SIGNATURE_DATA_DESCRIPTOR);
311
312         return (ARCHIVE_OK);
313 }
314
315 static int
316 is_all_ascii(const char *p)
317 {
318         const unsigned char *pp = (const unsigned char *)p;
319
320         while (*pp) {
321                 if (*pp++ > 127)
322                         return (0);
323         }
324         return (1);
325 }
326
327 static int
328 archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
329 {
330         struct zip *zip;
331         uint8_t h[SIZE_LOCAL_FILE_HEADER];
332         uint8_t e[SIZE_EXTRA_DATA_LOCAL];
333         uint8_t *d;
334         struct zip_file_header_link *l;
335         struct archive_string_conv *sconv;
336         int ret, ret2 = ARCHIVE_OK;
337         int64_t size;
338         mode_t type;
339
340         /* Entries other than a regular file or a folder are skipped. */
341         type = archive_entry_filetype(entry);
342         if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
343                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
344                     "Filetype not supported");
345                 return ARCHIVE_FAILED;
346         }; 
347
348         /* Directory entries should have a size of 0. */
349         if (type == AE_IFDIR)
350                 archive_entry_set_size(entry, 0);
351
352         zip = a->format_data;
353         /* Setup default conversion. */
354         if (zip->opt_sconv == NULL && !zip->init_default_conversion) {
355                 zip->sconv_default =
356                     archive_string_default_conversion_for_write(&(a->archive));
357                 zip->init_default_conversion = 1;
358         }
359
360         if (zip->flags == 0) {
361                 /* Initialize the general purpose flags. */
362                 zip->flags = ZIP_FLAGS;
363                 if (zip->opt_sconv != NULL) {
364                         if (strcmp(archive_string_conversion_charset_name(
365                             zip->opt_sconv), "UTF-8") == 0)
366                                 zip->flags |= ZIP_FLAGS_UTF8_NAME;
367 #if HAVE_NL_LANGINFO
368                 } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
369                         zip->flags |= ZIP_FLAGS_UTF8_NAME;
370 #endif
371                 }
372         }
373         d = zip->data_descriptor;
374         size = archive_entry_size(entry);
375         zip->remaining_data_bytes = size;
376
377         /* Append archive entry to the central directory data. */
378         l = (struct zip_file_header_link *) malloc(sizeof(*l));
379         if (l == NULL) {
380                 archive_set_error(&a->archive, ENOMEM,
381                     "Can't allocate zip header data");
382                 return (ARCHIVE_FATAL);
383         }
384 #if defined(_WIN32) && !defined(__CYGWIN__)
385         /* Make sure the path separators in pahtname, hardlink and symlink
386          * are all slash '/', not the Windows path separator '\'. */
387         l->entry = __la_win_entry_in_posix_pathseparator(entry);
388         if (l->entry == entry)
389                 l->entry = archive_entry_clone(entry);
390 #else
391         l->entry = archive_entry_clone(entry);
392 #endif
393         if (l->entry == NULL) {
394                 archive_set_error(&a->archive, ENOMEM,
395                     "Can't allocate zip header data");
396                 free(l);
397                 return (ARCHIVE_FATAL);
398         }
399         l->flags = zip->flags;
400         if (zip->opt_sconv != NULL)
401                 sconv = zip->opt_sconv;
402         else
403                 sconv = zip->sconv_default;
404         if (sconv != NULL) {
405                 const char *p;
406                 size_t len;
407
408                 if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
409                         if (errno == ENOMEM) {
410                                 archive_entry_free(l->entry);
411                                 free(l);
412                                 archive_set_error(&a->archive, ENOMEM,
413                                     "Can't allocate memory for Pathname");
414                                 return (ARCHIVE_FATAL);
415                         }
416                         archive_set_error(&a->archive,
417                             ARCHIVE_ERRNO_FILE_FORMAT,
418                             "Can't translate Pathname '%s' to %s",
419                             archive_entry_pathname(entry),
420                             archive_string_conversion_charset_name(sconv));
421                         ret2 = ARCHIVE_WARN;
422                 }
423                 if (len > 0)
424                         archive_entry_set_pathname(l->entry, p);
425
426                 /*
427                  * Although there is no character-set regulation for Symlink,
428                  * it is suitable to convert a character-set of Symlinke to
429                  * what those of the Pathname has been converted to.
430                  */
431                 if (type == AE_IFLNK) {
432                         if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
433                                 if (errno == ENOMEM) {
434                                         archive_entry_free(l->entry);
435                                         free(l);
436                                         archive_set_error(&a->archive, ENOMEM,
437                                             "Can't allocate memory "
438                                             " for Symlink");
439                                         return (ARCHIVE_FATAL);
440                                 }
441                                 /*
442                                  * Even if the strng conversion failed,
443                                  * we should not report the error since
444                                  * thre is no regulation for.
445                                  */
446                         } else if (len > 0)
447                                 archive_entry_set_symlink(l->entry, p);
448                 }
449         }
450         /* If all characters in a filename are ASCII, Reset UTF-8 Name flag. */
451         if ((l->flags & ZIP_FLAGS_UTF8_NAME) != 0 &&
452             is_all_ascii(archive_entry_pathname(l->entry)))
453                 l->flags &= ~ZIP_FLAGS_UTF8_NAME;
454
455         /* Initialize the CRC variable and potentially the local crc32(). */
456         l->crc32 = crc32(0, NULL, 0);
457         if (type == AE_IFLNK) {
458                 const char *p = archive_entry_symlink(l->entry);
459                 if (p != NULL)
460                         size = strlen(p);
461                 else
462                         size = 0;
463                 zip->remaining_data_bytes = 0;
464                 archive_entry_set_size(l->entry, size);
465                 l->compression = COMPRESSION_STORE;
466                 l->compressed_size = size;
467         } else {
468                 l->compression = zip->compression;
469                 l->compressed_size = 0;
470         }
471         l->next = NULL;
472         if (zip->central_directory == NULL) {
473                 zip->central_directory = l;
474         } else {
475                 zip->central_directory_end->next = l;
476         }
477         zip->central_directory_end = l;
478
479         /* Store the offset of this header for later use in central
480          * directory. */
481         l->offset = zip->written_bytes;
482
483         memset(h, 0, sizeof(h));
484         archive_le32enc(&h[LOCAL_FILE_HEADER_SIGNATURE],
485                 ZIP_SIGNATURE_LOCAL_FILE_HEADER);
486         archive_le16enc(&h[LOCAL_FILE_HEADER_VERSION], ZIP_VERSION_EXTRACT);
487         archive_le16enc(&h[LOCAL_FILE_HEADER_FLAGS], l->flags);
488         archive_le16enc(&h[LOCAL_FILE_HEADER_COMPRESSION], l->compression);
489         archive_le32enc(&h[LOCAL_FILE_HEADER_TIMEDATE],
490                 dos_time(archive_entry_mtime(entry)));
491         archive_le16enc(&h[LOCAL_FILE_HEADER_FILENAME_LENGTH],
492                 (uint16_t)path_length(l->entry));
493
494         switch (l->compression) {
495         case COMPRESSION_STORE:
496                 /* Setting compressed and uncompressed sizes even when
497                  * specification says to set to zero when using data
498                  * descriptors. Otherwise the end of the data for an
499                  * entry is rather difficult to find. */
500                 archive_le32enc(&h[LOCAL_FILE_HEADER_COMPRESSED_SIZE],
501                     (uint32_t)size);
502                 archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
503                     (uint32_t)size);
504                 break;
505 #ifdef HAVE_ZLIB_H
506         case COMPRESSION_DEFLATE:
507                 archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
508                     (uint32_t)size);
509
510                 zip->stream.zalloc = Z_NULL;
511                 zip->stream.zfree = Z_NULL;
512                 zip->stream.opaque = Z_NULL;
513                 zip->stream.next_out = zip->buf;
514                 zip->stream.avail_out = zip->len_buf;
515                 if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION,
516                     Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
517                         archive_set_error(&a->archive, ENOMEM,
518                             "Can't init deflate compressor");
519                         return (ARCHIVE_FATAL);
520                 }
521                 break;
522 #endif
523         }
524
525         /* Formatting extra data. */
526         archive_le16enc(&h[LOCAL_FILE_HEADER_EXTRA_LENGTH], sizeof(e));
527         archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_ID],
528                 ZIP_SIGNATURE_EXTRA_TIMESTAMP);
529         archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_SIZE], 1 + 4 * 3);
530         e[EXTRA_DATA_LOCAL_TIME_FLAG] = 0x07;
531         archive_le32enc(&e[EXTRA_DATA_LOCAL_MTIME],
532             (uint32_t)archive_entry_mtime(entry));
533         archive_le32enc(&e[EXTRA_DATA_LOCAL_ATIME],
534             (uint32_t)archive_entry_atime(entry));
535         archive_le32enc(&e[EXTRA_DATA_LOCAL_CTIME],
536             (uint32_t)archive_entry_ctime(entry));
537
538         archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_ID],
539                 ZIP_SIGNATURE_EXTRA_NEW_UNIX);
540         archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_SIZE], 1 + (1 + 4) * 2);
541         e[EXTRA_DATA_LOCAL_UNIX_VERSION] = 1;
542         e[EXTRA_DATA_LOCAL_UNIX_UID_SIZE] = 4;
543         archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_UID],
544                 (uint32_t)archive_entry_uid(entry));
545         e[EXTRA_DATA_LOCAL_UNIX_GID_SIZE] = 4;
546         archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_GID],
547                 (uint32_t)archive_entry_gid(entry));
548
549         archive_le32enc(&d[DATA_DESCRIPTOR_UNCOMPRESSED_SIZE],
550             (uint32_t)size);
551
552         ret = __archive_write_output(a, h, sizeof(h));
553         if (ret != ARCHIVE_OK)
554                 return (ARCHIVE_FATAL);
555         zip->written_bytes += sizeof(h);
556
557         ret = write_path(l->entry, a);
558         if (ret <= ARCHIVE_OK)
559                 return (ARCHIVE_FATAL);
560         zip->written_bytes += ret;
561
562         ret = __archive_write_output(a, e, sizeof(e));
563         if (ret != ARCHIVE_OK)
564                 return (ARCHIVE_FATAL);
565         zip->written_bytes += sizeof(e);
566
567         if (type == AE_IFLNK) {
568                 const unsigned char *p;
569
570                 p = (const unsigned char *)archive_entry_symlink(l->entry);
571                 ret = __archive_write_output(a, p, (size_t)size);
572                 if (ret != ARCHIVE_OK)
573                         return (ARCHIVE_FATAL);
574                 zip->written_bytes += size;
575                 l->crc32 = crc32(l->crc32, p, (unsigned)size);
576         }
577
578         if (ret2 != ARCHIVE_OK)
579                 return (ret2);
580         return (ARCHIVE_OK);
581 }
582
583 static ssize_t
584 archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
585 {
586         int ret;
587         struct zip *zip = a->format_data;
588         struct zip_file_header_link *l = zip->central_directory_end;
589
590         if ((int64_t)s > zip->remaining_data_bytes)
591                 s = (size_t)zip->remaining_data_bytes;
592
593         if (s == 0) return 0;
594
595         switch (l->compression) {
596         case COMPRESSION_STORE:
597                 ret = __archive_write_output(a, buff, s);
598                 if (ret != ARCHIVE_OK) return (ret);
599                 zip->written_bytes += s;
600                 zip->remaining_data_bytes -= s;
601                 l->compressed_size += s;
602                 l->crc32 = crc32(l->crc32, buff, s);
603                 return (s);
604 #if HAVE_ZLIB_H
605         case COMPRESSION_DEFLATE:
606                 zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
607                 zip->stream.avail_in = s;
608                 do {
609                         ret = deflate(&zip->stream, Z_NO_FLUSH);
610                         if (ret == Z_STREAM_ERROR)
611                                 return (ARCHIVE_FATAL);
612                         if (zip->stream.avail_out == 0) {
613                                 ret = __archive_write_output(a, zip->buf,
614                                         zip->len_buf);
615                                 if (ret != ARCHIVE_OK)
616                                         return (ret);
617                                 l->compressed_size += zip->len_buf;
618                                 zip->written_bytes += zip->len_buf;
619                                 zip->stream.next_out = zip->buf;
620                                 zip->stream.avail_out = zip->len_buf;
621                         }
622                 } while (zip->stream.avail_in != 0);
623                 zip->remaining_data_bytes -= s;
624                 /* If we have it, use zlib's fast crc32() */
625                 l->crc32 = crc32(l->crc32, buff, s);
626                 return (s);
627 #endif
628
629         default:
630                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
631                     "Invalid ZIP compression type");
632                 return ARCHIVE_FATAL;
633         }
634 }
635
636 static int
637 archive_write_zip_finish_entry(struct archive_write *a)
638 {
639         /* Write the data descripter after file data has been written. */
640         int ret;
641         struct zip *zip = a->format_data;
642         uint8_t *d = zip->data_descriptor;
643         struct zip_file_header_link *l = zip->central_directory_end;
644 #if HAVE_ZLIB_H
645         size_t reminder;
646 #endif
647
648         switch(l->compression) {
649         case COMPRESSION_STORE:
650                 break;
651 #if HAVE_ZLIB_H
652         case COMPRESSION_DEFLATE:
653                 for (;;) {
654                         ret = deflate(&zip->stream, Z_FINISH);
655                         if (ret == Z_STREAM_ERROR)
656                                 return (ARCHIVE_FATAL);
657                         reminder = zip->len_buf - zip->stream.avail_out;
658                         ret = __archive_write_output(a, zip->buf, reminder);
659                         if (ret != ARCHIVE_OK)
660                                 return (ret);
661                         l->compressed_size += reminder;
662                         zip->written_bytes += reminder;
663                         zip->stream.next_out = zip->buf;
664                         if (zip->stream.avail_out != 0)
665                                 break;
666                         zip->stream.avail_out = zip->len_buf;
667                 }
668                 deflateEnd(&zip->stream);
669                 break;
670 #endif
671         }
672
673         archive_le32enc(&d[DATA_DESCRIPTOR_CRC32], l->crc32);
674         archive_le32enc(&d[DATA_DESCRIPTOR_COMPRESSED_SIZE],
675                 (uint32_t)l->compressed_size);
676         ret = __archive_write_output(a, d, SIZE_DATA_DESCRIPTOR);
677         if (ret != ARCHIVE_OK)
678                 return (ARCHIVE_FATAL);
679         zip->written_bytes += SIZE_DATA_DESCRIPTOR;
680         return (ARCHIVE_OK);
681 }
682
683 static int
684 archive_write_zip_close(struct archive_write *a)
685 {
686         struct zip *zip;
687         struct zip_file_header_link *l;
688         uint8_t h[SIZE_FILE_HEADER];
689         uint8_t end[SIZE_CENTRAL_DIRECTORY_END];
690         uint8_t e[SIZE_EXTRA_DATA_CENTRAL];
691         int64_t offset_start, offset_end;
692         int entries;
693         int ret;
694
695         zip = a->format_data;
696         l = zip->central_directory;
697
698         /*
699          * Formatting central directory file header fields that are
700          * fixed for all entries.
701          * Fields not used (and therefor 0) are:
702          *
703          *   - comment_length
704          *   - disk_number
705          *   - attributes_internal
706          */
707         memset(h, 0, sizeof(h));
708         archive_le32enc(&h[FILE_HEADER_SIGNATURE], ZIP_SIGNATURE_FILE_HEADER);
709         archive_le16enc(&h[FILE_HEADER_VERSION_BY], ZIP_VERSION_BY);
710         archive_le16enc(&h[FILE_HEADER_VERSION_EXTRACT], ZIP_VERSION_EXTRACT);
711
712         entries = 0;
713         offset_start = zip->written_bytes;
714
715         /* Formatting individual header fields per entry and
716          * writing each entry. */
717         while (l != NULL) {
718                 archive_le16enc(&h[FILE_HEADER_FLAGS], l->flags);
719                 archive_le16enc(&h[FILE_HEADER_COMPRESSION], l->compression);
720                 archive_le32enc(&h[FILE_HEADER_TIMEDATE],
721                         dos_time(archive_entry_mtime(l->entry)));
722                 archive_le32enc(&h[FILE_HEADER_CRC32], l->crc32);
723                 archive_le32enc(&h[FILE_HEADER_COMPRESSED_SIZE],
724                         (uint32_t)l->compressed_size);
725                 archive_le32enc(&h[FILE_HEADER_UNCOMPRESSED_SIZE],
726                         (uint32_t)archive_entry_size(l->entry));
727                 archive_le16enc(&h[FILE_HEADER_FILENAME_LENGTH],
728                         (uint16_t)path_length(l->entry));
729                 archive_le16enc(&h[FILE_HEADER_EXTRA_LENGTH], sizeof(e));
730                 archive_le16enc(&h[FILE_HEADER_ATTRIBUTES_EXTERNAL+2],
731                         archive_entry_mode(l->entry));
732                 archive_le32enc(&h[FILE_HEADER_OFFSET], (uint32_t)l->offset);
733
734                 /* Formatting extra data. */
735                 archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_ID],
736                         ZIP_SIGNATURE_EXTRA_TIMESTAMP);
737                 archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_SIZE], 1 + 4);
738                 e[EXTRA_DATA_CENTRAL_TIME_FLAG] = 0x07;
739                 archive_le32enc(&e[EXTRA_DATA_CENTRAL_MTIME],
740                         (uint32_t)archive_entry_mtime(l->entry));
741                 archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_ID],
742                         ZIP_SIGNATURE_EXTRA_NEW_UNIX);
743                 archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_SIZE], 0x0000);
744
745                 ret = __archive_write_output(a, h, sizeof(h));
746                 if (ret != ARCHIVE_OK)
747                         return (ARCHIVE_FATAL);
748                 zip->written_bytes += sizeof(h);
749
750                 ret = write_path(l->entry, a);
751                 if (ret <= ARCHIVE_OK)
752                         return (ARCHIVE_FATAL);
753                 zip->written_bytes += ret;
754
755                 ret = __archive_write_output(a, e, sizeof(e));
756                 if (ret != ARCHIVE_OK)
757                         return (ARCHIVE_FATAL);
758                 zip->written_bytes += sizeof(e);
759
760                 l = l->next;
761                 entries++;
762         }
763         offset_end = zip->written_bytes;
764
765         /* Formatting end of central directory. */
766         memset(end, 0, sizeof(end));
767         archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIGNATURE],
768                 ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
769         archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES_DISK], entries);
770         archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES], entries);
771         archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIZE],
772                 (uint32_t)(offset_end - offset_start));
773         archive_le32enc(&end[CENTRAL_DIRECTORY_END_OFFSET],
774                 (uint32_t)offset_start);
775
776         /* Writing end of central directory. */
777         ret = __archive_write_output(a, end, sizeof(end));
778         if (ret != ARCHIVE_OK)
779                 return (ARCHIVE_FATAL);
780         zip->written_bytes += sizeof(end);
781         return (ARCHIVE_OK);
782 }
783
784 static int
785 archive_write_zip_free(struct archive_write *a)
786 {
787         struct zip *zip;
788         struct zip_file_header_link *l;
789
790         zip = a->format_data;
791         while (zip->central_directory != NULL) {
792            l = zip->central_directory;
793            zip->central_directory = l->next;
794            archive_entry_free(l->entry);
795            free(l);
796         }
797 #ifdef HAVE_ZLIB_H
798         free(zip->buf);
799 #endif
800         free(zip);
801         a->format_data = NULL;
802         return (ARCHIVE_OK);
803 }
804
805 /* Convert into MSDOS-style date/time. */
806 static unsigned int
807 dos_time(const time_t unix_time)
808 {
809         struct tm *t;
810         unsigned int dt;
811
812         /* This will not preserve time when creating/extracting the archive
813          * on two systems with different time zones. */
814         t = localtime(&unix_time);
815
816         /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
817         if (t->tm_year < 1980 - 1900)
818                 /* Set minimum date/time '1980-01-01 00:00:00'. */
819                 dt = 0x00210000U;
820         else if (t->tm_year > 2107 - 1900)
821                 /* Set maximum date/time '2107-12-31 23:59:58'. */
822                 dt = 0xff9fbf7dU;
823         else {
824                 dt = 0;
825                 dt += ((t->tm_year - 80) & 0x7f) << 9;
826                 dt += ((t->tm_mon + 1) & 0x0f) << 5;
827                 dt += (t->tm_mday & 0x1f);
828                 dt <<= 16;
829                 dt += (t->tm_hour & 0x1f) << 11;
830                 dt += (t->tm_min & 0x3f) << 5;
831                 dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
832         }
833         return dt;
834 }
835
836 static size_t
837 path_length(struct archive_entry *entry)
838 {
839         mode_t type;
840         const char *path;
841
842         type = archive_entry_filetype(entry);
843         path = archive_entry_pathname(entry);
844
845         if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
846                 return strlen(path) + 1;
847         } else {
848                 return strlen(path);
849         }
850 }
851
852 static int
853 write_path(struct archive_entry *entry, struct archive_write *archive)
854 {
855         int ret;
856         const char *path;
857         mode_t type;
858         size_t written_bytes;
859
860         path = archive_entry_pathname(entry);
861         type = archive_entry_filetype(entry);
862         written_bytes = 0;
863
864         ret = __archive_write_output(archive, path, strlen(path));
865         if (ret != ARCHIVE_OK)
866                 return (ARCHIVE_FATAL);
867         written_bytes += strlen(path);
868
869         /* Folders are recognized by a traling slash. */
870         if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
871                 ret = __archive_write_output(archive, "/", 1);
872                 if (ret != ARCHIVE_OK)
873                         return (ARCHIVE_FATAL);
874                 written_bytes += 1;
875         }
876
877         return ((int)written_bytes);
878 }