diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 3cdd4ffae..fbdb14e26 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c @@ -20,12 +20,6 @@ extern int dpkg_deb_main(int argc, char **argv) { - const int dpkg_deb_contents = 1; - const int dpkg_deb_control = 2; -// const int dpkg_deb_info = 4; - const int dpkg_deb_extract = 8; - const int dpkg_deb_verbose_extract = 16; - const int dpkg_deb_list = 32; char *target_dir = NULL; int opt = 0; int optflag = 0; @@ -33,22 +27,22 @@ extern int dpkg_deb_main(int argc, char **argv) while ((opt = getopt(argc, argv, "cexXl")) != -1) { switch (opt) { case 'c': - optflag |= dpkg_deb_contents; + optflag |= extract_contents; break; case 'e': - optflag |= dpkg_deb_control; + optflag |= extract_control; break; case 'X': - optflag |= dpkg_deb_verbose_extract; + optflag |= extract_verbose_extract; break; case 'x': - optflag |= dpkg_deb_extract; + optflag |= extract_extract; break; case 'l': - optflag |= dpkg_deb_list; + optflag |= extract_list; break; /* case 'I': - optflag |= dpkg_deb_info; + optflag |= extract_info; break; */ default: @@ -59,14 +53,19 @@ extern int dpkg_deb_main(int argc, char **argv) if (((optind + 1 ) > argc) || (optflag == 0)) { show_usage(); } - if ((optflag & dpkg_deb_control) || (optflag & dpkg_deb_extract) || (optflag & dpkg_deb_verbose_extract)) { - if ( (optind + 1) == argc ) { - target_dir = (char *) xmalloc(7); - strcpy(target_dir, "DEBIAN"); - } else { + switch (optflag) { + case (extract_control): + case (extract_extract): + case (extract_verbose_extract): + if ( (optind + 1) == argc ) { + target_dir = (char *) xmalloc(7); + strcpy(target_dir, "DEBIAN"); + } + break; + default: { target_dir = (char *) xmalloc(strlen(argv[optind + 1])); strcpy(target_dir, argv[optind + 1]); - } + } } deb_extract(argv[optind], optflag, target_dir); /* else if (optflag & dpkg_deb_info) { diff --git a/dpkg_deb.c b/dpkg_deb.c index 3cdd4ffae..fbdb14e26 100644 --- a/dpkg_deb.c +++ b/dpkg_deb.c @@ -20,12 +20,6 @@ extern int dpkg_deb_main(int argc, char **argv) { - const int dpkg_deb_contents = 1; - const int dpkg_deb_control = 2; -// const int dpkg_deb_info = 4; - const int dpkg_deb_extract = 8; - const int dpkg_deb_verbose_extract = 16; - const int dpkg_deb_list = 32; char *target_dir = NULL; int opt = 0; int optflag = 0; @@ -33,22 +27,22 @@ extern int dpkg_deb_main(int argc, char **argv) while ((opt = getopt(argc, argv, "cexXl")) != -1) { switch (opt) { case 'c': - optflag |= dpkg_deb_contents; + optflag |= extract_contents; break; case 'e': - optflag |= dpkg_deb_control; + optflag |= extract_control; break; case 'X': - optflag |= dpkg_deb_verbose_extract; + optflag |= extract_verbose_extract; break; case 'x': - optflag |= dpkg_deb_extract; + optflag |= extract_extract; break; case 'l': - optflag |= dpkg_deb_list; + optflag |= extract_list; break; /* case 'I': - optflag |= dpkg_deb_info; + optflag |= extract_info; break; */ default: @@ -59,14 +53,19 @@ extern int dpkg_deb_main(int argc, char **argv) if (((optind + 1 ) > argc) || (optflag == 0)) { show_usage(); } - if ((optflag & dpkg_deb_control) || (optflag & dpkg_deb_extract) || (optflag & dpkg_deb_verbose_extract)) { - if ( (optind + 1) == argc ) { - target_dir = (char *) xmalloc(7); - strcpy(target_dir, "DEBIAN"); - } else { + switch (optflag) { + case (extract_control): + case (extract_extract): + case (extract_verbose_extract): + if ( (optind + 1) == argc ) { + target_dir = (char *) xmalloc(7); + strcpy(target_dir, "DEBIAN"); + } + break; + default: { target_dir = (char *) xmalloc(strlen(argv[optind + 1])); strcpy(target_dir, argv[optind + 1]); - } + } } deb_extract(argv[optind], optflag, target_dir); /* else if (optflag & dpkg_deb_info) { diff --git a/include/libbb.h b/include/libbb.h index 8a5e6756f..46a0682b2 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -227,8 +227,18 @@ typedef struct ar_headers_s { } ar_headers_t; extern ar_headers_t *get_ar_headers(FILE *in_file); extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file); -extern int deb_extract(const char *package_filename, const int function, char *target_dir); -extern int untar(FILE *src_tar_file, int untar_function, char *base_path); + +typedef enum extract_function_e { + extract_contents = 1, + extract_control = 2, + extract_info = 4, + extract_extract = 8, + extract_verbose_extract = 16, + extract_list = 32 +} extract_function_t; +extern int deb_extract(const char *package_filename, int function, char *target_dir); +extern int untar(FILE *src_tar_file, int function, char *base_path); + extern int unzip(FILE *l_in_file, FILE *l_out_file); extern void gz_close(int gunzip_pid); extern int gz_open(FILE *compressed_file, int *pid); diff --git a/libbb/deb_extract.c b/libbb/deb_extract.c index 35ff99671..e982c14bb 100644 --- a/libbb/deb_extract.c +++ b/libbb/deb_extract.c @@ -29,25 +29,27 @@ #include #include "libbb.h" -const int dpkg_deb_contents = 1; -const int dpkg_deb_control = 2; -const int dpkg_deb_info = 4; -const int dpkg_deb_extract = 8; -const int dpkg_deb_verbose_extract = 16; -const int dpkg_deb_list = 32; - -extern int deb_extract(const char *package_filename, const int function, char *target_dir) +extern int deb_extract(const char *package_filename, int function, char *target_dir) { FILE *deb_file, *uncompressed_file; ar_headers_t *headers = NULL; - char *ared_file; + char *ared_file = NULL; int gunzip_pid; - if ((function == dpkg_deb_info) || (function == dpkg_deb_control)) { - ared_file = xstrdup("control.tar.gz"); - } else { - ared_file = xstrdup("data.tar.gz"); + switch (function) { + case (extract_info): + case (extract_control): + ared_file = xstrdup("control.tar.gz"); + break; + case (extract_contents): + case (extract_extract): + case (extract_verbose_extract): + case (extract_list): + ared_file = xstrdup("data.tar.gz"); + break; + default: + error_msg("Unknown extraction function"); } /* open the debian package to be worked on */ @@ -70,12 +72,14 @@ extern int deb_extract(const char *package_filename, const int function, char *t uncompressed_file = fdopen(gz_open(deb_file, &gunzip_pid), "r"); /* get a list of all tar headers inside the .gz file */ - untar(uncompressed_file, dpkg_deb_extract, target_dir); + untar(uncompressed_file, function, target_dir); /* we are deliberately terminating the child so we can safely ignore this */ - signal(SIGTERM, SIG_IGN); gz_close(gunzip_pid); + fclose(deb_file); fclose(uncompressed_file); + free(ared_file); + return(EXIT_SUCCESS); } \ No newline at end of file diff --git a/libbb/libbb.h b/libbb/libbb.h index 8a5e6756f..46a0682b2 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -227,8 +227,18 @@ typedef struct ar_headers_s { } ar_headers_t; extern ar_headers_t *get_ar_headers(FILE *in_file); extern int seek_ared_file(FILE *in_file, ar_headers_t *headers, const char *tar_gz_file); -extern int deb_extract(const char *package_filename, const int function, char *target_dir); -extern int untar(FILE *src_tar_file, int untar_function, char *base_path); + +typedef enum extract_function_e { + extract_contents = 1, + extract_control = 2, + extract_info = 4, + extract_extract = 8, + extract_verbose_extract = 16, + extract_list = 32 +} extract_function_t; +extern int deb_extract(const char *package_filename, int function, char *target_dir); +extern int untar(FILE *src_tar_file, int function, char *base_path); + extern int unzip(FILE *l_in_file, FILE *l_out_file); extern void gz_close(int gunzip_pid); extern int gz_open(FILE *compressed_file, int *pid); diff --git a/libbb/untar.c b/libbb/untar.c index 1542e390d..cb312d597 100644 --- a/libbb/untar.c +++ b/libbb/untar.c @@ -44,13 +44,6 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) char padding[12]; /* 500-512 */ } raw_tar_header_t; -// const int dpkg_deb_contents = 1; -// const int dpkg_deb_control = 2; -// const int dpkg_deb_info = 4; - const int untar_extract = 8; -// const int dpkg_deb_verbose_extract = 16; -// const int dpkg_deb_list = 32; - raw_tar_header_t raw_tar_header; unsigned char *temp = (unsigned char *) &raw_tar_header; long i; @@ -61,7 +54,7 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) // signal(SIGCHLD, child_died); - while (fread((char *) &raw_tar_header, 1, 512, src_tar_file)==512) { + while (fread((char *) &raw_tar_header, 1, 512, src_tar_file) == 512) { long sum = 0; char *dir; @@ -130,30 +123,41 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) * supposed to be a directory, and fall through */ if (raw_tar_header.name[strlen(raw_tar_header.name)-1] != '/') { - if (untar_function & untar_extract) { - int out_count=0; - FILE *dst_file; - - dst_file = wfopen(dir, "w"); - if (copy_file_chunk(src_tar_file, dst_file, size) == FALSE) { - error_msg_and_die("Couldnt extract file"); - } - uncompressed_count += out_count; - fclose(dst_file); - break; + switch (untar_function) { + case (extract_verbose_extract): + printf("%s\n", raw_tar_header.name); + case (extract_extract): { + FILE *dst_file = wfopen(dir, "w"); + copy_file_chunk(src_tar_file, dst_file, size); + fclose(dst_file); + } + break; + default: { + int remaining = size; + while (remaining-- > 0) { + fgetc(src_tar_file); + } + } } + uncompressed_count += size; + break; } case '5': - if (untar_function & untar_extract) { - if (create_path(dir, mode) != TRUE) { - free(dir); - perror_msg("%s: Cannot mkdir", raw_tar_header.name); - return(EXIT_FAILURE); - } + switch (untar_function) { + case (extract_verbose_extract): + printf("%s\n", raw_tar_header.name); + case (extract_extract): + if (create_path(dir, mode) != TRUE) { + free(dir); + perror_msg("%s: Cannot mkdir", raw_tar_header.name); + return(EXIT_FAILURE); + } + break; + default: } break; case '1': - if (untar_function & untar_extract) { + if (untar_function & extract_extract) { if (link(raw_tar_header.linkname, raw_tar_header.name) < 0) { free(dir); perror_msg("%s: Cannot create hard link to '%s'", raw_tar_header.name, raw_tar_header.linkname); @@ -162,7 +166,7 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) } break; case '2': - if (untar_function & untar_extract) { + if (untar_function & extract_extract) { if (symlink(raw_tar_header.linkname, raw_tar_header.name) < 0) { free(dir); perror_msg("%s: Cannot create symlink to '%s'", raw_tar_header.name, raw_tar_header.linkname); @@ -183,18 +187,5 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) } free(dir); } - /* skip to start of next header */ - while(uncompressed_count < next_header_offset) { - char ch[2]; - if (fread(ch, 1, 1, src_tar_file) != 1) { - error_msg("read error\n"); - getchar(); - } else { - uncompressed_count++; - } - } - /* - * TODO: Check that gunzip child hasnt finished - */ return(EXIT_SUCCESS); }