diff options
| author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-13 04:02:57 +0000 |
|---|---|---|
| committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-13 04:02:57 +0000 |
| commit | 445fb952b8becc78889d3079e3053f76aa2eba9c (patch) | |
| tree | feda0730549303c7fadd259741bea57207e46431 | |
| parent | 1e04ea388f5f673f44503052d0f8873e4017abc3 (diff) | |
| download | busybox-w32-445fb952b8becc78889d3079e3053f76aa2eba9c.tar.gz busybox-w32-445fb952b8becc78889d3079e3053f76aa2eba9c.tar.bz2 busybox-w32-445fb952b8becc78889d3079e3053f76aa2eba9c.zip | |
dpkg-deb -f and partial -I commands, adds 600 bytes
| -rw-r--r-- | archival/dpkg_deb.c | 48 | ||||
| -rw-r--r-- | dpkg_deb.c | 48 | ||||
| -rw-r--r-- | include/libbb.h | 5 | ||||
| -rw-r--r-- | libbb/deb_extract.c | 9 | ||||
| -rw-r--r-- | libbb/libbb.h | 5 | ||||
| -rw-r--r-- | libbb/untar.c | 66 |
6 files changed, 103 insertions, 78 deletions
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 3bec8cfc7..7c5a5de58 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
| @@ -20,11 +20,11 @@ | |||
| 20 | 20 | ||
| 21 | extern int dpkg_deb_main(int argc, char **argv) | 21 | extern int dpkg_deb_main(int argc, char **argv) |
| 22 | { | 22 | { |
| 23 | char *target_dir; | 23 | char *argument = NULL; |
| 24 | int opt = 0; | 24 | int opt = 0; |
| 25 | int optflag = 0; | 25 | int optflag = 0; |
| 26 | 26 | ||
| 27 | while ((opt = getopt(argc, argv, "cetXxl")) != -1) { | 27 | while ((opt = getopt(argc, argv, "ceftXxI")) != -1) { |
| 28 | switch (opt) { | 28 | switch (opt) { |
| 29 | case 'c': | 29 | case 'c': |
| 30 | optflag |= extract_contents; | 30 | optflag |= extract_contents; |
| @@ -32,6 +32,9 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 32 | case 'e': | 32 | case 'e': |
| 33 | optflag |= extract_control; | 33 | optflag |= extract_control; |
| 34 | break; | 34 | break; |
| 35 | case 'f': | ||
| 36 | optflag |= extract_field; | ||
| 37 | break; | ||
| 35 | case 't': | 38 | case 't': |
| 36 | optflag |= extract_fsys_tarfile; | 39 | optflag |= extract_fsys_tarfile; |
| 37 | break; | 40 | break; |
| @@ -41,13 +44,9 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 41 | case 'x': | 44 | case 'x': |
| 42 | optflag |= extract_extract; | 45 | optflag |= extract_extract; |
| 43 | break; | 46 | break; |
| 44 | case 'l': | 47 | case 'I': |
| 45 | optflag |= extract_list; | ||
| 46 | break; | ||
| 47 | /* case 'I': | ||
| 48 | optflag |= extract_info; | 48 | optflag |= extract_info; |
| 49 | break; | 49 | break; |
| 50 | */ | ||
| 51 | default: | 50 | default: |
| 52 | show_usage(); | 51 | show_usage(); |
| 53 | } | 52 | } |
| @@ -61,26 +60,33 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 61 | case (extract_control): | 60 | case (extract_control): |
| 62 | case (extract_extract): | 61 | case (extract_extract): |
| 63 | case (extract_verbose_extract): | 62 | case (extract_verbose_extract): |
| 63 | /* argument is a dir name */ | ||
| 64 | if ( (optind + 1) == argc ) { | 64 | if ( (optind + 1) == argc ) { |
| 65 | target_dir = (char *) xmalloc(7); | 65 | argument = xstrdup("DEBIAN"); |
| 66 | strcpy(target_dir, "DEBIAN"); | ||
| 67 | } else { | 66 | } else { |
| 68 | target_dir = (char *) xmalloc(strlen(argv[optind + 1]) + 1); | 67 | argument = xstrdup(argv[optind + 1]); |
| 69 | strcpy(target_dir, argv[optind + 1]); | ||
| 70 | } | 68 | } |
| 71 | break; | 69 | break; |
| 70 | case (extract_field): | ||
| 71 | /* argument is a control field name */ | ||
| 72 | if ((optind + 1) != argc) { | ||
| 73 | argument = xstrdup(argv[optind + 1]); | ||
| 74 | } | ||
| 75 | break; | ||
| 76 | case (extract_info): | ||
| 77 | /* argument is a control field name */ | ||
| 78 | if ((optind + 1) != argc) { | ||
| 79 | argument = xstrdup(argv[optind + 1]); | ||
| 80 | break; | ||
| 81 | } else { | ||
| 82 | error_msg("-I currently requires a filename to be specifies"); | ||
| 83 | return(EXIT_FAILURE); | ||
| 84 | } | ||
| 85 | /* argument is a filename */ | ||
| 72 | default: | 86 | default: |
| 73 | target_dir = NULL; | ||
| 74 | } | 87 | } |
| 75 | 88 | ||
| 76 | deb_extract(argv[optind], optflag, target_dir); | 89 | deb_extract(argv[optind], optflag, argument); |
| 77 | /* else if (optflag & dpkg_deb_info) { | 90 | |
| 78 | extract_flag = TRUE; | ||
| 79 | extract_to_stdout = TRUE; | ||
| 80 | strcpy(ar_filename, "control.tar.gz"); | ||
| 81 | extract_list = argv+optind+1; | ||
| 82 | printf("list one is [%s]\n",extract_list[0]); | ||
| 83 | } | ||
| 84 | */ | ||
| 85 | return(EXIT_SUCCESS); | 91 | return(EXIT_SUCCESS); |
| 86 | } | 92 | } |
diff --git a/dpkg_deb.c b/dpkg_deb.c index 3bec8cfc7..7c5a5de58 100644 --- a/dpkg_deb.c +++ b/dpkg_deb.c | |||
| @@ -20,11 +20,11 @@ | |||
| 20 | 20 | ||
| 21 | extern int dpkg_deb_main(int argc, char **argv) | 21 | extern int dpkg_deb_main(int argc, char **argv) |
| 22 | { | 22 | { |
| 23 | char *target_dir; | 23 | char *argument = NULL; |
| 24 | int opt = 0; | 24 | int opt = 0; |
| 25 | int optflag = 0; | 25 | int optflag = 0; |
| 26 | 26 | ||
| 27 | while ((opt = getopt(argc, argv, "cetXxl")) != -1) { | 27 | while ((opt = getopt(argc, argv, "ceftXxI")) != -1) { |
| 28 | switch (opt) { | 28 | switch (opt) { |
| 29 | case 'c': | 29 | case 'c': |
| 30 | optflag |= extract_contents; | 30 | optflag |= extract_contents; |
| @@ -32,6 +32,9 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 32 | case 'e': | 32 | case 'e': |
| 33 | optflag |= extract_control; | 33 | optflag |= extract_control; |
| 34 | break; | 34 | break; |
| 35 | case 'f': | ||
| 36 | optflag |= extract_field; | ||
| 37 | break; | ||
| 35 | case 't': | 38 | case 't': |
| 36 | optflag |= extract_fsys_tarfile; | 39 | optflag |= extract_fsys_tarfile; |
| 37 | break; | 40 | break; |
| @@ -41,13 +44,9 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 41 | case 'x': | 44 | case 'x': |
| 42 | optflag |= extract_extract; | 45 | optflag |= extract_extract; |
| 43 | break; | 46 | break; |
| 44 | case 'l': | 47 | case 'I': |
| 45 | optflag |= extract_list; | ||
| 46 | break; | ||
| 47 | /* case 'I': | ||
| 48 | optflag |= extract_info; | 48 | optflag |= extract_info; |
| 49 | break; | 49 | break; |
| 50 | */ | ||
| 51 | default: | 50 | default: |
| 52 | show_usage(); | 51 | show_usage(); |
| 53 | } | 52 | } |
| @@ -61,26 +60,33 @@ extern int dpkg_deb_main(int argc, char **argv) | |||
| 61 | case (extract_control): | 60 | case (extract_control): |
| 62 | case (extract_extract): | 61 | case (extract_extract): |
| 63 | case (extract_verbose_extract): | 62 | case (extract_verbose_extract): |
| 63 | /* argument is a dir name */ | ||
| 64 | if ( (optind + 1) == argc ) { | 64 | if ( (optind + 1) == argc ) { |
| 65 | target_dir = (char *) xmalloc(7); | 65 | argument = xstrdup("DEBIAN"); |
| 66 | strcpy(target_dir, "DEBIAN"); | ||
| 67 | } else { | 66 | } else { |
| 68 | target_dir = (char *) xmalloc(strlen(argv[optind + 1]) + 1); | 67 | argument = xstrdup(argv[optind + 1]); |
| 69 | strcpy(target_dir, argv[optind + 1]); | ||
| 70 | } | 68 | } |
| 71 | break; | 69 | break; |
| 70 | case (extract_field): | ||
| 71 | /* argument is a control field name */ | ||
| 72 | if ((optind + 1) != argc) { | ||
| 73 | argument = xstrdup(argv[optind + 1]); | ||
| 74 | } | ||
| 75 | break; | ||
| 76 | case (extract_info): | ||
| 77 | /* argument is a control field name */ | ||
| 78 | if ((optind + 1) != argc) { | ||
| 79 | argument = xstrdup(argv[optind + 1]); | ||
| 80 | break; | ||
| 81 | } else { | ||
| 82 | error_msg("-I currently requires a filename to be specifies"); | ||
| 83 | return(EXIT_FAILURE); | ||
| 84 | } | ||
| 85 | /* argument is a filename */ | ||
| 72 | default: | 86 | default: |
| 73 | target_dir = NULL; | ||
| 74 | } | 87 | } |
| 75 | 88 | ||
| 76 | deb_extract(argv[optind], optflag, target_dir); | 89 | deb_extract(argv[optind], optflag, argument); |
| 77 | /* else if (optflag & dpkg_deb_info) { | 90 | |
| 78 | extract_flag = TRUE; | ||
| 79 | extract_to_stdout = TRUE; | ||
| 80 | strcpy(ar_filename, "control.tar.gz"); | ||
| 81 | extract_list = argv+optind+1; | ||
| 82 | printf("list one is [%s]\n",extract_list[0]); | ||
| 83 | } | ||
| 84 | */ | ||
| 85 | return(EXIT_SUCCESS); | 91 | return(EXIT_SUCCESS); |
| 86 | } | 92 | } |
diff --git a/include/libbb.h b/include/libbb.h index bc8e3c5f3..515bf2760 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -235,10 +235,11 @@ typedef enum extract_function_e { | |||
| 235 | extract_extract = 8, | 235 | extract_extract = 8, |
| 236 | extract_verbose_extract = 16, | 236 | extract_verbose_extract = 16, |
| 237 | extract_list = 32, | 237 | extract_list = 32, |
| 238 | extract_fsys_tarfile = 64 | 238 | extract_fsys_tarfile = 64, |
| 239 | extract_field = 128 | ||
| 239 | } extract_function_t; | 240 | } extract_function_t; |
| 240 | extern int deb_extract(const char *package_filename, int function, char *target_dir); | 241 | extern int deb_extract(const char *package_filename, int function, char *target_dir); |
| 241 | extern int untar(FILE *src_tar_file, int untar_function, char *base_path); | 242 | extern int untar(FILE *src_tar_file, const int untar_function, const char *argument); |
| 242 | 243 | ||
| 243 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 244 | extern int unzip(FILE *l_in_file, FILE *l_out_file); |
| 244 | extern void gz_close(int gunzip_pid); | 245 | extern void gz_close(int gunzip_pid); |
diff --git a/libbb/deb_extract.c b/libbb/deb_extract.c index d3e615305..0f5a570b6 100644 --- a/libbb/deb_extract.c +++ b/libbb/deb_extract.c | |||
| @@ -30,7 +30,11 @@ | |||
| 30 | #include <signal.h> | 30 | #include <signal.h> |
| 31 | #include "libbb.h" | 31 | #include "libbb.h" |
| 32 | 32 | ||
| 33 | extern int deb_extract(const char *package_filename, int function, char *target_dir) | 33 | /* |
| 34 | * The contents of argument depend on the value of function. | ||
| 35 | * It is either a dir name or a control file or field name(see dpkg_deb.c) | ||
| 36 | */ | ||
| 37 | extern int deb_extract(const char *package_filename, int function, char *argument) | ||
| 34 | { | 38 | { |
| 35 | 39 | ||
| 36 | FILE *deb_file, *uncompressed_file; | 40 | FILE *deb_file, *uncompressed_file; |
| @@ -41,6 +45,7 @@ extern int deb_extract(const char *package_filename, int function, char *target_ | |||
| 41 | switch (function) { | 45 | switch (function) { |
| 42 | case (extract_info): | 46 | case (extract_info): |
| 43 | case (extract_control): | 47 | case (extract_control): |
| 48 | case (extract_field): | ||
| 44 | ared_file = xstrdup("control.tar.gz"); | 49 | ared_file = xstrdup("control.tar.gz"); |
| 45 | break; | 50 | break; |
| 46 | default: | 51 | default: |
| @@ -70,7 +75,7 @@ extern int deb_extract(const char *package_filename, int function, char *target_ | |||
| 70 | if (function & extract_fsys_tarfile) { | 75 | if (function & extract_fsys_tarfile) { |
| 71 | copy_file_chunk(uncompressed_file, stdout, -1); | 76 | copy_file_chunk(uncompressed_file, stdout, -1); |
| 72 | } else { | 77 | } else { |
| 73 | untar(uncompressed_file, function, target_dir); | 78 | untar(uncompressed_file, function, argument); |
| 74 | } | 79 | } |
| 75 | /* we are deliberately terminating the child so we can safely ignore this */ | 80 | /* we are deliberately terminating the child so we can safely ignore this */ |
| 76 | gz_close(gunzip_pid); | 81 | gz_close(gunzip_pid); |
diff --git a/libbb/libbb.h b/libbb/libbb.h index bc8e3c5f3..515bf2760 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h | |||
| @@ -235,10 +235,11 @@ typedef enum extract_function_e { | |||
| 235 | extract_extract = 8, | 235 | extract_extract = 8, |
| 236 | extract_verbose_extract = 16, | 236 | extract_verbose_extract = 16, |
| 237 | extract_list = 32, | 237 | extract_list = 32, |
| 238 | extract_fsys_tarfile = 64 | 238 | extract_fsys_tarfile = 64, |
| 239 | extract_field = 128 | ||
| 239 | } extract_function_t; | 240 | } extract_function_t; |
| 240 | extern int deb_extract(const char *package_filename, int function, char *target_dir); | 241 | extern int deb_extract(const char *package_filename, int function, char *target_dir); |
| 241 | extern int untar(FILE *src_tar_file, int untar_function, char *base_path); | 242 | extern int untar(FILE *src_tar_file, const int untar_function, const char *argument); |
| 242 | 243 | ||
| 243 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 244 | extern int unzip(FILE *l_in_file, FILE *l_out_file); |
| 244 | extern void gz_close(int gunzip_pid); | 245 | extern void gz_close(int gunzip_pid); |
diff --git a/libbb/untar.c b/libbb/untar.c index d3e424e25..b768c0be8 100644 --- a/libbb/untar.c +++ b/libbb/untar.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include <unistd.h> | 22 | #include <unistd.h> |
| 23 | #include "libbb.h" | 23 | #include "libbb.h" |
| 24 | 24 | ||
| 25 | extern int untar(FILE *src_tar_file, int untar_function, char *base_path) | 25 | extern int untar(FILE *src_tar_file, const int untar_function, const char *argument) |
| 26 | { | 26 | { |
| 27 | typedef struct raw_tar_header { | 27 | typedef struct raw_tar_header { |
| 28 | char name[100]; /* 0-99 */ | 28 | char name[100]; /* 0-99 */ |
| @@ -101,37 +101,18 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) | |||
| 101 | if (size % 512 != 0) { | 101 | if (size % 512 != 0) { |
| 102 | next_header_offset += (512 - size % 512); | 102 | next_header_offset += (512 - size % 512); |
| 103 | } | 103 | } |
| 104 | /* | ||
| 105 | * seek to start of control file, return length | ||
| 106 | * | ||
| 107 | if (dpkg_untar_function & dpkg_untar_seek_control) { | ||
| 108 | if ((raw_tar_header.typeflag == '0') || (raw_tar_header.typeflag == '\0')) { | ||
| 109 | char *tar_filename; | ||
| 110 | |||
| 111 | tar_filename = strrchr(raw_tar_header.name, '/'); | ||
| 112 | if (tar_filename == NULL) { | ||
| 113 | tar_filename = strdup(raw_tar_header.name); | ||
| 114 | } else { | ||
| 115 | tar_filename++; | ||
| 116 | } | ||
| 117 | |||
| 118 | if (strcmp(tar_filename, "control") == 0) { | ||
| 119 | return(size); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | 104 | ||
| 123 | } | ||
| 124 | */ | ||
| 125 | if (untar_function & (extract_contents | extract_verbose_extract)) { | 105 | if (untar_function & (extract_contents | extract_verbose_extract)) { |
| 126 | printf("%s\n", raw_tar_header.name); | 106 | printf("%s\n", raw_tar_header.name); |
| 127 | } | 107 | } |
| 128 | 108 | ||
| 129 | /* extract files */ | 109 | /* extract files */ |
| 130 | if (base_path != NULL) { | 110 | if (untar_function & (extract_extract | extract_verbose_extract | extract_control)) { |
| 131 | dir = xmalloc(strlen(raw_tar_header.name) + strlen(base_path) + 2); | 111 | dir = xmalloc(strlen(raw_tar_header.name) + strlen(argument) + 2); |
| 132 | sprintf(dir, "%s/%s", base_path, raw_tar_header.name); | 112 | sprintf(dir, "%s/%s", argument, raw_tar_header.name); |
| 133 | create_path(dir, 0777); | 113 | create_path(dir, 0777); |
| 134 | } | 114 | } |
| 115 | |||
| 135 | switch (raw_tar_header.typeflag ) { | 116 | switch (raw_tar_header.typeflag ) { |
| 136 | case '0': | 117 | case '0': |
| 137 | case '\0': | 118 | case '\0': |
| @@ -145,14 +126,28 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) | |||
| 145 | uncompressed_count += size; | 126 | uncompressed_count += size; |
| 146 | fclose(dst_file); | 127 | fclose(dst_file); |
| 147 | } | 128 | } |
| 148 | while (uncompressed_count < next_header_offset) { | 129 | else if (untar_function & extract_info) { |
| 149 | if (fgetc(src_tar_file) == EOF) { | 130 | if (strstr(raw_tar_header.name, argument) != NULL) { |
| 150 | perror_msg("untar"); | 131 | copy_file_chunk(src_tar_file, stdout, (unsigned long long) size); |
| 151 | break; | 132 | uncompressed_count += size; |
| 133 | } | ||
| 134 | } | ||
| 135 | else if (untar_function & extract_field) { | ||
| 136 | if (strstr(raw_tar_header.name, "./control") != NULL) { | ||
| 137 | char *line; | ||
| 138 | while ((line = get_line_from_file(src_tar_file)) != NULL) { | ||
| 139 | uncompressed_count += strlen(line); | ||
| 140 | if (argument == NULL) { | ||
| 141 | printf("%s",line); | ||
| 142 | } | ||
| 143 | else if (strncmp(line, argument, strlen(argument)) == 0) { | ||
| 144 | char *file_ptr; | ||
| 145 | file_ptr = strstr(line, ": "); | ||
| 146 | printf("%s", file_ptr + 2); | ||
| 147 | } | ||
| 148 | } | ||
| 152 | } | 149 | } |
| 153 | uncompressed_count++; | ||
| 154 | } | 150 | } |
| 155 | uncompressed_count += size; | ||
| 156 | break; | 151 | break; |
| 157 | } | 152 | } |
| 158 | case '5': | 153 | case '5': |
| @@ -193,6 +188,17 @@ extern int untar(FILE *src_tar_file, int untar_function, char *base_path) | |||
| 193 | free(dir); | 188 | free(dir); |
| 194 | return(EXIT_FAILURE); | 189 | return(EXIT_FAILURE); |
| 195 | } | 190 | } |
| 191 | |||
| 192 | /* | ||
| 193 | * Seek to start of next block, cant use fseek as unzip() does support it | ||
| 194 | */ | ||
| 195 | while (uncompressed_count < next_header_offset) { | ||
| 196 | if (fgetc(src_tar_file) == EOF) { | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | uncompressed_count++; | ||
| 200 | } | ||
| 201 | |||
| 196 | // free(dir); | 202 | // free(dir); |
| 197 | } | 203 | } |
| 198 | return(EXIT_SUCCESS); | 204 | return(EXIT_SUCCESS); |
