querycmd.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. /*
  2. * dpkg-query - program for query the dpkg database
  3. * querycmd.c - status enquiry and listing options
  4. *
  5. * Copyright © 1995,1996 Ian Jackson <ian@chiark.greenend.org.uk>
  6. * Copyright © 2000,2001 Wichert Akkerman <wakkerma@debian.org>
  7. * Copyright © 2006-2015 Guillem Jover <guillem@debian.org>
  8. * Copyright © 2011 Linaro Limited
  9. * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
  10. *
  11. * This is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  23. */
  24. #include <config.h>
  25. #include <compat.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <sys/ioctl.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 <fnmatch.h>
  36. #include <termios.h>
  37. #include <unistd.h>
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <dpkg/i18n.h>
  41. #include <dpkg/dpkg.h>
  42. #include <dpkg/dpkg-db.h>
  43. #include <dpkg/pkg-array.h>
  44. #include <dpkg/pkg-spec.h>
  45. #include <dpkg/pkg-format.h>
  46. #include <dpkg/pkg-show.h>
  47. #include <dpkg/string.h>
  48. #include <dpkg/path.h>
  49. #include <dpkg/file.h>
  50. #include <dpkg/options.h>
  51. #include "filesdb.h"
  52. #include "infodb.h"
  53. #include "main.h"
  54. static const char *showformat = "${binary:Package}\t${Version}\n";
  55. static int opt_loadavail = 0;
  56. static int getwidth(void) {
  57. int fd;
  58. int res;
  59. struct winsize ws;
  60. const char *columns;
  61. columns = getenv("COLUMNS");
  62. if (columns) {
  63. res = atoi(columns);
  64. if (res > 0)
  65. return res;
  66. }
  67. if (!isatty(1))
  68. return -1;
  69. else {
  70. res = 80;
  71. fd = open("/dev/tty", O_RDONLY);
  72. if (fd != -1) {
  73. if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
  74. res = ws.ws_col;
  75. close(fd);
  76. }
  77. return res;
  78. }
  79. }
  80. struct list_format {
  81. bool head;
  82. int nw;
  83. int vw;
  84. int aw;
  85. int dw;
  86. };
  87. static void
  88. list_format_init(struct list_format *fmt, struct pkg_array *array)
  89. {
  90. int w;
  91. if (fmt->nw != 0)
  92. return;
  93. w = getwidth();
  94. if (w == -1) {
  95. int i;
  96. fmt->nw = 14;
  97. fmt->vw = 12;
  98. fmt->aw = 12;
  99. fmt->dw = 33;
  100. for (i = 0; i < array->n_pkgs; i++) {
  101. int plen, vlen, alen, dlen;
  102. if (array->pkgs[i] == NULL)
  103. continue;
  104. plen = str_width(pkg_name(array->pkgs[i], pnaw_nonambig));
  105. vlen = str_width(versiondescribe(&array->pkgs[i]->installed.version,
  106. vdew_nonambig));
  107. alen = str_width(dpkg_arch_describe(array->pkgs[i]->installed.arch));
  108. pkg_summary(array->pkgs[i], &array->pkgs[i]->installed, &dlen);
  109. if (plen > fmt->nw)
  110. fmt->nw = plen;
  111. if (vlen > fmt->vw)
  112. fmt->vw = vlen;
  113. if (alen > fmt->aw)
  114. fmt->aw = alen;
  115. if (dlen > fmt->dw)
  116. fmt->dw = dlen;
  117. }
  118. } else {
  119. w -= 80;
  120. /* Let's not try to deal with terminals that are too small. */
  121. if (w < 0)
  122. w = 0;
  123. /* Halve that so we can add it to both the name and description. */
  124. w >>= 1;
  125. /* Name width. */
  126. fmt->nw = (14 + (w / 2));
  127. /* Version width. */
  128. fmt->vw = (12 + (w / 4));
  129. /* Architecture width. */
  130. fmt->aw = (12 + (w / 4));
  131. /* Description width. */
  132. fmt->dw = (33 + w);
  133. }
  134. }
  135. static void
  136. list_format_print(struct list_format *fmt,
  137. int c_want, int c_status, int c_eflag,
  138. const char *name, const char *version, const char *arch,
  139. const char *desc, int desc_len)
  140. {
  141. struct str_crop_info ns, vs, as, ds;
  142. str_gen_crop(name, fmt->nw, &ns);
  143. str_gen_crop(version, fmt->vw, &vs);
  144. str_gen_crop(arch, fmt->aw, &as);
  145. str_gen_crop(desc, desc_len, &ds);
  146. printf("%c%c%c %-*.*s %-*.*s %-*.*s %.*s\n", c_want, c_status, c_eflag,
  147. ns.max_bytes, ns.str_bytes, name,
  148. vs.max_bytes, vs.str_bytes, version,
  149. as.max_bytes, as.str_bytes, arch,
  150. ds.str_bytes, desc);
  151. }
  152. static void
  153. list_format_print_header(struct list_format *fmt)
  154. {
  155. int l;
  156. if (fmt->head)
  157. return;
  158. /* TRANSLATORS: This is the header that appears on 'dpkg-query -l'. The
  159. * string should remain under 80 characters. The uppercase letters in
  160. * the state values denote the abbreviated letter that will appear on
  161. * the first three columns, which should ideally match the English one
  162. * (e.g. Remove → supRimeix), see dpkg-query(1) for further details. The
  163. * translated message can use additional lines if needed. */
  164. fputs(_("\
  165. Desired=Unknown/Install/Remove/Purge/Hold\n\
  166. | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\n\
  167. |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\n"), stdout);
  168. list_format_print(fmt, '|', '|', '/', _("Name"), _("Version"),
  169. _("Architecture"), _("Description"), fmt->dw);
  170. /* Status */
  171. printf("+++-");
  172. /* Package name. */
  173. for (l = 0; l < fmt->nw; l++)
  174. printf("=");
  175. printf("-");
  176. /* Version. */
  177. for (l = 0; l < fmt->vw; l++)
  178. printf("=");
  179. printf("-");
  180. /* Architecture. */
  181. for (l = 0; l < fmt->aw; l++)
  182. printf("=");
  183. printf("-");
  184. /* Description. */
  185. for (l = 0; l < fmt->dw; l++)
  186. printf("=");
  187. printf("\n");
  188. fmt->head = true;
  189. }
  190. static void
  191. pkg_array_list_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
  192. {
  193. struct list_format *fmt = pkg_data;
  194. int l;
  195. const char *pdesc;
  196. list_format_init(fmt, array);
  197. list_format_print_header(fmt);
  198. pdesc = pkg_summary(pkg, &pkg->installed, &l);
  199. l = min(l, fmt->dw);
  200. list_format_print(fmt,
  201. pkg_abbrev_want(pkg),
  202. pkg_abbrev_status(pkg),
  203. pkg_abbrev_eflag(pkg),
  204. pkg_name(pkg, pnaw_nonambig),
  205. versiondescribe(&pkg->installed.version, vdew_nonambig),
  206. dpkg_arch_describe(pkg->installed.arch),
  207. pdesc, l);
  208. }
  209. static int
  210. listpackages(const char *const *argv)
  211. {
  212. struct pkg_array array;
  213. struct pkginfo *pkg;
  214. int i;
  215. int failures = 0;
  216. struct list_format fmt;
  217. if (!opt_loadavail)
  218. modstatdb_open(msdbrw_readonly);
  219. else
  220. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  221. pkg_array_init_from_db(&array);
  222. pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
  223. memset(&fmt, 0, sizeof(fmt));
  224. if (!*argv) {
  225. for (i = 0; i < array.n_pkgs; i++) {
  226. pkg = array.pkgs[i];
  227. if (pkg->status == PKG_STAT_NOTINSTALLED)
  228. array.pkgs[i] = NULL;
  229. }
  230. pkg_array_foreach(&array, pkg_array_list_item, &fmt);
  231. } else {
  232. int argc, ip, *found;
  233. struct pkg_spec *ps;
  234. for (argc = 0; argv[argc]; argc++);
  235. found = m_calloc(argc, sizeof(int));
  236. ps = m_malloc(sizeof(*ps) * argc);
  237. for (ip = 0; ip < argc; ip++) {
  238. pkg_spec_init(&ps[ip], PKG_SPEC_PATTERNS | PKG_SPEC_ARCH_WILDCARD);
  239. pkg_spec_parse(&ps[ip], argv[ip]);
  240. }
  241. for (i = 0; i < array.n_pkgs; i++) {
  242. bool pkg_found = false;
  243. pkg = array.pkgs[i];
  244. for (ip = 0; ip < argc; ip++) {
  245. if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
  246. pkg_found = true;
  247. found[ip]++;
  248. }
  249. }
  250. if (!pkg_found)
  251. array.pkgs[i] = NULL;
  252. }
  253. pkg_array_foreach(&array, pkg_array_list_item, &fmt);
  254. for (ip = 0; ip < argc; ip++) {
  255. if (!found[ip]) {
  256. notice(_("no packages found matching %s"), argv[ip]);
  257. failures++;
  258. }
  259. pkg_spec_destroy(&ps[ip]);
  260. }
  261. free(ps);
  262. free(found);
  263. }
  264. m_output(stdout, _("<standard output>"));
  265. m_output(stderr, _("<standard error>"));
  266. pkg_array_destroy(&array);
  267. modstatdb_shutdown();
  268. return failures;
  269. }
  270. static int searchoutput(struct filenamenode *namenode) {
  271. struct filepackages_iterator *iter;
  272. struct pkginfo *pkg_owner;
  273. int found;
  274. if (namenode->divert) {
  275. const char *name_from = namenode->divert->camefrom ?
  276. namenode->divert->camefrom->name : namenode->name;
  277. const char *name_to = namenode->divert->useinstead ?
  278. namenode->divert->useinstead->name : namenode->name;
  279. if (namenode->divert->pkgset) {
  280. printf(_("diversion by %s from: %s\n"),
  281. namenode->divert->pkgset->name, name_from);
  282. printf(_("diversion by %s to: %s\n"),
  283. namenode->divert->pkgset->name, name_to);
  284. } else {
  285. printf(_("local diversion from: %s\n"), name_from);
  286. printf(_("local diversion to: %s\n"), name_to);
  287. }
  288. }
  289. found= 0;
  290. iter = filepackages_iter_new(namenode);
  291. while ((pkg_owner = filepackages_iter_next(iter))) {
  292. if (found)
  293. fputs(", ", stdout);
  294. fputs(pkg_name(pkg_owner, pnaw_nonambig), stdout);
  295. found++;
  296. }
  297. filepackages_iter_free(iter);
  298. if (found) printf(": %s\n",namenode->name);
  299. return found + (namenode->divert ? 1 : 0);
  300. }
  301. static int
  302. searchfiles(const char *const *argv)
  303. {
  304. struct filenamenode *namenode;
  305. struct fileiterator *iter;
  306. const char *thisarg;
  307. int found;
  308. int failures = 0;
  309. struct varbuf path = VARBUF_INIT;
  310. static struct varbuf vb;
  311. if (!*argv)
  312. badusage(_("--search needs at least one file name pattern argument"));
  313. modstatdb_open(msdbrw_readonly);
  314. ensure_allinstfiles_available_quiet();
  315. ensure_diversions();
  316. while ((thisarg = *argv++) != NULL) {
  317. found= 0;
  318. if (!strchr("*[?/",*thisarg)) {
  319. varbuf_reset(&vb);
  320. varbuf_add_char(&vb, '*');
  321. varbuf_add_str(&vb, thisarg);
  322. varbuf_add_char(&vb, '*');
  323. varbuf_end_str(&vb);
  324. thisarg= vb.buf;
  325. }
  326. if (!strpbrk(thisarg, "*[?\\")) {
  327. /* Trim trailing ‘/’ and ‘/.’ from the argument if it is not
  328. * a pattern, just a pathname. */
  329. varbuf_reset(&path);
  330. varbuf_add_str(&path, thisarg);
  331. varbuf_end_str(&path);
  332. varbuf_trunc(&path, path_trim_slash_slashdot(path.buf));
  333. namenode = findnamenode(path.buf, 0);
  334. found += searchoutput(namenode);
  335. } else {
  336. iter = files_db_iter_new();
  337. while ((namenode = files_db_iter_next(iter)) != NULL) {
  338. if (fnmatch(thisarg,namenode->name,0)) continue;
  339. found+= searchoutput(namenode);
  340. }
  341. files_db_iter_free(iter);
  342. }
  343. if (!found) {
  344. notice(_("no path found matching pattern %s"), thisarg);
  345. failures++;
  346. m_output(stderr, _("<standard error>"));
  347. } else {
  348. m_output(stdout, _("<standard output>"));
  349. }
  350. }
  351. modstatdb_shutdown();
  352. varbuf_destroy(&path);
  353. return failures;
  354. }
  355. static int
  356. enqperpackage(const char *const *argv)
  357. {
  358. const char *thisarg;
  359. struct fileinlist *file;
  360. struct pkginfo *pkg;
  361. struct filenamenode *namenode;
  362. int failures = 0;
  363. if (!*argv)
  364. badusage(_("--%s needs at least one package name argument"), cipaction->olong);
  365. if (cipaction->arg_int == act_printavail)
  366. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  367. else
  368. modstatdb_open(msdbrw_readonly);
  369. while ((thisarg = *argv++) != NULL) {
  370. pkg = dpkg_options_parse_pkgname(cipaction, thisarg);
  371. switch (cipaction->arg_int) {
  372. case act_status:
  373. if (pkg->status == PKG_STAT_NOTINSTALLED &&
  374. pkg->priority == PKG_PRIO_UNKNOWN &&
  375. str_is_unset(pkg->section) &&
  376. !pkg->files &&
  377. pkg->want == PKG_WANT_UNKNOWN &&
  378. !pkg_is_informative(pkg, &pkg->installed)) {
  379. notice(_("package '%s' is not installed and no information is available"),
  380. pkg_name(pkg, pnaw_nonambig));
  381. failures++;
  382. } else {
  383. writerecord(stdout, _("<standard output>"), pkg, &pkg->installed);
  384. }
  385. break;
  386. case act_printavail:
  387. if (!pkg_is_informative(pkg, &pkg->available)) {
  388. notice(_("package '%s' is not available"),
  389. pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
  390. failures++;
  391. } else {
  392. writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
  393. }
  394. break;
  395. case act_listfiles:
  396. switch (pkg->status) {
  397. case PKG_STAT_NOTINSTALLED:
  398. notice(_("package '%s' is not installed"),
  399. pkg_name(pkg, pnaw_nonambig));
  400. failures++;
  401. break;
  402. default:
  403. ensure_packagefiles_available(pkg);
  404. ensure_diversions();
  405. file= pkg->clientdata->files;
  406. if (!file) {
  407. printf(_("Package '%s' does not contain any files (!)\n"),
  408. pkg_name(pkg, pnaw_nonambig));
  409. } else {
  410. while (file) {
  411. namenode= file->namenode;
  412. puts(namenode->name);
  413. if (namenode->divert && !namenode->divert->camefrom) {
  414. if (!namenode->divert->pkgset)
  415. printf(_("locally diverted to: %s\n"),
  416. namenode->divert->useinstead->name);
  417. else if (pkg->set == namenode->divert->pkgset)
  418. printf(_("package diverts others to: %s\n"),
  419. namenode->divert->useinstead->name);
  420. else
  421. printf(_("diverted by %s to: %s\n"),
  422. namenode->divert->pkgset->name,
  423. namenode->divert->useinstead->name);
  424. }
  425. file= file->next;
  426. }
  427. }
  428. break;
  429. }
  430. break;
  431. default:
  432. internerr("unknown action '%d'", cipaction->arg_int);
  433. }
  434. if (*argv != NULL)
  435. putchar('\n');
  436. m_output(stdout, _("<standard output>"));
  437. }
  438. if (failures) {
  439. fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files,\n"
  440. "and dpkg --contents (= dpkg-deb --contents) to list their contents.\n"),stderr);
  441. m_output(stderr, _("<standard error>"));
  442. }
  443. modstatdb_shutdown();
  444. return failures;
  445. }
  446. static void
  447. pkg_array_show_item(struct pkg_array *array, struct pkginfo *pkg, void *pkg_data)
  448. {
  449. struct pkg_format_node *fmt = pkg_data;
  450. pkg_format_show(fmt, pkg, &pkg->installed);
  451. }
  452. static int
  453. showpackages(const char *const *argv)
  454. {
  455. struct dpkg_error err;
  456. struct pkg_array array;
  457. struct pkginfo *pkg;
  458. struct pkg_format_node *fmt;
  459. int i;
  460. int failures = 0;
  461. fmt = pkg_format_parse(showformat, &err);
  462. if (!fmt) {
  463. notice(_("error in show format: %s"), err.str);
  464. dpkg_error_destroy(&err);
  465. failures++;
  466. return failures;
  467. }
  468. if (!opt_loadavail)
  469. modstatdb_open(msdbrw_readonly);
  470. else
  471. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  472. pkg_array_init_from_db(&array);
  473. pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
  474. if (!*argv) {
  475. for (i = 0; i < array.n_pkgs; i++) {
  476. pkg = array.pkgs[i];
  477. if (pkg->status == PKG_STAT_NOTINSTALLED)
  478. continue;
  479. pkg_format_show(fmt, pkg, &pkg->installed);
  480. }
  481. } else {
  482. int argc, ip, *found;
  483. struct pkg_spec *ps;
  484. for (argc = 0; argv[argc]; argc++);
  485. found = m_calloc(argc, sizeof(int));
  486. ps = m_malloc(sizeof(*ps) * argc);
  487. for (ip = 0; ip < argc; ip++) {
  488. pkg_spec_init(&ps[ip], PKG_SPEC_PATTERNS | PKG_SPEC_ARCH_WILDCARD);
  489. pkg_spec_parse(&ps[ip], argv[ip]);
  490. }
  491. for (i = 0; i < array.n_pkgs; i++) {
  492. bool pkg_found = false;
  493. pkg = array.pkgs[i];
  494. for (ip = 0; ip < argc; ip++) {
  495. if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
  496. pkg_found = true;
  497. found[ip]++;
  498. }
  499. }
  500. if (!pkg_found)
  501. array.pkgs[i] = NULL;
  502. }
  503. pkg_array_foreach(&array, pkg_array_show_item, fmt);
  504. for (ip = 0; ip < argc; ip++) {
  505. if (!found[ip]) {
  506. notice(_("no packages found matching %s"), argv[ip]);
  507. failures++;
  508. }
  509. pkg_spec_destroy(&ps[ip]);
  510. }
  511. free(ps);
  512. free(found);
  513. }
  514. m_output(stdout, _("<standard output>"));
  515. m_output(stderr, _("<standard error>"));
  516. pkg_array_destroy(&array);
  517. pkg_format_free(fmt);
  518. modstatdb_shutdown();
  519. return failures;
  520. }
  521. static bool
  522. pkg_infodb_is_internal(const char *filetype)
  523. {
  524. /* Do not expose internal database files. */
  525. if (strcmp(filetype, LISTFILE) == 0 ||
  526. strcmp(filetype, CONFFILESFILE) == 0)
  527. return true;
  528. if (strlen(filetype) > MAXCONTROLFILENAME)
  529. return true;
  530. return false;
  531. }
  532. static void
  533. pkg_infodb_check_filetype(const char *filetype)
  534. {
  535. const char *c;
  536. /* Validate control file name for sanity. */
  537. for (c = "/."; *c; c++)
  538. if (strchr(filetype, *c))
  539. badusage(_("control file contains %c"), *c);
  540. }
  541. static void
  542. pkg_infodb_print_filename(const char *filename, const char *filetype)
  543. {
  544. if (pkg_infodb_is_internal(filetype))
  545. return;
  546. printf("%s\n", filename);
  547. }
  548. static void
  549. pkg_infodb_print_filetype(const char *filename, const char *filetype)
  550. {
  551. if (pkg_infodb_is_internal(filetype))
  552. return;
  553. printf("%s\n", filetype);
  554. }
  555. static void
  556. control_path_file(struct pkginfo *pkg, const char *control_file)
  557. {
  558. const char *control_path;
  559. struct stat st;
  560. control_path = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
  561. if (stat(control_path, &st) < 0)
  562. return;
  563. if (!S_ISREG(st.st_mode))
  564. return;
  565. pkg_infodb_print_filename(control_path, control_file);
  566. }
  567. static int
  568. control_path(const char *const *argv)
  569. {
  570. struct pkginfo *pkg;
  571. const char *pkgname;
  572. const char *control_file;
  573. pkgname = *argv++;
  574. if (!pkgname)
  575. badusage(_("--%s needs at least one package name argument"),
  576. cipaction->olong);
  577. control_file = *argv++;
  578. if (control_file && *argv)
  579. badusage(_("--%s takes at most two arguments"), cipaction->olong);
  580. if (control_file)
  581. pkg_infodb_check_filetype(control_file);
  582. modstatdb_open(msdbrw_readonly);
  583. pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
  584. if (pkg->status == PKG_STAT_NOTINSTALLED)
  585. ohshit(_("package '%s' is not installed"),
  586. pkg_name(pkg, pnaw_nonambig));
  587. if (control_file)
  588. control_path_file(pkg, control_file);
  589. else
  590. pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filename);
  591. modstatdb_shutdown();
  592. return 0;
  593. }
  594. static int
  595. control_list(const char *const *argv)
  596. {
  597. struct pkginfo *pkg;
  598. const char *pkgname;
  599. pkgname = *argv++;
  600. if (!pkgname || *argv)
  601. badusage(_("--%s takes one package name argument"), cipaction->olong);
  602. modstatdb_open(msdbrw_readonly);
  603. pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
  604. if (pkg->status == PKG_STAT_NOTINSTALLED)
  605. ohshit(_("package '%s' is not installed"), pkg_name(pkg, pnaw_nonambig));
  606. pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filetype);
  607. modstatdb_shutdown();
  608. return 0;
  609. }
  610. static int
  611. control_show(const char *const *argv)
  612. {
  613. struct pkginfo *pkg;
  614. const char *pkgname;
  615. const char *filename;
  616. const char *control_file;
  617. pkgname = *argv++;
  618. if (!pkgname || !*argv)
  619. badusage(_("--%s takes exactly two arguments"),
  620. cipaction->olong);
  621. control_file = *argv++;
  622. if (!control_file || *argv)
  623. badusage(_("--%s takes exactly two arguments"), cipaction->olong);
  624. pkg_infodb_check_filetype(control_file);
  625. modstatdb_open(msdbrw_readonly);
  626. pkg = dpkg_options_parse_pkgname(cipaction, pkgname);
  627. if (pkg->status == PKG_STAT_NOTINSTALLED)
  628. ohshit(_("package '%s' is not installed"), pkg_name(pkg, pnaw_nonambig));
  629. if (pkg_infodb_has_file(pkg, &pkg->installed, control_file))
  630. filename = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
  631. else
  632. ohshit(_("control file '%s' does not exist"), control_file);
  633. modstatdb_shutdown();
  634. file_show(filename);
  635. return 0;
  636. }
  637. static void DPKG_ATTR_NORET
  638. printversion(const struct cmdinfo *ci, const char *value)
  639. {
  640. printf(_("Debian %s package management program query tool version %s.\n"),
  641. DPKGQUERY, PACKAGE_RELEASE);
  642. printf(_(
  643. "This is free software; see the GNU General Public License version 2 or\n"
  644. "later for copying conditions. There is NO warranty.\n"));
  645. m_output(stdout, _("<standard output>"));
  646. exit(0);
  647. }
  648. static void DPKG_ATTR_NORET
  649. usage(const struct cmdinfo *ci, const char *value)
  650. {
  651. printf(_(
  652. "Usage: %s [<option> ...] <command>\n"
  653. "\n"), DPKGQUERY);
  654. printf(_(
  655. "Commands:\n"
  656. " -s|--status <package> ... Display package status details.\n"
  657. " -p|--print-avail <package> ... Display available version details.\n"
  658. " -L|--listfiles <package> ... List files 'owned' by package(s).\n"
  659. " -l|--list [<pattern> ...] List packages concisely.\n"
  660. " -W|--show [<pattern> ...] Show information on package(s).\n"
  661. " -S|--search <pattern> ... Find package(s) owning file(s).\n"
  662. " --control-list <package> Print the package control file list.\n"
  663. " --control-show <package> <file>\n"
  664. " Show the package control file.\n"
  665. " -c|--control-path <package> [<file>]\n"
  666. " Print path for package control file.\n"
  667. "\n"));
  668. printf(_(
  669. " -?, --help Show this help message.\n"
  670. " --version Show the version.\n"
  671. "\n"));
  672. printf(_(
  673. "Options:\n"
  674. " --admindir=<directory> Use <directory> instead of %s.\n"
  675. " --load-avail Use available file on --show and --list.\n"
  676. " -f|--showformat=<format> Use alternative format for --show.\n"
  677. "\n"), ADMINDIR);
  678. printf(_(
  679. "Format syntax:\n"
  680. " A format is a string that will be output for each package. The format\n"
  681. " can include the standard escape sequences \\n (newline), \\r (carriage\n"
  682. " return) or \\\\ (plain backslash). Package information can be included\n"
  683. " by inserting variable references to package fields using the ${var[;width]}\n"
  684. " syntax. Fields will be right-aligned unless the width is negative in which\n"
  685. " case left alignment will be used.\n"));
  686. m_output(stdout, _("<standard output>"));
  687. exit(0);
  688. }
  689. static const char printforhelp[] = N_(
  690. "Use --help for help about querying packages.");
  691. static const char *admindir;
  692. /* This table has both the action entries in it and the normal options.
  693. * The action entries are made with the ACTION macro, as they all
  694. * have a very similar structure. */
  695. static const struct cmdinfo cmdinfos[]= {
  696. ACTION( "listfiles", 'L', act_listfiles, enqperpackage ),
  697. ACTION( "status", 's', act_status, enqperpackage ),
  698. ACTION( "print-avail", 'p', act_printavail, enqperpackage ),
  699. ACTION( "list", 'l', act_listpackages, listpackages ),
  700. ACTION( "search", 'S', act_searchfiles, searchfiles ),
  701. ACTION( "show", 'W', act_listpackages, showpackages ),
  702. ACTION( "control-path", 'c', act_controlpath, control_path ),
  703. ACTION( "control-list", 0, act_controllist, control_list ),
  704. ACTION( "control-show", 0, act_controlshow, control_show ),
  705. { "admindir", 0, 1, NULL, &admindir, NULL },
  706. { "load-avail", 0, 0, &opt_loadavail, NULL, NULL, 1 },
  707. { "showformat", 'f', 1, NULL, &showformat, NULL },
  708. { "help", '?', 0, NULL, NULL, usage },
  709. { "version", 0, 0, NULL, NULL, printversion },
  710. { NULL, 0, 0, NULL, NULL, NULL }
  711. };
  712. int main(int argc, const char *const *argv) {
  713. int ret;
  714. dpkg_set_report_piped_mode(_IOFBF);
  715. dpkg_locales_init(PACKAGE);
  716. dpkg_program_init("dpkg-query");
  717. dpkg_options_parse(&argv, cmdinfos, printforhelp);
  718. admindir = dpkg_db_set_dir(admindir);
  719. if (!cipaction) badusage(_("need an action option"));
  720. filesdbinit();
  721. ret = cipaction->action(argv);
  722. dpkg_program_done();
  723. return !!ret;
  724. }