Cut-n-paste strikes again
[oweals/busybox.git] / archival / dpkg_deb.c
1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU Library General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  *
16  */
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <getopt.h>
22
23 #include "unarchive.h"
24 #include "busybox.h"
25
26 #define DPKG_DEB_OPT_CONTENTS   1
27 #define DPKG_DEB_OPT_CONTROL    2
28 #define DPKG_DEB_OPT_FIELD      4
29 #define DPKG_DEB_OPT_EXTRACT    8
30 #define DPKG_DEB_OPT_EXTRACT_VERBOSE    16
31
32 extern int dpkg_deb_main(int argc, char **argv)
33 {
34         archive_handle_t *ar_archive;
35         archive_handle_t *tar_archive;
36         llist_t *control_tar_llist = NULL;
37         unsigned long opt;
38         char *extract_dir = NULL;
39         short argcount = 1;
40
41         /* Setup the tar archive handle */
42         tar_archive = init_handle();
43
44         /* Setup an ar archive handle that refers to the gzip sub archive */
45         ar_archive = init_handle();
46         ar_archive->sub_archive = tar_archive;
47         ar_archive->filter = filter_accept_list_reassign;
48
49 #ifdef CONFIG_FEATURE_DEB_TAR_GZ
50         ar_archive->accept = llist_add_to(NULL, "data.tar.gz");
51         control_tar_llist = llist_add_to(NULL, "control.tar.gz");
52 #endif
53
54 #ifdef CONFIG_FEATURE_DEB_TAR_BZ2
55         ar_archive->accept = llist_add_to(ar_archive->accept, "data.tar.bz2");
56         control_tar_llist = llist_add_to(control_tar_llist, "control.tar.bz2");
57 #endif
58
59         bb_opt_complementaly = "c~efXx:e~cfXx:f~ceXx:X~cefx:x~cefX";
60         opt = bb_getopt_ulflags(argc, argv, "cefXx");
61
62         if (opt & DPKG_DEB_OPT_CONTENTS) {
63                 tar_archive->action_header = header_verbose_list;
64         }
65         if (opt & DPKG_DEB_OPT_CONTROL) {
66                 ar_archive->accept = control_tar_llist;
67                 tar_archive->action_data = data_extract_all;
68                 if (optind + 1 == argc) {
69                         extract_dir = "./DEBIAN";
70                 } else {
71                         argcount++;
72                 }
73         }
74         if (opt & DPKG_DEB_OPT_FIELD) {
75                 /* Print the entire control file
76                  * it should accept a second argument which specifies a
77                  * specific field to print */
78                 ar_archive->accept = control_tar_llist;
79                 tar_archive->accept = llist_add_to(NULL, "./control");;
80                 tar_archive->filter = filter_accept_list;
81                 tar_archive->action_data = data_extract_to_stdout;
82         }
83         if (opt & DPKG_DEB_OPT_EXTRACT) {
84                 tar_archive->action_header = header_list;
85         }
86         if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) {
87                 tar_archive->action_data = data_extract_all;
88                 argcount = 2;
89         }
90
91         if ((optind + argcount != argc) || (opt & 0x80000000UL)) {
92                 bb_show_usage();
93         }
94
95         tar_archive->src_fd = ar_archive->src_fd = bb_xopen(argv[optind++], O_RDONLY);
96
97         /* Workout where to extract the files */
98         /* 2nd argument is a dir name */
99         if (argv[optind]) {
100                 extract_dir = argv[optind];
101         }
102         if (extract_dir) {
103                 mkdir(extract_dir, 0777);
104                 chdir(extract_dir);
105         }
106         unpack_ar_archive(ar_archive);
107
108         /* Cleanup */
109         close (ar_archive->src_fd);
110
111         return(EXIT_SUCCESS);
112 }