Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * pkg-show.c - primitives for pkg information display
4 : : *
5 : : * Copyright © 1995,1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 : : * Copyright © 2008-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/macros.h>
28 : : #include <dpkg/i18n.h>
29 : : #include <dpkg/dpkg.h>
30 : : #include <dpkg/dpkg-db.h>
31 : : #include <dpkg/pkg-show.h>
32 : :
33 : : static bool
34 : 13 : pkgbin_name_needs_arch(const struct pkgbin *pkgbin,
35 : : enum pkg_name_arch_when pnaw)
36 : : {
37 [ + + ]: 13 : if (pkgbin->arch->type == DPKG_ARCH_NONE ||
38 [ - + ]: 5 : pkgbin->arch->type == DPKG_ARCH_EMPTY)
39 : 8 : return false;
40 : :
41 [ + + + - : 5 : switch (pnaw) {
+ - ]
42 : 1 : case pnaw_never:
43 : 1 : break;
44 : 2 : case pnaw_same:
45 [ + + ]: 2 : if (pkgbin->multiarch == PKG_MULTIARCH_SAME)
46 : 1 : return true;
47 : 1 : return false;
48 : 1 : case pnaw_nonambig:
49 [ - + ]: 1 : if (pkgbin->multiarch == PKG_MULTIARCH_SAME)
50 : 0 : return true;
51 : : /* Fall through. */
52 : : case pnaw_foreign:
53 [ + - ]: 1 : if (pkgbin->arch->type == DPKG_ARCH_NATIVE ||
54 [ + - ]: 1 : pkgbin->arch->type == DPKG_ARCH_ALL)
55 : : break;
56 : : /* Fall through. */
57 : : case pnaw_always:
58 : 2 : return true;
59 : : }
60 : :
61 : 1 : return false;
62 : : }
63 : :
64 : : /**
65 : : * Add a string representation of the package name to a varbuf.
66 : : *
67 : : * Works exactly like pkgbin_name() but acts on the varbuf instead of
68 : : * returning a string. It NUL terminates the varbuf.
69 : : *
70 : : * @param vb The varbuf struct to modify.
71 : : * @param pkg The package to consider.
72 : : * @param pkgbin The binary package instance to consider.
73 : : * @param pnaw When to display the architecture qualifier.
74 : : */
75 : : void
76 : 0 : varbuf_add_pkgbin_name(struct varbuf *vb,
77 : : const struct pkginfo *pkg, const struct pkgbin *pkgbin,
78 : : enum pkg_name_arch_when pnaw)
79 : : {
80 : 0 : varbuf_add_str(vb, pkg->set->name);
81 [ # # ]: 0 : if (pkgbin_name_needs_arch(pkgbin, pnaw))
82 : 0 : varbuf_add_archqual(vb, pkgbin->arch);
83 : 0 : varbuf_end_str(vb);
84 : 0 : }
85 : :
86 : : const char *
87 : 25 : pkgbin_name_archqual(const struct pkginfo *pkg, const struct pkgbin *pkgbin)
88 : : {
89 : : char *pkgname;
90 : :
91 [ + - ]: 25 : if (pkgbin->arch->type == DPKG_ARCH_NONE ||
92 [ - + ]: 25 : pkgbin->arch->type == DPKG_ARCH_EMPTY)
93 : 0 : return pkg->set->name;
94 : :
95 : 25 : pkgname = nfmalloc(strlen(pkg->set->name) + 1 +
96 : 25 : strlen(pkgbin->arch->name) + 1);
97 : 25 : str_concat(pkgname, pkg->set->name, ":",
98 : 25 : pkgbin->arch->name, NULL);
99 : :
100 : 25 : return pkgname;
101 : : }
102 : :
103 : : /**
104 : : * Return a string representation of the package name.
105 : : *
106 : : * The returned string must not be freed, and it's permanently allocated so
107 : : * can be used as long as the non-freeing memory pool has not been freed.
108 : : *
109 : : * Note, that this const variant will "leak" a new non-freeing string on
110 : : * each call if the internal cache has not been previously initialized,
111 : : * so it is advised to use it only in error reporting code paths.
112 : : *
113 : : * The pnaw parameter should be one of pnaw_never (never print arch),
114 : : * pnaw_foreign (print arch for foreign packages only), pnaw_nonambig (print
115 : : * arch for non ambiguous cases) or pnaw_always (always print arch),
116 : : *
117 : : * @param pkg The package to consider.
118 : : * @param pkgbin The binary package instance to consider.
119 : : * @param pnaw When to display the architecture qualifier.
120 : : *
121 : : * @return The string representation.
122 : : */
123 : : const char *
124 : 0 : pkgbin_name_const(const struct pkginfo *pkg, const struct pkgbin *pkgbin,
125 : : enum pkg_name_arch_when pnaw)
126 : : {
127 [ # # ]: 0 : if (!pkgbin_name_needs_arch(pkgbin, pnaw))
128 : 0 : return pkg->set->name;
129 : :
130 : : /* Return a non-freeing package name representation, which
131 : : * is intended to be used in error-handling code, as we will keep
132 : : * "leaking" them until the next memory pool flush. */
133 [ # # ]: 0 : if (pkgbin->pkgname_archqual == NULL)
134 : 0 : return pkgbin_name_archqual(pkg, pkgbin);
135 : :
136 : 0 : return pkgbin->pkgname_archqual;
137 : : }
138 : :
139 : : /**
140 : : * Return a string representation of the installed package name.
141 : : *
142 : : * This is equivalent to pkgbin_name_const() but just for its installed pkgbin.
143 : : *
144 : : * @param pkg The package to consider.
145 : : * @param pnaw When to display the architecture qualifier.
146 : : *
147 : : * @return The string representation.
148 : : */
149 : : const char *
150 : 0 : pkg_name_const(const struct pkginfo *pkg, enum pkg_name_arch_when pnaw)
151 : : {
152 : 0 : return pkgbin_name_const(pkg, &pkg->installed, pnaw);
153 : : }
154 : :
155 : : /**
156 : : * Return a string representation of the package name.
157 : : *
158 : : * The returned string must not be freed, and it's permanently allocated so
159 : : * can be used as long as the non-freeing memory pool has not been freed.
160 : : *
161 : : * The pnaw parameter should be one of pnaw_never (never print arch),
162 : : * pnaw_foreign (print arch for foreign packages only), pnaw_nonambig (print
163 : : * arch for non ambiguous cases) or pnaw_always (always print arch),
164 : : *
165 : : * @param pkg The package to consider.
166 : : * @param pkgbin The binary package instance to consider.
167 : : * @param pnaw When to display the architecture qualifier.
168 : : *
169 : : * @return The string representation.
170 : : */
171 : : const char *
172 : 13 : pkgbin_name(struct pkginfo *pkg, struct pkgbin *pkgbin,
173 : : enum pkg_name_arch_when pnaw)
174 : : {
175 [ + + ]: 13 : if (!pkgbin_name_needs_arch(pkgbin, pnaw))
176 : 10 : return pkg->set->name;
177 : :
178 : : /* Cache the package name representation, for later reuse. */
179 [ + + ]: 3 : if (pkgbin->pkgname_archqual == NULL)
180 : 1 : pkgbin->pkgname_archqual = pkgbin_name_archqual(pkg, pkgbin);
181 : :
182 : 3 : return pkgbin->pkgname_archqual;
183 : : }
184 : :
185 : : /**
186 : : * Return a string representation of the installed package name.
187 : : *
188 : : * This is equivalent to pkgbin_name() but just for its installed pkgbin.
189 : : *
190 : : * @param pkg The package to consider.
191 : : * @param pnaw When to display the architecture qualifier.
192 : : *
193 : : * @return The string representation.
194 : : */
195 : : const char *
196 : 5 : pkg_name(struct pkginfo *pkg, enum pkg_name_arch_when pnaw)
197 : : {
198 : 5 : return pkgbin_name(pkg, &pkg->installed, pnaw);
199 : : }
200 : :
201 : : /**
202 : : * Return a string representation of the package synopsis.
203 : : *
204 : : * The returned string must not be freed, and it's permanently allocated so
205 : : * can be used as long as the non-freeing memory pool has not been freed.
206 : : *
207 : : * The package synopsis is the short description, but it is not NUL terminated,
208 : : * so the output len argument should be used to limit the string length.
209 : : *
210 : : * @param pkg The package to consider.
211 : : * @param pkgbin The binary package instance to consider.
212 : : * @param[out] len The length of the synopsis string within the description.
213 : : *
214 : : * @return The string representation.
215 : : */
216 : : const char *
217 : 2 : pkgbin_synopsis(const struct pkginfo *pkg, const struct pkgbin *pkgbin, int *len)
218 : : {
219 : : const char *pdesc;
220 : :
221 : 2 : pdesc = pkgbin->description;
222 [ - + ]: 2 : if (!pdesc)
223 : 0 : pdesc = _("(no description available)");
224 : :
225 : 2 : *len = strcspn(pdesc, "\n");
226 : :
227 : 2 : return pdesc;
228 : : }
229 : :
230 : : /**
231 : : * Return a string representation of the package synopsis.
232 : : *
233 : : * The returned string must not be freed, and it's permanently allocated so
234 : : * can be used as long as the non-freeing memory pool has not been freed.
235 : : *
236 : : * It will try to use the installed version, otherwise it will fallback to
237 : : * use the available version.
238 : : *
239 : : * The package synopsis is the short description, but it is not NUL terminated,
240 : : * so the output len argument should be used to limit the string length.
241 : : *
242 : : * @param pkg The package to consider.
243 : : * @param[out] len The length of the synopsis string within the description.
244 : : *
245 : : * @return The string representation.
246 : : */
247 : : const char *
248 : 0 : pkg_synopsis(const struct pkginfo *pkg, int *len)
249 : : {
250 : : const char *pdesc;
251 : :
252 : 0 : pdesc = pkg->installed.description;
253 [ # # ]: 0 : if (!pdesc)
254 : 0 : pdesc = pkg->available.description;
255 [ # # ]: 0 : if (!pdesc)
256 : 0 : pdesc = _("(no description available)");
257 : :
258 : 0 : *len = strcspn(pdesc, "\n");
259 : :
260 : 0 : return pdesc;
261 : : }
262 : :
263 : : /**
264 : : * Return a character abbreviated representation of the package want status.
265 : : *
266 : : * @param pkg The package to consider.
267 : : *
268 : : * @return The character abbreviated representation.
269 : : */
270 : : int
271 : 0 : pkg_abbrev_want(const struct pkginfo *pkg)
272 : : {
273 : 0 : return "uihrp"[pkg->want];
274 : : }
275 : :
276 : : /**
277 : : * Return a character abbreviated representation of the package current status.
278 : : *
279 : : * @param pkg The package to consider.
280 : : *
281 : : * @return The character abbreviated representation.
282 : : */
283 : : int
284 : 0 : pkg_abbrev_status(const struct pkginfo *pkg)
285 : : {
286 : 0 : return "ncHUFWti"[pkg->status];
287 : : }
288 : :
289 : : /**
290 : : * Return a character abbreviated representation of the package eflag status.
291 : : *
292 : : * @param pkg The package to consider.
293 : : *
294 : : * @return The character abbreviated representation.
295 : : */
296 : : int
297 : 0 : pkg_abbrev_eflag(const struct pkginfo *pkg)
298 : : {
299 : 0 : return " R"[pkg->eflag];
300 : : }
301 : :
302 : : /**
303 : : * Return a string representation of the package want status name.
304 : : *
305 : : * @param pkg The package to consider.
306 : : *
307 : : * @return The string representation.
308 : : */
309 : : const char *
310 : 0 : pkg_want_name(const struct pkginfo *pkg)
311 : : {
312 : 0 : return wantinfos[pkg->want].name;
313 : : }
314 : :
315 : : /**
316 : : * Return a string representation of the package eflag status name.
317 : : *
318 : : * @param pkg The package to consider.
319 : : *
320 : : * @return The string representation.
321 : : */
322 : : const char *
323 : 0 : pkg_eflag_name(const struct pkginfo *pkg)
324 : : {
325 : 0 : return eflaginfos[pkg->eflag].name;
326 : : }
327 : :
328 : : /**
329 : : * Return a string representation of the package current status name.
330 : : *
331 : : * @param pkg The package to consider.
332 : : *
333 : : * @return The string representation.
334 : : */
335 : : const char *
336 : 0 : pkg_status_name(const struct pkginfo *pkg)
337 : : {
338 : 0 : return statusinfos[pkg->status].name;
339 : : }
340 : :
341 : : /**
342 : : * Return a string representation of the package priority name.
343 : : *
344 : : * @param pkg The package to consider.
345 : : *
346 : : * @return The string representation.
347 : : */
348 : : const char *
349 : 2 : pkg_priority_name(const struct pkginfo *pkg)
350 : : {
351 [ - + ]: 2 : if (pkg->priority == PKG_PRIO_OTHER)
352 : 0 : return pkg->otherpriority;
353 : : else
354 : 2 : return priorityinfos[pkg->priority].name;
355 : : }
356 : :
357 : : /**
358 : : * Compare a package to be sorted by non-ambiguous name and architecture.
359 : : *
360 : : * @param a A pointer of a pointer to a struct pkginfo.
361 : : * @param b A pointer of a pointer to a struct pkginfo.
362 : : *
363 : : * @return An integer with the result of the comparison.
364 : : * @retval -1 a is earlier than b.
365 : : * @retval 0 a is equal to b.
366 : : * @retval 1 a is later than b.
367 : : */
368 : : int
369 : 0 : pkg_sorter_by_nonambig_name_arch(const void *a, const void *b)
370 : : {
371 : 0 : const struct pkginfo *pa = *(const struct pkginfo **)a;
372 : 0 : const struct pkginfo *pb = *(const struct pkginfo **)b;
373 : 0 : const struct pkgbin *pbina = &pa->installed;
374 : 0 : const struct pkgbin *pbinb = &pb->installed;
375 : : int res;
376 : :
377 : 0 : res = strcmp(pa->set->name, pb->set->name);
378 [ # # ]: 0 : if (res)
379 : 0 : return res;
380 : :
381 [ # # ]: 0 : if (pbina->arch == pbinb->arch)
382 : 0 : return 0;
383 : :
384 [ # # ]: 0 : if (pkgbin_name_needs_arch(pbina, pnaw_nonambig)) {
385 [ # # ]: 0 : if (pkgbin_name_needs_arch(pbinb, pnaw_nonambig))
386 : 0 : return strcmp(pbina->arch->name, pbinb->arch->name);
387 : : else
388 : 0 : return 1;
389 : : } else {
390 : 0 : return -1;
391 : : }
392 : : }
393 : :
394 : : /**
395 : : * Add a string representation of the source package version to a varbuf.
396 : : *
397 : : * It parses the Source field (if present), and extracts the optional
398 : : * version enclosed in parenthesis. Otherwise it fallsback to use the
399 : : * binary package version. It NUL terminates the varbuf.
400 : : *
401 : : * @param vb The varbuf struct to modify.
402 : : * @param pkg The package to consider.
403 : : * @param pkgbin The binary package instance to consider.
404 : : */
405 : : void
406 : 3 : varbuf_add_source_version(struct varbuf *vb,
407 : : const struct pkginfo *pkg, const struct pkgbin *pkgbin)
408 : : {
409 : 3 : struct dpkg_version version = DPKG_VERSION_INIT;
410 : :
411 : 3 : pkg_source_version(&version, pkg, pkgbin);
412 : 3 : varbufversion(vb, &version, vdew_nonambig);
413 : 3 : varbuf_end_str(vb);
414 : 3 : }
415 : :
416 : : void
417 : 5 : pkg_source_version(struct dpkg_version *version,
418 : : const struct pkginfo *pkg, const struct pkgbin *pkgbin)
419 : : {
420 : : const char *version_str;
421 : :
422 [ + + ]: 5 : if (pkgbin->source)
423 : 4 : version_str = strchr(pkgbin->source, '(');
424 : : else
425 : 1 : version_str = NULL;
426 : :
427 [ + + ]: 5 : if (version_str == NULL) {
428 : 3 : *version = pkgbin->version;
429 : : } else {
430 : : struct dpkg_error err;
431 : 2 : struct varbuf vb = VARBUF_INIT;
432 : : size_t len;
433 : :
434 : 2 : version_str++;
435 : 2 : len = strcspn(version_str, ")");
436 : 2 : varbuf_add_buf(&vb, version_str, len);
437 : 2 : varbuf_end_str(&vb);
438 : :
439 [ - + ]: 2 : if (parseversion(version, vb.buf, &err) < 0)
440 : 0 : ohshit(_("version '%s' has bad syntax: %s"),
441 : : vb.buf, err.str);
442 : : }
443 : 5 : }
|