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 } 879