po: Update German man pages translation
[dpkg.git] / src / deb / extract.c
blob08b2815640b04be016720628a71eb272a3d77782
1 /*
2 * dpkg-deb - construction and deconstruction of *.deb archives
3 * extract.c - extracting archives
5 * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2006-2014 Guillem Jover <guillem@debian.org>
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.
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.
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/>.
22 #include <config.h>
23 #include <compat.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/wait.h>
29 #include <errno.h>
30 #include <limits.h>
31 #include <string.h>
32 #include <dirent.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdbool.h>
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <stdio.h>
40 #include <dpkg/i18n.h>
41 #include <dpkg/dpkg.h>
42 #include <dpkg/fdio.h>
43 #include <dpkg/buffer.h>
44 #include <dpkg/subproc.h>
45 #include <dpkg/command.h>
46 #include <dpkg/compress.h>
47 #include <dpkg/ar.h>
48 #include <dpkg/deb-version.h>
49 #include <dpkg/options.h>
51 #include "dpkg-deb.h"
53 static void
54 movecontrolfiles(const char *dir, const char *thing)
56 char *cmd;
57 pid_t pid;
59 cmd = str_fmt("mv %s/%s/* %s/ && rmdir %s/%s", dir, thing, dir, dir, thing);
60 pid = subproc_fork();
61 if (pid == 0) {
62 command_shell(cmd, _("shell command to move files"));
64 subproc_reap(pid, _("shell command to move files"), 0);
65 free(cmd);
68 static void DPKG_ATTR_NORET
69 read_fail(int rc, const char *filename, const char *what)
71 if (rc >= 0)
72 ohshit(_("unexpected end of file in %s in %.255s"),what,filename);
73 else
74 ohshite(_("error reading %s from file %.255s"), what, filename);
77 static ssize_t
78 read_line(int fd, char *buf, size_t min_size, size_t max_size)
80 ssize_t line_size = 0;
81 size_t n = min_size;
83 while (line_size < (ssize_t)max_size) {
84 ssize_t nread;
85 char *nl;
87 nread = fd_read(fd, buf + line_size, n);
88 if (nread <= 0)
89 return nread;
91 nl = memchr(buf + line_size, '\n', nread);
92 line_size += nread;
94 if (nl != NULL) {
95 nl[1] = '\0';
96 return line_size;
99 n = 1;
102 buf[line_size] = '\0';
103 return line_size;
106 void
107 extracthalf(const char *debar, const char *dir,
108 enum dpkg_tar_options taroption, int admininfo)
110 struct dpkg_error err;
111 const char *errstr;
112 struct dpkg_ar *ar;
113 char versionbuf[40];
114 struct deb_version version;
115 off_t ctrllennum, memberlen = 0;
116 ssize_t rc;
117 int dummy;
118 pid_t c1=0,c2,c3;
119 int p1[2], p2[2];
120 int p2_out;
121 char nlc;
122 struct compress_params decompress_params = {
123 .type = COMPRESSOR_TYPE_GZIP,
124 .threads_max = compress_params.threads_max,
127 ar = dpkg_ar_open(debar);
129 rc = read_line(ar->fd, versionbuf, strlen(DPKG_AR_MAGIC), sizeof(versionbuf) - 1);
130 if (rc <= 0)
131 read_fail(rc, debar, _("archive magic version number"));
133 if (strcmp(versionbuf, DPKG_AR_MAGIC) == 0) {
134 int adminmember = -1;
135 bool header_done = false;
137 ctrllennum= 0;
138 for (;;) {
139 struct dpkg_ar_hdr arh;
141 rc = fd_read(ar->fd, &arh, sizeof(arh));
142 if (rc != sizeof(arh))
143 read_fail(rc, debar, _("archive member header"));
145 if (dpkg_ar_member_is_illegal(&arh))
146 ohshit(_("file '%.250s' is corrupt - bad archive header magic"), debar);
148 dpkg_ar_normalize_name(&arh);
150 memberlen = dpkg_ar_member_get_size(ar, &arh);
151 if (!header_done) {
152 char *infobuf;
154 if (strncmp(arh.ar_name, DEBMAGIC, sizeof(arh.ar_name)) != 0)
155 ohshit(_("file '%.250s' is not a Debian binary archive (try dpkg-split?)"),
156 debar);
157 infobuf= m_malloc(memberlen+1);
158 rc = fd_read(ar->fd, infobuf, memberlen + (memberlen & 1));
159 if (rc != (memberlen + (memberlen & 1)))
160 read_fail(rc, debar, _("archive information header member"));
161 infobuf[memberlen] = '\0';
163 if (strchr(infobuf, '\n') == NULL)
164 ohshit(_("archive has no newlines in header"));
165 errstr = deb_version_parse(&version, infobuf);
166 if (errstr)
167 ohshit(_("archive has invalid format version: %s"), errstr);
168 if (version.major != 2)
169 ohshit(_("archive is format version %d.%d; get a newer dpkg-deb"),
170 version.major, version.minor);
172 free(infobuf);
174 header_done = true;
175 } else if (arh.ar_name[0] == '_') {
176 /* Members with ‘_’ are noncritical, and if we don't understand
177 * them we skip them. */
178 if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
179 ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
180 } else {
181 if (strncmp(arh.ar_name, ADMINMEMBER, strlen(ADMINMEMBER)) == 0) {
182 const char *extension = arh.ar_name + strlen(ADMINMEMBER);
184 adminmember = 1;
185 decompress_params.type = compressor_find_by_extension(extension);
186 if (decompress_params.type != COMPRESSOR_TYPE_NONE &&
187 decompress_params.type != COMPRESSOR_TYPE_GZIP &&
188 decompress_params.type != COMPRESSOR_TYPE_ZSTD &&
189 decompress_params.type != COMPRESSOR_TYPE_XZ)
190 ohshit(_("archive '%s' uses unknown compression for member '%.*s', "
191 "giving up"),
192 debar, (int)sizeof(arh.ar_name), arh.ar_name);
194 if (ctrllennum != 0)
195 ohshit(_("archive '%.250s' contains two control members, giving up"),
196 debar);
197 ctrllennum = memberlen;
198 } else {
199 if (adminmember != 1)
200 ohshit(_("archive '%s' has premature member '%.*s' before '%s', "
201 "giving up"),
202 debar, (int)sizeof(arh.ar_name), arh.ar_name, ADMINMEMBER);
204 if (strncmp(arh.ar_name, DATAMEMBER, strlen(DATAMEMBER)) == 0) {
205 const char *extension = arh.ar_name + strlen(DATAMEMBER);
207 adminmember= 0;
208 decompress_params.type = compressor_find_by_extension(extension);
209 if (decompress_params.type == COMPRESSOR_TYPE_UNKNOWN)
210 ohshit(_("archive '%s' uses unknown compression for member '%.*s', "
211 "giving up"),
212 debar, (int)sizeof(arh.ar_name), arh.ar_name);
213 } else {
214 ohshit(_("archive '%s' has premature member '%.*s' before '%s', "
215 "giving up"),
216 debar, (int)sizeof(arh.ar_name), arh.ar_name, DATAMEMBER);
219 if (!adminmember != !admininfo) {
220 if (fd_skip(ar->fd, memberlen + (memberlen & 1), &err) < 0)
221 ohshit(_("cannot skip archive member from '%s': %s"), ar->name, err.str);
222 } else {
223 /* Yes! - found it. */
224 break;
229 if (admininfo >= 2) {
230 printf(_(" new Debian package, version %d.%d.\n"
231 " size %jd bytes: control archive=%jd bytes.\n"),
232 version.major, version.minor,
233 (intmax_t)ar->size, (intmax_t)ctrllennum);
234 m_output(stdout, _("<standard output>"));
236 } else if (strncmp(versionbuf, "0.93", 4) == 0) {
237 char ctrllenbuf[40];
238 int l;
240 l = strlen(versionbuf);
242 if (strchr(versionbuf, '\n') == NULL)
243 ohshit(_("archive has no newlines in header"));
244 errstr = deb_version_parse(&version, versionbuf);
245 if (errstr)
246 ohshit(_("archive has invalid format version: %s"), errstr);
248 rc = read_line(ar->fd, ctrllenbuf, 1, sizeof(ctrllenbuf) - 1);
249 if (rc <= 0)
250 read_fail(rc, debar, _("archive control member size"));
251 if (sscanf(ctrllenbuf, "%jd%c%d", (intmax_t *)&ctrllennum, &nlc, &dummy) != 2 ||
252 nlc != '\n')
253 ohshit(_("archive has malformed control member size '%s'"), ctrllenbuf);
255 if (admininfo) {
256 memberlen = ctrllennum;
257 } else {
258 memberlen = ar->size - ctrllennum - strlen(ctrllenbuf) - l;
259 if (fd_skip(ar->fd, ctrllennum, &err) < 0)
260 ohshit(_("cannot skip archive control member from '%s': %s"), ar->name,
261 err.str);
264 if (admininfo >= 2) {
265 printf(_(" old Debian package, version %d.%d.\n"
266 " size %jd bytes: control archive=%jd, main archive=%jd.\n"),
267 version.major, version.minor,
268 (intmax_t)ar->size, (intmax_t)ctrllennum,
269 (intmax_t)(ar->size - ctrllennum - strlen(ctrllenbuf) - l));
270 m_output(stdout, _("<standard output>"));
272 } else {
273 if (strncmp(versionbuf, "!<arch>", 7) == 0) {
274 notice(_("file looks like it might be an archive which has been\n"
275 " corrupted by being downloaded in ASCII mode"));
278 ohshit(_("'%.255s' is not a Debian format archive"), debar);
281 m_pipe(p1);
282 c1 = subproc_fork();
283 if (!c1) {
284 close(p1[0]);
285 if (fd_fd_copy(ar->fd, p1[1], memberlen, &err) < 0)
286 ohshit(_("cannot copy archive member from '%s' to decompressor pipe: %s"),
287 ar->name, err.str);
288 if (close(p1[1]))
289 ohshite(_("cannot close decompressor pipe"));
290 exit(0);
292 close(p1[1]);
294 if (taroption) {
295 m_pipe(p2);
296 p2_out = p2[1];
297 } else {
298 p2_out = 1;
301 c2 = subproc_fork();
302 if (!c2) {
303 if (taroption)
304 close(p2[0]);
305 decompress_filter(&decompress_params, p1[0], p2_out,
306 _("decompressing archive '%s' (size=%jd) member '%s'"),
307 ar->name, (intmax_t)ar->size,
308 admininfo ? ADMINMEMBER : DATAMEMBER);
309 dpkg_ar_close(ar);
310 exit(0);
312 close(p1[0]);
313 dpkg_ar_close(ar);
315 if (taroption) {
316 close(p2[1]);
318 c3 = subproc_fork();
319 if (!c3) {
320 struct command cmd;
322 command_init(&cmd, TAR, "tar");
323 command_add_arg(&cmd, "tar");
325 if ((taroption & DPKG_TAR_LIST) && (taroption & DPKG_TAR_EXTRACT))
326 command_add_arg(&cmd, "-xv");
327 else if (taroption & DPKG_TAR_EXTRACT)
328 command_add_arg(&cmd, "-x");
329 else if (taroption & DPKG_TAR_LIST)
330 command_add_arg(&cmd, "-tv");
331 else
332 internerr("unknown or missing tar action '%d'", taroption);
334 if (taroption & DPKG_TAR_PERMS)
335 command_add_arg(&cmd, "-p");
336 if (taroption & DPKG_TAR_NOMTIME)
337 command_add_arg(&cmd, "-m");
339 command_add_arg(&cmd, "-f");
340 command_add_arg(&cmd, "-");
341 command_add_arg(&cmd, "--warning=no-timestamp");
343 m_dup2(p2[0],0);
344 close(p2[0]);
346 unsetenv("TAR_OPTIONS");
348 if (dir) {
349 if (mkdir(dir, 0777) != 0) {
350 if (errno != EEXIST)
351 ohshite(_("failed to create directory"));
353 if (taroption & DPKG_TAR_CREATE_DIR)
354 ohshite(_("unexpected pre-existing pathname %s"), dir);
356 if (chdir(dir) != 0)
357 ohshite(_("failed to chdir to directory"));
360 command_exec(&cmd);
362 close(p2[0]);
363 subproc_reap(c3, "tar", 0);
366 subproc_reap(c2, _("<decompress>"), SUBPROC_NOPIPE);
367 if (c1 >= 0)
368 subproc_reap(c1, _("paste"), 0);
369 if (version.major == 0 && admininfo) {
370 /* Handle the version as a float to preserve the behavior of old code,
371 * because even if the format is defined to be padded by 0's that might
372 * not have been always true for really ancient versions... */
373 while (version.minor && (version.minor % 10) == 0)
374 version.minor /= 10;
376 if (version.minor == 931)
377 movecontrolfiles(dir, OLDOLDDEBDIR);
378 else if (version.minor == 932 || version.minor == 933)
379 movecontrolfiles(dir, OLDDEBDIR);
384 do_ctrltarfile(const char *const *argv)
386 const char *debar;
388 debar = *argv++;
389 if (debar == NULL)
390 badusage(_("--%s needs a .deb filename argument"), cipaction->olong);
391 if (*argv)
392 badusage(_("--%s takes only one argument (.deb filename)"),
393 cipaction->olong);
395 extracthalf(debar, NULL, DPKG_TAR_PASSTHROUGH, 1);
397 return 0;
401 do_fsystarfile(const char *const *argv)
403 const char *debar;
405 debar = *argv++;
406 if (debar == NULL)
407 badusage(_("--%s needs a .deb filename argument"),cipaction->olong);
408 if (*argv)
409 badusage(_("--%s takes only one argument (.deb filename)"),cipaction->olong);
410 extracthalf(debar, NULL, DPKG_TAR_PASSTHROUGH, 0);
412 return 0;
416 do_control(const char *const *argv)
418 const char *debar, *dir;
420 debar = *argv++;
421 if (debar == NULL)
422 badusage(_("--%s needs a .deb filename argument"), cipaction->olong);
424 dir = *argv++;
425 if (dir == NULL)
426 dir = EXTRACTCONTROLDIR;
427 else if (*argv)
428 badusage(_("--%s takes at most two arguments (.deb and directory)"),
429 cipaction->olong);
431 extracthalf(debar, dir, DPKG_TAR_EXTRACT, 1);
433 return 0;
437 do_extract(const char *const *argv)
439 const char *debar, *dir;
440 enum dpkg_tar_options options = DPKG_TAR_EXTRACT | DPKG_TAR_PERMS;
442 if (opt_verbose)
443 options |= DPKG_TAR_LIST;
445 debar = *argv++;
446 if (debar == NULL)
447 badusage(_("--%s needs .deb filename and directory arguments"),
448 cipaction->olong);
450 dir = *argv++;
451 if (dir == NULL)
452 badusage(_("--%s needs a target directory.\n"
453 "Perhaps you should be using dpkg --install ?"),
454 cipaction->olong);
455 else if (*argv)
456 badusage(_("--%s takes at most two arguments (.deb and directory)"),
457 cipaction->olong);
459 extracthalf(debar, dir, options, 0);
461 return 0;
465 do_vextract(const char *const *argv)
467 /* XXX: Backward compatibility. */
468 opt_verbose = 1;
469 return do_extract(argv);
473 do_raw_extract(const char *const *argv)
475 enum dpkg_tar_options data_options;
476 const char *debar, *dir;
477 char *control_dir;
479 debar = *argv++;
480 if (debar == NULL)
481 badusage(_("--%s needs .deb filename and directory arguments"),
482 cipaction->olong);
483 else if (strcmp(debar, "-") == 0)
484 badusage(_("--%s does not support (yet) reading the .deb from standard input"),
485 cipaction->olong);
487 dir = *argv++;
488 if (dir == NULL)
489 badusage(_("--%s needs a target directory.\n"
490 "Perhaps you should be using dpkg --install ?"),
491 cipaction->olong);
492 else if (*argv)
493 badusage(_("--%s takes at most two arguments (.deb and directory)"),
494 cipaction->olong);
496 control_dir = str_fmt("%s/%s", dir, EXTRACTCONTROLDIR);
498 data_options = DPKG_TAR_EXTRACT | DPKG_TAR_PERMS;
499 if (opt_verbose)
500 data_options |= DPKG_TAR_LIST;
502 extracthalf(debar, dir, data_options, 0);
503 extracthalf(debar, control_dir, DPKG_TAR_EXTRACT | DPKG_TAR_CREATE_DIR, 1);
505 free(control_dir);
507 return 0;