diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-18 23:27:46 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-10-18 23:27:46 +0000 |
commit | bc7c5d082e68488058a277d89c1b3a39b8f96faf (patch) | |
tree | 180217fea38a90c7f39526f12c7da212537fbb19 | |
parent | 34cd7afc49778eb8f0f5c72d38fdbda13c03a1dc (diff) | |
download | busybox-w32-bc7c5d082e68488058a277d89c1b3a39b8f96faf.tar.gz busybox-w32-bc7c5d082e68488058a277d89c1b3a39b8f96faf.tar.bz2 busybox-w32-bc7c5d082e68488058a277d89c1b3a39b8f96faf.zip |
unzip: fix endianness bugs
-rw-r--r-- | archival/unzip.c | 213 |
1 files changed, 113 insertions, 100 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index bd113af20..37781e44e 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -27,37 +27,59 @@ | |||
27 | #include "libbb.h" | 27 | #include "libbb.h" |
28 | #include "unarchive.h" | 28 | #include "unarchive.h" |
29 | 29 | ||
30 | #define ZIP_FILEHEADER_MAGIC SWAP_LE32(0x04034b50) | 30 | enum { |
31 | #define ZIP_CDS_MAGIC SWAP_LE32(0x02014b50) | 31 | #if BB_BIG_ENDIAN |
32 | #define ZIP_CDS_END_MAGIC SWAP_LE32(0x06054b50) | 32 | ZIP_FILEHEADER_MAGIC = 0x504b0304, |
33 | #define ZIP_DD_MAGIC SWAP_LE32(0x08074b50) | 33 | ZIP_CDS_MAGIC = 0x504b0102, |
34 | ZIP_CDS_END_MAGIC = 0x504b0506, | ||
35 | ZIP_DD_MAGIC = 0x504b0708, | ||
36 | #else | ||
37 | ZIP_FILEHEADER_MAGIC = 0x04034b50, | ||
38 | ZIP_CDS_MAGIC = 0x02014b50, | ||
39 | ZIP_CDS_END_MAGIC = 0x06054b50, | ||
40 | ZIP_DD_MAGIC = 0x08074b50, | ||
41 | #endif | ||
42 | }; | ||
34 | 43 | ||
35 | typedef union { | 44 | typedef union { |
36 | unsigned char raw[26]; | 45 | uint8_t raw[26]; |
37 | struct { | 46 | struct { |
38 | unsigned short version; /* 0-1 */ | 47 | uint16_t version; /* 0-1 */ |
39 | unsigned short flags; /* 2-3 */ | 48 | uint16_t flags; /* 2-3 */ |
40 | unsigned short method; /* 4-5 */ | 49 | uint16_t method; /* 4-5 */ |
41 | unsigned short modtime; /* 6-7 */ | 50 | uint16_t modtime; /* 6-7 */ |
42 | unsigned short moddate; /* 8-9 */ | 51 | uint16_t moddate; /* 8-9 */ |
43 | unsigned int crc32 ATTRIBUTE_PACKED; /* 10-13 */ | 52 | uint32_t crc32 ATTRIBUTE_PACKED; /* 10-13 */ |
44 | unsigned int cmpsize ATTRIBUTE_PACKED; /* 14-17 */ | 53 | uint32_t cmpsize ATTRIBUTE_PACKED; /* 14-17 */ |
45 | unsigned int ucmpsize ATTRIBUTE_PACKED; /* 18-21 */ | 54 | uint32_t ucmpsize ATTRIBUTE_PACKED; /* 18-21 */ |
46 | unsigned short filename_len; /* 22-23 */ | 55 | uint16_t filename_len; /* 22-23 */ |
47 | unsigned short extra_len; /* 24-25 */ | 56 | uint16_t extra_len; /* 24-25 */ |
48 | } formatted ATTRIBUTE_PACKED; | 57 | } formatted ATTRIBUTE_PACKED; |
49 | } zip_header_t; | 58 | } zip_header_t; |
50 | 59 | ||
60 | struct BUG_zip_header_must_be_26_bytes { | ||
61 | char BUG_zip_header_must_be_26_bytes[sizeof(zip_header_t) == 26 ? 1 : -1]; | ||
62 | }; | ||
63 | |||
64 | #define FIX_ENDIANNESS(zip_header) do { \ | ||
65 | (zip_header).formatted.version = SWAP_LE16((zip_header).formatted.version ); \ | ||
66 | (zip_header).formatted.flags = SWAP_LE16((zip_header).formatted.flags ); \ | ||
67 | (zip_header).formatted.method = SWAP_LE16((zip_header).formatted.method ); \ | ||
68 | (zip_header).formatted.modtime = SWAP_LE16((zip_header).formatted.modtime ); \ | ||
69 | (zip_header).formatted.moddate = SWAP_LE16((zip_header).formatted.moddate ); \ | ||
70 | (zip_header).formatted.crc32 = SWAP_LE32((zip_header).formatted.crc32 ); \ | ||
71 | (zip_header).formatted.cmpsize = SWAP_LE32((zip_header).formatted.cmpsize ); \ | ||
72 | (zip_header).formatted.ucmpsize = SWAP_LE32((zip_header).formatted.ucmpsize ); \ | ||
73 | (zip_header).formatted.filename_len = SWAP_LE16((zip_header).formatted.filename_len); \ | ||
74 | (zip_header).formatted.extra_len = SWAP_LE16((zip_header).formatted.extra_len ); \ | ||
75 | } while (0) | ||
76 | |||
51 | static void unzip_skip(int fd, off_t skip) | 77 | static void unzip_skip(int fd, off_t skip) |
52 | { | 78 | { |
53 | if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { | 79 | bb_copyfd_exact_size(fd, -1, skip); |
54 | if (errno != ESPIPE) | ||
55 | bb_error_msg_and_die("seek failure"); | ||
56 | bb_copyfd_exact_size(fd, -1, skip); | ||
57 | } | ||
58 | } | 80 | } |
59 | 81 | ||
60 | static void unzip_create_leading_dirs(char *fn) | 82 | static void unzip_create_leading_dirs(const char *fn) |
61 | { | 83 | { |
62 | /* Create all leading directories */ | 84 | /* Create all leading directories */ |
63 | char *name = xstrdup(fn); | 85 | char *name = xstrdup(fn); |
@@ -67,7 +89,7 @@ static void unzip_create_leading_dirs(char *fn) | |||
67 | free(name); | 89 | free(name); |
68 | } | 90 | } |
69 | 91 | ||
70 | static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) | 92 | static void unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) |
71 | { | 93 | { |
72 | if (zip_header->formatted.method == 0) { | 94 | if (zip_header->formatted.method == 0) { |
73 | /* Method 0 - stored (not compressed) */ | 95 | /* Method 0 - stored (not compressed) */ |
@@ -77,42 +99,43 @@ static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) | |||
77 | } else { | 99 | } else { |
78 | /* Method 8 - inflate */ | 100 | /* Method 8 - inflate */ |
79 | inflate_unzip_result res; | 101 | inflate_unzip_result res; |
80 | /* err = */ inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd); | 102 | if (inflate_unzip(&res, zip_header->formatted.cmpsize, src_fd, dst_fd) < 0) |
81 | // we should check for -1 error return | 103 | bb_error_msg_and_die("inflate error"); |
82 | /* Validate decompression - crc */ | 104 | /* Validate decompression - crc */ |
83 | if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { | 105 | if (zip_header->formatted.crc32 != (res.crc ^ 0xffffffffL)) { |
84 | bb_error_msg("invalid compressed data--%s error", "crc"); | 106 | bb_error_msg_and_die("crc error"); |
85 | return 1; | ||
86 | } | 107 | } |
87 | /* Validate decompression - size */ | 108 | /* Validate decompression - size */ |
88 | if (zip_header->formatted.ucmpsize != res.bytes_out) { | 109 | if (zip_header->formatted.ucmpsize != res.bytes_out) { |
89 | bb_error_msg("invalid compressed data--%s error", "length"); | 110 | bb_error_msg("bad length"); |
90 | return 1; | ||
91 | } | 111 | } |
92 | } | 112 | } |
93 | return 0; | ||
94 | } | 113 | } |
95 | 114 | ||
96 | int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 115 | int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
97 | int unzip_main(int argc, char **argv) | 116 | int unzip_main(int argc, char **argv) |
98 | { | 117 | { |
118 | enum { O_PROMPT, O_NEVER, O_ALWAYS }; | ||
119 | |||
99 | zip_header_t zip_header; | 120 | zip_header_t zip_header; |
100 | smallint verbose = 1; | 121 | smallint verbose = 1; |
101 | smallint listing = 0; | 122 | smallint listing = 0; |
102 | smallint list_header_done = 0; | 123 | smallint overwrite = O_PROMPT; |
103 | smallint failed; | 124 | unsigned total_size; |
104 | enum {o_prompt, o_never, o_always} overwrite = o_prompt; | 125 | unsigned total_entries; |
105 | unsigned int total_size = 0; | 126 | int src_fd = -1; |
106 | unsigned int total_entries = 0; | 127 | int dst_fd = -1; |
107 | int src_fd = -1, dst_fd = -1; | 128 | char *src_fn = NULL; |
108 | char *src_fn = NULL, *dst_fn = NULL; | 129 | char *dst_fn = NULL; |
109 | llist_t *zaccept = NULL; | 130 | llist_t *zaccept = NULL; |
110 | llist_t *zreject = NULL; | 131 | llist_t *zreject = NULL; |
111 | char *base_dir = NULL; | 132 | char *base_dir = NULL; |
112 | int i, opt, opt_range = 0; | 133 | int i, opt; |
113 | char key_buf[512]; | 134 | int opt_range = 0; |
135 | char key_buf[80]; | ||
114 | struct stat stat_buf; | 136 | struct stat stat_buf; |
115 | 137 | ||
138 | /* '-' makes getopt return 1 for non-options */ | ||
116 | while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { | 139 | while ((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { |
117 | switch (opt_range) { | 140 | switch (opt_range) { |
118 | case 0: /* Options */ | 141 | case 0: /* Options */ |
@@ -122,11 +145,11 @@ int unzip_main(int argc, char **argv) | |||
122 | break; | 145 | break; |
123 | 146 | ||
124 | case 'n': /* Never overwrite existing files */ | 147 | case 'n': /* Never overwrite existing files */ |
125 | overwrite = o_never; | 148 | overwrite = O_NEVER; |
126 | break; | 149 | break; |
127 | 150 | ||
128 | case 'o': /* Always overwrite existing files */ | 151 | case 'o': /* Always overwrite existing files */ |
129 | overwrite = o_always; | 152 | overwrite = O_ALWAYS; |
130 | break; | 153 | break; |
131 | 154 | ||
132 | case 'p': /* Extract files to stdout and fall through to set verbosity */ | 155 | case 'p': /* Extract files to stdout and fall through to set verbosity */ |
@@ -136,8 +159,9 @@ int unzip_main(int argc, char **argv) | |||
136 | verbose = 0; | 159 | verbose = 0; |
137 | break; | 160 | break; |
138 | 161 | ||
139 | case 1 : /* The zip file */ | 162 | case 1: /* The zip file */ |
140 | src_fn = xmalloc(strlen(optarg)+4); | 163 | /* +5: space for ".zip" and NUL */ |
164 | src_fn = xmalloc(strlen(optarg) + 5); | ||
141 | strcpy(src_fn, optarg); | 165 | strcpy(src_fn, optarg); |
142 | opt_range++; | 166 | opt_range++; |
143 | break; | 167 | break; |
@@ -151,31 +175,30 @@ int unzip_main(int argc, char **argv) | |||
151 | case 1: /* Include files */ | 175 | case 1: /* Include files */ |
152 | if (opt == 1) { | 176 | if (opt == 1) { |
153 | llist_add_to(&zaccept, optarg); | 177 | llist_add_to(&zaccept, optarg); |
154 | 178 | break; | |
155 | } else if (opt == 'd') { | 179 | } |
180 | if (opt == 'd') { | ||
156 | base_dir = optarg; | 181 | base_dir = optarg; |
157 | opt_range += 2; | 182 | opt_range += 2; |
158 | 183 | break; | |
159 | } else if (opt == 'x') { | 184 | } |
185 | if (opt == 'x') { | ||
160 | opt_range++; | 186 | opt_range++; |
161 | 187 | break; | |
162 | } else { | ||
163 | bb_show_usage(); | ||
164 | } | 188 | } |
165 | break; | 189 | bb_show_usage(); |
166 | 190 | ||
167 | case 2 : /* Exclude files */ | 191 | case 2 : /* Exclude files */ |
168 | if (opt == 1) { | 192 | if (opt == 1) { |
169 | llist_add_to(&zreject, optarg); | 193 | llist_add_to(&zreject, optarg); |
170 | 194 | break; | |
171 | } else if (opt == 'd') { /* Extract to base directory */ | 195 | } |
196 | if (opt == 'd') { /* Extract to base directory */ | ||
172 | base_dir = optarg; | 197 | base_dir = optarg; |
173 | opt_range++; | 198 | opt_range++; |
174 | 199 | break; | |
175 | } else { | ||
176 | bb_show_usage(); | ||
177 | } | 200 | } |
178 | break; | 201 | /* fall through */ |
179 | 202 | ||
180 | default: | 203 | default: |
181 | bb_show_usage(); | 204 | bb_show_usage(); |
@@ -190,17 +213,19 @@ int unzip_main(int argc, char **argv) | |||
190 | if (LONE_DASH(src_fn)) { | 213 | if (LONE_DASH(src_fn)) { |
191 | src_fd = STDIN_FILENO; | 214 | src_fd = STDIN_FILENO; |
192 | /* Cannot use prompt mode since zip data is arriving on STDIN */ | 215 | /* Cannot use prompt mode since zip data is arriving on STDIN */ |
193 | overwrite = (overwrite == o_prompt) ? o_never : overwrite; | 216 | if (overwrite == O_PROMPT) |
217 | overwrite = O_NEVER; | ||
194 | } else { | 218 | } else { |
195 | static const char *const extn[] = {"", ".zip", ".ZIP"}; | 219 | static const char extn[][5] = {"", ".zip", ".ZIP"}; |
196 | int orig_src_fn_len = strlen(src_fn); | 220 | int orig_src_fn_len = strlen(src_fn); |
221 | |||
197 | for (i = 0; (i < 3) && (src_fd == -1); i++) { | 222 | for (i = 0; (i < 3) && (src_fd == -1); i++) { |
198 | strcpy(src_fn + orig_src_fn_len, extn[i]); | 223 | strcpy(src_fn + orig_src_fn_len, extn[i]); |
199 | src_fd = open(src_fn, O_RDONLY); | 224 | src_fd = open(src_fn, O_RDONLY); |
200 | } | 225 | } |
201 | if (src_fd == -1) { | 226 | if (src_fd == -1) { |
202 | src_fn[orig_src_fn_len] = '\0'; | 227 | src_fn[orig_src_fn_len] = '\0'; |
203 | bb_error_msg_and_die("cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); | 228 | bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); |
204 | } | 229 | } |
205 | } | 230 | } |
206 | 231 | ||
@@ -208,36 +233,31 @@ int unzip_main(int argc, char **argv) | |||
208 | if (base_dir) | 233 | if (base_dir) |
209 | xchdir(base_dir); | 234 | xchdir(base_dir); |
210 | 235 | ||
211 | if (verbose) | 236 | if (verbose) { |
212 | printf("Archive: %s\n", src_fn); | 237 | printf("Archive: %s\n", src_fn); |
238 | if (listing){ | ||
239 | puts(" Length Date Time Name\n" | ||
240 | " -------- ---- ---- ----"); | ||
241 | } | ||
242 | } | ||
213 | 243 | ||
214 | failed = 0; | 244 | total_size = 0; |
215 | 245 | total_entries = 0; | |
216 | while (1) { | 246 | while (1) { |
217 | unsigned int magic; | 247 | uint32_t magic; |
218 | 248 | ||
219 | /* Check magic number */ | 249 | /* Check magic number */ |
220 | xread(src_fd, &magic, 4); | 250 | xread(src_fd, &magic, 4); |
221 | if (magic == ZIP_CDS_MAGIC) { | 251 | if (magic == ZIP_CDS_MAGIC) |
222 | break; | 252 | break; |
223 | } else if (magic != ZIP_FILEHEADER_MAGIC) { | 253 | if (magic != ZIP_FILEHEADER_MAGIC) |
224 | bb_error_msg_and_die("invalid zip magic %08X", magic); | 254 | bb_error_msg_and_die("invalid zip magic %08X", magic); |
225 | } | ||
226 | 255 | ||
227 | /* Read the file header */ | 256 | /* Read the file header */ |
228 | xread(src_fd, zip_header.raw, 26); | 257 | xread(src_fd, zip_header.raw, sizeof(zip_header)); |
229 | zip_header.formatted.version = SWAP_LE32(zip_header.formatted.version); | 258 | FIX_ENDIANNESS(zip_header); |
230 | zip_header.formatted.flags = SWAP_LE32(zip_header.formatted.flags); | ||
231 | zip_header.formatted.method = SWAP_LE32(zip_header.formatted.method); | ||
232 | zip_header.formatted.modtime = SWAP_LE32(zip_header.formatted.modtime); | ||
233 | zip_header.formatted.moddate = SWAP_LE32(zip_header.formatted.moddate); | ||
234 | zip_header.formatted.crc32 = SWAP_LE32(zip_header.formatted.crc32); | ||
235 | zip_header.formatted.cmpsize = SWAP_LE32(zip_header.formatted.cmpsize); | ||
236 | zip_header.formatted.ucmpsize = SWAP_LE32(zip_header.formatted.ucmpsize); | ||
237 | zip_header.formatted.filename_len = SWAP_LE32(zip_header.formatted.filename_len); | ||
238 | zip_header.formatted.extra_len = SWAP_LE32(zip_header.formatted.extra_len); | ||
239 | if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { | 259 | if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { |
240 | bb_error_msg_and_die("unsupported compression method %d", zip_header.formatted.method); | 260 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); |
241 | } | 261 | } |
242 | 262 | ||
243 | /* Read filename */ | 263 | /* Read filename */ |
@@ -248,23 +268,16 @@ int unzip_main(int argc, char **argv) | |||
248 | /* Skip extra header bytes */ | 268 | /* Skip extra header bytes */ |
249 | unzip_skip(src_fd, zip_header.formatted.extra_len); | 269 | unzip_skip(src_fd, zip_header.formatted.extra_len); |
250 | 270 | ||
251 | if (listing && verbose && !list_header_done){ | ||
252 | puts(" Length Date Time Name\n" | ||
253 | " -------- ---- ---- ----"); | ||
254 | list_header_done = 1; | ||
255 | } | ||
256 | |||
257 | /* Filter zip entries */ | 271 | /* Filter zip entries */ |
258 | if (find_list_entry(zreject, dst_fn) || | 272 | if (find_list_entry(zreject, dst_fn) |
259 | (zaccept && !find_list_entry(zaccept, dst_fn))) { /* Skip entry */ | 273 | || (zaccept && !find_list_entry(zaccept, dst_fn)) |
274 | ) { /* Skip entry */ | ||
260 | i = 'n'; | 275 | i = 'n'; |
261 | 276 | ||
262 | } else { /* Extract entry */ | 277 | } else { /* Extract entry */ |
263 | total_size += zip_header.formatted.ucmpsize; | ||
264 | |||
265 | if (listing) { /* List entry */ | 278 | if (listing) { /* List entry */ |
266 | if (verbose) { | 279 | if (verbose) { |
267 | unsigned int dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); | 280 | unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); |
268 | printf("%9u %02u-%02u-%02u %02u:%02u %s\n", | 281 | printf("%9u %02u-%02u-%02u %02u:%02u %s\n", |
269 | zip_header.formatted.ucmpsize, | 282 | zip_header.formatted.ucmpsize, |
270 | (dostime & 0x01e00000) >> 21, | 283 | (dostime & 0x01e00000) >> 21, |
@@ -273,6 +286,7 @@ int unzip_main(int argc, char **argv) | |||
273 | (dostime & 0x0000f800) >> 11, | 286 | (dostime & 0x0000f800) >> 11, |
274 | (dostime & 0x000007e0) >> 5, | 287 | (dostime & 0x000007e0) >> 5, |
275 | dst_fn); | 288 | dst_fn); |
289 | total_size += zip_header.formatted.ucmpsize; | ||
276 | total_entries++; | 290 | total_entries++; |
277 | } else { | 291 | } else { |
278 | /* short listing -- filenames only */ | 292 | /* short listing -- filenames only */ |
@@ -308,14 +322,14 @@ int unzip_main(int argc, char **argv) | |||
308 | } | 322 | } |
309 | i = 'y'; | 323 | i = 'y'; |
310 | } else { /* File already exists */ | 324 | } else { /* File already exists */ |
311 | if (overwrite == o_never) { | 325 | if (overwrite == O_NEVER) { |
312 | i = 'n'; | 326 | i = 'n'; |
313 | } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ | 327 | } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ |
314 | if (overwrite == o_always) { | 328 | if (overwrite == O_ALWAYS) { |
315 | i = 'y'; | 329 | i = 'y'; |
316 | } else { | 330 | } else { |
317 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); | 331 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); |
318 | if (!fgets(key_buf, 512, stdin)) { | 332 | if (!fgets(key_buf, sizeof(key_buf), stdin)) { |
319 | bb_perror_msg_and_die("cannot read input"); | 333 | bb_perror_msg_and_die("cannot read input"); |
320 | } | 334 | } |
321 | i = key_buf[0]; | 335 | i = key_buf[0]; |
@@ -329,7 +343,7 @@ int unzip_main(int argc, char **argv) | |||
329 | 343 | ||
330 | switch (i) { | 344 | switch (i) { |
331 | case 'A': | 345 | case 'A': |
332 | overwrite = o_always; | 346 | overwrite = O_ALWAYS; |
333 | case 'y': /* Open file and fall into unzip */ | 347 | case 'y': /* Open file and fall into unzip */ |
334 | unzip_create_leading_dirs(dst_fn); | 348 | unzip_create_leading_dirs(dst_fn); |
335 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); | 349 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); |
@@ -337,9 +351,7 @@ int unzip_main(int argc, char **argv) | |||
337 | if (verbose) { | 351 | if (verbose) { |
338 | printf(" inflating: %s\n", dst_fn); | 352 | printf(" inflating: %s\n", dst_fn); |
339 | } | 353 | } |
340 | if (unzip_extract(&zip_header, src_fd, dst_fd)) { | 354 | unzip_extract(&zip_header, src_fd, dst_fd); |
341 | failed = 1; | ||
342 | } | ||
343 | if (dst_fd != STDOUT_FILENO) { | 355 | if (dst_fd != STDOUT_FILENO) { |
344 | /* closing STDOUT is potentially bad for future business */ | 356 | /* closing STDOUT is potentially bad for future business */ |
345 | close(dst_fd); | 357 | close(dst_fd); |
@@ -347,7 +359,7 @@ int unzip_main(int argc, char **argv) | |||
347 | break; | 359 | break; |
348 | 360 | ||
349 | case 'N': | 361 | case 'N': |
350 | overwrite = o_never; | 362 | overwrite = O_NEVER; |
351 | case 'n': | 363 | case 'n': |
352 | /* Skip entry data */ | 364 | /* Skip entry data */ |
353 | unzip_skip(src_fd, zip_header.formatted.cmpsize); | 365 | unzip_skip(src_fd, zip_header.formatted.cmpsize); |
@@ -356,7 +368,7 @@ int unzip_main(int argc, char **argv) | |||
356 | case 'r': | 368 | case 'r': |
357 | /* Prompt for new name */ | 369 | /* Prompt for new name */ |
358 | printf("new name: "); | 370 | printf("new name: "); |
359 | if (!fgets(key_buf, 512, stdin)) { | 371 | if (!fgets(key_buf, sizeof(key_buf), stdin)) { |
360 | bb_perror_msg_and_die("cannot read input"); | 372 | bb_perror_msg_and_die("cannot read input"); |
361 | } | 373 | } |
362 | free(dst_fn); | 374 | free(dst_fn); |
@@ -378,8 +390,9 @@ int unzip_main(int argc, char **argv) | |||
378 | 390 | ||
379 | if (listing && verbose) { | 391 | if (listing && verbose) { |
380 | printf(" -------- -------\n" | 392 | printf(" -------- -------\n" |
381 | "%9d %d files\n", total_size, total_entries); | 393 | "%9d %d files\n", |
394 | total_size, total_entries); | ||
382 | } | 395 | } |
383 | 396 | ||
384 | return failed; | 397 | return 0; |
385 | } | 398 | } |