blob: 86850469d8c5ca7d5cdf662f5ae1dd8ee4822c8a
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * dpkg-deb packs, unpacks and provides information about Debian archives. |
4 | * |
5 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
6 | */ |
7 | |
8 | //config:config DPKG_DEB |
9 | //config: bool "dpkg_deb" |
10 | //config: default n |
11 | //config: select FEATURE_SEAMLESS_GZ |
12 | //config: help |
13 | //config: dpkg-deb unpacks and provides information about Debian archives. |
14 | //config: |
15 | //config: This implementation of dpkg-deb cannot pack archives. |
16 | //config: |
17 | //config: Unless you have a specific application which requires dpkg-deb, |
18 | //config: say N here. |
19 | |
20 | //applet:IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb)) |
21 | |
22 | //kbuild:lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o |
23 | |
24 | //usage:#define dpkg_deb_trivial_usage |
25 | //usage: "[-cefxX] FILE [DIR]" |
26 | //usage:#define dpkg_deb_full_usage "\n\n" |
27 | //usage: "Perform actions on Debian packages (.deb)\n" |
28 | //usage: "\n -c List files" |
29 | //usage: "\n -f Print control fields" |
30 | //usage: "\n -e Extract control files to DIR (default: ./DEBIAN)" |
31 | //usage: "\n -x Extract files to DIR (no default)" |
32 | //usage: "\n -X Verbose -x" |
33 | //usage: |
34 | //usage:#define dpkg_deb_example_usage |
35 | //usage: "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" |
36 | |
37 | #include "libbb.h" |
38 | #include "bb_archive.h" |
39 | |
40 | #define DPKG_DEB_OPT_CONTENTS 1 |
41 | #define DPKG_DEB_OPT_CONTROL 2 |
42 | #define DPKG_DEB_OPT_FIELD 4 |
43 | #define DPKG_DEB_OPT_EXTRACT_VERBOSE 8 |
44 | #define DPKG_DEB_OPT_EXTRACT 16 |
45 | |
46 | int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
47 | int dpkg_deb_main(int argc UNUSED_PARAM, char **argv) |
48 | { |
49 | archive_handle_t *ar_archive; |
50 | archive_handle_t *tar_archive; |
51 | llist_t *control_tar_llist = NULL; |
52 | unsigned opt; |
53 | const char *extract_dir; |
54 | |
55 | /* Setup the tar archive handle */ |
56 | tar_archive = init_handle(); |
57 | |
58 | /* Setup an ar archive handle that refers to the gzip sub archive */ |
59 | ar_archive = init_handle(); |
60 | ar_archive->dpkg__sub_archive = tar_archive; |
61 | ar_archive->filter = filter_accept_list_reassign; |
62 | |
63 | llist_add_to(&ar_archive->accept, (char*)"data.tar"); |
64 | llist_add_to(&control_tar_llist, (char*)"control.tar"); |
65 | #if ENABLE_FEATURE_SEAMLESS_GZ |
66 | llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); |
67 | llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); |
68 | #endif |
69 | #if ENABLE_FEATURE_SEAMLESS_BZ2 |
70 | llist_add_to(&ar_archive->accept, (char*)"data.tar.bz2"); |
71 | llist_add_to(&control_tar_llist, (char*)"control.tar.bz2"); |
72 | #endif |
73 | #if ENABLE_FEATURE_SEAMLESS_LZMA |
74 | llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); |
75 | llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); |
76 | #endif |
77 | #if ENABLE_FEATURE_SEAMLESS_XZ |
78 | llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); |
79 | llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); |
80 | #endif |
81 | |
82 | /* Must have 1 or 2 args */ |
83 | opt_complementary = "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; |
84 | opt = getopt32(argv, "cefXx"); |
85 | argv += optind; |
86 | //argc -= optind; |
87 | |
88 | extract_dir = argv[1]; |
89 | if (opt & DPKG_DEB_OPT_CONTENTS) { // -c |
90 | tar_archive->action_header = header_verbose_list; |
91 | if (extract_dir) |
92 | bb_show_usage(); |
93 | } |
94 | if (opt & DPKG_DEB_OPT_FIELD) { // -f |
95 | /* Print the entire control file */ |
96 | //TODO: standard tool accepts an optional list of fields to print |
97 | ar_archive->accept = control_tar_llist; |
98 | llist_add_to(&(tar_archive->accept), (char*)"./control"); |
99 | tar_archive->filter = filter_accept_list; |
100 | tar_archive->action_data = data_extract_to_stdout; |
101 | if (extract_dir) |
102 | bb_show_usage(); |
103 | } |
104 | if (opt & DPKG_DEB_OPT_CONTROL) { // -e |
105 | ar_archive->accept = control_tar_llist; |
106 | tar_archive->action_data = data_extract_all; |
107 | if (!extract_dir) |
108 | extract_dir = "./DEBIAN"; |
109 | } |
110 | if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { // -Xx |
111 | if (opt & DPKG_DEB_OPT_EXTRACT_VERBOSE) |
112 | tar_archive->action_header = header_list; |
113 | tar_archive->action_data = data_extract_all; |
114 | if (!extract_dir) |
115 | bb_show_usage(); |
116 | } |
117 | |
118 | /* Standard tool supports "-" */ |
119 | tar_archive->src_fd = ar_archive->src_fd = xopen_stdin(argv[0]); |
120 | |
121 | if (extract_dir) { |
122 | mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */ |
123 | xchdir(extract_dir); |
124 | } |
125 | |
126 | /* Do it */ |
127 | unpack_ar_archive(ar_archive); |
128 | |
129 | /* Cleanup */ |
130 | if (ENABLE_FEATURE_CLEAN_UP) |
131 | close(ar_archive->src_fd); |
132 | |
133 | return EXIT_SUCCESS; |
134 | } |
135 |