diff options
-rw-r--r-- | archival/dpkg.c | 50 | ||||
-rw-r--r-- | archival/libunarchive/Makefile.in | 2 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_all_prefix.c | 23 | ||||
-rw-r--r-- | archival/libunarchive/data_extract_to_buffer.c | 11 | ||||
-rw-r--r-- | include/unarchive.h | 6 |
5 files changed, 85 insertions, 7 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index 6cab77f38..df894472c 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -38,6 +38,7 @@ | |||
38 | * | 38 | * |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include <fcntl.h> | ||
41 | #include <getopt.h> | 42 | #include <getopt.h> |
42 | #include <stdlib.h> | 43 | #include <stdlib.h> |
43 | #include <string.h> | 44 | #include <string.h> |
@@ -1310,14 +1311,44 @@ void purge_package(const unsigned int package_num) | |||
1310 | set_status(status_num, "not-installed", 3); | 1311 | set_status(status_num, "not-installed", 3); |
1311 | } | 1312 | } |
1312 | 1313 | ||
1314 | static archive_handle_t *deb_extract(const char *filename, const char *ar_name, | ||
1315 | const char *tar_gz_name, char *prefix, void (*deb_action_data)(struct archive_handle_s *)) | ||
1316 | { | ||
1317 | archive_handle_t *ar_archive; | ||
1318 | archive_handle_t *tar_gz_archive; | ||
1319 | |||
1320 | /* Setup the tar archive handle */ | ||
1321 | tar_gz_archive = init_handle(); | ||
1322 | tar_gz_archive->filter = filter_accept_reject_list; | ||
1323 | tar_gz_archive->action_data = deb_action_data; | ||
1324 | tar_gz_archive->buffer = prefix; | ||
1325 | if (tar_gz_name) { | ||
1326 | tar_gz_archive->accept = add_to_list(NULL, tar_gz_name); | ||
1327 | } | ||
1328 | |||
1329 | /* Setup an ar archive handle that refers to the gzip sub archive */ | ||
1330 | ar_archive = init_handle(); | ||
1331 | ar_archive->action_data_subarchive = get_header_tar_gz; | ||
1332 | ar_archive->sub_archive = tar_gz_archive; | ||
1333 | ar_archive->filter = filter_accept_reject_list; | ||
1334 | ar_archive->accept = add_to_list(NULL, ar_name); | ||
1335 | |||
1336 | tar_gz_archive->src_fd = ar_archive->src_fd = xopen(filename, O_RDONLY); | ||
1337 | |||
1338 | unpack_ar_archive(ar_archive); | ||
1339 | close(ar_archive->src_fd); | ||
1340 | |||
1341 | return(ar_archive->sub_archive); | ||
1342 | } | ||
1343 | |||
1313 | void unpack_package(deb_file_t *deb_file) | 1344 | void unpack_package(deb_file_t *deb_file) |
1314 | { | 1345 | { |
1315 | const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; | 1346 | const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; |
1316 | const unsigned int status_num = search_status_hashtable(package_name); | 1347 | const unsigned int status_num = search_status_hashtable(package_name); |
1317 | const unsigned int status_package_num = status_hashtable[status_num]->package; | 1348 | const unsigned int status_package_num = status_hashtable[status_num]->package; |
1318 | |||
1319 | FILE *out_stream; | ||
1320 | char *info_prefix; | 1349 | char *info_prefix; |
1350 | archive_handle_t *archive_handle; | ||
1351 | FILE *out_stream; | ||
1321 | 1352 | ||
1322 | /* If existing version, remove it first */ | 1353 | /* If existing version, remove it first */ |
1323 | if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { | 1354 | if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) { |
@@ -1333,8 +1364,8 @@ void unpack_package(deb_file_t *deb_file) | |||
1333 | /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */ | 1364 | /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */ |
1334 | info_prefix = (char *) xmalloc(strlen(package_name) + 20 + 4 + 2); | 1365 | info_prefix = (char *) xmalloc(strlen(package_name) + 20 + 4 + 2); |
1335 | sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name); | 1366 | sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name); |
1336 | deb_extract(deb_file->filename, stdout, (extract_quiet | extract_control_tar_gz | extract_all_to_fs | extract_unconditional), info_prefix, NULL); | ||
1337 | 1367 | ||
1368 | deb_extract(deb_file->filename, "control.tar.gz", NULL, info_prefix, data_extract_all_prefix); | ||
1338 | /* Run the preinst prior to extracting */ | 1369 | /* Run the preinst prior to extracting */ |
1339 | if (run_package_script(package_name, "preinst") != 0) { | 1370 | if (run_package_script(package_name, "preinst") != 0) { |
1340 | /* when preinst returns exit code != 0 then quit installation process */ | 1371 | /* when preinst returns exit code != 0 then quit installation process */ |
@@ -1342,12 +1373,17 @@ void unpack_package(deb_file_t *deb_file) | |||
1342 | } | 1373 | } |
1343 | 1374 | ||
1344 | /* Extract data.tar.gz to the root directory */ | 1375 | /* Extract data.tar.gz to the root directory */ |
1345 | deb_extract(deb_file->filename, stdout, (extract_quiet | extract_data_tar_gz | extract_all_to_fs | extract_unconditional), "/", NULL); | 1376 | archive_handle = deb_extract(deb_file->filename, "data.tar.gz", NULL, NULL, data_extract_all); |
1346 | 1377 | ||
1347 | /* Create the list file */ | 1378 | /* Create the list file */ |
1348 | strcat(info_prefix, "list"); | 1379 | strcat(info_prefix, "list"); |
1349 | out_stream = xfopen(info_prefix, "w"); | 1380 | out_stream = xfopen(info_prefix, "w"); |
1350 | deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), "/", NULL); | 1381 | while (archive_handle->passed) { |
1382 | /* blindly skip over the leading '.' */ | ||
1383 | fputs(archive_handle->passed->data + 1, out_stream); | ||
1384 | fputc('\n', out_stream); | ||
1385 | archive_handle->passed = archive_handle->passed->link; | ||
1386 | } | ||
1351 | fclose(out_stream); | 1387 | fclose(out_stream); |
1352 | 1388 | ||
1353 | /* change status */ | 1389 | /* change status */ |
@@ -1440,8 +1476,10 @@ int dpkg_main(int argc, char **argv) | |||
1440 | deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2)); | 1476 | deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2)); |
1441 | deb_file[deb_count] = (deb_file_t *) xmalloc(sizeof(deb_file_t)); | 1477 | deb_file[deb_count] = (deb_file_t *) xmalloc(sizeof(deb_file_t)); |
1442 | if (dpkg_opt & dpkg_opt_filename) { | 1478 | if (dpkg_opt & dpkg_opt_filename) { |
1479 | archive_handle_t *archive_handle; | ||
1443 | deb_file[deb_count]->filename = xstrdup(argv[optind]); | 1480 | deb_file[deb_count]->filename = xstrdup(argv[optind]); |
1444 | deb_file[deb_count]->control_file = deb_extract(argv[optind], stdout, (extract_control_tar_gz | extract_one_to_buffer), NULL, "./control"); | 1481 | archive_handle = deb_extract(argv[optind], "control.tar.gz", "./control", NULL, data_extract_to_buffer); |
1482 | deb_file[deb_count]->control_file = archive_handle->buffer; | ||
1445 | if (deb_file[deb_count]->control_file == NULL) { | 1483 | if (deb_file[deb_count]->control_file == NULL) { |
1446 | error_msg_and_die("Couldnt extract control file"); | 1484 | error_msg_and_die("Couldnt extract control file"); |
1447 | } | 1485 | } |
diff --git a/archival/libunarchive/Makefile.in b/archival/libunarchive/Makefile.in index e559cb40e..87c888b0b 100644 --- a/archival/libunarchive/Makefile.in +++ b/archival/libunarchive/Makefile.in | |||
@@ -26,7 +26,9 @@ LIBUNARCHIVE-y:= \ | |||
26 | \ | 26 | \ |
27 | data_skip.o \ | 27 | data_skip.o \ |
28 | data_extract_all.o \ | 28 | data_extract_all.o \ |
29 | data_extract_all_prefix.o \ | ||
29 | data_extract_to_stdout.o \ | 30 | data_extract_to_stdout.o \ |
31 | data_extract_to_buffer.o \ | ||
30 | \ | 32 | \ |
31 | filter_accept_all.o \ | 33 | filter_accept_all.o \ |
32 | filter_accept_list.o \ | 34 | filter_accept_list.o \ |
diff --git a/archival/libunarchive/data_extract_all_prefix.c b/archival/libunarchive/data_extract_all_prefix.c new file mode 100644 index 000000000..e4e93fc74 --- /dev/null +++ b/archival/libunarchive/data_extract_all_prefix.c | |||
@@ -0,0 +1,23 @@ | |||
1 | #include <sys/types.h> | ||
2 | #include <errno.h> | ||
3 | #include <fcntl.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <utime.h> | ||
7 | #include <unistd.h> | ||
8 | #include <stdlib.h> | ||
9 | #include "libbb.h" | ||
10 | #include "unarchive.h" | ||
11 | |||
12 | extern void data_extract_all_prefix(archive_handle_t *archive_handle) | ||
13 | { | ||
14 | char *name_ptr = archive_handle->file_header->name; | ||
15 | |||
16 | name_ptr += strspn(name_ptr, "./"); | ||
17 | if (name_ptr[0] != '\0') { | ||
18 | archive_handle->file_header->name = xmalloc(strlen(archive_handle->buffer) + 2 + strlen(name_ptr)); | ||
19 | sprintf(archive_handle->file_header->name, "%s%s", archive_handle->buffer, name_ptr); | ||
20 | data_extract_all(archive_handle); | ||
21 | } | ||
22 | return; | ||
23 | } | ||
diff --git a/archival/libunarchive/data_extract_to_buffer.c b/archival/libunarchive/data_extract_to_buffer.c new file mode 100644 index 000000000..02ee4b362 --- /dev/null +++ b/archival/libunarchive/data_extract_to_buffer.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdio.h> | ||
3 | #include "unarchive.h" | ||
4 | #include "libbb.h" | ||
5 | |||
6 | extern void data_extract_to_buffer(archive_handle_t *archive_handle) | ||
7 | { | ||
8 | archive_handle->buffer = xmalloc(archive_handle->file_header->size + 1); | ||
9 | |||
10 | xread_all(archive_handle->src_fd, archive_handle->buffer, archive_handle->file_header->size); | ||
11 | } | ||
diff --git a/include/unarchive.h b/include/unarchive.h index 956c74fb8..d9cf3c05c 100644 --- a/include/unarchive.h +++ b/include/unarchive.h | |||
@@ -57,6 +57,9 @@ typedef struct archive_handle_s { | |||
57 | /* Count the number of bytes processed */ | 57 | /* Count the number of bytes processed */ |
58 | off_t offset; | 58 | off_t offset; |
59 | 59 | ||
60 | /* Temperary storage */ | ||
61 | char *buffer; | ||
62 | |||
60 | /* Misc. stuff */ | 63 | /* Misc. stuff */ |
61 | unsigned char flags; | 64 | unsigned char flags; |
62 | 65 | ||
@@ -70,10 +73,11 @@ extern char filter_accept_reject_list(const llist_t *accept_list, const llist_t | |||
70 | 73 | ||
71 | extern void unpack_ar_archive(archive_handle_t *ar_archive); | 74 | extern void unpack_ar_archive(archive_handle_t *ar_archive); |
72 | 75 | ||
73 | extern void data_gunzip(archive_handle_t *archive_handle); | ||
74 | extern void data_skip(archive_handle_t *archive_handle); | 76 | extern void data_skip(archive_handle_t *archive_handle); |
75 | extern void data_extract_all(archive_handle_t *archive_handle); | 77 | extern void data_extract_all(archive_handle_t *archive_handle); |
78 | extern void data_extract_all_prefix(archive_handle_t *archive_handle); | ||
76 | extern void data_extract_to_stdout(archive_handle_t *archive_handle); | 79 | extern void data_extract_to_stdout(archive_handle_t *archive_handle); |
80 | extern void data_extract_to_buffer(archive_handle_t *archive_handle); | ||
77 | 81 | ||
78 | extern void header_skip(const file_header_t *file_header); | 82 | extern void header_skip(const file_header_t *file_header); |
79 | extern void header_list(const file_header_t *file_header); | 83 | extern void header_list(const file_header_t *file_header); |