1 /*
2 * Copyright (C) 2012-2014 Red Hat, Inc.
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dnf-package
23 * @short_description: Package
24 * @include: libdnf.h
25 * @stability: Unstable
26 *
27 * An object representing a package in the system.
28 *
29 * See also: #DnfContext
30 */
31
32 #include "libdnf/utils/utils.hpp"
33
34 #include <algorithm>
35 #include <ctime>
36 #include <stdlib.h>
37 #include <solv/evr.h>
38 #include <solv/pool.h>
39 #include <solv/repo.h>
40 #include <solv/queue.h>
41
42 #include "dnf-advisory-private.hpp"
43 #include "dnf-packagedelta-private.hpp"
44 #include "dnf-sack-private.hpp"
45 #include "hy-iutil-private.hpp"
46 #include "hy-package-private.hpp"
47 #include "hy-repo-private.hpp"
48 #include "repo/solvable/DependencyContainer.hpp"
49 #include "sack/advisorymodule.hpp"
50
51 #define BLOCK_SIZE 31
52
53 typedef struct
54 {
55 gboolean loaded;
56 Id id;
57 DnfSack *sack;
58 } DnfPackagePrivate;
59
G_DEFINE_TYPE_WITH_PRIVATE(DnfPackage,dnf_package,G_TYPE_OBJECT)60 G_DEFINE_TYPE_WITH_PRIVATE(DnfPackage, dnf_package, G_TYPE_OBJECT)
61 #define GET_PRIVATE(o) (static_cast<DnfPackagePrivate *>(dnf_package_get_instance_private (o)))
62
63 /**
64 * dnf_package_finalize:
65 **/
66 static void
67 dnf_package_finalize(GObject *object)
68 {
69 G_OBJECT_CLASS(dnf_package_parent_class)->finalize(object);
70 }
71
72 /**
73 * dnf_package_init:
74 **/
75 static void
dnf_package_init(DnfPackage * package)76 dnf_package_init(DnfPackage *package)
77 {
78 }
79
80 /**
81 * dnf_package_class_init:
82 **/
83 static void
dnf_package_class_init(DnfPackageClass * klass)84 dnf_package_class_init(DnfPackageClass *klass)
85 {
86 GObjectClass *object_class = G_OBJECT_CLASS(klass);
87 object_class->finalize = dnf_package_finalize;
88 }
89
90
91 /**
92 * dnf_package_new:
93 *
94 * Creates a new #DnfPackage.
95 *
96 * Returns:(transfer full): a #DnfPackage
97 *
98 * Since: 0.7.0
99 **/
100 DnfPackage *
dnf_package_new(DnfSack * sack,Id id)101 dnf_package_new(DnfSack *sack, Id id)
102 {
103 auto pkg = DNF_PACKAGE(g_object_new(DNF_TYPE_PACKAGE, NULL));
104 auto priv = GET_PRIVATE(pkg);
105 priv->sack = sack;
106 priv->id = id;
107 return pkg;
108 }
109
110
111 /* internal */
112 static Solvable *
get_solvable(DnfPackage * pkg)113 get_solvable(DnfPackage *pkg)
114 {
115 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
116 return pool_id2solvable(dnf_package_get_pool(pkg), priv->id);
117 }
118
119 /**
120 * dnf_package_get_pool: (skip)
121 * @pkg: a #DnfPackage instance.
122 *
123 * Gets the pool used for storage.
124 *
125 * Returns: (transfer none): a %Pool
126 *
127 * Since: 0.7.0
128 */
129 Pool *
dnf_package_get_pool(DnfPackage * pkg)130 dnf_package_get_pool(DnfPackage *pkg)
131 {
132 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
133 return dnf_sack_get_pool(priv->sack);
134 }
135
136 static guint64
lookup_num(DnfPackage * pkg,unsigned type)137 lookup_num(DnfPackage *pkg, unsigned type)
138 {
139 Solvable *s = get_solvable(pkg);
140 repo_internalize_trigger(s->repo);
141 return solvable_lookup_num(s, type, 0);
142 }
143
144 static DnfReldepList *
reldeps_for(DnfPackage * pkg,Id type)145 reldeps_for(DnfPackage *pkg, Id type)
146 {
147 Solvable *s = get_solvable(pkg);
148 DnfReldepList *reldeplist;
149 Queue q;
150 Id marker = -1;
151 Id solv_type = type;
152
153 if (type == SOLVABLE_REQUIRES)
154 marker = -1;
155
156 if (type == SOLVABLE_PREREQMARKER) {
157 solv_type = SOLVABLE_REQUIRES;
158 marker = 1;
159 }
160 queue_init(&q);
161 solvable_lookup_deparray(s, solv_type, &q, marker);
162
163 reldeplist = new libdnf::DependencyContainer(dnf_package_get_sack(pkg), std::move(q));
164
165 return reldeplist;
166 }
167
168 /**
169 * dnf_package_get_id: (skip):
170 * @pkg: a #DnfPackage instance.
171 *
172 * Gets the internal ID used to identify the package in the pool.
173 *
174 * Returns: an integer, or 0 for unknown
175 *
176 * Since: 0.7.0
177 */
178 Id
dnf_package_get_id(DnfPackage * pkg)179 dnf_package_get_id(DnfPackage *pkg)
180 {
181 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
182 return priv->id;
183 }
184
185 /**
186 * dnf_package_get_sack:
187 * @pkg: a #DnfPackage instance.
188 *
189 * Gets the package sack for the package.
190 *
191 * Returns: a #DnfSack, or %NULL
192 *
193 * Since: 0.7.0
194 */
195 DnfSack *
dnf_package_get_sack(DnfPackage * pkg)196 dnf_package_get_sack(DnfPackage *pkg)
197 {
198 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
199 return priv->sack;
200 }
201
202 /**
203 * dnf_package_get_identical:
204 * @pkg1: a #DnfPackage instance.
205 * @pkg2: another #DnfPackage instance.
206 *
207 * Tests two packages for equality.
208 *
209 * Returns: %TRUE if the packages are the same
210 *
211 * Since: 0.7.0
212 */
213 gboolean
dnf_package_get_identical(DnfPackage * pkg1,DnfPackage * pkg2)214 dnf_package_get_identical(DnfPackage *pkg1, DnfPackage *pkg2)
215 {
216 DnfPackagePrivate *priv1 = GET_PRIVATE(pkg1);
217 DnfPackagePrivate *priv2 = GET_PRIVATE(pkg2);
218 return priv1->id == priv2->id;
219 }
220
221 /**
222 * dnf_package_installed:
223 * @pkg: a #DnfPackage instance.
224 *
225 * Tests if the package is installed.
226 *
227 * Returns: %TRUE if installed
228 *
229 * Since: 0.7.0
230 */
231 gboolean
dnf_package_installed(DnfPackage * pkg)232 dnf_package_installed(DnfPackage *pkg)
233 {
234 Solvable *s = get_solvable(pkg);
235 return (dnf_package_get_pool(pkg)->installed == s->repo);
236 }
237
238 /**
239 * dnf_package_cmp:
240 * @pkg1: a #DnfPackage instance.
241 * @pkg2: another #DnfPackage instance.
242 *
243 * Compares two packages.
244 *
245 * Returns: %TRUE for success
246 *
247 * Since: 0.7.0
248 */
249 int
dnf_package_cmp(DnfPackage * pkg1,DnfPackage * pkg2)250 dnf_package_cmp(DnfPackage *pkg1, DnfPackage *pkg2)
251 {
252 Pool *pool1 = dnf_package_get_pool(pkg1);
253 Pool *pool2 = dnf_package_get_pool(pkg2);
254 Solvable *s1 = pool_id2solvable(pool1, dnf_package_get_id(pkg1));
255 Solvable *s2 = pool_id2solvable(pool2, dnf_package_get_id(pkg2));
256 const char *str1 = pool_id2str(pool1, s1->name);
257 const char *str2 = pool_id2str(pool2, s2->name);
258 int ret = strcmp(str1, str2);
259 if (ret)
260 return ret;
261
262 ret = dnf_package_evr_cmp(pkg1, pkg2);
263 if (ret)
264 return ret;
265
266 str1 = pool_id2str(pool1, s1->arch);
267 str2 = pool_id2str(pool2, s2->arch);
268 return strcmp(str1, str2);
269 }
270
271 /**
272 * dnf_package_evr_cmp:
273 * @pkg1: a #DnfPackage instance.
274 * @pkg2: another #DnfPackage instance.
275 *
276 * Compares two packages, only using the EVR values.
277 *
278 * Returns: %TRUE for success
279 *
280 * Since: 0.7.0
281 */
282 int
dnf_package_evr_cmp(DnfPackage * pkg1,DnfPackage * pkg2)283 dnf_package_evr_cmp(DnfPackage *pkg1, DnfPackage *pkg2)
284 {
285 Pool *pool1 = dnf_package_get_pool(pkg1);
286 Pool *pool2 = dnf_package_get_pool(pkg2);
287 Solvable *s1 = get_solvable(pkg1);
288 Solvable *s2 = get_solvable(pkg2);
289 const char *str1 = pool_id2str(pool1, s1->evr);
290 const char *str2 = pool_id2str(pool2, s2->evr);
291
292 return pool_evrcmp_str(dnf_package_get_pool(pkg1), str1, str2, EVRCMP_COMPARE);
293 }
294
295 /**
296 * dnf_package_get_location:
297 * @pkg: a #DnfPackage instance.
298 *
299 * Gets the location (XXX??) for the package. Note that the returned string has
300 * an undefined lifetime and may become invalid at a later time. You should copy
301 * the string if storing it into a long-lived data structure.
302 *
303 * Returns: (transfer none): string
304 *
305 * Since: 0.7.0
306 */
307 const char *
dnf_package_get_location(DnfPackage * pkg)308 dnf_package_get_location(DnfPackage *pkg)
309 {
310 Solvable *s = get_solvable(pkg);
311 repo_internalize_trigger(s->repo);
312 return solvable_get_location(s, NULL);
313 }
314
315 /**
316 * dnf_package_get_baseurl:
317 * @pkg: a #DnfPackage instance.
318 *
319 * Gets the baseurl for the package.
320 *
321 * Returns: a string, or %NULL
322 *
323 * Since: 0.7.0
324 */
325 const char *
dnf_package_get_baseurl(DnfPackage * pkg)326 dnf_package_get_baseurl(DnfPackage *pkg)
327 {
328 Solvable *s = get_solvable(pkg);
329 return solvable_lookup_str(s, SOLVABLE_MEDIABASE);
330 }
331
332 /**
333 * dnf_package_get_nevra:
334 * @pkg: a #DnfPackage instance.
335 *
336 * Gets the package NEVRA. Note that the returned string has an undefined
337 * lifetime and may become invalid at a later time. You should copy the string
338 * if storing it into a long-lived data structure.
339 *
340 * Returns: (transfer none): a string, or %NULL
341 *
342 * Since: 0.7.0
343 */
344 const char *
dnf_package_get_nevra(DnfPackage * pkg)345 dnf_package_get_nevra(DnfPackage *pkg)
346 {
347 Solvable *s = get_solvable(pkg);
348 return pool_solvable2str(dnf_package_get_pool(pkg), s);
349 }
350
351 /**
352 * dnf_package_get_sourcerpm:
353 * @pkg: a #DnfPackage instance.
354 *
355 * Gets the source RPM for the package.
356 *
357 * Returns: (transfer none): a string, or %NULL
358 *
359 * Since: 0.7.0
360 */
361 const char *
dnf_package_get_sourcerpm(DnfPackage * pkg)362 dnf_package_get_sourcerpm(DnfPackage *pkg)
363 {
364 Solvable *s = get_solvable(pkg);
365 repo_internalize_trigger(s->repo);
366 return solvable_lookup_sourcepkg(s);
367 }
368
369 /**
370 * dnf_package_get_version:
371 * @pkg: a #DnfPackage instance.
372 *
373 * Gets the version for the package.
374 *
375 * Returns: (transfer none): a string, or %NULL
376 *
377 * Since: 0.7.0
378 */
379 const char *
dnf_package_get_version(DnfPackage * pkg)380 dnf_package_get_version(DnfPackage *pkg)
381 {
382 char *e, *v, *r;
383 pool_split_evr(dnf_package_get_pool(pkg), dnf_package_get_evr(pkg), &e, &v, &r);
384 return v;
385 }
386
387 /**
388 * dnf_package_get_release:
389 * @pkg: a #DnfPackage instance.
390 *
391 * Gets the release for the package.
392 *
393 * Returns: (transfer none): a string, or %NULL
394 *
395 * Since: 0.7.0
396 */
397 const char *
dnf_package_get_release(DnfPackage * pkg)398 dnf_package_get_release(DnfPackage *pkg)
399 {
400 char *e, *v, *r;
401 pool_split_evr(dnf_package_get_pool(pkg), dnf_package_get_evr(pkg), &e, &v, &r);
402 return r;
403 }
404
405 /**
406 * dnf_package_get_name:
407 * @pkg: a #DnfPackage instance.
408 *
409 * Gets the name for the package.
410 *
411 * Returns: a string, or %NULL
412 *
413 * Since: 0.7.0
414 */
415 const char *
dnf_package_get_name(DnfPackage * pkg)416 dnf_package_get_name(DnfPackage *pkg)
417 {
418 Pool *pool = dnf_package_get_pool(pkg);
419 return pool_id2str(pool, get_solvable(pkg)->name);
420 }
421
422 /**
423 * dnf_package_get_vendor:
424 * @pkg: a #DnfPackage instance.
425 *
426 * Gets the name for the package.
427 *
428 * Returns: a string, or %NULL
429 *
430 * Since: 0.54.4
431 */
432 const char *
dnf_package_get_vendor(DnfPackage * pkg)433 dnf_package_get_vendor(DnfPackage *pkg)
434 {
435 Pool *pool = dnf_package_get_pool(pkg);
436 return pool_id2str(pool, get_solvable(pkg)->vendor);
437 }
438
439 /**
440 * dnf_package_get_packager:
441 * @pkg: a #DnfPackage instance.
442 *
443 * Gets the XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX for the package.
444 *
445 * Returns: a string, or %NULL
446 *
447 * Since: 0.7.0
448 */
449 const char *
dnf_package_get_packager(DnfPackage * pkg)450 dnf_package_get_packager(DnfPackage *pkg)
451 {
452 return solvable_lookup_str(get_solvable(pkg), SOLVABLE_PACKAGER);
453 }
454
455 /**
456 * dnf_package_get_arch:
457 * @pkg: a #DnfPackage instance.
458 *
459 * Gets the architecture for the package.
460 *
461 * Returns: a string, or %NULL
462 *
463 * Since: 0.7.0
464 */
465 const char *
dnf_package_get_arch(DnfPackage * pkg)466 dnf_package_get_arch(DnfPackage *pkg)
467 {
468 Pool *pool = dnf_package_get_pool(pkg);
469 return pool_id2str(pool, get_solvable(pkg)->arch);
470 }
471
472 /**
473 * dnf_package_get_chksum:
474 * @pkg: a #DnfPackage instance.
475 *
476 * Gets the checksum for the package.
477 *
478 * Returns: raw checksum bytes
479 *
480 * Since: 0.7.0
481 */
482 const unsigned char *
dnf_package_get_chksum(DnfPackage * pkg,int * type)483 dnf_package_get_chksum(DnfPackage *pkg, int *type)
484 {
485 Solvable *s = get_solvable(pkg);
486 const unsigned char* ret;
487
488 repo_internalize_trigger(s->repo);
489 ret = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, type);
490 if (ret)
491 *type = checksumt_l2h(*type);
492 return ret;
493 }
494
495 /**
496 * dnf_package_get_hdr_chksum:
497 * @pkg: a #DnfPackage instance.
498 *
499 * Gets the SHA1 checksum of the packages header.
500 * This is only set for packages in the rpmdb.
501 *
502 * Returns: raw checksum bytes
503 *
504 * Since: 0.7.0
505 */
506 const unsigned char *
dnf_package_get_hdr_chksum(DnfPackage * pkg,int * type)507 dnf_package_get_hdr_chksum(DnfPackage *pkg, int *type)
508 {
509 Solvable *s = get_solvable(pkg);
510 const unsigned char *ret;
511
512 repo_internalize_trigger(s->repo);
513 ret = solvable_lookup_bin_checksum(s, SOLVABLE_HDRID, type);
514 if (ret)
515 *type = checksumt_l2h(*type);
516 return ret;
517 }
518
519 /**
520 * dnf_package_get_description:
521 * @pkg: a #DnfPackage instance.
522 *
523 * Gets the description for the package.
524 *
525 * Returns: a string, or %NULL
526 *
527 * Since: 0.7.0
528 */
529 const char *
dnf_package_get_description(DnfPackage * pkg)530 dnf_package_get_description(DnfPackage *pkg)
531 {
532 return solvable_lookup_str(get_solvable(pkg), SOLVABLE_DESCRIPTION);
533 }
534
535 /**
536 * dnf_package_get_evr:
537 * @pkg: a #DnfPackage instance.
538 *
539 * Gets the EVR for the package.
540 *
541 * Returns: a string
542 *
543 * Since: 0.7.0
544 */
545 const char *
dnf_package_get_evr(DnfPackage * pkg)546 dnf_package_get_evr(DnfPackage *pkg)
547 {
548 Pool *pool = dnf_package_get_pool(pkg);
549 return pool_id2str(pool, get_solvable(pkg)->evr);
550 }
551
552 /**
553 * dnf_package_get_group:
554 * @pkg: a #DnfPackage instance.
555 *
556 * Gets the group for the package.
557 *
558 * Returns: a string, or %NULL
559 *
560 * Since: 0.7.0
561 */
562 const char *
dnf_package_get_group(DnfPackage * pkg)563 dnf_package_get_group(DnfPackage *pkg)
564 {
565 return solvable_lookup_str(get_solvable(pkg), SOLVABLE_GROUP);
566 }
567
568 /**
569 * dnf_package_get_license:
570 * @pkg: a #DnfPackage instance.
571 *
572 * Gets the license for the package.
573 *
574 * Returns: a string, or %NULL
575 *
576 * Since: 0.7.0
577 */
578 const char *
dnf_package_get_license(DnfPackage * pkg)579 dnf_package_get_license(DnfPackage *pkg)
580 {
581 return solvable_lookup_str(get_solvable(pkg), SOLVABLE_LICENSE);
582 }
583
584 /**
585 * dnf_package_get_reponame:
586 * @pkg: a #DnfPackage instance.
587 *
588 * Gets the reponame for the package.
589 *
590 * Returns: a string, or %NULL
591 *
592 * Since: 0.7.0
593 */
594 const char *
dnf_package_get_reponame(DnfPackage * pkg)595 dnf_package_get_reponame(DnfPackage *pkg)
596 {
597 Solvable *s = get_solvable(pkg);
598 return s->repo->name;
599 }
600
601 /**
602 * dnf_package_get_summary:
603 * @pkg: a #DnfPackage instance.
604 *
605 * Gets the summary for the package.
606 *
607 * Returns: a string, or %NULL
608 *
609 * Since: 0.7.0
610 */
611 const char *
dnf_package_get_summary(DnfPackage * pkg)612 dnf_package_get_summary(DnfPackage *pkg)
613 {
614 Solvable *s = get_solvable(pkg);
615 return solvable_lookup_str(s, SOLVABLE_SUMMARY);
616 }
617
618 /**
619 * dnf_package_get_url:
620 * @pkg: a #DnfPackage instance.
621 *
622 * Gets the url for the package.
623 *
624 * Returns: a string, or %NULL
625 *
626 * Since: 0.7.0
627 */
628 const char *
dnf_package_get_url(DnfPackage * pkg)629 dnf_package_get_url(DnfPackage *pkg)
630 {
631 return solvable_lookup_str(get_solvable(pkg), SOLVABLE_URL);
632 }
633
634 /**
635 * dnf_package_get_downloadsize:
636 * @pkg: a #DnfPackage instance.
637 *
638 * Gets the download size for the package.
639 *
640 * Returns: %TRUE for success
641 *
642 * Since: 0.7.0
643 */
644 guint64
dnf_package_get_downloadsize(DnfPackage * pkg)645 dnf_package_get_downloadsize(DnfPackage *pkg)
646 {
647 return lookup_num(pkg, SOLVABLE_DOWNLOADSIZE);
648 }
649
650 /**
651 * dnf_package_get_epoch:
652 * @pkg: a #DnfPackage instance.
653 *
654 * Gets the epoch for the package.
655 *
656 * Returns: %TRUE for success
657 *
658 * Since: 0.7.0
659 */
660 guint64
dnf_package_get_epoch(DnfPackage * pkg)661 dnf_package_get_epoch(DnfPackage *pkg)
662 {
663 return pool_get_epoch(dnf_package_get_pool(pkg), dnf_package_get_evr(pkg));
664 }
665
666 /**
667 * dnf_package_get_hdr_end:
668 * @pkg: a #DnfPackage instance.
669 *
670 * Gets the header end index for the package.
671 *
672 * Returns: an index, or 0 for not known
673 *
674 * Since: 0.7.0
675 */
676 guint64
dnf_package_get_hdr_end(DnfPackage * pkg)677 dnf_package_get_hdr_end(DnfPackage *pkg)
678 {
679 return lookup_num(pkg, SOLVABLE_HEADEREND);
680 }
681
682 /**
683 * dnf_package_get_installsize:
684 * @pkg: a #DnfPackage instance.
685 *
686 * Gets the installed size for the package.
687 *
688 * Returns: size in bytes
689 *
690 * Since: 0.7.0
691 */
692 guint64
dnf_package_get_installsize(DnfPackage * pkg)693 dnf_package_get_installsize(DnfPackage *pkg)
694 {
695 return lookup_num(pkg, SOLVABLE_INSTALLSIZE);
696 }
697
698 /**
699 * dnf_package_get_buildtime:
700 * @pkg: a #DnfPackage instance.
701 *
702 * Gets the build time for the package.
703 *
704 * Returns: UNIX time
705 *
706 * Since: 0.7.0
707 */
708 guint64
dnf_package_get_buildtime(DnfPackage * pkg)709 dnf_package_get_buildtime(DnfPackage *pkg)
710 {
711 return lookup_num(pkg, SOLVABLE_BUILDTIME);
712 }
713
714 /**
715 * dnf_package_get_installtime:
716 * @pkg: a #DnfPackage instance.
717 *
718 * Gets the install time for the package.
719 *
720 * Returns: UNIX time
721 *
722 * Since: 0.7.0
723 */
724 guint64
dnf_package_get_installtime(DnfPackage * pkg)725 dnf_package_get_installtime(DnfPackage *pkg)
726 {
727 return lookup_num(pkg, SOLVABLE_INSTALLTIME);
728 }
729
730 /**
731 * dnf_package_get_medianr:
732 * @pkg: a #DnfPackage instance.
733 *
734 * Gets the media number for the package.
735 *
736 * Returns: integer value
737 *
738 * Since: 0.7.0
739 */
740 guint64
dnf_package_get_medianr(DnfPackage * pkg)741 dnf_package_get_medianr(DnfPackage *pkg)
742 {
743 return lookup_num(pkg, SOLVABLE_MEDIANR);
744 }
745
746 /**
747 * dnf_package_get_rpmdbid:
748 * @pkg: a #DnfPackage instance.
749 *
750 * Gets the RPMDB ID for the package.
751 *
752 * Returns: an ID, or 0 for not known
753 *
754 * Since: 0.7.0
755 */
756 guint64
dnf_package_get_rpmdbid(DnfPackage * pkg)757 dnf_package_get_rpmdbid(DnfPackage *pkg)
758 {
759 guint64 ret = lookup_num(pkg, RPM_RPMDBID);
760 return ret;
761 }
762
763 /**
764 * dnf_package_get_size:
765 * @pkg: a #DnfPackage instance.
766 *
767 * Gets the size for the package.
768 *
769 * Returns: size in bytes
770 *
771 * Since: 0.7.0
772 */
773 guint64
dnf_package_get_size(DnfPackage * pkg)774 dnf_package_get_size(DnfPackage *pkg)
775 {
776 unsigned type = dnf_package_installed(pkg) ? SOLVABLE_INSTALLSIZE :
777 SOLVABLE_DOWNLOADSIZE;
778 return lookup_num(pkg, type);
779 }
780
781 /**
782 * dnf_package_get_conflicts:
783 * @pkg: a #DnfPackage instance.
784 *
785 * Gets the conflicts for the package.
786 *
787 * Returns: A #DnfReldepList
788 *
789 * Since: 0.7.0
790 */
791 DnfReldepList *
dnf_package_get_conflicts(DnfPackage * pkg)792 dnf_package_get_conflicts(DnfPackage *pkg)
793 {
794 return reldeps_for(pkg, SOLVABLE_CONFLICTS);
795 }
796
797 /**
798 * dnf_package_get_enhances:
799 * @pkg: a #DnfPackage instance.
800 *
801 * Gets the enhances for the package.
802 *
803 * Returns: A #DnfReldepList
804 *
805 * Since: 0.7.0
806 */
807 DnfReldepList *
dnf_package_get_enhances(DnfPackage * pkg)808 dnf_package_get_enhances(DnfPackage *pkg)
809 {
810 return reldeps_for(pkg, SOLVABLE_ENHANCES);
811 }
812
813 /**
814 * dnf_package_get_obsoletes:
815 * @pkg: a #DnfPackage instance.
816 *
817 * Gets the obsoletes for the package.
818 *
819 * Returns: A #DnfReldepList
820 *
821 * Since: 0.7.0
822 */
823 DnfReldepList *
dnf_package_get_obsoletes(DnfPackage * pkg)824 dnf_package_get_obsoletes(DnfPackage *pkg)
825 {
826 return reldeps_for(pkg, SOLVABLE_OBSOLETES);
827 }
828
829 /**
830 * dnf_package_get_provides:
831 * @pkg: a #DnfPackage instance.
832 *
833 * Gets the provides for the package.
834 *
835 * Returns: A #DnfReldepList
836 *
837 * Since: 0.7.0
838 */
839 DnfReldepList *
dnf_package_get_provides(DnfPackage * pkg)840 dnf_package_get_provides(DnfPackage *pkg)
841 {
842 return reldeps_for(pkg, SOLVABLE_PROVIDES);
843 }
844
845 /**
846 * dnf_package_get_recommends:
847 * @pkg: a #DnfPackage instance.
848 *
849 * Gets the recommends for the package.
850 *
851 * Returns: A #DnfReldepList
852 *
853 * Since: 0.7.0
854 */
855 DnfReldepList *
dnf_package_get_recommends(DnfPackage * pkg)856 dnf_package_get_recommends(DnfPackage *pkg)
857 {
858 return reldeps_for(pkg, SOLVABLE_RECOMMENDS);
859 }
860
861 /**
862 * dnf_package_get_requires:
863 * @pkg: a #DnfPackage instance.
864 *
865 * Gets the requires for the package.
866 *
867 * Returns: A #DnfReldepList
868 *
869 * Since: 0.7.0
870 */
871 DnfReldepList *
dnf_package_get_requires(DnfPackage * pkg)872 dnf_package_get_requires(DnfPackage *pkg)
873 {
874
875 DnfReldepList * l = reldeps_for(pkg, SOLVABLE_REQUIRES);
876 DnfReldepList * prereq_l = reldeps_for(pkg, SOLVABLE_PREREQMARKER);
877 l->extend(prereq_l);
878 delete prereq_l;
879 return l;
880 }
881
882 /**
883 * dnf_package_get_requires_pre:
884 * @pkg: a #DnfPackage instance.
885 *
886 * If the package is not installed gets the Requires(pre) and Requires(post).
887 * If the package is installed it gets Requires(pre), Requires(post),
888 * Requies(preun) and Requires(postun).
889 *
890 * Returns: A #DnfReldepList
891 *
892 * Since: 0.7.0
893 */
894 DnfReldepList *
dnf_package_get_requires_pre(DnfPackage * pkg)895 dnf_package_get_requires_pre (DnfPackage *pkg)
896 {
897 return reldeps_for(pkg, SOLVABLE_PREREQMARKER);
898 }
899
900 /**
901 * dnf_package_get_suggests:
902 * @pkg: a #DnfPackage instance.
903 *
904 * Gets the suggests for the package.
905 *
906 * Returns: A #DnfReldepList
907 *
908 * Since: 0.7.0
909 */
910 DnfReldepList *
dnf_package_get_suggests(DnfPackage * pkg)911 dnf_package_get_suggests(DnfPackage *pkg)
912 {
913 return reldeps_for(pkg, SOLVABLE_SUGGESTS);
914 }
915
916 /**
917 * dnf_package_get_supplements:
918 * @pkg: a #DnfPackage instance.
919 *
920 * Gets the supplements for the package.
921 *
922 * Returns: A #DnfReldepList
923 *
924 * Since: 0.7.0
925 */
926 DnfReldepList *
dnf_package_get_supplements(DnfPackage * pkg)927 dnf_package_get_supplements(DnfPackage *pkg)
928 {
929 return reldeps_for(pkg, SOLVABLE_SUPPLEMENTS);
930 }
931
932 /**
933 * dnf_package_get_prereq_ignoreinst
934 * @pkg: a #DnfPackage instance.
935 *
936 * Returns safe to remove Requires(pre) and Requires(post) dependencies
937 * of the package. Safe to remove means that the dependency is not needed by
938 * Requires(preun) nor by Requires(postun).
939 * The package must be installed otherwise empty list is returned.
940 *
941 * Returns: A #DnfReldepList
942 *
943 * Since: 0.45.1
944 */
945 DnfReldepList *
dnf_package_get_prereq_ignoreinst(DnfPackage * pkg)946 dnf_package_get_prereq_ignoreinst(DnfPackage *pkg)
947 {
948 return reldeps_for(pkg, SOLVABLE_PREREQ_IGNOREINST);
949 }
950
951 /**
952 * dnf_package_get_regular_requires
953 * @pkg: a #DnfPackage instance.
954 *
955 * Get the requires for the package without Requires(pre), Requires(post)
956 * Requires(preun) and Requires(postun).
957 *
958 * Returns: A #DnfReldepList
959 *
960 * Since: 0.45.1
961 */
962 DnfReldepList *
dnf_package_get_regular_requires(DnfPackage * pkg)963 dnf_package_get_regular_requires(DnfPackage *pkg)
964 {
965 return reldeps_for(pkg, SOLVABLE_REQUIRES);
966 }
967
968 /**
969 * dnf_package_get_files:
970 * @pkg: a #DnfPackage instance.
971 *
972 * Gets the files contained in the package.
973 *
974 * Returns: (transfer full): the file list
975 *
976 * Since: 0.7.0
977 */
978 gchar **
dnf_package_get_files(DnfPackage * pkg)979 dnf_package_get_files(DnfPackage *pkg)
980 {
981 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
982 Pool *pool = dnf_package_get_pool(pkg);
983 Solvable *s = get_solvable(pkg);
984 Dataiterator di;
985 GPtrArray *ret = g_ptr_array_new();
986
987 repo_internalize_trigger(s->repo);
988 dataiterator_init(&di, pool, s->repo, priv->id, SOLVABLE_FILELIST, NULL,
989 SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
990 while (dataiterator_step(&di)) {
991 g_ptr_array_add(ret, g_strdup(di.kv.str));
992 }
993 dataiterator_free(&di);
994 g_ptr_array_add(ret, NULL);
995 return (gchar**)g_ptr_array_free (ret, FALSE);
996 }
997
998 /**
999 * dnf_package_get_changelogs:
1000 * @pkg: a #DnfPackage instance.
1001 *
1002 * Gets the list of changelogs for the package.
1003 *
1004 * Returns: (transfer container) (element-type Changelog): a list
1005 *
1006 * Since: 0.19.1
1007 */
1008 std::vector<libdnf::Changelog>
dnf_package_get_changelogs(DnfPackage * pkg)1009 dnf_package_get_changelogs(DnfPackage *pkg)
1010 {
1011 DnfPackagePrivate *priv = GET_PRIVATE(pkg);
1012 Pool *pool = dnf_package_get_pool(pkg);
1013 Solvable *s = get_solvable(pkg);
1014 Dataiterator di;
1015 std::vector<libdnf::Changelog> changelogslist;
1016
1017 dataiterator_init(&di, pool, s->repo, priv->id, SOLVABLE_CHANGELOG_AUTHOR, NULL, 0);
1018 dataiterator_prepend_keyname(&di, SOLVABLE_CHANGELOG);
1019 while (dataiterator_step(&di)) {
1020 dataiterator_setpos_parent(&di);
1021 std::string author(pool_lookup_str(pool, SOLVID_POS, SOLVABLE_CHANGELOG_AUTHOR));
1022 std::string text(pool_lookup_str(pool, SOLVID_POS, SOLVABLE_CHANGELOG_TEXT));
1023 changelogslist.emplace_back(
1024 static_cast<time_t>(pool_lookup_num(pool, SOLVID_POS, SOLVABLE_CHANGELOG_TIME, 0)),
1025 std::move(author), std::move(text));
1026 }
1027 dataiterator_free(&di);
1028 std::reverse(changelogslist.begin(), changelogslist.end());
1029 return changelogslist;
1030 }
1031
1032 /**
1033 * dnf_package_get_advisories:
1034 * @pkg: a #DnfPackage instance.
1035 *
1036 * Gets the list of advisories for the package.
1037 *
1038 * Returns: (transfer container) (element-type DnfAdvisory): a list
1039 *
1040 * Since: 0.7.0
1041 */
1042 GPtrArray *
dnf_package_get_advisories(DnfPackage * pkg,int cmp_type)1043 dnf_package_get_advisories(DnfPackage *pkg, int cmp_type)
1044 {
1045 Dataiterator di;
1046 Id evr;
1047 int cmp;
1048 Pool *pool = dnf_package_get_pool(pkg);
1049 DnfSack *sack = dnf_package_get_sack(pkg);
1050 GPtrArray *advisorylist = g_ptr_array_new_with_free_func((GDestroyNotify) dnf_advisory_free);
1051 Solvable *s = get_solvable(pkg);
1052
1053 dataiterator_init(&di, pool, 0, 0, UPDATE_COLLECTION_NAME,
1054 pool_id2str(pool, s->name), SEARCH_STRING);
1055 dataiterator_prepend_keyname(&di, UPDATE_COLLECTION);
1056 dataiterator_prepend_keyname(&di, UPDATE_COLLECTIONLIST);
1057 while (dataiterator_step(&di)) {
1058 dataiterator_setpos_parent(&di);
1059 if (pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_ARCH) != s->arch)
1060 continue;
1061 evr = pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_EVR);
1062 if (!evr)
1063 continue;
1064
1065 cmp = pool_evrcmp(pool, evr, s->evr, EVRCMP_COMPARE);
1066 if ((cmp > 0 && (cmp_type & HY_GT)) ||
1067 (cmp < 0 && (cmp_type & HY_LT)) ||
1068 (cmp == 0 && (cmp_type & HY_EQ))) {
1069
1070 // We need to move the di dataiterator to the start of the advisory collection
1071 // so that di_advisory_collection can be initialized with SOLVID_POS because
1072 // the collection it self doesn't have an id.
1073 dataiterator_seek(&di, DI_SEEK_PARENT);
1074 dataiterator_setpos_parent(&di);
1075 dataiterator_seek(&di, DI_SEEK_PARENT);
1076
1077 bool isModuleCollectionApplicable = true;
1078 Dataiterator di_advisory_collection;
1079 dataiterator_init(&di_advisory_collection, pool, 0, SOLVID_POS, UPDATE_MODULE, 0, 0);
1080 while (dataiterator_step(&di_advisory_collection)) {
1081 dataiterator_setpos(&di_advisory_collection);
1082 Id name = pool_lookup_id(pool, SOLVID_POS, UPDATE_MODULE_NAME);
1083 Id stream = pool_lookup_id(pool, SOLVID_POS, UPDATE_MODULE_STREAM);
1084 Id version = pool_lookup_id(pool, SOLVID_POS, UPDATE_MODULE_VERSION);
1085 Id context = pool_lookup_id(pool, SOLVID_POS, UPDATE_MODULE_CONTEXT);
1086 Id arch = pool_lookup_id(pool, SOLVID_POS, UPDATE_MODULE_ARCH);
1087
1088 libdnf::AdvisoryModule moduleAdvisory(sack, di.solvid, name, stream, version, context, arch);
1089 if (moduleAdvisory.isApplicable()) {
1090 isModuleCollectionApplicable = true;
1091 break;
1092 } else {
1093 isModuleCollectionApplicable = false;
1094 }
1095 }
1096 dataiterator_free(&di_advisory_collection);
1097
1098 if (isModuleCollectionApplicable) {
1099 g_ptr_array_add(advisorylist, dnf_advisory_new(sack, di.solvid));
1100 }
1101
1102 dataiterator_skip_solvable(&di);
1103 }
1104 }
1105 dataiterator_free(&di);
1106 return advisorylist;
1107 }
1108
1109 /**
1110 * dnf_package_get_delta_from_evr:
1111 * @pkg: a #DnfPackage instance.
1112 * @from_evr: the EVR string of what's installed
1113 *
1114 * Gets the package delta for the package given an existing EVR.
1115 *
1116 * Returns: a #DnfPackageDelta, or %NULL
1117 *
1118 * Since: 0.7.0
1119 */
1120 DnfPackageDelta *
dnf_package_get_delta_from_evr(DnfPackage * pkg,const char * from_evr)1121 dnf_package_get_delta_from_evr(DnfPackage *pkg, const char *from_evr)
1122 {
1123 Pool *pool = dnf_package_get_pool(pkg);
1124 Solvable *s = get_solvable(pkg);
1125 DnfPackageDelta *delta = NULL;
1126 Dataiterator di;
1127 const char *name = dnf_package_get_name(pkg);
1128
1129 dataiterator_init(&di, pool, s->repo, SOLVID_META, DELTA_PACKAGE_NAME, name,
1130 SEARCH_STRING);
1131 dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO);
1132 while (dataiterator_step(&di)) {
1133 dataiterator_setpos_parent(&di);
1134 if (pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_EVR) != s->evr ||
1135 pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_ARCH) != s->arch)
1136 continue;
1137 const char * base_evr = pool_id2str(pool, pool_lookup_id(pool, SOLVID_POS,
1138 DELTA_BASE_EVR));
1139 if (strcmp(base_evr, from_evr))
1140 continue;
1141
1142 // we have the right delta info, set up DnfPackageDelta *and break out:
1143 delta = dnf_packagedelta_new(pool);
1144
1145 break;
1146 }
1147 dataiterator_free(&di);
1148
1149 return delta;
1150 }
1151