1 /*
2 * libdpkg - Debian packaging suite library routines
3 * pkg.c - primitives for pkg handling
4 *
5 * Copyright © 1995, 1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2009-2014 Guillem Jover <guillem@debian.org>
7 *
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <compat.h>
24
25 #include <string.h>
26
27 #include <dpkg/ehandle.h>
28 #include <dpkg/string.h>
29 #include <dpkg/dpkg-db.h>
30 #include <dpkg/pkg.h>
31
32 /**
33 * Set the package installation status.
34 */
35 void
pkg_set_status(struct pkginfo * pkg,enum pkgstatus status)36 pkg_set_status(struct pkginfo *pkg, enum pkgstatus status)
37 {
38 if (pkg->status == status)
39 return;
40 else if (pkg->status == PKG_STAT_NOTINSTALLED)
41 pkg->set->installed_instances++;
42 else if (status == PKG_STAT_NOTINSTALLED)
43 pkg->set->installed_instances--;
44
45 if (pkg->set->installed_instances < 0)
46 internerr("pkgset %s went into negative installed instances %d",
47 pkg->set->name, pkg->set->installed_instances);
48
49 pkg->status = status;
50 pkg->status_dirty = true;
51 }
52
53 /**
54 * Set the specified flags to 1 in the package error flags.
55 */
56 void
pkg_set_eflags(struct pkginfo * pkg,enum pkgeflag eflag)57 pkg_set_eflags(struct pkginfo *pkg, enum pkgeflag eflag)
58 {
59 pkg->eflag |= eflag;
60 }
61
62 /**
63 * Clear the specified flags to 0 in the package error flags.
64 */
65 void
pkg_clear_eflags(struct pkginfo * pkg,enum pkgeflag eflag)66 pkg_clear_eflags(struct pkginfo *pkg, enum pkgeflag eflag)
67 {
68 pkg->eflag &= ~eflag;
69 }
70
71 /**
72 * Reset the package error flags to 0.
73 */
74 void
pkg_reset_eflags(struct pkginfo * pkg)75 pkg_reset_eflags(struct pkginfo *pkg)
76 {
77 pkg->eflag = PKG_EFLAG_OK;
78 }
79
80 /**
81 * Copy the package error flags to another package.
82 */
83 void
pkg_copy_eflags(struct pkginfo * pkg_dst,struct pkginfo * pkg_src)84 pkg_copy_eflags(struct pkginfo *pkg_dst, struct pkginfo *pkg_src)
85 {
86 pkg_dst->eflag = pkg_src->eflag;
87 }
88
89 /**
90 * Set the package selection status.
91 */
92 void
pkg_set_want(struct pkginfo * pkg,enum pkgwant want)93 pkg_set_want(struct pkginfo *pkg, enum pkgwant want)
94 {
95 pkg->want = want;
96 }
97
98 void
pkgbin_blank(struct pkgbin * pkgbin)99 pkgbin_blank(struct pkgbin *pkgbin)
100 {
101 pkgbin->essential = false;
102 pkgbin->depends = NULL;
103 pkgbin->pkgname_archqual = NULL;
104 pkgbin->description = NULL;
105 pkgbin->maintainer = NULL;
106 pkgbin->source = NULL;
107 pkgbin->installedsize = NULL;
108 pkgbin->bugs = NULL;
109 pkgbin->origin = NULL;
110 dpkg_version_blank(&pkgbin->version);
111 pkgbin->conffiles = NULL;
112 pkgbin->arbs = NULL;
113 }
114
115 void
pkg_blank(struct pkginfo * pkg)116 pkg_blank(struct pkginfo *pkg)
117 {
118 pkg->status = PKG_STAT_NOTINSTALLED;
119 pkg->status_dirty = false;
120 pkg->eflag = PKG_EFLAG_OK;
121 pkg->want = PKG_WANT_UNKNOWN;
122 pkg->priority = PKG_PRIO_UNKNOWN;
123 pkg->otherpriority = NULL;
124 pkg->section = NULL;
125 dpkg_version_blank(&pkg->configversion);
126 pkg->files_list_valid = false;
127 pkg->files_list_phys_offs = 0;
128 pkg->files = NULL;
129 pkg->archives = NULL;
130 pkg->clientdata = NULL;
131 pkg->trigaw.head = NULL;
132 pkg->trigaw.tail = NULL;
133 pkg->othertrigaw_head = NULL;
134 pkg->trigpend_head = NULL;
135 pkgbin_blank(&pkg->installed);
136 pkgbin_blank(&pkg->available);
137
138 /* The architectures are reset here (instead of in pkgbin_blank),
139 * because they are part of the package specification, and needed
140 * for selections. */
141 pkg->installed.arch = dpkg_arch_get(DPKG_ARCH_NONE);
142 pkg->installed.multiarch = PKG_MULTIARCH_NO;
143 pkg->available.arch = dpkg_arch_get(DPKG_ARCH_NONE);
144 pkg->available.multiarch = PKG_MULTIARCH_NO;
145 }
146
147 void
pkgset_blank(struct pkgset * set)148 pkgset_blank(struct pkgset *set)
149 {
150 set->name = NULL;
151 set->depended.available = NULL;
152 set->depended.installed = NULL;
153 pkg_blank(&set->pkg);
154 set->installed_instances = 0;
155 set->pkg.set = set;
156 set->pkg.arch_next = NULL;
157 }
158
159 /**
160 * Link a pkginfo instance into a package set.
161 *
162 * @param set The package set to use.
163 * @param pkg The package to link into the set.
164 */
165 void
pkgset_link_pkg(struct pkgset * set,struct pkginfo * pkg)166 pkgset_link_pkg(struct pkgset *set, struct pkginfo *pkg)
167 {
168 pkg->set = set;
169 pkg->arch_next = set->pkg.arch_next;
170 set->pkg.arch_next = pkg;
171 }
172
173 /**
174 * Get the number of installed package instances in a package set.
175 *
176 * @param set The package set to use.
177 *
178 * @return The count of installed packages.
179 */
180 int
pkgset_installed_instances(struct pkgset * set)181 pkgset_installed_instances(struct pkgset *set)
182 {
183 return set->installed_instances;
184 }
185
186 /**
187 * Check if a pkg is informative.
188 *
189 * Used by dselect and dpkg query options as an aid to decide whether to
190 * display things, and by dump to decide whether to write them out.
191 */
192 bool
pkg_is_informative(struct pkginfo * pkg,struct pkgbin * pkgbin)193 pkg_is_informative(struct pkginfo *pkg, struct pkgbin *pkgbin)
194 {
195 /* We ignore Section and Priority, as these tend to hang around. */
196 if (pkgbin == &pkg->installed &&
197 (pkg->want != PKG_WANT_UNKNOWN ||
198 pkg->eflag != PKG_EFLAG_OK ||
199 pkg->status != PKG_STAT_NOTINSTALLED ||
200 dpkg_version_is_informative(&pkg->configversion)))
201 return true;
202
203 if (pkgbin->depends ||
204 str_is_set(pkgbin->description) ||
205 str_is_set(pkgbin->maintainer) ||
206 str_is_set(pkgbin->origin) ||
207 str_is_set(pkgbin->bugs) ||
208 str_is_set(pkgbin->installedsize) ||
209 str_is_set(pkgbin->source) ||
210 dpkg_version_is_informative(&pkgbin->version) ||
211 pkgbin->conffiles ||
212 pkgbin->arbs)
213 return true;
214
215 return false;
216 }
217