chiark / gitweb /
awful debugging hacking
[dpkg] / dpkg-deb / main.c
1 /*
2  * dpkg-deb - construction and deconstruction of *.deb archives
3  * main.c - main program
4  *
5  * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6  * Copyright © 2006-2014 Guillem Jover <guillem@debian.org>
7  *
8  * This is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <compat.h>
24
25 #include <sys/types.h>
26 #include <sys/wait.h>
27
28 #include <limits.h>
29 #if HAVE_LOCALE_H
30 #include <locale.h>
31 #endif
32 #include <errno.h>
33 #include <string.h>
34 #include <dirent.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38
39 #include <dpkg/macros.h>
40 #include <dpkg/i18n.h>
41 #include <dpkg/dpkg.h>
42 #include <dpkg/dpkg-db.h>
43 #include <dpkg/compress.h>
44 #include <dpkg/options.h>
45
46 #include "dpkg-deb.h"
47
48 const char *showformat = "${Package}\t${Version}\n";
49
50 static void DPKG_ATTR_NORET
51 printversion(const struct cmdinfo *cip, const char *value)
52 {
53   printf(_("Debian '%s' package archive backend version %s.\n"),
54          BACKEND, PACKAGE_RELEASE);
55   printf(_(
56 "This is free software; see the GNU General Public License version 2 or\n"
57 "later for copying conditions. There is NO warranty.\n"));
58
59   m_output(stdout, _("<standard output>"));
60
61   exit(0);
62 }
63
64 static void DPKG_ATTR_NORET
65 usage(const struct cmdinfo *cip, const char *value)
66 {
67   printf(_(
68 "Usage: %s [<option> ...] <command>\n"
69 "\n"), BACKEND);
70
71   printf(_(
72 "Commands:\n"
73 "  -b|--build <directory> [<deb>]   Build an archive.\n"
74 "  -c|--contents <deb>              List contents.\n"
75 "  -I|--info <deb> [<cfile> ...]    Show info to stdout.\n"
76 "  -W|--show <deb>                  Show information on package(s)\n"
77 "  -f|--field <deb> [<cfield> ...]  Show field(s) to stdout.\n"
78 "  -e|--control <deb> [<directory>] Extract control info.\n"
79 "  -x|--extract <deb> <directory>   Extract files.\n"
80 "  -X|--vextract <deb> <directory>  Extract & list files.\n"
81 "  -R|--raw-extract <deb> <directory>\n"
82 "                                   Extract control info and files.\n"
83 "  --ctrl-tarfile <deb>             Output control tarfile.\n"
84 "  --fsys-tarfile <deb>             Output filesystem tarfile.\n"
85 "\n"));
86
87   printf(_(
88 "  -?, --help                       Show this help message.\n"
89 "      --version                    Show the version.\n"
90 "\n"));
91
92   printf(_(
93 "<deb> is the filename of a Debian format archive.\n"
94 "<cfile> is the name of an administrative file component.\n"
95 "<cfield> is the name of a field in the main 'control' file.\n"
96 "\n"));
97
98   printf(_(
99 "Options:\n"
100 "  -v, --verbose                    Enable verbose output.\n"
101 "  -D, --debug                      Enable debugging output.\n"
102 "      --showformat=<format>        Use alternative format for --show.\n"
103 "      --deb-format=<format>        Select archive format.\n"
104 "                                     Allowed values: 0.939000, 2.0 (default).\n"
105 "      --nocheck                    Suppress control file check (build bad\n"
106 "                                     packages).\n"
107 "      --uniform-compression        Use the compression params on all members.\n"
108 "  -z#                              Set the compression level when building.\n"
109 "  -Z<type>                         Set the compression type used when building.\n"
110 "                                     Allowed types: gzip, xz, none.\n"
111 "  -S<strategy>                     Set the compression strategy when building.\n"
112 "                                     Allowed values: none; extreme (xz);\n"
113 "                                     filtered, huffman, rle, fixed (gzip).\n"
114 "\n"));
115
116   printf(_(
117 "Format syntax:\n"
118 "  A format is a string that will be output for each package. The format\n"
119 "  can include the standard escape sequences \\n (newline), \\r (carriage\n"
120 "  return) or \\\\ (plain backslash). Package information can be included\n"
121 "  by inserting variable references to package fields using the ${var[;width]}\n"
122 "  syntax. Fields will be right-aligned unless the width is negative in which\n"
123 "  case left alignment will be used.\n"));
124
125   printf(_(
126 "\n"
127 "Use 'dpkg' to install and remove packages from your system, or\n"
128 "'apt' or 'aptitude' for user-friendly package management. Packages\n"
129 "unpacked using 'dpkg-deb --extract' will be incorrectly installed !\n"));
130
131   m_output(stdout, _("<standard output>"));
132
133   exit(0);
134 }
135
136 static const char printforhelp[] =
137   N_("Type dpkg-deb --help for help about manipulating *.deb files;\n"
138      "Type dpkg --help for help about installing and deinstalling packages.");
139
140 int debugflag = 0;
141 int nocheckflag = 0;
142 int opt_verbose = 0;
143 int opt_uniform_compression = 0;
144
145 struct deb_version deb_format = DEB_VERSION(2, 0);
146
147 static void
148 set_deb_format(const struct cmdinfo *cip, const char *value)
149 {
150   const char *err;
151
152   err = deb_version_parse(&deb_format, value);
153   if (err)
154     badusage(_("invalid deb format version: %s"), err);
155
156   if ((deb_format.major == 2 && deb_format.minor == 0) ||
157       (deb_format.major == 0 && deb_format.minor == 939000))
158     return;
159   else
160     badusage(_("unknown deb format version: %s"), value);
161 }
162
163 struct compress_params compress_params = {
164   .type = DPKG_DEB_DEFAULT_COMPRESSOR,
165   .strategy = COMPRESSOR_STRATEGY_NONE,
166   .level = -1,
167 };
168
169 static void
170 set_compress_level(const struct cmdinfo *cip, const char *value)
171 {
172   long level;
173
174   level = dpkg_options_parse_arg_int(cip, value);
175   if (level < 0 || level > 9)
176     badusage(_("invalid compression level for -%c: %ld"), cip->oshort, level);
177
178   compress_params.level = level;
179 }
180
181 static void
182 set_compress_strategy(const struct cmdinfo *cip, const char *value)
183 {
184   compress_params.strategy = compressor_get_strategy(value);
185   if (compress_params.strategy == COMPRESSOR_STRATEGY_UNKNOWN)
186     badusage(_("unknown compression strategy '%s'!"), value);
187 }
188
189 static void
190 set_compress_type(const struct cmdinfo *cip, const char *value)
191 {
192   compress_params.type = compressor_find_by_name(value);
193   if (compress_params.type == COMPRESSOR_TYPE_UNKNOWN)
194     badusage(_("unknown compression type '%s'!"), value);
195   if (compress_params.type == COMPRESSOR_TYPE_LZMA)
196     badusage(_("obsolete compression type '%s'; use xz instead"), value);
197   if (compress_params.type == COMPRESSOR_TYPE_BZIP2)
198     badusage(_("obsolete compression type '%s'; use xz or gzip instead"), value);
199 }
200
201 static const struct cmdinfo cmdinfos[]= {
202   ACTION("build",         'b', 0, do_build),
203   ACTION("contents",      'c', 0, do_contents),
204   ACTION("control",       'e', 0, do_control),
205   ACTION("info",          'I', 0, do_info),
206   ACTION("field",         'f', 0, do_field),
207   ACTION("extract",       'x', 0, do_extract),
208   ACTION("vextract",      'X', 0, do_vextract),
209   ACTION("raw-extract",   'R', 0, do_raw_extract),
210   ACTION("ctrl-tarfile",  0,   0, do_ctrltarfile),
211   ACTION("fsys-tarfile",  0,   0, do_fsystarfile),
212   ACTION("show",          'W', 0, do_showinfo),
213
214   { "deb-format",    0,   1, NULL,           NULL,         set_deb_format   },
215   { "debug",         'D', 0, &debugflag,     NULL,         NULL,          1 },
216   { "verbose",       'v', 0, &opt_verbose,   NULL,         NULL,          1 },
217   { "nocheck",       0,   0, &nocheckflag,   NULL,         NULL,          1 },
218   { "uniform-compression", 0, 0, &opt_uniform_compression, NULL, NULL,    1 },
219   { NULL,            'z', 1, NULL,           NULL,         set_compress_level },
220   { NULL,            'Z', 1, NULL,           NULL,         set_compress_type  },
221   { NULL,            'S', 1, NULL,           NULL,         set_compress_strategy },
222   { "showformat",    0,   1, NULL,           &showformat,  NULL             },
223   { "help",          '?', 0, NULL,           NULL,         usage            },
224   { "version",       0,   0, NULL,           NULL,         printversion     },
225   {  NULL,           0,   0, NULL,           NULL,         NULL             }
226 };
227
228 int main(int argc, const char *const *argv) {
229   struct dpkg_error err;
230   int ret;
231
232   dpkg_locales_init(PACKAGE);
233   dpkg_program_init(BACKEND);
234   dpkg_options_parse(&argv, cmdinfos, printforhelp);
235
236   if (!cipaction) badusage(_("need an action option"));
237
238   if (!compressor_check_params(&compress_params, &err))
239     badusage(_("invalid compressor parameters: %s"), err.str);
240
241   if (opt_uniform_compression &&
242       (compress_params.type != COMPRESSOR_TYPE_NONE &&
243        compress_params.type != COMPRESSOR_TYPE_GZIP &&
244        compress_params.type != COMPRESSOR_TYPE_XZ))
245     badusage(_("unsupported compression type '%s' with uniform compression"),
246              compressor_get_name(compress_params.type));
247
248   ret = cipaction->action(argv);
249
250   dpkg_program_done();
251
252   return ret;
253 }