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$");
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
91enum compression {
92	COMPRESSION_STORE = 0
93#ifdef HAVE_ZLIB_H
94	,
95	COMPRESSION_DEFLATE = 8
96#endif
97};
98
99static ssize_t archive_write_zip_data(struct archive_write *,
100		   const void *buff, size_t s);
101static int archive_write_zip_close(struct archive_write *);
102static int archive_write_zip_free(struct archive_write *);
103static int archive_write_zip_finish_entry(struct archive_write *);
104static int archive_write_zip_header(struct archive_write *,
105	      struct archive_entry *);
106static int archive_write_zip_options(struct archive_write *,
107	      const char *, const char *);
108static unsigned int dos_time(const time_t);
109static size_t path_length(struct archive_entry *);
110static 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
182struct 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
192struct 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
212static int
213archive_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
259int
260archive_write_zip_set_compression_deflate(struct archive *_a)
261{
262	struct archive_write *a = (struct archive_write *)_a;
263	int ret = ARCHIVE_FAILED;
264
265	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
266		ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER,
267		"archive_write_zip_set_compression_deflate");
268	if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
269		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
270		"Can only use archive_write_zip_set_compression_deflate"
271		" with zip format");
272		ret = ARCHIVE_FATAL;
273	} else {
274#ifdef HAVE_ZLIB_H
275		struct zip *zip = a->format_data;
276		zip->compression = COMPRESSION_DEFLATE;
277		ret = ARCHIVE_OK;
278#else
279		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
280			"deflate compression not supported");
281#endif
282	}
283	return (ret);
284}
285
286int
287archive_write_zip_set_compression_store(struct archive *_a)
288{
289	struct archive_write *a = (struct archive_write *)_a;
290	struct zip *zip = a->format_data;
291	int ret = ARCHIVE_FAILED;
292
293	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
294		ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER,
295		"archive_write_zip_set_compression_deflate");
296	if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) {
297		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
298			"Can only use archive_write_zip_set_compression_store"
299			" with zip format");
300		ret = ARCHIVE_FATAL;
301	} else {
302		zip->compression = COMPRESSION_STORE;
303		ret = ARCHIVE_OK;
304	}
305	return (ret);
306}
307
308int
309archive_write_set_format_zip(struct archive *_a)
310{
311	struct archive_write *a = (struct archive_write *)_a;
312	struct zip *zip;
313
314	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
315	    ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
316
317	/* If another format was already registered, unregister it. */
318	if (a->format_free != NULL)
319		(a->format_free)(a);
320
321	zip = (struct zip *) calloc(1, sizeof(*zip));
322	if (zip == NULL) {
323		archive_set_error(&a->archive, ENOMEM,
324		    "Can't allocate zip data");
325		return (ARCHIVE_FATAL);
326	}
327	zip->central_directory = NULL;
328	zip->central_directory_end = NULL;
329	zip->offset = 0;
330	zip->written_bytes = 0;
331	zip->remaining_data_bytes = 0;
332
333#ifdef HAVE_ZLIB_H
334	zip->compression = COMPRESSION_DEFLATE;
335	zip->len_buf = 65536;
336	zip->buf = malloc(zip->len_buf);
337	if (zip->buf == NULL) {
338		free(zip);
339		archive_set_error(&a->archive, ENOMEM,
340		    "Can't allocate compression buffer");
341		return (ARCHIVE_FATAL);
342	}
343#else
344	zip->compression = COMPRESSION_STORE;
345#endif
346
347	a->format_data = zip;
348	a->format_name = "zip";
349	a->format_options = archive_write_zip_options;
350	a->format_write_header = archive_write_zip_header;
351	a->format_write_data = archive_write_zip_data;
352	a->format_finish_entry = archive_write_zip_finish_entry;
353	a->format_close = archive_write_zip_close;
354	a->format_free = archive_write_zip_free;
355	a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
356	a->archive.archive_format_name = "ZIP";
357
358	archive_le32enc(&zip->data_descriptor[DATA_DESCRIPTOR_SIGNATURE],
359	    ZIP_SIGNATURE_DATA_DESCRIPTOR);
360
361	return (ARCHIVE_OK);
362}
363
364static int
365is_all_ascii(const char *p)
366{
367	const unsigned char *pp = (const unsigned char *)p;
368
369	while (*pp) {
370		if (*pp++ > 127)
371			return (0);
372	}
373	return (1);
374}
375
376static int
377archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
378{
379	struct zip *zip;
380	uint8_t h[SIZE_LOCAL_FILE_HEADER];
381	uint8_t e[SIZE_EXTRA_DATA_LOCAL];
382	uint8_t *d;
383	struct zip_file_header_link *l;
384	struct archive_string_conv *sconv;
385	int ret, ret2 = ARCHIVE_OK;
386	int64_t size;
387	mode_t type;
388
389	/* Entries other than a regular file or a folder are skipped. */
390	type = archive_entry_filetype(entry);
391	if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
392		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
393		    "Filetype not supported");
394		return ARCHIVE_FAILED;
395	};
396
397	/* Directory entries should have a size of 0. */
398	if (type == AE_IFDIR)
399		archive_entry_set_size(entry, 0);
400
401	zip = a->format_data;
402	/* Setup default conversion. */
403	if (zip->opt_sconv == NULL && !zip->init_default_conversion) {
404		zip->sconv_default =
405		    archive_string_default_conversion_for_write(&(a->archive));
406		zip->init_default_conversion = 1;
407	}
408
409	if (zip->flags == 0) {
410		/* Initialize the general purpose flags. */
411		zip->flags = ZIP_FLAGS;
412		if (zip->opt_sconv != NULL) {
413			if (strcmp(archive_string_conversion_charset_name(
414			    zip->opt_sconv), "UTF-8") == 0)
415				zip->flags |= ZIP_FLAGS_UTF8_NAME;
416#if HAVE_NL_LANGINFO
417		} else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
418			zip->flags |= ZIP_FLAGS_UTF8_NAME;
419#endif
420		}
421	}
422	d = zip->data_descriptor;
423	size = archive_entry_size(entry);
424	zip->remaining_data_bytes = size;
425
426	/* Append archive entry to the central directory data. */
427	l = (struct zip_file_header_link *) malloc(sizeof(*l));
428	if (l == NULL) {
429		archive_set_error(&a->archive, ENOMEM,
430		    "Can't allocate zip header data");
431		return (ARCHIVE_FATAL);
432	}
433#if defined(_WIN32) && !defined(__CYGWIN__)
434	/* Make sure the path separators in pahtname, hardlink and symlink
435	 * are all slash '/', not the Windows path separator '\'. */
436	l->entry = __la_win_entry_in_posix_pathseparator(entry);
437	if (l->entry == entry)
438		l->entry = archive_entry_clone(entry);
439#else
440	l->entry = archive_entry_clone(entry);
441#endif
442	if (l->entry == NULL) {
443		archive_set_error(&a->archive, ENOMEM,
444		    "Can't allocate zip header data");
445		free(l);
446		return (ARCHIVE_FATAL);
447	}
448	l->flags = zip->flags;
449	if (zip->opt_sconv != NULL)
450		sconv = zip->opt_sconv;
451	else
452		sconv = zip->sconv_default;
453	if (sconv != NULL) {
454		const char *p;
455		size_t len;
456
457		if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) {
458			if (errno == ENOMEM) {
459				archive_entry_free(l->entry);
460				free(l);
461				archive_set_error(&a->archive, ENOMEM,
462				    "Can't allocate memory for Pathname");
463				return (ARCHIVE_FATAL);
464			}
465			archive_set_error(&a->archive,
466			    ARCHIVE_ERRNO_FILE_FORMAT,
467			    "Can't translate Pathname '%s' to %s",
468			    archive_entry_pathname(entry),
469			    archive_string_conversion_charset_name(sconv));
470			ret2 = ARCHIVE_WARN;
471		}
472		if (len > 0)
473			archive_entry_set_pathname(l->entry, p);
474
475		/*
476		 * Although there is no character-set regulation for Symlink,
477		 * it is suitable to convert a character-set of Symlinke to
478		 * what those of the Pathname has been converted to.
479		 */
480		if (type == AE_IFLNK) {
481			if (archive_entry_symlink_l(entry, &p, &len, sconv)) {
482				if (errno == ENOMEM) {
483					archive_entry_free(l->entry);
484					free(l);
485					archive_set_error(&a->archive, ENOMEM,
486					    "Can't allocate memory "
487					    " for Symlink");
488					return (ARCHIVE_FATAL);
489				}
490				/*
491				 * Even if the strng conversion failed,
492				 * we should not report the error since
493				 * thre is no regulation for.
494				 */
495			} else if (len > 0)
496				archive_entry_set_symlink(l->entry, p);
497		}
498	}
499	/* If all characters in a filename are ASCII, Reset UTF-8 Name flag. */
500	if ((l->flags & ZIP_FLAGS_UTF8_NAME) != 0 &&
501	    is_all_ascii(archive_entry_pathname(l->entry)))
502		l->flags &= ~ZIP_FLAGS_UTF8_NAME;
503
504	/* Initialize the CRC variable and potentially the local crc32(). */
505	l->crc32 = crc32(0, NULL, 0);
506	if (type == AE_IFLNK) {
507		const char *p = archive_entry_symlink(l->entry);
508		if (p != NULL)
509			size = strlen(p);
510		else
511			size = 0;
512		zip->remaining_data_bytes = 0;
513		archive_entry_set_size(l->entry, size);
514		l->compression = COMPRESSION_STORE;
515		l->compressed_size = size;
516	} else {
517		l->compression = zip->compression;
518		l->compressed_size = 0;
519	}
520	l->next = NULL;
521	if (zip->central_directory == NULL) {
522		zip->central_directory = l;
523	} else {
524		zip->central_directory_end->next = l;
525	}
526	zip->central_directory_end = l;
527
528	/* Store the offset of this header for later use in central
529	 * directory. */
530	l->offset = zip->written_bytes;
531
532	memset(h, 0, sizeof(h));
533	archive_le32enc(&h[LOCAL_FILE_HEADER_SIGNATURE],
534		ZIP_SIGNATURE_LOCAL_FILE_HEADER);
535	archive_le16enc(&h[LOCAL_FILE_HEADER_VERSION], ZIP_VERSION_EXTRACT);
536	archive_le16enc(&h[LOCAL_FILE_HEADER_FLAGS], l->flags);
537	archive_le16enc(&h[LOCAL_FILE_HEADER_COMPRESSION], l->compression);
538	archive_le32enc(&h[LOCAL_FILE_HEADER_TIMEDATE],
539		dos_time(archive_entry_mtime(entry)));
540	archive_le16enc(&h[LOCAL_FILE_HEADER_FILENAME_LENGTH],
541		(uint16_t)path_length(l->entry));
542
543	switch (l->compression) {
544	case COMPRESSION_STORE:
545		/* Setting compressed and uncompressed sizes even when
546		 * specification says to set to zero when using data
547		 * descriptors. Otherwise the end of the data for an
548		 * entry is rather difficult to find. */
549		archive_le32enc(&h[LOCAL_FILE_HEADER_COMPRESSED_SIZE],
550		    (uint32_t)size);
551		archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
552		    (uint32_t)size);
553		break;
554#ifdef HAVE_ZLIB_H
555	case COMPRESSION_DEFLATE:
556		archive_le32enc(&h[LOCAL_FILE_HEADER_UNCOMPRESSED_SIZE],
557		    (uint32_t)size);
558
559		zip->stream.zalloc = Z_NULL;
560		zip->stream.zfree = Z_NULL;
561		zip->stream.opaque = Z_NULL;
562		zip->stream.next_out = zip->buf;
563		zip->stream.avail_out = (uInt)zip->len_buf;
564		if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION,
565		    Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
566			archive_set_error(&a->archive, ENOMEM,
567			    "Can't init deflate compressor");
568			return (ARCHIVE_FATAL);
569		}
570		break;
571#endif
572	}
573
574	/* Formatting extra data. */
575	archive_le16enc(&h[LOCAL_FILE_HEADER_EXTRA_LENGTH], sizeof(e));
576	archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_ID],
577		ZIP_SIGNATURE_EXTRA_TIMESTAMP);
578	archive_le16enc(&e[EXTRA_DATA_LOCAL_TIME_SIZE], 1 + 4 * 3);
579	e[EXTRA_DATA_LOCAL_TIME_FLAG] = 0x07;
580	archive_le32enc(&e[EXTRA_DATA_LOCAL_MTIME],
581	    (uint32_t)archive_entry_mtime(entry));
582	archive_le32enc(&e[EXTRA_DATA_LOCAL_ATIME],
583	    (uint32_t)archive_entry_atime(entry));
584	archive_le32enc(&e[EXTRA_DATA_LOCAL_CTIME],
585	    (uint32_t)archive_entry_ctime(entry));
586
587	archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_ID],
588		ZIP_SIGNATURE_EXTRA_NEW_UNIX);
589	archive_le16enc(&e[EXTRA_DATA_LOCAL_UNIX_SIZE], 1 + (1 + 4) * 2);
590	e[EXTRA_DATA_LOCAL_UNIX_VERSION] = 1;
591	e[EXTRA_DATA_LOCAL_UNIX_UID_SIZE] = 4;
592	archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_UID],
593		(uint32_t)archive_entry_uid(entry));
594	e[EXTRA_DATA_LOCAL_UNIX_GID_SIZE] = 4;
595	archive_le32enc(&e[EXTRA_DATA_LOCAL_UNIX_GID],
596		(uint32_t)archive_entry_gid(entry));
597
598	archive_le32enc(&d[DATA_DESCRIPTOR_UNCOMPRESSED_SIZE],
599	    (uint32_t)size);
600
601	ret = __archive_write_output(a, h, sizeof(h));
602	if (ret != ARCHIVE_OK)
603		return (ARCHIVE_FATAL);
604	zip->written_bytes += sizeof(h);
605
606	ret = write_path(l->entry, a);
607	if (ret <= ARCHIVE_OK)
608		return (ARCHIVE_FATAL);
609	zip->written_bytes += ret;
610
611	ret = __archive_write_output(a, e, sizeof(e));
612	if (ret != ARCHIVE_OK)
613		return (ARCHIVE_FATAL);
614	zip->written_bytes += sizeof(e);
615
616	if (type == AE_IFLNK) {
617		const unsigned char *p;
618
619		p = (const unsigned char *)archive_entry_symlink(l->entry);
620		ret = __archive_write_output(a, p, (size_t)size);
621		if (ret != ARCHIVE_OK)
622			return (ARCHIVE_FATAL);
623		zip->written_bytes += size;
624		l->crc32 = crc32(l->crc32, p, (unsigned)size);
625	}
626
627	if (ret2 != ARCHIVE_OK)
628		return (ret2);
629	return (ARCHIVE_OK);
630}
631
632static ssize_t
633archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
634{
635	int ret;
636	struct zip *zip = a->format_data;
637	struct zip_file_header_link *l = zip->central_directory_end;
638
639	if ((int64_t)s > zip->remaining_data_bytes)
640		s = (size_t)zip->remaining_data_bytes;
641
642	if (s == 0) return 0;
643
644	switch (l->compression) {
645	case COMPRESSION_STORE:
646		ret = __archive_write_output(a, buff, s);
647		if (ret != ARCHIVE_OK) return (ret);
648		zip->written_bytes += s;
649		zip->remaining_data_bytes -= s;
650		l->compressed_size += s;
651		l->crc32 = crc32(l->crc32, buff, (unsigned)s);
652		return (s);
653#if HAVE_ZLIB_H
654	case COMPRESSION_DEFLATE:
655		zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
656		zip->stream.avail_in = (uInt)s;
657		do {
658			ret = deflate(&zip->stream, Z_NO_FLUSH);
659			if (ret == Z_STREAM_ERROR)
660				return (ARCHIVE_FATAL);
661			if (zip->stream.avail_out == 0) {
662				ret = __archive_write_output(a, zip->buf,
663					zip->len_buf);
664				if (ret != ARCHIVE_OK)
665					return (ret);
666				l->compressed_size += zip->len_buf;
667				zip->written_bytes += zip->len_buf;
668				zip->stream.next_out = zip->buf;
669				zip->stream.avail_out = (uInt)zip->len_buf;
670			}
671		} while (zip->stream.avail_in != 0);
672		zip->remaining_data_bytes -= s;
673		/* If we have it, use zlib's fast crc32() */
674		l->crc32 = crc32(l->crc32, buff, (uInt)s);
675		return (s);
676#endif
677
678	default:
679		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
680		    "Invalid ZIP compression type");
681		return ARCHIVE_FATAL;
682	}
683}
684
685static int
686archive_write_zip_finish_entry(struct archive_write *a)
687{
688	/* Write the data descripter after file data has been written. */
689	int ret;
690	struct zip *zip = a->format_data;
691	uint8_t *d = zip->data_descriptor;
692	struct zip_file_header_link *l = zip->central_directory_end;
693#if HAVE_ZLIB_H
694	size_t reminder;
695#endif
696
697	switch(l->compression) {
698	case COMPRESSION_STORE:
699		break;
700#if HAVE_ZLIB_H
701	case COMPRESSION_DEFLATE:
702		for (;;) {
703			ret = deflate(&zip->stream, Z_FINISH);
704			if (ret == Z_STREAM_ERROR)
705				return (ARCHIVE_FATAL);
706			reminder = zip->len_buf - zip->stream.avail_out;
707			ret = __archive_write_output(a, zip->buf, reminder);
708			if (ret != ARCHIVE_OK)
709				return (ret);
710			l->compressed_size += reminder;
711			zip->written_bytes += reminder;
712			zip->stream.next_out = zip->buf;
713			if (zip->stream.avail_out != 0)
714				break;
715			zip->stream.avail_out = (uInt)zip->len_buf;
716		}
717		deflateEnd(&zip->stream);
718		break;
719#endif
720	}
721
722	archive_le32enc(&d[DATA_DESCRIPTOR_CRC32], l->crc32);
723	archive_le32enc(&d[DATA_DESCRIPTOR_COMPRESSED_SIZE],
724		(uint32_t)l->compressed_size);
725	ret = __archive_write_output(a, d, SIZE_DATA_DESCRIPTOR);
726	if (ret != ARCHIVE_OK)
727		return (ARCHIVE_FATAL);
728	zip->written_bytes += SIZE_DATA_DESCRIPTOR;
729	return (ARCHIVE_OK);
730}
731
732static int
733archive_write_zip_close(struct archive_write *a)
734{
735	struct zip *zip;
736	struct zip_file_header_link *l;
737	uint8_t h[SIZE_FILE_HEADER];
738	uint8_t end[SIZE_CENTRAL_DIRECTORY_END];
739	uint8_t e[SIZE_EXTRA_DATA_CENTRAL];
740	int64_t offset_start, offset_end;
741	int entries;
742	int ret;
743
744	zip = a->format_data;
745	l = zip->central_directory;
746
747	/*
748	 * Formatting central directory file header fields that are
749	 * fixed for all entries.
750	 * Fields not used (and therefor 0) are:
751	 *
752	 *   - comment_length
753	 *   - disk_number
754	 *   - attributes_internal
755	 */
756	memset(h, 0, sizeof(h));
757	archive_le32enc(&h[FILE_HEADER_SIGNATURE], ZIP_SIGNATURE_FILE_HEADER);
758	archive_le16enc(&h[FILE_HEADER_VERSION_BY], ZIP_VERSION_BY);
759	archive_le16enc(&h[FILE_HEADER_VERSION_EXTRACT], ZIP_VERSION_EXTRACT);
760
761	entries = 0;
762	offset_start = zip->written_bytes;
763
764	/* Formatting individual header fields per entry and
765	 * writing each entry. */
766	while (l != NULL) {
767		archive_le16enc(&h[FILE_HEADER_FLAGS], l->flags);
768		archive_le16enc(&h[FILE_HEADER_COMPRESSION], l->compression);
769		archive_le32enc(&h[FILE_HEADER_TIMEDATE],
770			dos_time(archive_entry_mtime(l->entry)));
771		archive_le32enc(&h[FILE_HEADER_CRC32], l->crc32);
772		archive_le32enc(&h[FILE_HEADER_COMPRESSED_SIZE],
773			(uint32_t)l->compressed_size);
774		archive_le32enc(&h[FILE_HEADER_UNCOMPRESSED_SIZE],
775			(uint32_t)archive_entry_size(l->entry));
776		archive_le16enc(&h[FILE_HEADER_FILENAME_LENGTH],
777			(uint16_t)path_length(l->entry));
778		archive_le16enc(&h[FILE_HEADER_EXTRA_LENGTH], sizeof(e));
779		archive_le16enc(&h[FILE_HEADER_ATTRIBUTES_EXTERNAL+2],
780			archive_entry_mode(l->entry));
781		archive_le32enc(&h[FILE_HEADER_OFFSET], (uint32_t)l->offset);
782
783		/* Formatting extra data. */
784		archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_ID],
785			ZIP_SIGNATURE_EXTRA_TIMESTAMP);
786		archive_le16enc(&e[EXTRA_DATA_CENTRAL_TIME_SIZE], 1 + 4);
787		e[EXTRA_DATA_CENTRAL_TIME_FLAG] = 0x07;
788		archive_le32enc(&e[EXTRA_DATA_CENTRAL_MTIME],
789			(uint32_t)archive_entry_mtime(l->entry));
790		archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_ID],
791			ZIP_SIGNATURE_EXTRA_NEW_UNIX);
792		archive_le16enc(&e[EXTRA_DATA_CENTRAL_UNIX_SIZE], 0x0000);
793
794		ret = __archive_write_output(a, h, sizeof(h));
795		if (ret != ARCHIVE_OK)
796			return (ARCHIVE_FATAL);
797		zip->written_bytes += sizeof(h);
798
799		ret = write_path(l->entry, a);
800		if (ret <= ARCHIVE_OK)
801			return (ARCHIVE_FATAL);
802		zip->written_bytes += ret;
803
804		ret = __archive_write_output(a, e, sizeof(e));
805		if (ret != ARCHIVE_OK)
806			return (ARCHIVE_FATAL);
807		zip->written_bytes += sizeof(e);
808
809		l = l->next;
810		entries++;
811	}
812	offset_end = zip->written_bytes;
813
814	/* Formatting end of central directory. */
815	memset(end, 0, sizeof(end));
816	archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIGNATURE],
817		ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
818	archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES_DISK], entries);
819	archive_le16enc(&end[CENTRAL_DIRECTORY_END_ENTRIES], entries);
820	archive_le32enc(&end[CENTRAL_DIRECTORY_END_SIZE],
821		(uint32_t)(offset_end - offset_start));
822	archive_le32enc(&end[CENTRAL_DIRECTORY_END_OFFSET],
823		(uint32_t)offset_start);
824
825	/* Writing end of central directory. */
826	ret = __archive_write_output(a, end, sizeof(end));
827	if (ret != ARCHIVE_OK)
828		return (ARCHIVE_FATAL);
829	zip->written_bytes += sizeof(end);
830	return (ARCHIVE_OK);
831}
832
833static int
834archive_write_zip_free(struct archive_write *a)
835{
836	struct zip *zip;
837	struct zip_file_header_link *l;
838
839	zip = a->format_data;
840	while (zip->central_directory != NULL) {
841	   l = zip->central_directory;
842	   zip->central_directory = l->next;
843	   archive_entry_free(l->entry);
844	   free(l);
845	}
846#ifdef HAVE_ZLIB_H
847	free(zip->buf);
848#endif
849	free(zip);
850	a->format_data = NULL;
851	return (ARCHIVE_OK);
852}
853
854/* Convert into MSDOS-style date/time. */
855static unsigned int
856dos_time(const time_t unix_time)
857{
858	struct tm *t;
859	unsigned int dt;
860
861	/* This will not preserve time when creating/extracting the archive
862	 * on two systems with different time zones. */
863	t = localtime(&unix_time);
864
865	/* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
866	if (t->tm_year < 1980 - 1900)
867		/* Set minimum date/time '1980-01-01 00:00:00'. */
868		dt = 0x00210000U;
869	else if (t->tm_year > 2107 - 1900)
870		/* Set maximum date/time '2107-12-31 23:59:58'. */
871		dt = 0xff9fbf7dU;
872	else {
873		dt = 0;
874		dt += ((t->tm_year - 80) & 0x7f) << 9;
875		dt += ((t->tm_mon + 1) & 0x0f) << 5;
876		dt += (t->tm_mday & 0x1f);
877		dt <<= 16;
878		dt += (t->tm_hour & 0x1f) << 11;
879		dt += (t->tm_min & 0x3f) << 5;
880		dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
881	}
882	return dt;
883}
884
885static size_t
886path_length(struct archive_entry *entry)
887{
888	mode_t type;
889	const char *path;
890
891	type = archive_entry_filetype(entry);
892	path = archive_entry_pathname(entry);
893
894	if (path == NULL)
895		return (0);
896	if (type == AE_IFDIR &&
897	    (path[0] == '\0' || path[strlen(path) - 1] != '/')) {
898		return strlen(path) + 1;
899	} else {
900		return strlen(path);
901	}
902}
903
904static int
905write_path(struct archive_entry *entry, struct archive_write *archive)
906{
907	int ret;
908	const char *path;
909	mode_t type;
910	size_t written_bytes;
911
912	path = archive_entry_pathname(entry);
913	type = archive_entry_filetype(entry);
914	written_bytes = 0;
915
916	ret = __archive_write_output(archive, path, strlen(path));
917	if (ret != ARCHIVE_OK)
918		return (ARCHIVE_FATAL);
919	written_bytes += strlen(path);
920
921	/* Folders are recognized by a traling slash. */
922	if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
923		ret = __archive_write_output(archive, "/", 1);
924		if (ret != ARCHIVE_OK)
925			return (ARCHIVE_FATAL);
926		written_bytes += 1;
927	}
928
929	return ((int)written_bytes);
930}
931