diff options
Diffstat (limited to 'libbb/deb_extract.c')
-rw-r--r-- | libbb/deb_extract.c | 113 |
1 files changed, 36 insertions, 77 deletions
diff --git a/libbb/deb_extract.c b/libbb/deb_extract.c index 358c4d0a8..35ff99671 100644 --- a/libbb/deb_extract.c +++ b/libbb/deb_extract.c | |||
@@ -29,94 +29,53 @@ | |||
29 | #include <signal.h> | 29 | #include <signal.h> |
30 | #include "libbb.h" | 30 | #include "libbb.h" |
31 | 31 | ||
32 | /* From gunzip.c */ | 32 | const int dpkg_deb_contents = 1; |
33 | extern int gz_open(FILE *compressed_file, int *pid); | 33 | const int dpkg_deb_control = 2; |
34 | extern void gz_close(int gunzip_pid); | 34 | const int dpkg_deb_info = 4; |
35 | const int dpkg_deb_extract = 8; | ||
36 | const int dpkg_deb_verbose_extract = 16; | ||
37 | const int dpkg_deb_list = 32; | ||
35 | 38 | ||
36 | extern int tar_unzip_init(int tarFd); | 39 | extern int deb_extract(const char *package_filename, const int function, char *target_dir) |
37 | extern int readTarFile(int tarFd, int extractFlag, int listFlag, | ||
38 | int tostdoutFlag, int verboseFlag, char** extractList, char** excludeList); | ||
39 | |||
40 | extern int deb_extract(int optflags, const char *dir_name, const char *deb_filename) | ||
41 | { | 40 | { |
42 | const int dpkg_deb_contents = 1; | ||
43 | const int dpkg_deb_control = 2; | ||
44 | // const int dpkg_deb_info = 4; | ||
45 | const int dpkg_deb_extract = 8; | ||
46 | const int dpkg_deb_verbose_extract = 16; | ||
47 | const int dpkg_deb_list = 32; | ||
48 | 41 | ||
49 | char **extract_list = NULL; | 42 | FILE *deb_file, *uncompressed_file; |
50 | ar_headers_t *ar_headers = NULL; | 43 | ar_headers_t *headers = NULL; |
51 | char ar_filename[15]; | 44 | char *ared_file; |
52 | int extract_flag = FALSE; | 45 | int gunzip_pid; |
53 | int list_flag = FALSE; | ||
54 | int verbose_flag = FALSE; | ||
55 | int extract_to_stdout = FALSE; | ||
56 | int srcFd = 0; | ||
57 | int status; | ||
58 | pid_t pid; | ||
59 | FILE *comp_file = NULL; | ||
60 | 46 | ||
61 | if (dpkg_deb_contents == (dpkg_deb_contents & optflags)) { | 47 | if ((function == dpkg_deb_info) || (function == dpkg_deb_control)) { |
62 | strcpy(ar_filename, "data.tar.gz"); | 48 | ared_file = xstrdup("control.tar.gz"); |
63 | verbose_flag = TRUE; | 49 | } else { |
64 | list_flag = TRUE; | 50 | ared_file = xstrdup("data.tar.gz"); |
65 | } | ||
66 | if (dpkg_deb_list == (dpkg_deb_list & optflags)) { | ||
67 | strcpy(ar_filename, "data.tar.gz"); | ||
68 | list_flag = TRUE; | ||
69 | } | ||
70 | if (dpkg_deb_control == (dpkg_deb_control & optflags)) { | ||
71 | strcpy(ar_filename, "control.tar.gz"); | ||
72 | extract_flag = TRUE; | ||
73 | } | ||
74 | if (dpkg_deb_extract == (dpkg_deb_extract & optflags)) { | ||
75 | strcpy(ar_filename, "data.tar.gz"); | ||
76 | extract_flag = TRUE; | ||
77 | } | ||
78 | if (dpkg_deb_verbose_extract == (dpkg_deb_verbose_extract & optflags)) { | ||
79 | strcpy(ar_filename, "data.tar.gz"); | ||
80 | extract_flag = TRUE; | ||
81 | list_flag = TRUE; | ||
82 | } | 51 | } |
83 | 52 | ||
84 | ar_headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); | 53 | /* open the debian package to be worked on */ |
85 | srcFd = open(deb_filename, O_RDONLY); | 54 | deb_file = wfopen(package_filename, "r"); |
55 | |||
56 | headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); | ||
86 | 57 | ||
87 | *ar_headers = get_ar_headers(srcFd); | 58 | /* get a linked list of all ar entries */ |
88 | if (ar_headers->next == NULL) { | 59 | if ((headers = get_ar_headers(deb_file)) == NULL) { |
89 | error_msg_and_die("Couldnt find %s in %s", ar_filename, deb_filename); | 60 | error_msg("Couldnt get ar headers\n"); |
61 | return(EXIT_FAILURE); | ||
90 | } | 62 | } |
91 | 63 | ||
92 | while (ar_headers->next != NULL) { | 64 | /* seek to the start of the .tar.gz file within the ar file*/ |
93 | if (strcmp(ar_headers->name, ar_filename) == 0) { | 65 | if (seek_ared_file(deb_file, headers, ared_file) == EXIT_FAILURE) { |
94 | break; | 66 | error_msg("Couldnt seek to ar file"); |
95 | } | ||
96 | ar_headers = ar_headers->next; | ||
97 | } | 67 | } |
98 | lseek(srcFd, ar_headers->offset, SEEK_SET); | 68 | |
99 | /* Uncompress the file */ | 69 | /* open a stream of decompressed data */ |
100 | comp_file = fdopen(srcFd, "r"); | 70 | uncompressed_file = fdopen(gz_open(deb_file, &gunzip_pid), "r"); |
101 | if ((srcFd = gz_open(comp_file, &pid)) == EXIT_FAILURE) { | 71 | |
102 | error_msg_and_die("Couldnt unzip file"); | 72 | /* get a list of all tar headers inside the .gz file */ |
103 | } | 73 | untar(uncompressed_file, dpkg_deb_extract, target_dir); |
104 | if ( dir_name != NULL) { | ||
105 | if (is_directory(dir_name, TRUE, NULL)==FALSE) { | ||
106 | mkdir(dir_name, 0755); | ||
107 | } | ||
108 | if (chdir(dir_name)==-1) { | ||
109 | error_msg_and_die("Cannot change to dir %s", dir_name); | ||
110 | } | ||
111 | } | ||
112 | status = readTarFile(srcFd, extract_flag, list_flag, | ||
113 | extract_to_stdout, verbose_flag, NULL, extract_list); | ||
114 | 74 | ||
115 | /* we are deliberately terminating the child so we can safely ignore this */ | 75 | /* we are deliberately terminating the child so we can safely ignore this */ |
116 | signal(SIGTERM, SIG_IGN); | 76 | signal(SIGTERM, SIG_IGN); |
117 | gz_close(pid); | 77 | gz_close(gunzip_pid); |
118 | close(srcFd); | 78 | fclose(deb_file); |
119 | fclose(comp_file); | 79 | fclose(uncompressed_file); |
120 | 80 | return(EXIT_SUCCESS); | |
121 | return status; | ||
122 | } \ No newline at end of file | 81 | } \ No newline at end of file |