querycmd.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  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-2012 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 <http://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. #include <sys/termios.h>
  30. #if HAVE_LOCALE_H
  31. #include <locale.h>
  32. #endif
  33. #include <string.h>
  34. #include <fcntl.h>
  35. #include <dirent.h>
  36. #include <fnmatch.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/options.h>
  50. #include "filesdb.h"
  51. #include "infodb.h"
  52. #include "main.h"
  53. static const char *showformat = "${binary:Package}\t${Version}\n";
  54. static int opt_loadavail = 0;
  55. static int getwidth(void) {
  56. int fd;
  57. int res;
  58. struct winsize ws;
  59. const char *columns;
  60. if ((columns=getenv("COLUMNS")) && ((res=atoi(columns))>0))
  61. return res;
  62. else if (!isatty(1))
  63. return -1;
  64. else {
  65. res = 80;
  66. if ((fd=open("/dev/tty",O_RDONLY))!=-1) {
  67. if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
  68. res = ws.ws_col;
  69. close(fd);
  70. }
  71. return res;
  72. }
  73. }
  74. struct list_format {
  75. bool head;
  76. int nw, vw, dw;
  77. };
  78. static void
  79. list_format_init(struct list_format *fmt, struct pkg_array *array)
  80. {
  81. int w;
  82. if (fmt->nw != 0)
  83. return;
  84. w = getwidth();
  85. if (w == -1) {
  86. int i;
  87. fmt->nw = 14;
  88. fmt->vw = 14;
  89. fmt->dw = 44;
  90. for (i = 0; i < array->n_pkgs; i++) {
  91. int plen, vlen, dlen;
  92. plen = strlen(pkg_name(array->pkgs[i], pnaw_nonambig));
  93. vlen = strlen(versiondescribe(&array->pkgs[i]->installed.version,
  94. vdew_nonambig));
  95. pkg_summary(array->pkgs[i], &array->pkgs[i]->installed, &dlen);
  96. if (plen > fmt->nw)
  97. fmt->nw = plen;
  98. if (vlen > fmt->vw)
  99. fmt->vw = vlen;
  100. if (dlen > fmt->dw)
  101. fmt->dw = dlen;
  102. }
  103. } else {
  104. w -= 80;
  105. /* Let's not try to deal with terminals that are too small. */
  106. if (w < 0)
  107. w = 0;
  108. /* Halve that so we can add it to both the name and description. */
  109. w >>= 2;
  110. /* Name width. */
  111. fmt->nw = (14 + w);
  112. /* Version width. */
  113. fmt->vw = (14 + w);
  114. /* Description width. */
  115. fmt->dw = (44 + (2 * w));
  116. }
  117. }
  118. static void
  119. list_format_print(struct list_format *fmt,
  120. int c_want, int c_status, int c_eflag,
  121. const char *name, const char *version,
  122. const char *desc, int desc_len)
  123. {
  124. printf("%c%c%c %-*.*s %-*.*s %.*s\n", c_want, c_status, c_eflag,
  125. fmt->nw, fmt->nw, name, fmt->vw, fmt->vw, version, desc_len, desc);
  126. }
  127. static void
  128. list_format_print_header(struct list_format *fmt)
  129. {
  130. int l;
  131. if (fmt->head)
  132. return;
  133. /* TRANSLATORS: This is the header that appears on 'dpkg-query -l'. The
  134. * string should remain under 80 characters. The uppercase letters in
  135. * the state values denote the abbreviated letter that will appear on
  136. * the first three columns, which should ideally match the English one
  137. * (e.g. Remove → supRimeix), see dpkg-query(1) for further details. The
  138. * translated message can use additional lines if needed. */
  139. fputs(_("\
  140. Desired=Unknown/Install/Remove/Purge/Hold\n\
  141. | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend\n\
  142. |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)\n"), stdout);
  143. list_format_print(fmt, '|', '|', '/', _("Name"), _("Version"),
  144. _("Description"), 40);
  145. /* Status */
  146. printf("+++-");
  147. /* Package name. */
  148. for (l = 0; l < fmt->nw; l++)
  149. printf("=");
  150. printf("-");
  151. /* Version. */
  152. for (l = 0; l < fmt->vw; l++)
  153. printf("=");
  154. printf("-");
  155. /* Description. */
  156. for (l = 0; l < fmt->dw; l++)
  157. printf("=");
  158. printf("\n");
  159. fmt->head = true;
  160. }
  161. static void
  162. list1package(struct pkginfo *pkg, struct list_format *fmt, struct pkg_array *array)
  163. {
  164. int l;
  165. const char *pdesc;
  166. list_format_init(fmt, array);
  167. list_format_print_header(fmt);
  168. pdesc = pkg_summary(pkg, &pkg->installed, &l);
  169. l = min(l, fmt->dw);
  170. list_format_print(fmt,
  171. pkg_abbrev_want(pkg),
  172. pkg_abbrev_status(pkg),
  173. pkg_abbrev_eflag(pkg),
  174. pkg_name(pkg, pnaw_nonambig),
  175. versiondescribe(&pkg->installed.version, vdew_nonambig),
  176. pdesc, l);
  177. }
  178. static int
  179. listpackages(const char *const *argv)
  180. {
  181. struct pkg_array array;
  182. struct pkginfo *pkg;
  183. int i;
  184. int failures = 0;
  185. struct list_format fmt;
  186. if (!opt_loadavail)
  187. modstatdb_open(msdbrw_readonly);
  188. else
  189. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  190. pkg_array_init_from_db(&array);
  191. pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
  192. memset(&fmt, 0, sizeof(fmt));
  193. if (!*argv) {
  194. for (i = 0; i < array.n_pkgs; i++) {
  195. pkg = array.pkgs[i];
  196. if (pkg->status == stat_notinstalled) continue;
  197. list1package(pkg, &fmt, &array);
  198. }
  199. } else {
  200. int argc, ip, *found;
  201. struct pkg_spec *ps;
  202. for (argc = 0; argv[argc]; argc++);
  203. found = m_calloc(sizeof(int) * argc);
  204. ps = m_malloc(sizeof(*ps) * argc);
  205. for (ip = 0; ip < argc; ip++) {
  206. pkg_spec_init(&ps[ip], psf_patterns | psf_arch_def_wildcard);
  207. pkg_spec_parse(&ps[ip], argv[ip]);
  208. }
  209. for (i = 0; i < array.n_pkgs; i++) {
  210. pkg = array.pkgs[i];
  211. for (ip = 0; ip < argc; ip++) {
  212. if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
  213. list1package(pkg, &fmt, &array);
  214. found[ip]++;
  215. break;
  216. }
  217. }
  218. }
  219. /* FIXME: we might get non-matching messages for sub-patterns specified
  220. * after their super-patterns, due to us skipping on first match. */
  221. for (ip = 0; ip < argc; ip++) {
  222. if (!found[ip]) {
  223. fprintf(stderr, _("No packages found matching %s.\n"), argv[ip]);
  224. failures++;
  225. }
  226. pkg_spec_destroy(&ps[ip]);
  227. }
  228. free(ps);
  229. free(found);
  230. }
  231. m_output(stdout, _("<standard output>"));
  232. m_output(stderr, _("<standard error>"));
  233. pkg_array_destroy(&array);
  234. modstatdb_shutdown();
  235. return failures;
  236. }
  237. static int searchoutput(struct filenamenode *namenode) {
  238. struct filepackages_iterator *iter;
  239. struct pkginfo *pkg_owner;
  240. int found;
  241. if (namenode->divert) {
  242. const char *name_from = namenode->divert->camefrom ?
  243. namenode->divert->camefrom->name : namenode->name;
  244. const char *name_to = namenode->divert->useinstead ?
  245. namenode->divert->useinstead->name : namenode->name;
  246. if (namenode->divert->pkgset) {
  247. printf(_("diversion by %s from: %s\n"),
  248. namenode->divert->pkgset->name, name_from);
  249. printf(_("diversion by %s to: %s\n"),
  250. namenode->divert->pkgset->name, name_to);
  251. } else {
  252. printf(_("local diversion from: %s\n"), name_from);
  253. printf(_("local diversion to: %s\n"), name_to);
  254. }
  255. }
  256. found= 0;
  257. iter = filepackages_iter_new(namenode);
  258. while ((pkg_owner = filepackages_iter_next(iter))) {
  259. if (found)
  260. fputs(", ", stdout);
  261. fputs(pkg_name(pkg_owner, pnaw_nonambig), stdout);
  262. found++;
  263. }
  264. filepackages_iter_free(iter);
  265. if (found) printf(": %s\n",namenode->name);
  266. return found + (namenode->divert ? 1 : 0);
  267. }
  268. static int
  269. searchfiles(const char *const *argv)
  270. {
  271. struct filenamenode *namenode;
  272. struct fileiterator *iter;
  273. const char *thisarg;
  274. int found;
  275. int failures = 0;
  276. struct varbuf path = VARBUF_INIT;
  277. static struct varbuf vb;
  278. if (!*argv)
  279. badusage(_("--search needs at least one file name pattern argument"));
  280. modstatdb_open(msdbrw_readonly);
  281. ensure_allinstfiles_available_quiet();
  282. ensure_diversions();
  283. while ((thisarg = *argv++) != NULL) {
  284. found= 0;
  285. /* Trim trailing ‘/’ and ‘/.’ from the argument if it's
  286. * not a pattern, just a path. */
  287. if (!strpbrk(thisarg, "*[?\\")) {
  288. varbuf_reset(&path);
  289. varbuf_add_str(&path, thisarg);
  290. varbuf_end_str(&path);
  291. varbuf_trunc(&path, path_trim_slash_slashdot(path.buf));
  292. thisarg = path.buf;
  293. }
  294. if (!strchr("*[?/",*thisarg)) {
  295. varbuf_reset(&vb);
  296. varbuf_add_char(&vb, '*');
  297. varbuf_add_str(&vb, thisarg);
  298. varbuf_add_char(&vb, '*');
  299. varbuf_end_str(&vb);
  300. thisarg= vb.buf;
  301. }
  302. if (!strpbrk(thisarg, "*[?\\")) {
  303. namenode= findnamenode(thisarg, 0);
  304. found += searchoutput(namenode);
  305. } else {
  306. iter = files_db_iter_new();
  307. while ((namenode = files_db_iter_next(iter)) != NULL) {
  308. if (fnmatch(thisarg,namenode->name,0)) continue;
  309. found+= searchoutput(namenode);
  310. }
  311. files_db_iter_free(iter);
  312. }
  313. if (!found) {
  314. fprintf(stderr, _("%s: no path found matching pattern %s.\n"),
  315. dpkg_get_progname(), thisarg);
  316. failures++;
  317. m_output(stderr, _("<standard error>"));
  318. } else {
  319. m_output(stdout, _("<standard output>"));
  320. }
  321. }
  322. modstatdb_shutdown();
  323. varbuf_destroy(&path);
  324. return failures;
  325. }
  326. static int
  327. enqperpackage(const char *const *argv)
  328. {
  329. const char *thisarg;
  330. struct fileinlist *file;
  331. struct pkginfo *pkg;
  332. struct filenamenode *namenode;
  333. int failures = 0;
  334. if (!*argv)
  335. badusage(_("--%s needs at least one package name argument"), cipaction->olong);
  336. if (cipaction->arg_int == act_printavail)
  337. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  338. else
  339. modstatdb_open(msdbrw_readonly);
  340. while ((thisarg = *argv++) != NULL) {
  341. struct dpkg_error err;
  342. pkg = pkg_spec_parse_pkg(thisarg, &err);
  343. if (pkg == NULL)
  344. badusage(_("--%s needs a valid package name but '%.250s' is not: %s"),
  345. cipaction->olong, thisarg, err.str);
  346. switch (cipaction->arg_int) {
  347. case act_status:
  348. if (pkg->status == stat_notinstalled &&
  349. pkg->priority == pri_unknown &&
  350. str_is_unset(pkg->section) &&
  351. !pkg->files &&
  352. pkg->want == want_unknown &&
  353. !pkg_is_informative(pkg, &pkg->installed)) {
  354. fprintf(stderr,
  355. _("Package `%s' is not installed and no info is available.\n"),
  356. pkg_name(pkg, pnaw_nonambig));
  357. failures++;
  358. } else {
  359. writerecord(stdout, _("<standard output>"), pkg, &pkg->installed);
  360. }
  361. break;
  362. case act_printavail:
  363. if (!pkg_is_informative(pkg, &pkg->available)) {
  364. fprintf(stderr, _("Package `%s' is not available.\n"),
  365. pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
  366. failures++;
  367. } else {
  368. writerecord(stdout, _("<standard output>"), pkg, &pkg->available);
  369. }
  370. break;
  371. case act_listfiles:
  372. switch (pkg->status) {
  373. case stat_notinstalled:
  374. fprintf(stderr, _("Package `%s' is not installed.\n"),
  375. pkg_name(pkg, pnaw_nonambig));
  376. failures++;
  377. break;
  378. default:
  379. ensure_packagefiles_available(pkg);
  380. ensure_diversions();
  381. file= pkg->clientdata->files;
  382. if (!file) {
  383. printf(_("Package `%s' does not contain any files (!)\n"),
  384. pkg_name(pkg, pnaw_nonambig));
  385. } else {
  386. while (file) {
  387. namenode= file->namenode;
  388. puts(namenode->name);
  389. if (namenode->divert && !namenode->divert->camefrom) {
  390. if (!namenode->divert->pkgset)
  391. printf(_("locally diverted to: %s\n"),
  392. namenode->divert->useinstead->name);
  393. else if (pkg->set == namenode->divert->pkgset)
  394. printf(_("package diverts others to: %s\n"),
  395. namenode->divert->useinstead->name);
  396. else
  397. printf(_("diverted by %s to: %s\n"),
  398. namenode->divert->pkgset->name,
  399. namenode->divert->useinstead->name);
  400. }
  401. file= file->next;
  402. }
  403. }
  404. break;
  405. }
  406. break;
  407. default:
  408. internerr("unknown action '%d'", cipaction->arg_int);
  409. }
  410. if (*argv != NULL)
  411. putchar('\n');
  412. m_output(stdout, _("<standard output>"));
  413. }
  414. if (failures) {
  415. fputs(_("Use dpkg --info (= dpkg-deb --info) to examine archive files,\n"
  416. "and dpkg --contents (= dpkg-deb --contents) to list their contents.\n"),stderr);
  417. m_output(stderr, _("<standard error>"));
  418. }
  419. modstatdb_shutdown();
  420. return failures;
  421. }
  422. static int
  423. showpackages(const char *const *argv)
  424. {
  425. struct pkg_array array;
  426. struct pkginfo *pkg;
  427. struct pkg_format_node *fmt = pkg_format_parse(showformat);
  428. int i;
  429. int failures = 0;
  430. if (!fmt) {
  431. failures++;
  432. return failures;
  433. }
  434. if (!opt_loadavail)
  435. modstatdb_open(msdbrw_readonly);
  436. else
  437. modstatdb_open(msdbrw_readonly | msdbrw_available_readonly);
  438. pkg_array_init_from_db(&array);
  439. pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
  440. if (!*argv) {
  441. for (i = 0; i < array.n_pkgs; i++) {
  442. pkg = array.pkgs[i];
  443. if (pkg->status == stat_notinstalled) continue;
  444. pkg_format_show(fmt, pkg, &pkg->installed);
  445. }
  446. } else {
  447. int argc, ip, *found;
  448. struct pkg_spec *ps;
  449. for (argc = 0; argv[argc]; argc++);
  450. found = m_calloc(sizeof(int) * argc);
  451. ps = m_malloc(sizeof(*ps) * argc);
  452. for (ip = 0; ip < argc; ip++) {
  453. pkg_spec_init(&ps[ip], psf_patterns | psf_arch_def_wildcard);
  454. pkg_spec_parse(&ps[ip], argv[ip]);
  455. }
  456. for (i = 0; i < array.n_pkgs; i++) {
  457. pkg = array.pkgs[i];
  458. for (ip = 0; ip < argc; ip++) {
  459. if (pkg_spec_match_pkg(&ps[ip], pkg, &pkg->installed)) {
  460. pkg_format_show(fmt, pkg, &pkg->installed);
  461. found[ip]++;
  462. break;
  463. }
  464. }
  465. }
  466. /* FIXME: we might get non-matching messages for sub-patterns specified
  467. * after their super-patterns, due to us skipping on first match. */
  468. for (ip = 0; ip < argc; ip++) {
  469. if (!found[ip]) {
  470. fprintf(stderr, _("No packages found matching %s.\n"), argv[ip]);
  471. failures++;
  472. }
  473. pkg_spec_destroy(&ps[ip]);
  474. }
  475. free(ps);
  476. free(found);
  477. }
  478. m_output(stdout, _("<standard output>"));
  479. m_output(stderr, _("<standard error>"));
  480. pkg_array_destroy(&array);
  481. pkg_format_free(fmt);
  482. modstatdb_shutdown();
  483. return failures;
  484. }
  485. static void
  486. pkg_infodb_print_filename(const char *filename, const char *filetype)
  487. {
  488. /* Do not expose internal database files. */
  489. if (strcmp(filetype, LISTFILE) == 0 ||
  490. strcmp(filetype, CONFFILESFILE) == 0)
  491. return;
  492. if (strlen(filetype) > MAXCONTROLFILENAME)
  493. return;
  494. printf("%s\n", filename);
  495. }
  496. static void
  497. control_path_file(struct pkginfo *pkg, const char *control_file)
  498. {
  499. const char *control_path;
  500. struct stat st;
  501. control_path = pkg_infodb_get_file(pkg, &pkg->installed, control_file);
  502. if (stat(control_path, &st) < 0)
  503. return;
  504. if (!S_ISREG(st.st_mode))
  505. return;
  506. pkg_infodb_print_filename(control_path, control_file);
  507. }
  508. static int
  509. control_path(const char *const *argv)
  510. {
  511. struct dpkg_error err;
  512. struct pkginfo *pkg;
  513. const char *pkgname;
  514. const char *control_file;
  515. pkgname = *argv++;
  516. if (!pkgname)
  517. badusage(_("--%s needs at least one package name argument"),
  518. cipaction->olong);
  519. control_file = *argv++;
  520. if (control_file && *argv)
  521. badusage(_("--%s takes at most two arguments"), cipaction->olong);
  522. /* Validate control file name for sanity. */
  523. if (control_file) {
  524. const char *c;
  525. for (c = "/."; *c; c++)
  526. if (strchr(control_file, *c))
  527. badusage(_("control file contains %c"), *c);
  528. }
  529. modstatdb_open(msdbrw_readonly);
  530. pkg = pkg_spec_parse_pkg(pkgname, &err);
  531. if (pkg == NULL)
  532. badusage(_("--%s needs a valid package name but '%.250s' is not: %s"),
  533. cipaction->olong, pkgname, err.str);
  534. if (pkg->status == stat_notinstalled)
  535. ohshit(_("Package `%s' is not installed.\n"),
  536. pkg_name(pkg, pnaw_nonambig));
  537. if (control_file)
  538. control_path_file(pkg, control_file);
  539. else
  540. pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_print_filename);
  541. modstatdb_shutdown();
  542. return 0;
  543. }
  544. static void DPKG_ATTR_NORET
  545. printversion(const struct cmdinfo *ci, const char *value)
  546. {
  547. printf(_("Debian %s package management program query tool version %s.\n"),
  548. DPKGQUERY, DPKG_VERSION_ARCH);
  549. printf(_(
  550. "This is free software; see the GNU General Public License version 2 or\n"
  551. "later for copying conditions. There is NO warranty.\n"));
  552. m_output(stdout, _("<standard output>"));
  553. exit(0);
  554. }
  555. static void DPKG_ATTR_NORET
  556. usage(const struct cmdinfo *ci, const char *value)
  557. {
  558. printf(_(
  559. "Usage: %s [<option> ...] <command>\n"
  560. "\n"), DPKGQUERY);
  561. printf(_(
  562. "Commands:\n"
  563. " -s|--status <package> ... Display package status details.\n"
  564. " -p|--print-avail <package> ... Display available version details.\n"
  565. " -L|--listfiles <package> ... List files `owned' by package(s).\n"
  566. " -l|--list [<pattern> ...] List packages concisely.\n"
  567. " -W|--show [<pattern> ...] Show information on package(s).\n"
  568. " -S|--search <pattern> ... Find package(s) owning file(s).\n"
  569. " -c|--control-path <package> [<file>]\n"
  570. " Print path for package control file.\n"
  571. "\n"));
  572. printf(_(
  573. " -h|--help Show this help message.\n"
  574. " --version Show the version.\n"
  575. "\n"));
  576. printf(_(
  577. "Options:\n"
  578. " --admindir=<directory> Use <directory> instead of %s.\n"
  579. " --load-avail Use available file on --show and --list.\n"
  580. " -f|--showformat=<format> Use alternative format for --show.\n"
  581. "\n"), ADMINDIR);
  582. printf(_(
  583. "Format syntax:\n"
  584. " A format is a string that will be output for each package. The format\n"
  585. " can include the standard escape sequences \\n (newline), \\r (carriage\n"
  586. " return) or \\\\ (plain backslash). Package information can be included\n"
  587. " by inserting variable references to package fields using the ${var[;width]}\n"
  588. " syntax. Fields will be right-aligned unless the width is negative in which\n"
  589. " case left alignment will be used.\n"));
  590. m_output(stdout, _("<standard output>"));
  591. exit(0);
  592. }
  593. static const char printforhelp[] = N_(
  594. "Use --help for help about querying packages.");
  595. static const char *admindir;
  596. /* This table has both the action entries in it and the normal options.
  597. * The action entries are made with the ACTION macro, as they all
  598. * have a very similar structure. */
  599. static const struct cmdinfo cmdinfos[]= {
  600. ACTION( "listfiles", 'L', act_listfiles, enqperpackage ),
  601. ACTION( "status", 's', act_status, enqperpackage ),
  602. ACTION( "print-avail", 'p', act_printavail, enqperpackage ),
  603. ACTION( "list", 'l', act_listpackages, listpackages ),
  604. ACTION( "search", 'S', act_searchfiles, searchfiles ),
  605. ACTION( "show", 'W', act_listpackages, showpackages ),
  606. ACTION( "control-path", 'c', act_controlpath, control_path ),
  607. { "admindir", 0, 1, NULL, &admindir, NULL },
  608. { "load-avail", 0, 0, &opt_loadavail, NULL, NULL, 1 },
  609. { "showformat", 'f', 1, NULL, &showformat, NULL },
  610. { "help", 'h', 0, NULL, NULL, usage },
  611. { "version", 0, 0, NULL, NULL, printversion },
  612. { NULL, 0, 0, NULL, NULL, NULL }
  613. };
  614. int main(int argc, const char *const *argv) {
  615. int ret;
  616. setlocale(LC_ALL, "");
  617. bindtextdomain(PACKAGE, LOCALEDIR);
  618. textdomain(PACKAGE);
  619. dpkg_set_progname("dpkg-query");
  620. standard_startup();
  621. myopt(&argv, cmdinfos, printforhelp);
  622. admindir = dpkg_db_set_dir(admindir);
  623. if (!cipaction) badusage(_("need an action option"));
  624. setvbuf(stdout, NULL, _IONBF, 0);
  625. filesdbinit();
  626. ret = cipaction->action(argv);
  627. standard_shutdown();
  628. return !!ret;
  629. }