summaryrefslogtreecommitdiff
path: root/archival/dpkg_deb.c (plain)
blob: ebbc7f035482bebe736ac8cd8542a301bd394a69
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 y
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
46int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
47int 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