- archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1);
- archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len);
- archive_handle->offset += zip_header.formated.filename_len;
- archive_handle->file_header->name[zip_header.formated.filename_len] = '\0';
-
- /* Skip extra header bits */
- archive_handle->file_header->size = zip_header.formated.extra_len;
- data_skip(archive_handle);
- archive_handle->offset += zip_header.formated.extra_len;
-
- /* Handle directories */
- archive_handle->file_header->mode = S_IFREG | 0777;
- if (last_char_is(archive_handle->file_header->name, '/')) {
- archive_handle->file_header->mode ^= S_IFREG;
- archive_handle->file_header->mode |= S_IFDIR;
+ free(dst_fn);
+ dst_fn = xzalloc(zip_header.formatted.filename_len + 1);
+ xread(src_fd, dst_fn, zip_header.formatted.filename_len);
+
+ /* Skip extra header bytes */
+ unzip_skip(src_fd, zip_header.formatted.extra_len);
+
+ /* Filter zip entries */
+ if (find_list_entry(zreject, dst_fn)
+ || (zaccept && !find_list_entry(zaccept, dst_fn))
+ ) { /* Skip entry */
+ i = 'n';
+
+ } else { /* Extract entry */
+ if (listing) { /* List entry */
+ if (verbose) {
+ unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16);
+ printf("%9u %02u-%02u-%02u %02u:%02u %s\n",
+ zip_header.formatted.ucmpsize,
+ (dostime & 0x01e00000) >> 21,
+ (dostime & 0x001f0000) >> 16,
+ (((dostime & 0xfe000000) >> 25) + 1980) % 100,
+ (dostime & 0x0000f800) >> 11,
+ (dostime & 0x000007e0) >> 5,
+ dst_fn);
+ total_size += zip_header.formatted.ucmpsize;
+ total_entries++;
+ } else {
+ /* short listing -- filenames only */
+ puts(dst_fn);
+ }
+ i = 'n';
+ } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */
+ i = -1;
+ } else if (last_char_is(dst_fn, '/')) { /* Extract directory */
+ if (stat(dst_fn, &stat_buf) == -1) {
+ if (errno != ENOENT) {
+ bb_perror_msg_and_die("cannot stat '%s'",dst_fn);
+ }
+ if (verbose) {
+ printf(" creating: %s\n", dst_fn);
+ }
+ unzip_create_leading_dirs(dst_fn);
+ if (bb_make_directory(dst_fn, 0777, 0)) {
+ bb_error_msg_and_die("exiting");
+ }
+ } else {
+ if (!S_ISDIR(stat_buf.st_mode)) {
+ bb_error_msg_and_die("'%s' exists but is not directory", dst_fn);
+ }
+ }
+ i = 'n';
+
+ } else { /* Extract file */
+ _check_file:
+ if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */
+ if (errno != ENOENT) {
+ bb_perror_msg_and_die("cannot stat '%s'",dst_fn);
+ }
+ i = 'y';
+ } else { /* File already exists */
+ if (overwrite == O_NEVER) {
+ i = 'n';
+ } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */
+ if (overwrite == O_ALWAYS) {
+ i = 'y';
+ } else {
+ printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn);
+ if (!fgets(key_buf, sizeof(key_buf), stdin)) {
+ bb_perror_msg_and_die("cannot read input");
+ }
+ i = key_buf[0];
+ }
+ } else { /* File is not regular file */
+ bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn);
+ }
+ }
+ }