2 * dpkg - main program for package management
3 * enquiry.c - status enquiry and listing options
5 * Copyright © 1995,1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2006, 2008-2016 Guillem Jover <guillem@debian.org>
7 * Copyright © 2011 Linaro Limited
8 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
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.
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.
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/>.
27 #include <sys/types.h>
36 #include <dpkg/i18n.h>
37 #include <dpkg/dpkg.h>
38 #include <dpkg/dpkg-db.h>
39 #include <dpkg/arch.h>
40 #include <dpkg/pkg-array.h>
41 #include <dpkg/pkg-show.h>
42 #include <dpkg/triglib.h>
43 #include <dpkg/string.h>
44 #include <dpkg/options.h>
45 #include <dpkg/db-ctrl.h>
46 #include <dpkg/db-fsys.h>
50 struct audit_problem
{
51 bool (*check
)(struct pkginfo
*, const struct audit_problem
*problem
);
56 const char *explanation
;
60 audit_reinstreq(struct pkginfo
*pkg
, const struct audit_problem
*problem
)
62 return pkg
->eflag
& PKG_EFLAG_REINSTREQ
;
66 audit_status(struct pkginfo
*pkg
, const struct audit_problem
*problem
)
68 if (pkg
->eflag
& PKG_EFLAG_REINSTREQ
)
70 return (int)pkg
->status
== problem
->value
.number
;
74 audit_infofile(struct pkginfo
*pkg
, const struct audit_problem
*problem
)
76 if (pkg
->status
< PKG_STAT_HALFINSTALLED
)
78 return !pkg_infodb_has_file(pkg
, &pkg
->installed
, problem
->value
.string
);
82 audit_arch(struct pkginfo
*pkg
, const struct audit_problem
*problem
)
84 if (pkg
->status
< PKG_STAT_HALFINSTALLED
)
86 return pkg
->installed
.arch
->type
== (enum dpkg_arch_type
)problem
->value
.number
;
89 static const struct audit_problem audit_problems
[] = {
91 .check
= audit_reinstreq
,
94 "The following packages are in a mess due to serious problems during\n"
95 "installation. They must be reinstalled for them (and any packages\n"
96 "that depend on them) to function properly:\n")
98 .check
= audit_status
,
99 .value
.number
= PKG_STAT_UNPACKED
,
101 "The following packages have been unpacked but not yet configured.\n"
102 "They must be configured using dpkg --configure or the configure\n"
103 "menu option in dselect for them to work:\n")
105 .check
= audit_status
,
106 .value
.number
= PKG_STAT_HALFCONFIGURED
,
108 "The following packages are only half configured, probably due to problems\n"
109 "configuring them the first time. The configuration should be retried using\n"
110 "dpkg --configure <package> or the configure menu option in dselect:\n")
112 .check
= audit_status
,
113 .value
.number
= PKG_STAT_HALFINSTALLED
,
115 "The following packages are only half installed, due to problems during\n"
116 "installation. The installation can probably be completed by retrying it;\n"
117 "the packages can be removed using dselect or dpkg --remove:\n")
119 .check
= audit_status
,
120 .value
.number
= PKG_STAT_TRIGGERSAWAITED
,
122 "The following packages are awaiting processing of triggers that they\n"
123 "have activated in other packages. This processing can be requested using\n"
124 "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
126 .check
= audit_status
,
127 .value
.number
= PKG_STAT_TRIGGERSPENDING
,
129 "The following packages have been triggered, but the trigger processing\n"
130 "has not yet been done. Trigger processing can be requested using\n"
131 "dselect or dpkg --configure --pending (or dpkg --triggers-only):\n")
133 .check
= audit_infofile
,
134 .value
.string
= LISTFILE
,
136 "The following packages are missing the list control file in the\n"
137 "database, they need to be reinstalled:\n")
139 .check
= audit_infofile
,
140 .value
.string
= HASHFILE
,
142 "The following packages are missing the md5sums control file in the\n"
143 "database, they need to be reinstalled:\n")
146 .value
.number
= DPKG_ARCH_EMPTY
,
147 .explanation
= N_("The following packages do not have an architecture:\n")
150 .value
.number
= DPKG_ARCH_ILLEGAL
,
151 .explanation
= N_("The following packages have an illegal architecture:\n")
154 .value
.number
= DPKG_ARCH_UNKNOWN
,
156 "The following packages have an unknown foreign architecture, which will\n"
157 "cause dependency issues on front-ends. This can be fixed by registering\n"
158 "the foreign architecture with dpkg --add-architecture:\n")
164 static void describebriefly(struct pkginfo
*pkg
) {
169 l
= strlen(pkg
->set
->name
);
170 if (l
>20) maxl
-= (l
-20);
172 pdesc
= pkgbin_synopsis(pkg
, &pkg
->installed
, &l
);
175 printf(" %-20s %.*s\n", pkg_name(pkg
, pnaw_nonambig
), l
, pdesc
);
178 static struct pkginfo
*
179 pkg_array_mapper(const char *name
)
183 pkg
= dpkg_options_parse_pkgname(cipaction
, name
);
184 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
185 notice(_("package '%s' is not installed"), pkg_name(pkg
, pnaw_nonambig
));
191 audit(const char *const *argv
)
193 const struct audit_problem
*problem
;
194 struct pkg_array array
;
195 bool head_running
= false;
198 modstatdb_open(msdbrw_readonly
);
201 pkg_array_init_from_hash(&array
);
203 pkg_array_init_from_names(&array
, pkg_array_mapper
, (const char **)argv
);
205 pkg_array_sort(&array
, pkg_sorter_by_nonambig_name_arch
);
207 for (problem
= audit_problems
; problem
->check
; problem
++) {
210 for (i
= 0; i
< array
.n_pkgs
; i
++) {
211 struct pkginfo
*pkg
= array
.pkgs
[i
];
213 if (!problem
->check(pkg
, problem
))
216 if (modstatdb_is_locked())
218 "Another process has locked the database for writing, and might currently be\n"
219 "modifying it, some of the following problems might just be due to that.\n"));
223 fputs(gettext(problem
->explanation
), stdout
);
226 describebriefly(pkg
);
229 if (head
) putchar('\n');
232 pkg_array_destroy(&array
);
234 m_output(stdout
, _("<standard output>"));
239 struct sectionentry
{
240 struct sectionentry
*next
;
246 yettobeunpacked(struct pkginfo
*pkg
, const char **thissect
)
248 if (pkg
->want
!= PKG_WANT_INSTALL
)
251 switch (pkg
->status
) {
252 case PKG_STAT_UNPACKED
:
253 case PKG_STAT_INSTALLED
:
254 case PKG_STAT_HALFCONFIGURED
:
255 case PKG_STAT_TRIGGERSPENDING
:
256 case PKG_STAT_TRIGGERSAWAITED
:
258 case PKG_STAT_NOTINSTALLED
:
259 case PKG_STAT_HALFINSTALLED
:
260 case PKG_STAT_CONFIGFILES
:
262 *thissect
= str_is_set(pkg
->section
) ? pkg
->section
:
263 C_("section", "<unknown>");
266 internerr("unknown package status '%d'", pkg
->status
);
272 unpackchk(const char *const *argv
)
274 int totalcount
, sects
;
275 struct sectionentry
*sectionentries
, *se
, **sep
;
276 struct pkg_hash_iter
*iter
;
278 const char *thissect
;
283 badusage(_("--%s takes no arguments"), cipaction
->olong
);
285 modstatdb_open(msdbrw_readonly
);
288 sectionentries
= NULL
;
290 iter
= pkg_hash_iter_new();
291 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
292 if (!yettobeunpacked(pkg
, &thissect
)) continue;
293 for (se
= sectionentries
; se
&& strcasecmp(thissect
,se
->name
); se
= se
->next
);
295 se
= nfmalloc(sizeof(*se
));
296 for (sep
= §ionentries
;
297 *sep
&& strcasecmp(thissect
,(*sep
)->name
) > 0;
305 se
->count
++; totalcount
++;
307 pkg_hash_iter_free(iter
);
312 if (totalcount
<= 12) {
313 iter
= pkg_hash_iter_new();
314 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
315 if (!yettobeunpacked(pkg
, NULL
))
317 describebriefly(pkg
);
319 pkg_hash_iter_free(iter
);
320 } else if (sects
<= 12) {
321 for (se
= sectionentries
; se
; se
= se
->next
) {
322 sprintf(buf
,"%d",se
->count
);
323 printf(_(" %d in %s: "),se
->count
,se
->name
);
324 width
= 70-strlen(se
->name
)-strlen(buf
);
325 while (width
> 59) { putchar(' '); width
--; }
326 iter
= pkg_hash_iter_new();
327 while ((pkg
= pkg_hash_iter_next_pkg(iter
))) {
330 if (!yettobeunpacked(pkg
,&thissect
)) continue;
331 if (strcasecmp(thissect
,se
->name
)) continue;
332 pkgname
= pkg_name(pkg
, pnaw_nonambig
);
333 width
-= strlen(pkgname
);
335 if (width
< 4) { printf(" ..."); break; }
336 printf(" %s", pkgname
);
338 pkg_hash_iter_free(iter
);
342 printf(P_(" %d package, from the following section:",
343 " %d packages, from the following sections:", totalcount
),
346 for (se
= sectionentries
; se
; se
= se
->next
) {
347 sprintf(buf
,"%d",se
->count
);
348 width
-= (6 + strlen(se
->name
) + strlen(buf
));
349 if (width
< 0) { putchar('\n'); width
= 73 - strlen(se
->name
) - strlen(buf
); }
350 printf(" %s (%d)",se
->name
,se
->count
);
355 m_output(stdout
, _("<standard output>"));
360 static const struct assert_feature
{
364 } assert_features
[] = {
366 .name
= "support-predepends",
367 .desc
= N_("the Pre-Depends field"),
370 .name
= "working-epoch",
371 .desc
= N_("epochs in versions"),
372 .version
= "1.4.0.7",
374 .name
= "long-filenames",
375 .desc
= N_("long filenames in .deb archives"),
376 .version
= "1.4.1.17",
378 .name
= "multi-conrep",
379 .desc
= N_("multiple Conflicts and Replaces"),
380 .version
= "1.4.1.19",
382 .name
= "multi-arch",
383 .desc
= N_("multi-arch fields and semantics"),
386 .name
= "versioned-provides",
387 .desc
= N_("versioned relationships in the Provides field"),
388 .version
= "1.17.11",
390 .name
= "protected-field",
391 .desc
= N_("the Protected field"),
399 assert_version_support(const char *const *argv
,
400 const struct assert_feature
*feature
)
402 const char *running_version_str
;
403 struct dpkg_version running_version
= DPKG_VERSION_INIT
;
404 struct dpkg_version version
= { 0, feature
->version
, NULL
};
405 struct dpkg_error err
= DPKG_ERROR_INIT
;
408 badusage(_("--%s takes no arguments"), cipaction
->olong
);
411 * When using the feature asserts, we want to know whether the currently
412 * running dpkg, which we might be running under (say from within a
413 * maintainer script) and which might have a different version, supports
414 * the requested feature. As dpkg is an Essential package, it is expected
415 * to work even when just unpacked, and so its own version is enough.
417 running_version_str
= getenv("DPKG_RUNNING_VERSION");
420 * If we are not running from within a maintainer script, then that means
421 * once we do, the executed dpkg will support the requested feature, if
422 * we know about it. Always return success in that case.
424 if (str_is_unset(running_version_str
))
427 if (parseversion(&running_version
, running_version_str
, &err
) < 0)
428 ohshit(_("cannot parse dpkg running version '%s': %s"),
429 running_version_str
, err
.str
);
431 if (dpkg_version_relate(&running_version
, DPKG_RELATION_GE
, &version
))
434 printf(_("Running version of dpkg does not support %s.\n"
435 " Please upgrade to at least dpkg %s, and then try again.\n"),
436 feature
->desc
, versiondescribe(&version
, vdew_nonambig
));
440 const char *assert_feature_name
;
443 assert_feature(const char *const *argv
)
445 const struct assert_feature
*feature
;
447 if (strcmp(assert_feature_name
, "help") == 0) {
448 printf(_("%s assert options - assert whether features are supported:\n"),
449 dpkg_get_progname());
451 for (feature
= assert_features
; feature
->name
; feature
++) {
452 printf(" %-19s %-9s %s\n", feature
->name
, feature
->version
,
453 gettext(feature
->desc
));
459 for (feature
= assert_features
; feature
->name
; feature
++) {
460 if (strcmp(feature
->name
, assert_feature_name
) != 0)
463 return assert_version_support(argv
, feature
);
466 badusage(_("unknown --%s-<feature>"), cipaction
->olong
);
470 * Print a single package which:
471 * (a) is the target of one or more relevant predependencies.
472 * (b) has itself no unsatisfied pre-dependencies.
474 * If such a package is present output is the Packages file entry,
475 * which can be massaged as appropriate.
478 * 0 = a package printed, OK
479 * 1 = no suitable package available
483 predeppackage(const char *const *argv
)
485 static struct varbuf vb
;
487 struct pkg_hash_iter
*iter
;
488 struct pkginfo
*pkg
= NULL
, *startpkg
, *trypkg
;
489 struct dependency
*dep
;
490 struct deppossi
*possi
, *provider
;
493 badusage(_("--%s takes no arguments"), cipaction
->olong
);
495 modstatdb_open(msdbrw_readonly
| msdbrw_available_readonly
);
496 /* We use clientdata->istobe to detect loops. */
500 iter
= pkg_hash_iter_new();
501 while (!dep
&& (pkg
= pkg_hash_iter_next_pkg(iter
))) {
502 /* Ignore packages user doesn't want. */
503 if (pkg
->want
!= PKG_WANT_INSTALL
)
505 /* Ignore packages not available. */
508 pkg
->clientdata
->istobe
= PKG_ISTOBE_PREINSTALL
;
509 for (dep
= pkg
->available
.depends
; dep
; dep
= dep
->next
) {
510 if (dep
->type
!= dep_predepends
) continue;
511 if (depisok(dep
, &vb
, NULL
, NULL
, true))
513 /* This will leave dep non-NULL, and so exit the loop. */
516 pkg
->clientdata
->istobe
= PKG_ISTOBE_NORMAL
;
517 /* If dep is NULL we go and get the next package. */
519 pkg_hash_iter_free(iter
);
522 return 1; /* Not found. */
524 internerr("unexpected unfound package");
527 pkg
->clientdata
->istobe
= PKG_ISTOBE_PREINSTALL
;
529 /* OK, we have found an unsatisfied predependency.
530 * Now go and find the first thing we need to install, as a first step
531 * towards satisfying it. */
533 /* We search for a package which would satisfy dep, and put it in pkg. */
534 for (possi
= dep
->list
, pkg
= NULL
;
537 struct deppossi_pkg_iterator
*possi_iter
;
539 possi_iter
= deppossi_pkg_iter_new(possi
, wpb_available
);
540 while (!pkg
&& (trypkg
= deppossi_pkg_iter_next(possi_iter
))) {
541 if (trypkg
->archives
&&
542 trypkg
->clientdata
->istobe
== PKG_ISTOBE_NORMAL
&&
543 versionsatisfied(&trypkg
->available
, possi
)) {
547 for (provider
= possi
->ed
->depended
.available
;
549 provider
= provider
->next
) {
550 if (provider
->up
->type
!= dep_provides
)
552 if (!pkg_virtual_deppossi_satisfied(possi
, provider
))
554 trypkg
= provider
->up
->up
;
555 if (!trypkg
->archives
)
557 if (trypkg
->clientdata
->istobe
== PKG_ISTOBE_NORMAL
) {
563 deppossi_pkg_iter_free(possi_iter
);
567 describedepcon(&vb
,dep
);
568 notice(_("cannot see how to satisfy pre-dependency:\n %s"), vb
.buf
);
569 ohshit(_("cannot satisfy pre-dependencies for %.250s (wanted due to %.250s)"),
570 pkgbin_name(dep
->up
, &dep
->up
->available
, pnaw_nonambig
),
571 pkgbin_name(startpkg
, &startpkg
->available
, pnaw_nonambig
));
573 pkg
->clientdata
->istobe
= PKG_ISTOBE_PREINSTALL
;
574 for (dep
= pkg
->available
.depends
; dep
; dep
= dep
->next
) {
575 if (dep
->type
!= dep_predepends
) continue;
576 if (depisok(dep
, &vb
, NULL
, NULL
, true))
578 /* This will leave dep non-NULL, and so exit the loop. */
583 /* OK, we've found it - pkg has no unsatisfied pre-dependencies! */
584 write_stanza(stdout
, _("<standard output>"), pkg
, &pkg
->available
);
586 m_output(stdout
, _("<standard output>"));
592 printarch(const char *const *argv
)
595 badusage(_("--%s takes no arguments"), cipaction
->olong
);
597 printf("%s\n", dpkg_arch_get(DPKG_ARCH_NATIVE
)->name
);
599 m_output(stdout
, _("<standard output>"));
605 print_foreign_arches(const char *const *argv
)
607 struct dpkg_arch
*arch
;
610 badusage(_("--%s takes no arguments"), cipaction
->olong
);
612 dpkg_arch_load_list();
614 for (arch
= dpkg_arch_get_list(); arch
; arch
= arch
->next
) {
615 if (arch
->type
!= DPKG_ARCH_FOREIGN
)
618 printf("%s\n", arch
->name
);
621 m_output(stdout
, _("<standard output>"));
627 validate_pkgname(const char *const *argv
)
631 if (!argv
[0] || argv
[1])
632 badusage(_("--%s takes one <pkgname> argument"), cipaction
->olong
);
634 emsg
= pkg_name_is_illegal(argv
[0]);
636 ohshit(_("package name '%s' is invalid: %s"), argv
[0], emsg
);
642 validate_trigname(const char *const *argv
)
646 if (!argv
[0] || argv
[1])
647 badusage(_("--%s takes one <trigname> argument"), cipaction
->olong
);
649 emsg
= trig_name_is_illegal(argv
[0]);
651 ohshit(_("trigger name '%s' is invalid: %s"), argv
[0], emsg
);
657 validate_archname(const char *const *argv
)
661 if (!argv
[0] || argv
[1])
662 badusage(_("--%s takes one <archname> argument"), cipaction
->olong
);
664 emsg
= dpkg_arch_name_is_illegal(argv
[0]);
666 ohshit(_("architecture name '%s' is invalid: %s"), argv
[0], emsg
);
672 validate_version(const char *const *argv
)
674 struct dpkg_version version
;
675 struct dpkg_error err
;
677 if (!argv
[0] || argv
[1])
678 badusage(_("--%s takes one <version> argument"), cipaction
->olong
);
680 if (parseversion(&version
, argv
[0], &err
) < 0) {
681 dpkg_error_print(&err
, _("version '%s' has bad syntax"), argv
[0]);
682 dpkg_error_destroy(&err
);
691 cmpversions(const char *const *argv
)
693 struct relationinfo
{
695 /* These values are exit status codes. */
696 int if_lesser
, if_equal
, if_greater
;
697 int if_none_a
, if_none_both
, if_none_b
;
701 static const struct relationinfo relationinfos
[]= {
704 .if_lesser
= EXIT_SUCCESS
,
705 .if_equal
= EXIT_SUCCESS
,
706 .if_greater
= EXIT_FAILURE
,
707 .if_none_a
= EXIT_SUCCESS
,
708 .if_none_both
= EXIT_SUCCESS
,
709 .if_none_b
= EXIT_FAILURE
,
712 .if_lesser
= EXIT_SUCCESS
,
713 .if_equal
= EXIT_FAILURE
,
714 .if_greater
= EXIT_FAILURE
,
715 .if_none_a
= EXIT_SUCCESS
,
716 .if_none_both
= EXIT_FAILURE
,
717 .if_none_b
= EXIT_FAILURE
,
720 .if_lesser
= EXIT_FAILURE
,
721 .if_equal
= EXIT_SUCCESS
,
722 .if_greater
= EXIT_FAILURE
,
723 .if_none_a
= EXIT_FAILURE
,
724 .if_none_both
= EXIT_SUCCESS
,
725 .if_none_b
= EXIT_FAILURE
,
728 .if_lesser
= EXIT_SUCCESS
,
729 .if_equal
= EXIT_FAILURE
,
730 .if_greater
= EXIT_SUCCESS
,
731 .if_none_a
= EXIT_SUCCESS
,
732 .if_none_both
= EXIT_FAILURE
,
733 .if_none_b
= EXIT_SUCCESS
,
736 .if_lesser
= EXIT_FAILURE
,
737 .if_equal
= EXIT_SUCCESS
,
738 .if_greater
= EXIT_SUCCESS
,
739 .if_none_a
= EXIT_FAILURE
,
740 .if_none_both
= EXIT_SUCCESS
,
741 .if_none_b
= EXIT_SUCCESS
,
744 .if_lesser
= EXIT_FAILURE
,
745 .if_equal
= EXIT_FAILURE
,
746 .if_greater
= EXIT_SUCCESS
,
747 .if_none_a
= EXIT_FAILURE
,
748 .if_none_both
= EXIT_FAILURE
,
749 .if_none_b
= EXIT_SUCCESS
,
752 /* These treat an empty version as later than any version. */
755 .if_lesser
= EXIT_SUCCESS
,
756 .if_equal
= EXIT_SUCCESS
,
757 .if_greater
= EXIT_FAILURE
,
758 .if_none_a
= EXIT_FAILURE
,
759 .if_none_both
= EXIT_SUCCESS
,
760 .if_none_b
= EXIT_SUCCESS
,
763 .if_lesser
= EXIT_SUCCESS
,
764 .if_equal
= EXIT_FAILURE
,
765 .if_greater
= EXIT_FAILURE
,
766 .if_none_a
= EXIT_FAILURE
,
767 .if_none_both
= EXIT_FAILURE
,
768 .if_none_b
= EXIT_SUCCESS
,
771 .if_lesser
= EXIT_FAILURE
,
772 .if_equal
= EXIT_SUCCESS
,
773 .if_greater
= EXIT_SUCCESS
,
774 .if_none_a
= EXIT_SUCCESS
,
775 .if_none_both
= EXIT_SUCCESS
,
776 .if_none_b
= EXIT_FAILURE
,
779 .if_lesser
= EXIT_FAILURE
,
780 .if_equal
= EXIT_FAILURE
,
781 .if_greater
= EXIT_SUCCESS
,
782 .if_none_a
= EXIT_SUCCESS
,
783 .if_none_both
= EXIT_FAILURE
,
784 .if_none_b
= EXIT_FAILURE
,
787 /* For compatibility with dpkg control file syntax. */
790 .if_lesser
= EXIT_SUCCESS
,
791 .if_equal
= EXIT_SUCCESS
,
792 .if_greater
= EXIT_FAILURE
,
793 .if_none_a
= EXIT_SUCCESS
,
794 .if_none_both
= EXIT_SUCCESS
,
795 .if_none_b
= EXIT_FAILURE
,
799 .if_lesser
= EXIT_SUCCESS
,
800 .if_equal
= EXIT_SUCCESS
,
801 .if_greater
= EXIT_FAILURE
,
802 .if_none_a
= EXIT_SUCCESS
,
803 .if_none_both
= EXIT_SUCCESS
,
804 .if_none_b
= EXIT_FAILURE
,
807 .if_lesser
= EXIT_SUCCESS
,
808 .if_equal
= EXIT_FAILURE
,
809 .if_greater
= EXIT_FAILURE
,
810 .if_none_a
= EXIT_SUCCESS
,
811 .if_none_both
= EXIT_FAILURE
,
812 .if_none_b
= EXIT_FAILURE
,
815 .if_lesser
= EXIT_FAILURE
,
816 .if_equal
= EXIT_SUCCESS
,
817 .if_greater
= EXIT_FAILURE
,
818 .if_none_a
= EXIT_FAILURE
,
819 .if_none_both
= EXIT_SUCCESS
,
820 .if_none_b
= EXIT_FAILURE
,
823 .if_lesser
= EXIT_FAILURE
,
824 .if_equal
= EXIT_SUCCESS
,
825 .if_greater
= EXIT_SUCCESS
,
826 .if_none_a
= EXIT_FAILURE
,
827 .if_none_both
= EXIT_SUCCESS
,
828 .if_none_b
= EXIT_SUCCESS
,
832 .if_lesser
= EXIT_FAILURE
,
833 .if_equal
= EXIT_SUCCESS
,
834 .if_greater
= EXIT_SUCCESS
,
835 .if_none_a
= EXIT_FAILURE
,
836 .if_none_both
= EXIT_SUCCESS
,
837 .if_none_b
= EXIT_SUCCESS
,
840 .if_lesser
= EXIT_FAILURE
,
841 .if_equal
= EXIT_FAILURE
,
842 .if_greater
= EXIT_SUCCESS
,
843 .if_none_a
= EXIT_FAILURE
,
844 .if_none_both
= EXIT_FAILURE
,
845 .if_none_b
= EXIT_SUCCESS
,
851 const struct relationinfo
*rip
;
852 struct dpkg_version a
, b
;
853 struct dpkg_error err
;
856 if (!argv
[0] || !argv
[1] || !argv
[2] || argv
[3])
857 badusage(_("--compare-versions takes three arguments:"
858 " <version> <relation> <version>"));
860 for (rip
= relationinfos
; rip
->op
&& strcmp(rip
->op
, argv
[1]); rip
++)
864 badusage(_("--compare-versions bad relation"));
867 warning(_("--%s used with obsolete relation operator '%s'"),
868 cipaction
->olong
, rip
->op
);
870 if (*argv
[0] && strcmp(argv
[0],"<unknown>")) {
871 if (parseversion(&a
, argv
[0], &err
) < 0) {
872 dpkg_error_print(&err
, _("version '%s' has bad syntax"), argv
[0]);
873 dpkg_error_destroy(&err
);
876 dpkg_version_blank(&a
);
878 if (*argv
[2] && strcmp(argv
[2],"<unknown>")) {
879 if (parseversion(&b
, argv
[2], &err
) < 0) {
880 dpkg_error_print(&err
, _("version '%s' has bad syntax"), argv
[2]);
881 dpkg_error_destroy(&err
);
884 dpkg_version_blank(&b
);
886 if (!dpkg_version_is_informative(&a
)) {
887 if (dpkg_version_is_informative(&b
))
888 return rip
->if_none_a
;
890 return rip
->if_none_both
;
891 } else if (!dpkg_version_is_informative(&b
)) {
892 return rip
->if_none_b
;
894 rc
= dpkg_version_compare(&a
, &b
);
895 debug(dbg_general
, "cmpversions a='%s' b='%s' r=%d",
896 versiondescribe_c(&a
,vdew_always
),
897 versiondescribe_c(&b
,vdew_always
),
900 return rip
->if_greater
;
902 return rip
->if_lesser
;
904 return rip
->if_equal
;