Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/archival/bbunzip.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/archival/bbunzip.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Common code for gunzip-like applets 4 * 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 6 */ 7 3 * Common code for gunzip-like applets 4 * 5 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 */ 8 7 #include "libbb.h" 9 #include " unarchive.h"8 #include "archive.h" 10 9 11 10 enum { 12 OPT_STDOUT = 0x1,13 OPT_FORCE = 0x2,14 /* gunzip only: */15 OPT_VERBOSE = 0x4,16 OPT_DECOMPRESS = 0x8,17 OPT_TEST = 0x10,11 OPT_STDOUT = 1 << 0, 12 OPT_FORCE = 1 << 1, 13 /* only some decompressors: */ 14 OPT_VERBOSE = 1 << 2, 15 OPT_DECOMPRESS = 1 << 3, 16 OPT_TEST = 1 << 4, 18 17 }; 19 18 … … 29 28 } 30 29 31 int bbunpack(char **argv, 32 char* (*make_new_name)(char *filename), 33 USE_DESKTOP(long long) int (*unpacker)(void) 30 char* FAST_FUNC append_ext(char *filename, const char *expected_ext) 31 { 32 return xasprintf("%s.%s", filename, expected_ext); 33 } 34 35 int FAST_FUNC bbunpack(char **argv, 36 IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), 37 char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), 38 const char *expected_ext 34 39 ) 35 40 { 36 41 struct stat stat_buf; 37 USE_DESKTOP(long long) int status;42 IF_DESKTOP(long long) int status; 38 43 char *filename, *new_name; 39 44 smallint exitcode = 0; 45 unpack_info_t info; 40 46 41 47 do { … … 50 56 if (filename) { 51 57 if (stat(filename, &stat_buf) != 0) { 52 bb_ perror_msg("%s",filename);58 bb_simple_perror_msg(filename); 53 59 err: 54 60 exitcode = 1; … … 69 75 /* Open dst if we are going to unpack to file */ 70 76 if (filename) { 71 new_name = make_new_name(filename );77 new_name = make_new_name(filename, expected_ext); 72 78 if (!new_name) { 73 79 bb_error_msg("%s: unknown suffix - ignored", filename); 74 80 goto err; 75 81 } 82 83 /* -f: overwrite existing output files */ 84 if (option_mask32 & OPT_FORCE) { 85 unlink(new_name); 86 } 87 76 88 /* O_EXCL: "real" bunzip2 doesn't overwrite files */ 77 /* GNU gunzip goes not bail out, but goes to next file */89 /* GNU gunzip does not bail out, but goes to next file */ 78 90 if (open_to_or_warn(STDOUT_FILENO, new_name, O_WRONLY | O_CREAT | O_EXCL, 79 91 stat_buf.st_mode)) … … 87 99 } 88 100 89 status = unpacker(); 101 /* memset(&info, 0, sizeof(info)); */ 102 info.mtime = 0; /* so far it has one member only */ 103 status = unpacker(&info); 90 104 if (status < 0) 91 105 exitcode = 1; 106 xclose(STDOUT_FILENO); /* with error check! */ 92 107 93 108 if (filename) { 94 109 char *del = new_name; 95 110 if (status >= 0) { 96 /* TODO: restore user/group/times here? */ 111 /* TODO: restore other things? */ 112 if (info.mtime) { 113 struct timeval times[2]; 114 115 times[1].tv_sec = times[0].tv_sec = info.mtime; 116 times[1].tv_usec = times[0].tv_usec = 0; 117 /* Note: we closed it first. 118 * On some systems calling utimes 119 * then closing resets the mtime 120 * back to current time. */ 121 utimes(new_name, times); /* ignoring errors */ 122 } 123 97 124 /* Delete _compressed_ file */ 98 125 del = filename; … … 120 147 } 121 148 122 #if ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNCOMPRESS 123 124 static 125 char* make_new_name_generic(char *filename, const char *expected_ext) 149 #if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ 150 static 151 char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) 126 152 { 127 153 char *extension = strrchr(filename, '.'); … … 134 160 return filename; 135 161 } 136 137 #endif 138 139 140 /* 141 * Modified for busybox by Glenn McGrath <bug1@iinet.net.au> 142 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no> 143 * 144 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 145 */ 146 147 #if ENABLE_BUNZIP2 148 149 static 150 char* make_new_name_bunzip2(char *filename) 151 { 152 return make_new_name_generic(filename, "bz2"); 153 } 154 155 static 156 USE_DESKTOP(long long) int unpack_bunzip2(void) 157 { 158 return unpack_bz2_stream(STDIN_FILENO, STDOUT_FILENO); 159 } 160 161 int bunzip2_main(int argc, char **argv); 162 int bunzip2_main(int argc, char **argv) 162 #endif 163 164 165 /* 166 * Uncompress applet for busybox (c) 2002 Glenn McGrath 167 * 168 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 169 */ 170 #if ENABLE_UNCOMPRESS 171 static 172 IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM) 173 { 174 IF_DESKTOP(long long) int status = -1; 175 176 if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { 177 bb_error_msg("invalid magic"); 178 } else { 179 status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); 180 } 181 return status; 182 } 183 int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 184 int uncompress_main(int argc UNUSED_PARAM, char **argv) 163 185 { 164 186 getopt32(argv, "cf"); 165 187 argv += optind; 166 if (applet_name[2] == 'c') 167 option_mask32 |= OPT_STDOUT; 168 169 return bbunpack(argv, make_new_name_bunzip2, unpack_bunzip2); 170 } 171 188 189 return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z"); 190 } 172 191 #endif 173 192 … … 186 205 * 187 206 * General cleanup to better adhere to the style guide and make use of standard 188 * busybox functions by Glenn McGrath <bug1@iinet.net.au>189 * 190 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.207 * busybox functions by Glenn McGrath 208 * 209 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 191 210 * 192 211 * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface … … 200 219 * See the file algorithm.doc for the compression algorithms and file formats. 201 220 */ 202 203 221 #if ENABLE_GUNZIP 204 205 static 206 char* make_new_name_gunzip(char *filename) 222 static 223 char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) 207 224 { 208 225 char *extension = strrchr(filename, '.'); … … 213 230 extension++; 214 231 if (strcmp(extension, "tgz" + 1) == 0 215 #if ENABLE_FEATURE_ GUNZIP_UNCOMPRESS216 || strcmp(extension, "Z") == 0232 #if ENABLE_FEATURE_SEAMLESS_Z 233 || (extension[0] == 'Z' && extension[1] == '\0') 217 234 #endif 218 235 ) { … … 228 245 return filename; 229 246 } 230 231 static 232 USE_DESKTOP(long long) int unpack_gunzip(void) 233 { 234 USE_DESKTOP(long long) int status = -1; 247 static 248 IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info) 249 { 250 IF_DESKTOP(long long) int status = -1; 235 251 236 252 /* do the decompression, and cleanup */ … … 239 255 240 256 magic2 = xread_char(STDIN_FILENO); 241 if (ENABLE_FEATURE_ GUNZIP_UNCOMPRESS&& magic2 == 0x9d) {242 status = un compress(STDIN_FILENO, STDOUT_FILENO);257 if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) { 258 status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); 243 259 } else if (magic2 == 0x8b) { 244 check_header_gzip_or_die(STDIN_FILENO); 245 status = unpack_gz_stream(STDIN_FILENO, STDOUT_FILENO); 260 status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info); 246 261 } else { 247 262 goto bad_magic; … … 257 272 return status; 258 273 } 259 260 int gunzip_main(int argc, char **argv); 261 int gunzip_main(int argc, char **argv) 262 { 263 getopt32(argv, "cfvdt"); 274 /* 275 * Linux kernel build uses gzip -d -n. We accept and ignore it. 276 * Man page says: 277 * -n --no-name 278 * gzip: do not save the original file name and time stamp. 279 * (The original name is always saved if the name had to be truncated.) 280 * gunzip: do not restore the original file name/time even if present 281 * (remove only the gzip suffix from the compressed file name). 282 * This option is the default when decompressing. 283 * -N --name 284 * gzip: always save the original file name and time stamp (this is the default) 285 * gunzip: restore the original file name and time stamp if present. 286 */ 287 int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 288 int gunzip_main(int argc UNUSED_PARAM, char **argv) 289 { 290 getopt32(argv, "cfvdtn"); 264 291 argv += optind; 265 292 /* if called as zcat */ … … 267 294 option_mask32 |= OPT_STDOUT; 268 295 269 return bbunpack(argv, make_new_name_gunzip, unpack_gunzip); 270 } 271 296 return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL); 297 } 298 #endif 299 300 301 /* 302 * Modified for busybox by Glenn McGrath 303 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no> 304 * 305 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 306 */ 307 //usage:#define bunzip2_trivial_usage 308 //usage: "[-cf] [FILE]..." 309 //usage:#define bunzip2_full_usage "\n\n" 310 //usage: "Decompress FILEs (or stdin)\n" 311 //usage: "\nOptions:" 312 //usage: "\n -c Write to stdout" 313 //usage: "\n -f Force" 314 //usage:#define bzcat_trivial_usage 315 //usage: "FILE" 316 //usage:#define bzcat_full_usage "\n\n" 317 //usage: "Decompress to stdout" 318 //applet:IF_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 319 //applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_DROP, bzcat)) 320 #if ENABLE_BUNZIP2 321 static 322 IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) 323 { 324 return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); 325 } 326 int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 327 int bunzip2_main(int argc UNUSED_PARAM, char **argv) 328 { 329 getopt32(argv, "cfvdt"); 330 argv += optind; 331 if (applet_name[2] == 'c') /* bzcat */ 332 option_mask32 |= OPT_STDOUT; 333 334 return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2"); 335 } 272 336 #endif 273 337 … … 279 343 * Based on bunzip.c from busybox 280 344 * 281 * Licensed under GPL v2, see file LICENSE in this tarball for details. 282 */ 283 345 * Licensed under GPLv2, see file LICENSE in this source tree. 346 */ 284 347 #if ENABLE_UNLZMA 285 286 static 287 char* make_new_name_unlzma(char *filename) 288 { 289 return make_new_name_generic(filename, "lzma"); 290 } 291 292 static 293 USE_DESKTOP(long long) int unpack_unlzma(void) 348 static 349 IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM) 294 350 { 295 351 return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); 296 352 } 297 298 int unlzma_main(int argc, char **argv); 299 int unlzma_main(int argc, char **argv) 300 { 301 getopt32(argv, "cf"); 353 int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 354 int unlzma_main(int argc UNUSED_PARAM, char **argv) 355 { 356 IF_LZMA(int opts =) getopt32(argv, "cfvdt"); 357 # if ENABLE_LZMA 358 /* lzma without -d or -t? */ 359 if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) 360 bb_show_usage(); 361 # endif 362 /* lzcat? */ 363 if (applet_name[2] == 'c') 364 option_mask32 |= OPT_STDOUT; 365 302 366 argv += optind; 303 /* lzmacat? */ 304 if (applet_name[4] == 'c') 367 return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma"); 368 } 369 #endif 370 371 372 #if ENABLE_UNXZ 373 static 374 IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) 375 { 376 struct { 377 uint32_t v1; 378 uint16_t v2; 379 } magic; 380 xread(STDIN_FILENO, &magic, 6); 381 if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { 382 bb_error_msg("invalid magic"); 383 return -1; 384 } 385 return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); 386 } 387 int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 388 int unxz_main(int argc UNUSED_PARAM, char **argv) 389 { 390 IF_XZ(int opts =) getopt32(argv, "cfvdt"); 391 # if ENABLE_XZ 392 /* xz without -d or -t? */ 393 if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) 394 bb_show_usage(); 395 # endif 396 /* xzcat? */ 397 if (applet_name[2] == 'c') 305 398 option_mask32 |= OPT_STDOUT; 306 399 307 return bbunpack(argv, make_new_name_unlzma, unpack_unlzma);308 }309 310 #endif311 312 313 /*314 * Uncompress applet for busybox (c) 2002 Glenn McGrath315 *316 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.317 */318 319 #if ENABLE_UNCOMPRESS320 321 static322 char* make_new_name_uncompress(char *filename)323 {324 return make_new_name_generic(filename, "Z");325 }326 327 static328 USE_DESKTOP(long long) int unpack_uncompress(void)329 {330 USE_DESKTOP(long long) int status = -1;331 332 if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {333 bb_error_msg("invalid magic");334 } else {335 status = uncompress(STDIN_FILENO, STDOUT_FILENO);336 }337 return status;338 }339 340 int uncompress_main(int argc, char **argv);341 int uncompress_main(int argc, char **argv)342 {343 getopt32(argv, "cf");344 400 argv += optind; 345 346 return bbunpack(argv, make_new_name_uncompress, unpack_uncompress); 347 } 348 349 #endif 401 return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz"); 402 } 403 #endif
Note:
See TracChangeset
for help on using the changeset viewer.