enquiry.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. * dpkg - main program for package management
  3. * enquiry.c - status enquiry and listing options
  4. *
  5. * Copyright © 1995,1996 Ian Jackson <ian@chiark.greenend.org.uk>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /* FIXME: per-package audit. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <sys/types.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/stat.h>
  26. #include <sys/termios.h>
  27. #include <assert.h>
  28. #include <string.h>
  29. #include <fcntl.h>
  30. #include <unistd.h>
  31. #include <stdbool.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <dpkg/i18n.h>
  35. #include <dpkg/dpkg.h>
  36. #include <dpkg/dpkg-db.h>
  37. #include <dpkg/arch.h>
  38. #include <dpkg/pkg-show.h>
  39. #include <dpkg/options.h>
  40. #include "filesdb.h"
  41. #include "main.h"
  42. struct badstatinfo {
  43. bool (*yesno)(struct pkginfo *, const struct badstatinfo *bsi);
  44. int value;
  45. const char *explanation;
  46. };
  47. static bool
  48. bsyn_reinstreq(struct pkginfo *pkg, const struct badstatinfo *bsi)
  49. {
  50. return pkg->eflag &= eflag_reinstreq;
  51. }
  52. static bool
  53. bsyn_status(struct pkginfo *pkg, const struct badstatinfo *bsi)
  54. {
  55. if (pkg->eflag &= eflag_reinstreq)
  56. return false;
  57. return (int)pkg->status == bsi->value;
  58. }
  59. static const struct badstatinfo badstatinfos[]= {
  60. {
  61. .yesno = bsyn_reinstreq,
  62. .value = 0,
  63. .explanation = N_(
  64. "The following packages are in a mess due to serious problems during\n"
  65. "installation. They must be reinstalled for them (and any packages\n"
  66. "that depend on them) to function properly:\n")
  67. }, {
  68. .yesno = bsyn_status,
  69. .value = stat_unpacked,
  70. .explanation = N_(
  71. "The following packages have been unpacked but not yet configured.\n"
  72. "They must be configured using dpkg --configure or the configure\n"
  73. "menu option in dselect for them to work:\n")
  74. }, {
  75. .yesno = bsyn_status,
  76. .value = stat_halfconfigured,
  77. .explanation = N_(
  78. "The following packages are only half configured, probably due to problems\n"
  79. "configuring them the first time. The configuration should be retried using\n"
  80. "dpkg --configure <package> or the configure menu option in dselect:\n")
  81. }, {
  82. .yesno = bsyn_status,
  83. .value = stat_halfinstalled,
  84. .explanation = N_(
  85. "The following packages are only half installed, due to problems during\n"
  86. "installation. The installation can probably be completed by retrying it;\n"
  87. "the packages can be removed using dselect or dpkg --remove:\n")
  88. }, {
  89. .yesno = bsyn_status,
  90. .value = stat_triggersawaited,
  91. .explanation = N_(
  92. "The following packages are awaiting processing of triggers that they\n"
  93. "have activated in other packages. This processing can be requested using\n"
  94. "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
  95. }, {
  96. .yesno = bsyn_status,
  97. .value = stat_triggerspending,
  98. .explanation = N_(
  99. "The following packages have been triggered, but the trigger processing\n"
  100. "has not yet been done. Trigger processing can be requested using\n"
  101. "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
  102. }, {
  103. .yesno = NULL
  104. }
  105. };
  106. static void describebriefly(struct pkginfo *pkg) {
  107. int maxl, l;
  108. const char *pdesc;
  109. maxl= 57;
  110. l= strlen(pkg->set->name);
  111. if (l>20) maxl -= (l-20);
  112. pdesc = pkg_summary(pkg, &l);
  113. l = min(l, maxl);
  114. printf(" %-20s %.*s\n", pkg->set->name, l, pdesc);
  115. }
  116. int
  117. audit(const char *const *argv)
  118. {
  119. const struct badstatinfo *bsi;
  120. bool head_running = false;
  121. if (*argv)
  122. badusage(_("--%s takes no arguments"), cipaction->olong);
  123. modstatdb_open(msdbrw_readonly);
  124. for (bsi= badstatinfos; bsi->yesno; bsi++) {
  125. struct pkgiterator *it;
  126. struct pkginfo *pkg;
  127. bool head = false;
  128. it = pkg_db_iter_new();
  129. while ((pkg = pkg_db_iter_next_pkg(it))) {
  130. if (!bsi->yesno(pkg,bsi)) continue;
  131. if (!head_running) {
  132. if (modstatdb_is_locked())
  133. puts(_(
  134. "Another process has locked the database for writing, and might currently be\n"
  135. "modifying it, some of the following problems might just be due to that.\n"));
  136. head_running = true;
  137. }
  138. if (!head) {
  139. fputs(gettext(bsi->explanation),stdout);
  140. head = true;
  141. }
  142. describebriefly(pkg);
  143. }
  144. pkg_db_iter_free(it);
  145. if (head) putchar('\n');
  146. }
  147. m_output(stdout, _("<standard output>"));
  148. return 0;
  149. }
  150. struct sectionentry {
  151. struct sectionentry *next;
  152. const char *name;
  153. int count;
  154. };
  155. static bool
  156. yettobeunpacked(struct pkginfo *pkg, const char **thissect)
  157. {
  158. if (pkg->want != want_install)
  159. return false;
  160. switch (pkg->status) {
  161. case stat_unpacked: case stat_installed: case stat_halfconfigured:
  162. case stat_triggerspending:
  163. case stat_triggersawaited:
  164. return false;
  165. case stat_notinstalled: case stat_halfinstalled: case stat_configfiles:
  166. if (thissect)
  167. *thissect = pkg->section && *pkg->section ? pkg->section :
  168. C_("section", "<unknown>");
  169. return true;
  170. default:
  171. internerr("unknown package status '%d'", pkg->status);
  172. }
  173. return false;
  174. }
  175. int
  176. unpackchk(const char *const *argv)
  177. {
  178. int totalcount, sects;
  179. struct sectionentry *sectionentries, *se, **sep;
  180. struct pkgiterator *it;
  181. struct pkginfo *pkg;
  182. const char *thissect;
  183. char buf[20];
  184. int width;
  185. if (*argv)
  186. badusage(_("--%s takes no arguments"), cipaction->olong);
  187. modstatdb_open(msdbrw_readonly);
  188. totalcount= 0;
  189. sectionentries = NULL;
  190. sects= 0;
  191. it = pkg_db_iter_new();
  192. while ((pkg = pkg_db_iter_next_pkg(it))) {
  193. if (!yettobeunpacked(pkg, &thissect)) continue;
  194. for (se= sectionentries; se && strcasecmp(thissect,se->name); se= se->next);
  195. if (!se) {
  196. se= nfmalloc(sizeof(struct sectionentry));
  197. for (sep= &sectionentries;
  198. *sep && strcasecmp(thissect,(*sep)->name) > 0;
  199. sep= &(*sep)->next);
  200. se->name= thissect;
  201. se->count= 0;
  202. se->next= *sep;
  203. *sep= se;
  204. sects++;
  205. }
  206. se->count++; totalcount++;
  207. }
  208. pkg_db_iter_free(it);
  209. if (totalcount == 0)
  210. return 0;
  211. if (totalcount <= 12) {
  212. it = pkg_db_iter_new();
  213. while ((pkg = pkg_db_iter_next_pkg(it))) {
  214. if (!yettobeunpacked(pkg, NULL))
  215. continue;
  216. describebriefly(pkg);
  217. }
  218. pkg_db_iter_free(it);
  219. } else if (sects <= 12) {
  220. for (se= sectionentries; se; se= se->next) {
  221. sprintf(buf,"%d",se->count);
  222. printf(_(" %d in %s: "),se->count,se->name);
  223. width= 70-strlen(se->name)-strlen(buf);
  224. while (width > 59) { putchar(' '); width--; }
  225. it = pkg_db_iter_new();
  226. while ((pkg = pkg_db_iter_next_pkg(it))) {
  227. if (!yettobeunpacked(pkg,&thissect)) continue;
  228. if (strcasecmp(thissect,se->name)) continue;
  229. width -= strlen(pkg->set->name);
  230. width--;
  231. if (width < 4) { printf(" ..."); break; }
  232. printf(" %s", pkg->set->name);
  233. }
  234. pkg_db_iter_free(it);
  235. putchar('\n');
  236. }
  237. } else {
  238. printf(P_(" %d package, from the following section:",
  239. " %d packages, from the following sections:", totalcount),
  240. totalcount);
  241. width= 0;
  242. for (se= sectionentries; se; se= se->next) {
  243. sprintf(buf,"%d",se->count);
  244. width -= (6 + strlen(se->name) + strlen(buf));
  245. if (width < 0) { putchar('\n'); width= 73 - strlen(se->name) - strlen(buf); }
  246. printf(" %s (%d)",se->name,se->count);
  247. }
  248. putchar('\n');
  249. }
  250. m_output(stdout, _("<standard output>"));
  251. return 0;
  252. }
  253. static int
  254. assert_version_support(const char *const *argv,
  255. struct versionrevision *version,
  256. const char *feature_name)
  257. {
  258. struct pkginfo *pkg;
  259. if (*argv)
  260. badusage(_("--%s takes no arguments"), cipaction->olong);
  261. modstatdb_open(msdbrw_readonly);
  262. pkg = pkg_db_find_pkg("dpkg", NULL);
  263. switch (pkg->status) {
  264. case stat_installed:
  265. case stat_triggerspending:
  266. return 0;
  267. case stat_unpacked: case stat_halfconfigured: case stat_halfinstalled:
  268. case stat_triggersawaited:
  269. if (versionsatisfied3(&pkg->configversion, version, dvr_laterequal))
  270. return 0;
  271. printf(_("Version of dpkg with working %s support not yet configured.\n"
  272. " Please use 'dpkg --configure dpkg', and then try again.\n"),
  273. feature_name);
  274. return 1;
  275. default:
  276. printf(_("dpkg not recorded as installed, cannot check for %s support!\n"),
  277. feature_name);
  278. return 1;
  279. }
  280. }
  281. int
  282. assertpredep(const char *const *argv)
  283. {
  284. struct versionrevision version = { 0, "1.1.0", NULL };
  285. return assert_version_support(argv, &version, _("Pre-Depends field"));
  286. }
  287. int
  288. assertepoch(const char *const *argv)
  289. {
  290. struct versionrevision version = { 0, "1.4.0.7", NULL };
  291. return assert_version_support(argv, &version, _("epoch"));
  292. }
  293. int
  294. assertlongfilenames(const char *const *argv)
  295. {
  296. struct versionrevision version = { 0, "1.4.1.17", NULL };
  297. return assert_version_support(argv, &version, _("long filenames"));
  298. }
  299. int
  300. assertmulticonrep(const char *const *argv)
  301. {
  302. struct versionrevision version = { 0, "1.4.1.19", NULL };
  303. return assert_version_support(argv, &version,
  304. _("multiple Conflicts and Replaces"));
  305. }
  306. /**
  307. * Print a single package which:
  308. * (a) is the target of one or more relevant predependencies.
  309. * (b) has itself no unsatisfied pre-dependencies.
  310. *
  311. * If such a package is present output is the Packages file entry,
  312. * which can be massaged as appropriate.
  313. *
  314. * Exit status:
  315. * 0 = a package printed, OK
  316. * 1 = no suitable package available
  317. * 2 = error
  318. */
  319. int
  320. predeppackage(const char *const *argv)
  321. {
  322. static struct varbuf vb;
  323. struct pkgiterator *it;
  324. struct pkginfo *pkg = NULL, *startpkg, *trypkg;
  325. struct dependency *dep;
  326. struct deppossi *possi, *provider;
  327. if (*argv)
  328. badusage(_("--%s takes no arguments"), cipaction->olong);
  329. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  330. /* We use clientdata->istobe to detect loops. */
  331. clear_istobes();
  332. dep = NULL;
  333. it = pkg_db_iter_new();
  334. while (!dep && (pkg = pkg_db_iter_next_pkg(it))) {
  335. /* Ignore packages user doesn't want. */
  336. if (pkg->want != want_install)
  337. continue;
  338. /* Ignore packages not available. */
  339. if (!pkg->files)
  340. continue;
  341. pkg->clientdata->istobe= itb_preinstall;
  342. for (dep= pkg->available.depends; dep; dep= dep->next) {
  343. if (dep->type != dep_predepends) continue;
  344. if (depisok(dep, &vb, NULL, NULL, true))
  345. continue;
  346. /* This will leave dep non-NULL, and so exit the loop. */
  347. break;
  348. }
  349. pkg->clientdata->istobe= itb_normal;
  350. /* If dep is NULL we go and get the next package. */
  351. }
  352. pkg_db_iter_free(it);
  353. if (!dep)
  354. return 1; /* Not found. */
  355. assert(pkg);
  356. startpkg= pkg;
  357. pkg->clientdata->istobe= itb_preinstall;
  358. /* OK, we have found an unsatisfied predependency.
  359. * Now go and find the first thing we need to install, as a first step
  360. * towards satisfying it. */
  361. do {
  362. /* We search for a package which would satisfy dep, and put it in pkg. */
  363. for (possi = dep->list, pkg = NULL;
  364. !pkg && possi;
  365. possi=possi->next) {
  366. trypkg = &possi->ed->pkg;
  367. if (trypkg->files && versionsatisfied(&trypkg->available,possi)) {
  368. if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; }
  369. }
  370. if (possi->verrel != dvr_none) continue;
  371. for (provider = possi->ed->depended.available;
  372. !pkg && provider;
  373. provider=provider->next) {
  374. if (provider->up->type != dep_provides) continue;
  375. trypkg= provider->up->up;
  376. if (!trypkg->files)
  377. continue;
  378. if (trypkg->clientdata->istobe == itb_normal) { pkg= trypkg; break; }
  379. }
  380. }
  381. if (!pkg) {
  382. varbuf_reset(&vb);
  383. describedepcon(&vb,dep);
  384. varbuf_end_str(&vb);
  385. fprintf(stderr, _("dpkg: cannot see how to satisfy pre-dependency:\n %s\n"),vb.buf);
  386. ohshit(_("cannot satisfy pre-dependencies for %.250s (wanted due to %.250s)"),
  387. dep->up->set->name, startpkg->set->name);
  388. }
  389. pkg->clientdata->istobe= itb_preinstall;
  390. for (dep= pkg->available.depends; dep; dep= dep->next) {
  391. if (dep->type != dep_predepends) continue;
  392. if (depisok(dep, &vb, NULL, NULL, true))
  393. continue;
  394. /* This will leave dep non-NULL, and so exit the loop. */
  395. break;
  396. }
  397. } while (dep);
  398. /* OK, we've found it - pkg has no unsatisfied pre-dependencies! */
  399. writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
  400. m_output(stdout, _("<standard output>"));
  401. return 0;
  402. }
  403. int
  404. printarch(const char *const *argv)
  405. {
  406. if (*argv)
  407. badusage(_("--%s takes no arguments"), cipaction->olong);
  408. printf("%s\n", dpkg_arch_get_native()->name);
  409. m_output(stdout, _("<standard output>"));
  410. return 0;
  411. }
  412. int
  413. printinstarch(const char *const *argv)
  414. {
  415. warning(_("obsolete option '--%s', please use '--%s' instead."),
  416. "print-installation-architecture", "print-architecture");
  417. return printarch(argv);
  418. }
  419. int
  420. print_foreign_arches(const char *const *argv)
  421. {
  422. struct dpkg_arch *arch;
  423. if (*argv)
  424. badusage(_("--%s takes no arguments"), cipaction->olong);
  425. for (arch = dpkg_arch_get_list(); arch; arch = arch->next) {
  426. if (arch->type != arch_foreign)
  427. continue;
  428. printf("%s\n", arch->name);
  429. }
  430. m_output(stdout, _("<standard output>"));
  431. return 0;
  432. }
  433. int
  434. cmpversions(const char *const *argv)
  435. {
  436. struct relationinfo {
  437. const char *string;
  438. /* These values are exit status codes, so 0 = true, 1 = false. */
  439. int if_lesser, if_equal, if_greater;
  440. int if_none_a, if_none_both, if_none_b;
  441. };
  442. static const struct relationinfo relationinfos[]= {
  443. /* < = > !a!2!b */
  444. { "le", 0,0,1, 0,0,1 },
  445. { "lt", 0,1,1, 0,1,1 },
  446. { "eq", 1,0,1, 1,0,1 },
  447. { "ne", 0,1,0, 0,1,0 },
  448. { "ge", 1,0,0, 1,0,0 },
  449. { "gt", 1,1,0, 1,1,0 },
  450. /* These treat an empty version as later than any version. */
  451. { "le-nl", 0,0,1, 1,0,0 },
  452. { "lt-nl", 0,1,1, 1,1,0 },
  453. { "ge-nl", 1,0,0, 0,0,1 },
  454. { "gt-nl", 1,1,0, 0,1,1 },
  455. /* For compatibility with dpkg control file syntax. */
  456. { "<", 0,0,1, 0,0,1 },
  457. { "<=", 0,0,1, 0,0,1 },
  458. { "<<", 0,1,1, 0,1,1 },
  459. { "=", 1,0,1, 1,0,1 },
  460. { ">", 1,0,0, 1,0,0 },
  461. { ">=", 1,0,0, 1,0,0 },
  462. { ">>", 1,1,0, 1,1,0 },
  463. { NULL }
  464. };
  465. const struct relationinfo *rip;
  466. struct versionrevision a, b;
  467. struct dpkg_error err;
  468. int r;
  469. if (!argv[0] || !argv[1] || !argv[2] || argv[3])
  470. badusage(_("--compare-versions takes three arguments:"
  471. " <version> <relation> <version>"));
  472. for (rip=relationinfos; rip->string && strcmp(rip->string,argv[1]); rip++);
  473. if (!rip->string) badusage(_("--compare-versions bad relation"));
  474. if (*argv[0] && strcmp(argv[0],"<unknown>")) {
  475. if (parseversion(&a, argv[0], &err) < 0) {
  476. if (err.type == DPKG_MSG_WARN)
  477. warning(_("version '%s' has bad syntax: %s"), argv[0], err.str);
  478. else
  479. ohshit(_("version '%s' has bad syntax: %s"), argv[0], err.str);
  480. dpkg_error_destroy(&err);
  481. }
  482. } else {
  483. blankversion(&a);
  484. }
  485. if (*argv[2] && strcmp(argv[2],"<unknown>")) {
  486. if (parseversion(&b, argv[2], &err) < 0) {
  487. if (err.type == DPKG_MSG_WARN)
  488. warning(_("version '%s' has bad syntax: %s"), argv[2], err.str);
  489. else
  490. ohshit(_("version '%s' has bad syntax: %s"), argv[2], err.str);
  491. dpkg_error_destroy(&err);
  492. }
  493. } else {
  494. blankversion(&b);
  495. }
  496. if (!informativeversion(&a)) {
  497. return informativeversion(&b) ? rip->if_none_a : rip->if_none_both;
  498. } else if (!informativeversion(&b)) {
  499. return rip->if_none_b;
  500. }
  501. r= versioncompare(&a,&b);
  502. debug(dbg_general,"cmpversions a=`%s' b=`%s' r=%d",
  503. versiondescribe(&a,vdew_always),
  504. versiondescribe(&b,vdew_always),
  505. r);
  506. if (r > 0)
  507. return rip->if_greater;
  508. else if (r < 0)
  509. return rip->if_lesser;
  510. else
  511. return rip->if_equal;
  512. }