main.c 30 KB

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