Patch from Felipe Kellermann, fix endless loop when first > last and
[oweals/busybox.git] / archival / unzip.c
index 86416d327cfdfb0ec513319acf97aef5e4749459..eea2f5438b67563a7b8371835dc78c70e89df3fb 100644 (file)
  *
  */
 
-/* For reference to format see http://www.pkware.com/support/appnote.html */
+/* For reference see
+ * http://www.pkware.com/products/enterprise/white_papers/appnote.txt
+ * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
+ */
 
 /* TODO Endian issues, exclude, should we accept input from stdin ? */
 
@@ -120,12 +123,12 @@ extern int unzip_main(int argc, char **argv)
                                break;
 #endif
                        default:
-                               show_usage();
+                               bb_show_usage();
                }
        }
 
        if (argc == optind) {
-               show_usage();
+               bb_show_usage();
        }
 
        printf("Archive:  %s\n", argv[optind]);
@@ -135,14 +138,14 @@ extern int unzip_main(int argc, char **argv)
        }
 
        if (*argv[optind] == '-') {
-               archive_handle->src_fd = fileno(stdin);
+               archive_handle->src_fd = STDIN_FILENO;
                archive_handle->seek = seek_by_char;
        } else {
-               archive_handle->src_fd = xopen(argv[optind++], O_RDONLY);
+               archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);
        }
 
        if ((base_dir) && (chdir(base_dir))) {
-               perror_msg_and_die("Couldnt chdir");
+               bb_perror_msg_and_die("Couldnt chdir");
        }
 
        while (optind < argc) {
@@ -163,7 +166,7 @@ extern int unzip_main(int argc, char **argv)
                        break;
                }
                else if (magic != ZIP_FILEHEADER_MAGIC) {
-                       error_msg_and_die("Invlaide zip magic");
+                       bb_error_msg_and_die("Invlaide zip magic");
                }
 
                /* Read the file header */
@@ -172,7 +175,7 @@ extern int unzip_main(int argc, char **argv)
                archive_handle->file_header->mode = S_IFREG | 0777;
 
                if (zip_header.formated.method != 8) {
-                       error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method);
+                       bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method);
                }
 
                /* Read filename */
@@ -198,19 +201,20 @@ extern int unzip_main(int argc, char **argv)
                if (archive_handle->action_data) {
                        archive_handle->action_data(archive_handle);
                } else {
-                       dst_fd = xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT);
-                       inflate(archive_handle->src_fd, dst_fd);
+                       dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT);
+                       inflate_init(zip_header.formated.cmpsize);
+                       inflate_unzip(archive_handle->src_fd, dst_fd);
                        close(dst_fd);
                        chmod(archive_handle->file_header->name, archive_handle->file_header->mode);
 
                        /* Validate decompression - crc */
                        if (zip_header.formated.crc32 != (gunzip_crc ^ 0xffffffffL)) {
-                               error_msg("Invalid compressed data--crc error");
+                               bb_error_msg("Invalid compressed data--crc error");
                        }
 
                        /* Validate decompression - size */
                        if (gunzip_bytes_out != zip_header.formated.ucmpsize) {
-                               error_msg("Invalid compressed data--length error");
+                               bb_error_msg("Invalid compressed data--length error");
                        }
                }
 
@@ -227,10 +231,8 @@ extern int unzip_main(int argc, char **argv)
                /* Data descriptor section */
                if (zip_header.formated.flags & 4) {
                        /* skip over duplicate crc, compressed size and uncompressed size */
-                       unsigned short i;
-                       for (i = 0; i != 12; i++) {
-                               archive_xread_char(archive_handle);
-                       }
+                       unsigned char data_description[12];
+                       archive_xread_all(archive_handle, data_description, 12);
                        archive_handle->offset += 12;
                }
        }