chiark / gitweb /
lib/dpkg/tarfn.c: Kludge `tar_header_decode' to handle spurious `errno'.
[dpkg] / src / main.c
1 /*
2  * dpkg - main program for package management
3  * main.c - main program
4  *
5  * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6  * Copyright © 2006-2016 Guillem Jover <guillem@debian.org>
7  * Copyright © 2010 Canonical Ltd.
8  *   written by Martin Pitt <martin.pitt@canonical.com>
9  *
10  * This is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
22  */
23
24 #include <config.h>
25 #include <compat.h>
26
27 #include <sys/types.h>
28 #include <sys/wait.h>
29
30 #include <errno.h>
31 #include <limits.h>
32 #if HAVE_LOCALE_H
33 #include <locale.h>
34 #endif
35 #include <string.h>
36 #include <fcntl.h>
37 #include <dirent.h>
38 #include <unistd.h>
39 #include <stdbool.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42
43 #include <dpkg/macros.h>
44 #include <dpkg/i18n.h>
45 #include <dpkg/c-ctype.h>
46 #include <dpkg/dpkg.h>
47 #include <dpkg/dpkg-db.h>
48 #include <dpkg/arch.h>
49 #include <dpkg/path.h>
50 #include <dpkg/subproc.h>
51 #include <dpkg/command.h>
52 #include <dpkg/options.h>
53
54 #include "main.h"
55 #include "filesdb.h"
56 #include "filters.h"
57
58 static void DPKG_ATTR_NORET
59 printversion(const struct cmdinfo *ci, const char *value)
60 {
61   printf(_("Debian '%s' package management program version %s.\n"),
62          DPKG, PACKAGE_RELEASE);
63   printf(_(
64 "This is free software; see the GNU General Public License version 2 or\n"
65 "later for copying conditions. There is NO warranty.\n"));
66
67   m_output(stdout, _("<standard output>"));
68
69   exit(0);
70 }
71
72 /*
73  * FIXME: Options that need fixing:
74  * dpkg --command-fd
75  */
76
77 static void DPKG_ATTR_NORET
78 usage(const struct cmdinfo *ci, const char *value)
79 {
80   printf(_(
81 "Usage: %s [<option> ...] <command>\n"
82 "\n"), DPKG);
83
84   printf(_(
85 "Commands:\n"
86 "  -i|--install       <.deb file name> ... | -R|--recursive <directory> ...\n"
87 "  --unpack           <.deb file name> ... | -R|--recursive <directory> ...\n"
88 "  -A|--record-avail  <.deb file name> ... | -R|--recursive <directory> ...\n"
89 "  --configure        <package> ... | -a|--pending\n"
90 "  --triggers-only    <package> ... | -a|--pending\n"
91 "  -r|--remove        <package> ... | -a|--pending\n"
92 "  -P|--purge         <package> ... | -a|--pending\n"
93 "  -V|--verify <package> ...        Verify the integrity of package(s).\n"
94 "  --get-selections [<pattern> ...] Get list of selections to stdout.\n"
95 "  --set-selections                 Set package selections from stdin.\n"
96 "  --clear-selections               Deselect every non-essential package.\n"
97 "  --update-avail [<Packages-file>] Replace available packages info.\n"
98 "  --merge-avail [<Packages-file>]  Merge with info from file.\n"
99 "  --clear-avail                    Erase existing available info.\n"
100 "  --forget-old-unavail             Forget uninstalled unavailable pkgs.\n"
101 "  -s|--status <package> ...        Display package status details.\n"
102 "  -p|--print-avail <package> ...   Display available version details.\n"
103 "  -L|--listfiles <package> ...     List files 'owned' by package(s).\n"
104 "  -l|--list [<pattern> ...]        List packages concisely.\n"
105 "  -S|--search <pattern> ...        Find package(s) owning file(s).\n"
106 "  -C|--audit [<package> ...]       Check for broken package(s).\n"
107 "  --yet-to-unpack                  Print packages selected for installation.\n"
108 "  --predep-package                 Print pre-dependencies to unpack.\n"
109 "  --add-architecture <arch>        Add <arch> to the list of architectures.\n"
110 "  --remove-architecture <arch>     Remove <arch> from the list of architectures.\n"
111 "  --print-architecture             Print dpkg architecture.\n"
112 "  --print-foreign-architectures    Print allowed foreign architectures.\n"
113 "  --assert-<feature>               Assert support for the specified feature.\n"
114 "  --validate-<thing> <string>      Validate a <thing>'s <string>.\n"
115 "  --compare-versions <a> <op> <b>  Compare version numbers - see below.\n"
116 "  --force-help                     Show help on forcing.\n"
117 "  -Dh|--debug=help                 Show help on debugging.\n"
118 "\n"));
119
120   printf(_(
121 "  -?, --help                       Show this help message.\n"
122 "      --version                    Show the version.\n"
123 "\n"));
124
125   printf(_(
126 "Assertable features: support-predepends, working-epoch, long-filenames,\n"
127 "  multi-conrep, multi-arch, versioned-provides.\n"
128 "\n"));
129
130   printf(_(
131 "Validatable things: pkgname, archname, trigname, version.\n"
132 "\n"));
133
134   printf(_(
135 "Use dpkg with -b, --build, -c, --contents, -e, --control, -I, --info,\n"
136 "  -f, --field, -x, --extract, -X, --vextract, --ctrl-tarfile, --fsys-tarfile\n"
137 "on archives (type %s --help).\n"
138 "\n"), BACKEND);
139
140   printf(_(
141 "Options:\n"
142 "  --admindir=<directory>     Use <directory> instead of %s.\n"
143 "  --root=<directory>         Install on a different root directory.\n"
144 "  --instdir=<directory>      Change installation dir without changing admin dir.\n"
145 "  --path-exclude=<pattern>   Do not install paths which match a shell pattern.\n"
146 "  --path-include=<pattern>   Re-include a pattern after a previous exclusion.\n"
147 "  -O|--selected-only         Skip packages not selected for install/upgrade.\n"
148 "  -E|--skip-same-version     Skip packages whose same version is installed.\n"
149 "  -G|--refuse-downgrade      Skip packages with earlier version than installed.\n"
150 "  -B|--auto-deconfigure      Install even if it would break some other package.\n"
151 "  --[no-]triggers            Skip or force consequential trigger processing.\n"
152 "  --verify-format=<format>   Verify output format (supported: 'rpm').\n"
153 "  --no-debsig                Do not try to verify package signatures.\n"
154 "  --no-act|--dry-run|--simulate\n"
155 "                             Just say what we would do - don't do it.\n"
156 "  -D|--debug=<octal>         Enable debugging (see -Dhelp or --debug=help).\n"
157 "  --status-fd <n>            Send status change updates to file descriptor <n>.\n"
158 "  --status-logger=<command>  Send status change updates to <command>'s stdin.\n"
159 "  --log=<filename>           Log status changes and actions to <filename>.\n"
160 "  --ignore-depends=<package>,...\n"
161 "                             Ignore dependencies involving <package>.\n"
162 "  --force-...                Override problems (see --force-help).\n"
163 "  --no-force-...|--refuse-...\n"
164 "                             Stop when problems encountered.\n"
165 "  --abort-after <n>          Abort after encountering <n> errors.\n"
166 "\n"), ADMINDIR);
167
168   printf(_(
169 "Comparison operators for --compare-versions are:\n"
170 "  lt le eq ne ge gt       (treat empty version as earlier than any version);\n"
171 "  lt-nl le-nl ge-nl gt-nl (treat empty version as later than any version);\n"
172 "  < << <= = >= >> >       (only for compatibility with control file syntax).\n"
173 "\n"));
174
175   printf(_(
176 "Use 'apt' or 'aptitude' for user-friendly package management.\n"));
177
178   m_output(stdout, _("<standard output>"));
179
180   exit(0);
181 }
182
183 static const char printforhelp[] = N_(
184 "Type dpkg --help for help about installing and deinstalling packages [*];\n"
185 "Use 'apt' or 'aptitude' for user-friendly package management;\n"
186 "Type dpkg -Dhelp for a list of dpkg debug flag values;\n"
187 "Type dpkg --force-help for a list of forcing options;\n"
188 "Type dpkg-deb --help for help about manipulating *.deb files;\n"
189 "\n"
190 "Options marked [*] produce a lot of output - pipe it through 'less' or 'more' !");
191
192 int f_pending=0, f_recursive=0, f_alsoselect=1, f_skipsame=0, f_noact=0;
193 int f_autodeconf=0, f_nodebsig=0;
194 int f_triggers = 0;
195 int fc_downgrade=1, fc_configureany=0, fc_hold=0, fc_removereinstreq=0, fc_overwrite=0;
196 int fc_removeessential=0, fc_conflicts=0, fc_depends=0, fc_dependsversion=0;
197 int fc_breaks=0, fc_badpath=0, fc_overwritediverted=0, fc_architecture=0;
198 int fc_nonroot=0, fc_overwritedir=0, fc_conff_new=0, fc_conff_miss=0;
199 int fc_conff_old=0, fc_conff_def=0;
200 int fc_conff_ask = 0;
201 int fc_unsafe_io = 0;
202 int fc_badverify = 0;
203 int fc_badversion = 0;
204 int fc_script_chrootless = 0;
205
206 int errabort = 50;
207 static const char *admindir = ADMINDIR;
208 const char *instdir= "";
209 struct pkg_list *ignoredependss = NULL;
210
211 static const char *
212 forcetype_str(char type)
213 {
214   switch (type) {
215   case '\0':
216   case ' ':
217     return "   ";
218   case '*':
219     return "[*]";
220   case '!':
221     return "[!]";
222   default:
223     internerr("unknown force type '%c'", type);
224   }
225 }
226
227 static const struct forceinfo {
228   const char *name;
229   int *opt;
230   char type;
231   const char *desc;
232 } forceinfos[]= {
233   { "all",                 NULL,
234     '!', N_("Set all force options")},
235   { "downgrade",           &fc_downgrade,
236     '*', N_("Replace a package with a lower version") },
237   { "configure-any",       &fc_configureany,
238     ' ', N_("Configure any package which may help this one") },
239   { "hold",                &fc_hold,
240     ' ', N_("Process incidental packages even when on hold") },
241   { "not-root",            &fc_nonroot,
242     ' ', N_("Try to (de)install things even when not root") },
243   { "bad-path",            &fc_badpath,
244     ' ', N_("PATH is missing important programs, problems likely") },
245   { "bad-verify",          &fc_badverify,
246     ' ', N_("Install a package even if it fails authenticity check") },
247   { "bad-version",         &fc_badversion,
248     ' ', N_("Process even packages with wrong versions") },
249   { "overwrite",           &fc_overwrite,
250     ' ', N_("Overwrite a file from one package with another") },
251   { "overwrite-diverted",  &fc_overwritediverted,
252     ' ', N_("Overwrite a diverted file with an undiverted version") },
253   { "overwrite-dir",       &fc_overwritedir,
254     '!', N_("Overwrite one package's directory with another's file") },
255   { "unsafe-io",           &fc_unsafe_io,
256     '!', N_("Do not perform safe I/O operations when unpacking") },
257   { "script-chrootless",   &fc_script_chrootless,
258     '!', N_("Do not chroot into maintainer script environment") },
259   { "confnew",             &fc_conff_new,
260     '!', N_("Always use the new config files, don't prompt") },
261   { "confold",             &fc_conff_old,
262     '!', N_("Always use the old config files, don't prompt") },
263   { "confdef",             &fc_conff_def,
264     '!', N_("Use the default option for new config files if one\n"
265             "is available, don't prompt. If no default can be found,\n"
266             "you will be prompted unless one of the confold or\n"
267             "confnew options is also given") },
268   { "confmiss",            &fc_conff_miss,
269     '!', N_("Always install missing config files") },
270   { "confask",             &fc_conff_ask,
271     '!', N_("Offer to replace config files with no new versions") },
272   { "architecture",        &fc_architecture,
273     '!', N_("Process even packages with wrong or no architecture") },
274   { "breaks",              &fc_breaks,
275     '!', N_("Install even if it would break another package") },
276   { "conflicts",           &fc_conflicts,
277     '!', N_("Allow installation of conflicting packages") },
278   { "depends",             &fc_depends,
279     '!', N_("Turn all dependency problems into warnings") },
280   { "depends-version",     &fc_dependsversion,
281     '!', N_("Turn dependency version problems into warnings") },
282   { "remove-reinstreq",    &fc_removereinstreq,
283     '!', N_("Remove packages which require installation") },
284   { "remove-essential",    &fc_removeessential,
285     '!', N_("Remove an essential package") },
286   { NULL }
287 };
288
289 #define DBG_DEF(n, d) \
290   { .flag = dbg_##n, .name = #n, .desc = d }
291
292 static const struct debuginfo {
293   int flag;
294   const char *name;
295   const char *desc;
296 } debuginfos[] = {
297   DBG_DEF(general,         N_("Generally helpful progress information")),
298   DBG_DEF(scripts,         N_("Invocation and status of maintainer scripts")),
299   DBG_DEF(eachfile,        N_("Output for each file processed")),
300   DBG_DEF(eachfiledetail,  N_("Lots of output for each file processed")),
301   DBG_DEF(conff,           N_("Output for each configuration file")),
302   DBG_DEF(conffdetail,     N_("Lots of output for each configuration file")),
303   DBG_DEF(depcon,          N_("Dependencies and conflicts")),
304   DBG_DEF(depcondetail,    N_("Lots of dependencies/conflicts output")),
305   DBG_DEF(triggers,        N_("Trigger activation and processing")),
306   DBG_DEF(triggersdetail,  N_("Lots of output regarding triggers")),
307   DBG_DEF(triggersstupid,  N_("Silly amounts of output regarding triggers")),
308   DBG_DEF(veryverbose,     N_("Lots of drivel about eg the dpkg/info directory")),
309   DBG_DEF(stupidlyverbose, N_("Insane amounts of drivel")),
310   { 0, NULL, NULL }
311 };
312
313 static void
314 set_debug(const struct cmdinfo *cpi, const char *value)
315 {
316   char *endp;
317   long mask;
318   const struct debuginfo *dip;
319
320   if (*value == 'h') {
321     printf(_(
322 "%s debugging option, --debug=<octal> or -D<octal>:\n"
323 "\n"
324 " Number  Ref. in source   Description\n"), DPKG);
325
326     for (dip = debuginfos; dip->name; dip++)
327       printf(" %6o  %-16s %s\n", dip->flag, dip->name, gettext(dip->desc));
328
329     printf(_("\n"
330 "Debugging options can be mixed using bitwise-or.\n"
331 "Note that the meanings and values are subject to change.\n"));
332     m_output(stdout, _("<standard output>"));
333     exit(0);
334   }
335
336   errno = 0;
337   mask = strtol(value, &endp, 8);
338   if (value == endp || *endp || mask < 0 || errno == ERANGE)
339     badusage(_("--%s requires a positive octal argument"), cpi->olong);
340
341   debug_set_mask(mask);
342 }
343
344 static void
345 set_filter(const struct cmdinfo *cip, const char *value)
346 {
347   filter_add(value, cip->arg_int);
348 }
349
350 static void
351 set_verify_format(const struct cmdinfo *cip, const char *value)
352 {
353   if (!verify_set_output(value))
354     badusage(_("unknown verify output format '%s'"), value);
355 }
356
357 static void
358 set_instdir(const struct cmdinfo *cip, const char *value)
359 {
360   char *new_instdir;
361
362   new_instdir = m_strdup(value);
363   path_trim_slash_slashdot(new_instdir);
364
365   instdir = new_instdir;
366 }
367
368 static void
369 set_root(const struct cmdinfo *cip, const char *value)
370 {
371   set_instdir(cip, value);
372   admindir = str_fmt("%s%s", instdir, ADMINDIR);
373 }
374
375 static void
376 set_ignore_depends(const struct cmdinfo *cip, const char *value)
377 {
378   char *copy, *p;
379
380   copy= m_malloc(strlen(value)+2);
381   strcpy(copy,value);
382   copy[strlen(value) + 1] = '\0';
383   for (p=copy; *p; p++) {
384     if (*p != ',') continue;
385     *p++ = '\0';
386     if (!*p || *p==',' || p==copy+1)
387       badusage(_("null package name in --%s comma-separated list '%.250s'"),
388                cip->olong, value);
389   }
390   p= copy;
391   while (*p) {
392     struct pkginfo *pkg;
393
394     pkg = dpkg_options_parse_pkgname(cip, p);
395     pkg_list_prepend(&ignoredependss, pkg);
396
397     p+= strlen(p)+1;
398   }
399
400   free(copy);
401 }
402
403 static void
404 set_integer(const struct cmdinfo *cip, const char *value)
405 {
406   *cip->iassignto = dpkg_options_parse_arg_int(cip, value);
407 }
408
409 static void
410 set_pipe(const struct cmdinfo *cip, const char *value)
411 {
412   long v;
413
414   v = dpkg_options_parse_arg_int(cip, value);
415
416   statusfd_add(v);
417 }
418
419 static bool
420 is_invoke_action(enum action action)
421 {
422   switch (action) {
423   case act_unpack:
424   case act_configure:
425   case act_install:
426   case act_triggers:
427   case act_remove:
428   case act_purge:
429   case act_arch_add:
430   case act_arch_remove:
431     return true;
432   default:
433     return false;
434   }
435 }
436
437 struct invoke_list pre_invoke_hooks = { .head = NULL, .tail = &pre_invoke_hooks.head };
438 struct invoke_list post_invoke_hooks = { .head = NULL, .tail = &post_invoke_hooks.head };
439 struct invoke_list status_loggers = { .head = NULL, .tail = &status_loggers.head };
440
441 static void
442 set_invoke_hook(const struct cmdinfo *cip, const char *value)
443 {
444   struct invoke_list *hook_list = cip->arg_ptr;
445   struct invoke_hook *hook_new;
446
447   hook_new = m_malloc(sizeof(struct invoke_hook));
448   hook_new->command = m_strdup(value);
449   hook_new->next = NULL;
450
451   /* Add the new hook at the tail of the list to preserve the order. */
452   *hook_list->tail = hook_new;
453   hook_list->tail = &hook_new->next;
454 }
455
456 static void
457 run_invoke_hooks(const char *action, struct invoke_list *hook_list)
458 {
459   struct invoke_hook *hook;
460
461   setenv("DPKG_HOOK_ACTION", action, 1);
462
463   for (hook = hook_list->head; hook; hook = hook->next) {
464     int status;
465
466     /* XXX: As an optimization, use exec instead if no shell metachar are
467      * used “!$=&|\\`'"^~;<>{}[]()?*#”. */
468     status = system(hook->command);
469     if (status != 0)
470       ohshit(_("error executing hook '%s', exit code %d"), hook->command,
471              status);
472   }
473
474   unsetenv("DPKG_HOOK_ACTION");
475 }
476
477 static void
478 free_invoke_hooks(struct invoke_list *hook_list)
479 {
480   struct invoke_hook *hook, *hook_next;
481
482   for (hook = hook_list->head; hook; hook = hook_next) {
483     hook_next = hook->next;
484     free(hook->command);
485     free(hook);
486   }
487 }
488
489 static int
490 run_logger(struct invoke_hook *hook, const char *name)
491 {
492   pid_t pid;
493   int p[2];
494
495   m_pipe(p);
496
497   pid = subproc_fork();
498   if (pid == 0) {
499     /* Setup stdin and stdout. */
500     m_dup2(p[0], 0);
501     close(1);
502
503     close(p[0]);
504     close(p[1]);
505
506     command_shell(hook->command, name);
507   }
508   close(p[0]);
509
510   return p[1];
511 }
512
513 static void
514 run_status_loggers(struct invoke_list *hook_list)
515 {
516   struct invoke_hook *hook;
517
518   for (hook = hook_list->head; hook; hook = hook->next) {
519     int fd;
520
521     fd = run_logger(hook, _("status logger"));
522     statusfd_add(fd);
523   }
524 }
525
526 static int
527 arch_add(const char *const *argv)
528 {
529   struct dpkg_arch *arch;
530   const char *archname = *argv++;
531
532   if (archname == NULL || *argv)
533     badusage(_("--%s takes exactly one argument"), cipaction->olong);
534
535   dpkg_arch_load_list();
536
537   arch = dpkg_arch_add(archname);
538   switch (arch->type) {
539   case DPKG_ARCH_NATIVE:
540   case DPKG_ARCH_FOREIGN:
541     break;
542   case DPKG_ARCH_ILLEGAL:
543     ohshit(_("architecture '%s' is illegal: %s"), archname,
544            dpkg_arch_name_is_illegal(archname));
545   default:
546     ohshit(_("architecture '%s' is reserved and cannot be added"), archname);
547   }
548
549   dpkg_arch_save_list();
550
551   return 0;
552 }
553
554 static int
555 arch_remove(const char *const *argv)
556 {
557   const char *archname = *argv++;
558   struct dpkg_arch *arch;
559   struct pkgiterator *iter;
560   struct pkginfo *pkg;
561
562   if (archname == NULL || *argv)
563     badusage(_("--%s takes exactly one argument"), cipaction->olong);
564
565   modstatdb_open(msdbrw_readonly);
566
567   arch = dpkg_arch_find(archname);
568   if (arch->type != DPKG_ARCH_FOREIGN) {
569     warning(_("cannot remove non-foreign architecture '%s'"), arch->name);
570     return 0;
571   }
572
573   /* Check if it's safe to remove the architecture from the db. */
574   iter = pkg_db_iter_new();
575   while ((pkg = pkg_db_iter_next_pkg(iter))) {
576     if (pkg->status < PKG_STAT_HALFINSTALLED)
577       continue;
578     if (pkg->installed.arch == arch) {
579       if (fc_architecture)
580         warning(_("removing architecture '%s' currently in use by database"),
581                 arch->name);
582       else
583         ohshit(_("cannot remove architecture '%s' currently in use by the database"),
584                arch->name);
585       break;
586     }
587   }
588   pkg_db_iter_free(iter);
589
590   dpkg_arch_unmark(arch);
591   dpkg_arch_save_list();
592
593   modstatdb_shutdown();
594
595   return 0;
596 }
597
598 static inline void
599 print_forceinfo_line(int type, const char *name, const char *desc)
600 {
601   printf("  %s %-18s %s\n", forcetype_str(type), name, desc);
602 }
603
604 static void
605 print_forceinfo(const struct forceinfo *fi)
606 {
607   char *desc, *line;
608
609   desc = m_strdup(gettext(fi->desc));
610
611   line = strtok(desc, "\n");
612   print_forceinfo_line(fi->type, fi->name, line);
613   while ((line = strtok(NULL, "\n")))
614     print_forceinfo_line(' ', "", line);
615
616   free(desc);
617 }
618
619 static void
620 set_force(const struct cmdinfo *cip, const char *value)
621 {
622   const char *comma;
623   size_t l;
624   const struct forceinfo *fip;
625
626   if (strcmp(value, "help") == 0) {
627     printf(_(
628 "%s forcing options - control behaviour when problems found:\n"
629 "  warn but continue:  --force-<thing>,<thing>,...\n"
630 "  stop with error:    --refuse-<thing>,<thing>,... | --no-force-<thing>,...\n"
631 " Forcing things:\n"), DPKG);
632
633     for (fip = forceinfos; fip->name; fip++)
634       print_forceinfo(fip);
635
636     printf(_(
637 "\n"
638 "WARNING - use of options marked [!] can seriously damage your installation.\n"
639 "Forcing options marked [*] are enabled by default.\n"));
640     m_output(stdout, _("<standard output>"));
641     exit(0);
642   }
643
644   for (;;) {
645     comma= strchr(value,',');
646     l = comma ? (size_t)(comma - value) : strlen(value);
647     for (fip=forceinfos; fip->name; fip++)
648       if (strncmp(fip->name, value, l) == 0 && strlen(fip->name) == l)
649         break;
650
651     if (!fip->name) {
652       badusage(_("unknown force/refuse option '%.*s'"),
653                (int)min(l, 250), value);
654     } else if (strcmp(fip->name, "all") == 0) {
655       for (fip = forceinfos; fip->name; fip++)
656         if (fip->opt)
657           *fip->opt = cip->arg_int;
658     } else if (fip->opt) {
659       *fip->opt = cip->arg_int;
660     } else {
661       warning(_("obsolete force/refuse option '%s'"), fip->name);
662     }
663
664     if (!comma) break;
665     value= ++comma;
666   }
667 }
668
669 int execbackend(const char *const *argv) DPKG_ATTR_NORET;
670 int commandfd(const char *const *argv);
671
672 /* This table has both the action entries in it and the normal options.
673  * The action entries are made with the ACTION macro, as they all
674  * have a very similar structure. */
675 static const struct cmdinfo cmdinfos[]= {
676 #define ACTIONBACKEND(longopt, shortopt, backend) \
677  { longopt, shortopt, 0, NULL, NULL, setaction, 0, (void *)backend, execbackend }
678
679   ACTION( "install",                        'i', act_install,              archivefiles    ),
680   ACTION( "unpack",                          0,  act_unpack,               archivefiles    ),
681   ACTION( "record-avail",                   'A', act_avail,                archivefiles    ),
682   ACTION( "configure",                       0,  act_configure,            packages        ),
683   ACTION( "remove",                         'r', act_remove,               packages        ),
684   ACTION( "purge",                          'P', act_purge,                packages        ),
685   ACTION( "triggers-only",                   0,  act_triggers,             packages        ),
686   ACTION( "verify",                         'V', act_verify,               verify          ),
687   ACTIONBACKEND( "listfiles",               'L', DPKGQUERY),
688   ACTIONBACKEND( "status",                  's', DPKGQUERY),
689   ACTION( "get-selections",                  0,  act_getselections,        getselections   ),
690   ACTION( "set-selections",                  0,  act_setselections,        setselections   ),
691   ACTION( "clear-selections",                0,  act_clearselections,      clearselections ),
692   ACTIONBACKEND( "print-avail",             'p', DPKGQUERY),
693   ACTION( "update-avail",                    0,  act_avreplace,            updateavailable ),
694   ACTION( "merge-avail",                     0,  act_avmerge,              updateavailable ),
695   ACTION( "clear-avail",                     0,  act_avclear,              updateavailable ),
696   ACTION( "forget-old-unavail",              0,  act_forgetold,            forgetold       ),
697   ACTION( "audit",                          'C', act_audit,                audit           ),
698   ACTION( "yet-to-unpack",                   0,  act_unpackchk,            unpackchk       ),
699   ACTIONBACKEND( "list",                    'l', DPKGQUERY),
700   ACTIONBACKEND( "search",                  'S', DPKGQUERY),
701   ACTION( "assert-support-predepends",       0,  act_assertpredep,         assertpredep    ),
702   ACTION( "assert-working-epoch",            0,  act_assertepoch,          assertepoch     ),
703   ACTION( "assert-long-filenames",           0,  act_assertlongfilenames,  assertlongfilenames ),
704   ACTION( "assert-multi-conrep",             0,  act_assertmulticonrep,    assertmulticonrep ),
705   ACTION( "assert-multi-arch",               0,  act_assertmultiarch,      assertmultiarch ),
706   ACTION( "assert-versioned-provides",       0,  act_assertverprovides,    assertverprovides ),
707   ACTION( "add-architecture",                0,  act_arch_add,             arch_add        ),
708   ACTION( "remove-architecture",             0,  act_arch_remove,          arch_remove     ),
709   ACTION( "print-architecture",              0,  act_printarch,            printarch   ),
710   ACTION( "print-foreign-architectures",     0,  act_printforeignarches,   print_foreign_arches ),
711   ACTION( "predep-package",                  0,  act_predeppackage,        predeppackage   ),
712   ACTION( "validate-pkgname",                0,  act_validate_pkgname,     validate_pkgname ),
713   ACTION( "validate-trigname",               0,  act_validate_trigname,    validate_trigname ),
714   ACTION( "validate-archname",               0,  act_validate_archname,    validate_archname ),
715   ACTION( "validate-version",                0,  act_validate_version,     validate_version ),
716   ACTION( "compare-versions",                0,  act_cmpversions,          cmpversions     ),
717 /*
718   ACTION( "command-fd",                   'c', act_commandfd,   commandfd     ),
719 */
720
721   { "pre-invoke",        0,   1, NULL,          NULL,      set_invoke_hook, 0, &pre_invoke_hooks },
722   { "post-invoke",       0,   1, NULL,          NULL,      set_invoke_hook, 0, &post_invoke_hooks },
723   { "path-exclude",      0,   1, NULL,          NULL,      set_filter,     0 },
724   { "path-include",      0,   1, NULL,          NULL,      set_filter,     1 },
725   { "verify-format",     0,   1, NULL,          NULL,      set_verify_format },
726   { "status-logger",     0,   1, NULL,          NULL,      set_invoke_hook, 0, &status_loggers },
727   { "status-fd",         0,   1, NULL,          NULL,      set_pipe, 0 },
728   { "log",               0,   1, NULL,          &log_file, NULL,    0 },
729   { "pending",           'a', 0, &f_pending,    NULL,      NULL,    1 },
730   { "recursive",         'R', 0, &f_recursive,  NULL,      NULL,    1 },
731   { "no-act",            0,   0, &f_noact,      NULL,      NULL,    1 },
732   { "dry-run",           0,   0, &f_noact,      NULL,      NULL,    1 },
733   { "simulate",          0,   0, &f_noact,      NULL,      NULL,    1 },
734   { "no-debsig",         0,   0, &f_nodebsig,   NULL,      NULL,    1 },
735   /* Alias ('G') for --refuse. */
736   {  NULL,               'G', 0, &fc_downgrade, NULL,      NULL,    0 },
737   { "selected-only",     'O', 0, &f_alsoselect, NULL,      NULL,    0 },
738   { "triggers",           0,  0, &f_triggers,   NULL,      NULL,    1 },
739   { "no-triggers",        0,  0, &f_triggers,   NULL,      NULL,   -1 },
740   /* FIXME: Remove ('N') sometime. */
741   { "no-also-select",    'N', 0, &f_alsoselect, NULL,      NULL,    0 },
742   { "skip-same-version", 'E', 0, &f_skipsame,   NULL,      NULL,    1 },
743   { "auto-deconfigure",  'B', 0, &f_autodeconf, NULL,      NULL,    1 },
744   { "root",              0,   1, NULL,          NULL,      set_root,      0 },
745   { "abort-after",       0,   1, &errabort,     NULL,      set_integer,   0 },
746   { "admindir",          0,   1, NULL,          &admindir, NULL,          0 },
747   { "instdir",           0,   1, NULL,          NULL,      set_instdir,   0 },
748   { "ignore-depends",    0,   1, NULL,          NULL,      set_ignore_depends, 0 },
749   { "force",             0,   2, NULL,          NULL,      set_force,     1 },
750   { "refuse",            0,   2, NULL,          NULL,      set_force,     0 },
751   { "no-force",          0,   2, NULL,          NULL,      set_force,     0 },
752   { "debug",             'D', 1, NULL,          NULL,      set_debug,     0 },
753   { "help",              '?', 0, NULL,          NULL,      usage,         0 },
754   { "version",           0,   0, NULL,          NULL,      printversion,  0 },
755   ACTIONBACKEND( "build",               'b', BACKEND),
756   ACTIONBACKEND( "contents",            'c', BACKEND),
757   ACTIONBACKEND( "control",             'e', BACKEND),
758   ACTIONBACKEND( "info",                'I', BACKEND),
759   ACTIONBACKEND( "field",               'f', BACKEND),
760   ACTIONBACKEND( "extract",             'x', BACKEND),
761   ACTIONBACKEND( "vextract",            'X', BACKEND),
762   ACTIONBACKEND( "ctrl-tarfile",        0,   BACKEND),
763   ACTIONBACKEND( "fsys-tarfile",        0,   BACKEND),
764   { NULL,                0,   0, NULL,          NULL,      NULL,          0 }
765 };
766
767 int
768 execbackend(const char *const *argv)
769 {
770   struct command cmd;
771
772   command_init(&cmd, cipaction->arg_ptr, NULL);
773   command_add_arg(&cmd, cipaction->arg_ptr);
774   command_add_arg(&cmd, str_fmt("--%s", cipaction->olong));
775
776   /* Explicitly separate arguments from options as any user-supplied
777    * separator got stripped by the option parser */
778   command_add_arg(&cmd, "--");
779   command_add_argl(&cmd, (const char **)argv);
780
781   command_exec(&cmd);
782 }
783
784 int
785 commandfd(const char *const *argv)
786 {
787   struct varbuf linevb = VARBUF_INIT;
788   const char * pipein;
789   const char **newargs = NULL, **endargs;
790   char *ptr, *endptr;
791   FILE *in;
792   long infd;
793   int ret = 0;
794   int c, lno, i;
795   bool skipchar;
796
797   pipein = *argv++;
798   if (pipein == NULL || *argv)
799     badusage(_("--%s takes exactly one argument"), cipaction->olong);
800
801   infd = dpkg_options_parse_arg_int(cipaction, pipein);
802   in = fdopen(infd, "r");
803   if (in == NULL)
804     ohshite(_("couldn't open '%i' for stream"), (int)infd);
805
806   for (;;) {
807     bool mode = false;
808     int argc= 1;
809     lno= 0;
810
811     push_error_context();
812
813     do {
814       c = getc(in);
815       if (c == '\n')
816         lno++;
817     } while (c != EOF && c_isspace(c));
818     if (c == EOF) break;
819     if (c == '#') {
820       do { c= getc(in); if (c == '\n') lno++; } while (c != EOF && c != '\n');
821       continue;
822     }
823     varbuf_reset(&linevb);
824     do {
825       varbuf_add_char(&linevb, c);
826       c= getc(in);
827       if (c == '\n') lno++;
828
829       /* This isn't fully accurate, but overestimating can't hurt. */
830       if (c_isspace(c))
831         argc++;
832     } while (c != EOF && c != '\n');
833     if (c == EOF)
834       ohshit(_("unexpected end of file before end of line %d"), lno);
835     if (!argc) continue;
836     varbuf_end_str(&linevb);
837     newargs = m_realloc(newargs, sizeof(const char *) * (argc + 1));
838     argc= 1;
839     ptr= linevb.buf;
840     endptr = ptr + linevb.used + 1;
841     skipchar = false;
842     while(ptr < endptr) {
843       if (skipchar) {
844         skipchar = false;
845       } else if (*ptr == '\\') {
846         memmove(ptr, (ptr+1), (linevb.used-(linevb.buf - ptr)-1));
847         endptr--;
848         skipchar = true;
849         continue;
850       } else if (c_isspace(*ptr)) {
851         if (mode == true) {
852           *ptr = '\0';
853           mode = false;
854         }
855       } else {
856         if (mode == false) {
857           newargs[argc]= ptr;
858           argc++;
859           mode = true;
860         }
861       }
862       ptr++;
863     }
864     *ptr = '\0';
865     newargs[argc++] = NULL;
866
867     /* We strdup() each argument, but never free it, because the
868      * error messages contain references back to these strings.
869      * Freeing them, and reusing the memory, would make those
870      * error messages confusing, to say the least. */
871     for(i=1;i<argc;i++)
872       if (newargs[i])
873         newargs[i] = m_strdup(newargs[i]);
874     endargs = newargs;
875
876     setaction(NULL, NULL);
877     dpkg_options_parse((const char *const **)&endargs, cmdinfos, printforhelp);
878     if (!cipaction) badusage(_("need an action option"));
879
880     filesdbinit();
881
882     ret |= cipaction->action(endargs);
883
884     files_db_reset();
885
886     pop_error_context(ehflag_normaltidy);
887   }
888
889   return ret;
890 }
891
892 int main(int argc, const char *const *argv) {
893   int ret;
894
895   dpkg_locales_init(PACKAGE);
896   dpkg_program_init("dpkg");
897   dpkg_options_load(DPKG, cmdinfos);
898   dpkg_options_parse(&argv, cmdinfos, printforhelp);
899
900   /* When running as root, make sure our primary group is also root, so
901    * that files created by maintainer scripts have correct ownership. */
902   if (!fc_nonroot && getuid() == 0)
903     if (setgid(0) < 0)
904       ohshite(_("cannot set primary group ID to root"));
905
906   if (!cipaction) badusage(_("need an action option"));
907
908   admindir = dpkg_db_set_dir(admindir);
909
910   /* Always set environment, to avoid possible security risks. */
911   if (setenv("DPKG_ADMINDIR", admindir, 1) < 0)
912     ohshite(_("unable to setenv for subprocesses"));
913   if (setenv("DPKG_ROOT", instdir, 1) < 0)
914     ohshite(_("unable to setenv for subprocesses"));
915
916   if (!f_triggers)
917     f_triggers = (cipaction->arg_int == act_triggers && *argv) ? -1 : 1;
918
919   if (is_invoke_action(cipaction->arg_int)) {
920     run_invoke_hooks(cipaction->olong, &pre_invoke_hooks);
921     run_status_loggers(&status_loggers);
922   }
923
924   filesdbinit();
925
926   ret = cipaction->action(argv);
927
928   if (is_invoke_action(cipaction->arg_int))
929     run_invoke_hooks(cipaction->olong, &post_invoke_hooks);
930
931   free_invoke_hooks(&pre_invoke_hooks);
932   free_invoke_hooks(&post_invoke_hooks);
933
934   dpkg_program_done();
935
936   return reportbroken_retexitstatus(ret);
937 }