1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2013 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program 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 #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
27 #include <solv/pool.h>
28 #include <solv/pooltypes.h>
29 #include <solv/repo.h>
30 #include <solv/solvable.h>
32 #include <pakfire/archive.h>
33 #include <pakfire/constants.h>
34 #include <pakfire/file.h>
35 #include <pakfire/i18n.h>
36 #include <pakfire/logging.h>
37 #include <pakfire/package.h>
38 #include <pakfire/pakfire.h>
39 #include <pakfire/private.h>
40 #include <pakfire/relation.h>
41 #include <pakfire/relationlist.h>
42 #include <pakfire/repo.h>
43 #include <pakfire/util.h>
45 struct _PakfirePackage
{
49 PakfireArchive archive
;
53 static Pool
* pakfire_package_get_solv_pool(PakfirePackage pkg
) {
54 return pakfire_get_solv_pool(pkg
->pakfire
);
57 static void pakfire_package_add_self_provides(Pakfire pakfire
, PakfirePackage pkg
, const char* name
, const char* evr
) {
58 PakfireRelation relation
= pakfire_relation_create(pakfire
, name
, PAKFIRE_EQ
, evr
);
60 pakfire_package_add_provides(pkg
, relation
);
62 pakfire_relation_unref(relation
);
65 PAKFIRE_EXPORT PakfirePackage
pakfire_package_create(Pakfire pakfire
, Id id
) {
66 PakfirePackage pkg
= pakfire_calloc(1, sizeof(*pkg
));
68 DEBUG("Allocated Package at %p\n", pkg
);
70 pkg
->pakfire
= pakfire_ref(pakfire
);
73 // Initialize reference counter
80 PAKFIRE_EXPORT PakfirePackage
pakfire_package_create2(Pakfire pakfire
, PakfireRepo repo
, const char* name
, const char* evr
, const char* arch
) {
81 PakfirePackage pkg
= pakfire_repo_add_package(repo
);
83 pakfire_package_set_name(pkg
, name
);
84 pakfire_package_set_evr(pkg
, evr
);
85 pakfire_package_set_arch(pkg
, arch
);
87 pakfire_package_add_self_provides(pakfire
, pkg
, name
, evr
);
92 static void pakfire_package_free(PakfirePackage pkg
) {
93 pakfire_archive_unref(pkg
->archive
);
94 pakfire_package_filelist_remove(pkg
);
95 pakfire_unref(pkg
->pakfire
);
98 DEBUG("Released Package at %p\n", pkg
);
101 PAKFIRE_EXPORT PakfirePackage
pakfire_package_ref(PakfirePackage pkg
) {
107 PAKFIRE_EXPORT PakfirePackage
pakfire_package_unref(PakfirePackage pkg
) {
111 if (--pkg
->nrefs
> 0)
114 pakfire_package_free(pkg
);
118 static Solvable
* get_solvable(PakfirePackage pkg
) {
119 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
121 return pool_id2solvable(pool
, pkg
->id
);
124 static Repo
* pakfire_package_solv_repo(PakfirePackage pkg
) {
125 Solvable
* s
= get_solvable(pkg
);
130 static Id
pakfire_package_get_handle(PakfirePackage pkg
) {
131 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
132 Solvable
* s
= get_solvable(pkg
);
134 return s
- pool
->solvables
;
137 PAKFIRE_EXPORT
int pakfire_package_identical(PakfirePackage pkg1
, PakfirePackage pkg2
) {
138 return pkg1
->id
== pkg2
->id
;
141 PAKFIRE_EXPORT
int pakfire_package_cmp(PakfirePackage pkg1
, PakfirePackage pkg2
) {
142 Pool
* pool
= pakfire_package_get_solv_pool(pkg1
);
144 Solvable
* s1
= get_solvable(pkg1
);
145 Solvable
* s2
= get_solvable(pkg2
);
148 const char* str1
= pool_id2str(pool
, s1
->name
);
149 const char* str2
= pool_id2str(pool
, s2
->name
);
151 int ret
= strcmp(str1
, str2
);
155 // Check the version string
156 ret
= pakfire_package_evr_cmp(pkg1
, pkg2
);
160 // Check repositories
161 PakfireRepo repo1
= pakfire_package_get_repo(pkg1
);
162 PakfireRepo repo2
= pakfire_package_get_repo(pkg2
);
164 if (repo1
&& repo2
) {
165 ret
= pakfire_repo_cmp(repo1
, repo2
);
168 pakfire_repo_unref(repo1
);
169 pakfire_repo_unref(repo2
);
174 // Check package architectures
175 str1
= pool_id2str(pool
, s1
->arch
);
176 str2
= pool_id2str(pool
, s2
->arch
);
178 return strcmp(str1
, str2
);
181 PAKFIRE_EXPORT
int pakfire_package_evr_cmp(PakfirePackage pkg1
, PakfirePackage pkg2
) {
182 Pool
* pool
= pakfire_package_get_solv_pool(pkg1
);
184 Solvable
* s1
= get_solvable(pkg1
);
185 Solvable
* s2
= get_solvable(pkg2
);
187 return pool_evrcmp(pool
, s1
->evr
, s2
->evr
, EVRCMP_COMPARE
);
190 PAKFIRE_EXPORT Id
pakfire_package_id(PakfirePackage pkg
) {
194 PAKFIRE_EXPORT
char* pakfire_package_get_nevra(PakfirePackage pkg
) {
195 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
196 Solvable
* s
= get_solvable(pkg
);
198 const char* nevra
= pool_solvable2str(pool
, s
);
200 return pakfire_strdup(nevra
);
203 PAKFIRE_EXPORT
const char* pakfire_package_get_name(PakfirePackage pkg
) {
204 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
205 Solvable
* s
= get_solvable(pkg
);
207 return pool_id2str(pool
, s
->name
);
210 PAKFIRE_EXPORT
void pakfire_package_set_name(PakfirePackage pkg
, const char* name
) {
211 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
212 Solvable
* s
= get_solvable(pkg
);
214 s
->name
= pool_str2id(pool
, name
, 1);
217 PAKFIRE_EXPORT
const char* pakfire_package_get_evr(PakfirePackage pkg
) {
218 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
219 Solvable
* s
= get_solvable(pkg
);
221 return pool_id2str(pool
, s
->evr
);
224 PAKFIRE_EXPORT
void pakfire_package_set_evr(PakfirePackage pkg
, const char* evr
) {
225 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
226 Solvable
* s
= get_solvable(pkg
);
228 s
->evr
= pool_str2id(pool
, evr
, 1);
231 static void split_evr(Pool
* pool
, const char* evr_c
, char** epoch
, char** version
, char** release
) {
234 char* evr
= pool_alloctmpspace(pool
, strlen(evr_c
) + 1);
237 for (e
= evr
+ 1; *e
!= ':' && *e
!= '-'; ++e
)
245 } else { /* *e == ':' */
249 for (r
= v
+ 1; *r
!= '-'; ++r
)
260 PAKFIRE_EXPORT
unsigned long pakfire_package_get_epoch(PakfirePackage pkg
) {
261 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
262 char *e
, *v
, *r
, *endptr
;
264 unsigned long epoch
= 0;
266 split_evr(pool
, pakfire_package_get_evr(pkg
), &e
, &v
, &r
);
269 long int converted
= strtol(e
, &endptr
, 10);
270 assert(converted
> 0);
271 assert(*endptr
== '\0');
278 PAKFIRE_EXPORT
const char* pakfire_package_get_version(PakfirePackage pkg
) {
279 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
282 split_evr(pool
, pakfire_package_get_evr(pkg
), &e
, &v
, &r
);
283 return pakfire_strdup(v
);
286 PAKFIRE_EXPORT
const char* pakfire_package_get_release(PakfirePackage pkg
) {
287 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
290 split_evr(pool
, pakfire_package_get_evr(pkg
), &e
, &v
, &r
);
291 return pakfire_strdup(r
);
294 PAKFIRE_EXPORT
const char* pakfire_package_get_arch(PakfirePackage pkg
) {
295 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
296 Solvable
* s
= get_solvable(pkg
);
298 return pool_id2str(pool
, s
->arch
);
301 PAKFIRE_EXPORT
void pakfire_package_set_arch(PakfirePackage pkg
, const char* arch
) {
302 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
303 Solvable
* s
= get_solvable(pkg
);
305 s
->arch
= pool_str2id(pool
, arch
, 1);
308 static void pakfire_package_internalize_repo(PakfirePackage pkg
) {
309 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
311 pakfire_repo_internalize(repo
);
312 pakfire_repo_unref(repo
);
316 static const char* pakfire_package_get_string(PakfirePackage pkg
, int key
) {
317 pakfire_package_internalize_repo(pkg
);
319 Solvable
* s
= get_solvable(pkg
);
320 const char* str
= solvable_lookup_str(s
, key
);
325 if (strlen(str
) == 0)
331 static void pakfire_package_set_string(PakfirePackage pkg
, int key
, const char* value
) {
332 Solvable
* s
= get_solvable(pkg
);
337 solvable_set_str(s
, key
, value
);
340 PAKFIRE_EXPORT
const char* pakfire_package_get_uuid(PakfirePackage pkg
) {
341 return pakfire_package_get_string(pkg
, SOLVABLE_PKGID
);
344 PAKFIRE_EXPORT
void pakfire_package_set_uuid(PakfirePackage pkg
, const char* uuid
) {
345 pakfire_package_set_string(pkg
, SOLVABLE_PKGID
, uuid
);
348 PAKFIRE_EXPORT
const char* pakfire_package_get_checksum(PakfirePackage pkg
) {
349 return pakfire_package_get_string(pkg
, SOLVABLE_CHECKSUM
);
352 PAKFIRE_EXPORT
void pakfire_package_set_checksum(PakfirePackage pkg
, const char* checksum
) {
353 pakfire_package_set_string(pkg
, SOLVABLE_CHECKSUM
, checksum
);
356 PAKFIRE_EXPORT
const char* pakfire_package_get_summary(PakfirePackage pkg
) {
357 return pakfire_package_get_string(pkg
, SOLVABLE_SUMMARY
);
360 PAKFIRE_EXPORT
void pakfire_package_set_summary(PakfirePackage pkg
, const char* summary
) {
361 pakfire_package_set_string(pkg
, SOLVABLE_SUMMARY
, summary
);
364 PAKFIRE_EXPORT
const char* pakfire_package_get_description(PakfirePackage pkg
) {
365 return pakfire_package_get_string(pkg
, SOLVABLE_DESCRIPTION
);
368 PAKFIRE_EXPORT
void pakfire_package_set_description(PakfirePackage pkg
, const char* description
) {
369 pakfire_package_set_string(pkg
, SOLVABLE_DESCRIPTION
, description
);
372 PAKFIRE_EXPORT
const char* pakfire_package_get_license(PakfirePackage pkg
) {
373 return pakfire_package_get_string(pkg
, SOLVABLE_LICENSE
);
376 PAKFIRE_EXPORT
void pakfire_package_set_license(PakfirePackage pkg
, const char* license
) {
377 pakfire_package_set_string(pkg
, SOLVABLE_LICENSE
, license
);
380 PAKFIRE_EXPORT
const char* pakfire_package_get_url(PakfirePackage pkg
) {
381 return pakfire_package_get_string(pkg
, SOLVABLE_URL
);
384 PAKFIRE_EXPORT
void pakfire_package_set_url(PakfirePackage pkg
, const char* url
) {
385 pakfire_package_set_string(pkg
, SOLVABLE_URL
, url
);
388 #warning the groups functions need to be refactored
390 PAKFIRE_EXPORT
const char** pakfire_package_get_groups(PakfirePackage pkg
) {
391 const char* groups
= pakfire_package_get_string(pkg
, SOLVABLE_GROUP
);
393 const char** grouplist
= NULL
;
394 char* group
= strtok((char *)groups
, " ");
397 while (group
!= NULL
) {
398 grouplist
= realloc(grouplist
, sizeof(char *) * ++i
);
400 grouplist
[i
- 1] = group
;
402 group
= strtok(NULL
, " ");
409 PAKFIRE_EXPORT
void pakfire_package_set_groups(PakfirePackage pkg
, const char** grouplist
) {
410 char groups
[2048] = "";
414 while ((group
= *grouplist
++) != NULL
) {
418 strcat(groups
, group
);
420 groups
[sizeof(groups
) - 1] = '\0';
424 pakfire_package_set_string(pkg
, SOLVABLE_GROUP
, (const char *)&groups
);
427 PAKFIRE_EXPORT
const char* pakfire_package_get_vendor(PakfirePackage pkg
) {
428 return pakfire_package_get_string(pkg
, SOLVABLE_VENDOR
);
431 PAKFIRE_EXPORT
void pakfire_package_set_vendor(PakfirePackage pkg
, const char* vendor
) {
432 pakfire_package_set_string(pkg
, SOLVABLE_VENDOR
, vendor
);
435 PAKFIRE_EXPORT
const char* pakfire_package_get_maintainer(PakfirePackage pkg
) {
436 return pakfire_package_get_string(pkg
, SOLVABLE_PACKAGER
);
439 PAKFIRE_EXPORT
void pakfire_package_set_maintainer(PakfirePackage pkg
, const char* maintainer
) {
440 pakfire_package_set_string(pkg
, SOLVABLE_PACKAGER
, maintainer
);
443 PAKFIRE_EXPORT
const char* pakfire_package_get_filename(PakfirePackage pkg
) {
444 return pakfire_package_get_string(pkg
, SOLVABLE_MEDIAFILE
);
447 PAKFIRE_EXPORT
void pakfire_package_set_filename(PakfirePackage pkg
, const char* filename
) {
448 pakfire_package_set_string(pkg
, SOLVABLE_MEDIAFILE
, filename
);
451 PAKFIRE_EXPORT
int pakfire_package_is_installed(PakfirePackage pkg
) {
452 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
453 Solvable
* s
= get_solvable(pkg
);
455 return pool
->installed
== s
->repo
;
458 static unsigned long long pakfire_package_get_num(PakfirePackage pkg
, Id type
) {
459 pakfire_package_internalize_repo(pkg
);
461 Solvable
* s
= get_solvable(pkg
);
462 return solvable_lookup_num(s
, type
, 0);
465 static void pakfire_package_set_num(PakfirePackage pkg
, Id type
, unsigned long long value
) {
466 Solvable
* s
= get_solvable(pkg
);
468 solvable_set_num(s
, type
, value
);
471 PAKFIRE_EXPORT
unsigned long long pakfire_package_get_downloadsize(PakfirePackage pkg
) {
472 return pakfire_package_get_num(pkg
, SOLVABLE_DOWNLOADSIZE
);
475 PAKFIRE_EXPORT
void pakfire_package_set_downloadsize(PakfirePackage pkg
, unsigned long long downloadsize
) {
476 return pakfire_package_set_num(pkg
, SOLVABLE_DOWNLOADSIZE
, downloadsize
);
479 PAKFIRE_EXPORT
unsigned long long pakfire_package_get_installsize(PakfirePackage pkg
) {
480 return pakfire_package_get_num(pkg
, SOLVABLE_INSTALLSIZE
);
483 PAKFIRE_EXPORT
void pakfire_package_set_installsize(PakfirePackage pkg
, unsigned long long installsize
) {
484 return pakfire_package_set_num(pkg
, SOLVABLE_INSTALLSIZE
, installsize
);
487 PAKFIRE_EXPORT
unsigned long long pakfire_package_get_size(PakfirePackage pkg
) {
488 if (pakfire_package_is_installed(pkg
))
489 return pakfire_package_get_installsize(pkg
);
491 return pakfire_package_get_downloadsize(pkg
);
494 PAKFIRE_EXPORT
const char* pakfire_package_get_buildhost(PakfirePackage pkg
) {
495 return pakfire_package_get_string(pkg
, SOLVABLE_BUILDHOST
);
498 PAKFIRE_EXPORT
void pakfire_package_set_buildhost(PakfirePackage pkg
, const char* buildhost
) {
499 pakfire_package_set_string(pkg
, SOLVABLE_BUILDHOST
, buildhost
);
502 PAKFIRE_EXPORT
unsigned long long pakfire_package_get_buildtime(PakfirePackage pkg
) {
503 return pakfire_package_get_num(pkg
, SOLVABLE_BUILDTIME
);
506 PAKFIRE_EXPORT
void pakfire_package_set_buildtime(PakfirePackage pkg
, unsigned long long buildtime
) {
507 pakfire_package_set_num(pkg
, SOLVABLE_BUILDTIME
, buildtime
);
510 PAKFIRE_EXPORT
unsigned long long pakfire_package_get_installtime(PakfirePackage pkg
) {
511 return pakfire_package_get_num(pkg
, SOLVABLE_INSTALLTIME
);
514 static PakfireRelationList
pakfire_package_get_relationlist(PakfirePackage pkg
, Id type
) {
518 Solvable
* s
= get_solvable(pkg
);
519 solvable_lookup_idarray(s
, type
, &q
);
521 PakfireRelationList relationlist
= pakfire_relationlist_from_queue(pkg
->pakfire
, q
);
527 static void pakfire_package_set_relationlist(PakfirePackage pkg
, Id type
, PakfireRelationList relationlist
) {
529 // This implemention should be the fastest, but unfortunately does not work.
531 pakfire_relationlist_clone_to_queue(relationlist
, &q
);
533 Solvable
* s
= get_solvable(pkg
);
534 solvable_set_idarray(s
, type
, &q
);
539 Solvable
* s
= get_solvable(pkg
);
540 solvable_unset(s
, type
);
542 int count
= pakfire_relationlist_count(relationlist
);
543 for (int i
= 0; i
< count
; i
++) {
544 PakfireRelation relation
= pakfire_relationlist_get_clone(relationlist
, i
);
545 solvable_add_idarray(s
, type
, pakfire_relation_get_id(relation
));
547 pakfire_relation_unref(relation
);
551 static void pakfire_package_add_relation(PakfirePackage pkg
, Id type
, PakfireRelation relation
) {
552 Solvable
* s
= get_solvable(pkg
);
554 solvable_add_idarray(s
, type
, pakfire_relation_get_id(relation
));
557 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_provides(PakfirePackage pkg
) {
558 return pakfire_package_get_relationlist(pkg
, SOLVABLE_PROVIDES
);
561 PAKFIRE_EXPORT
void pakfire_package_set_provides(PakfirePackage pkg
, PakfireRelationList relationlist
) {
562 pakfire_package_set_relationlist(pkg
, SOLVABLE_PROVIDES
, relationlist
);
565 PAKFIRE_EXPORT
void pakfire_package_add_provides(PakfirePackage pkg
, PakfireRelation relation
) {
566 pakfire_package_add_relation(pkg
, SOLVABLE_PROVIDES
, relation
);
569 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_prerequires(PakfirePackage pkg
) {
574 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_requires(PakfirePackage pkg
) {
575 return pakfire_package_get_relationlist(pkg
, SOLVABLE_REQUIRES
);
578 PAKFIRE_EXPORT
void pakfire_package_set_requires(PakfirePackage pkg
, PakfireRelationList relationlist
) {
579 pakfire_package_set_relationlist(pkg
, SOLVABLE_REQUIRES
, relationlist
);
582 PAKFIRE_EXPORT
void pakfire_package_add_requires(PakfirePackage pkg
, PakfireRelation relation
) {
583 pakfire_package_add_relation(pkg
, SOLVABLE_REQUIRES
, relation
);
586 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_conflicts(PakfirePackage pkg
) {
587 return pakfire_package_get_relationlist(pkg
, SOLVABLE_CONFLICTS
);
590 PAKFIRE_EXPORT
void pakfire_package_set_conflicts(PakfirePackage pkg
, PakfireRelationList relationlist
) {
591 pakfire_package_set_relationlist(pkg
, SOLVABLE_CONFLICTS
, relationlist
);
594 PAKFIRE_EXPORT
void pakfire_package_add_conflicts(PakfirePackage pkg
, PakfireRelation relation
) {
595 pakfire_package_add_relation(pkg
, SOLVABLE_CONFLICTS
, relation
);
598 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_obsoletes(PakfirePackage pkg
) {
599 return pakfire_package_get_relationlist(pkg
, SOLVABLE_OBSOLETES
);
602 PAKFIRE_EXPORT
void pakfire_package_set_obsoletes(PakfirePackage pkg
, PakfireRelationList relationlist
) {
603 pakfire_package_set_relationlist(pkg
, SOLVABLE_OBSOLETES
, relationlist
);
606 PAKFIRE_EXPORT
void pakfire_package_add_obsoletes(PakfirePackage pkg
, PakfireRelation relation
) {
607 pakfire_package_add_relation(pkg
, SOLVABLE_OBSOLETES
, relation
);
610 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_recommends(PakfirePackage pkg
) {
611 return pakfire_package_get_relationlist(pkg
, SOLVABLE_RECOMMENDS
);
614 PAKFIRE_EXPORT
void pakfire_package_set_recommends(PakfirePackage pkg
, PakfireRelationList relationlist
) {
615 pakfire_package_set_relationlist(pkg
, SOLVABLE_RECOMMENDS
, relationlist
);
618 PAKFIRE_EXPORT
void pakfire_package_add_recommends(PakfirePackage pkg
, PakfireRelation relation
) {
619 pakfire_package_add_relation(pkg
, SOLVABLE_RECOMMENDS
, relation
);
622 PAKFIRE_EXPORT PakfireRelationList
pakfire_package_get_suggests(PakfirePackage pkg
) {
623 return pakfire_package_get_relationlist(pkg
, SOLVABLE_SUGGESTS
);
626 PAKFIRE_EXPORT
void pakfire_package_set_suggests(PakfirePackage pkg
, PakfireRelationList relationlist
) {
627 pakfire_package_set_relationlist(pkg
, SOLVABLE_SUGGESTS
, relationlist
);
630 PAKFIRE_EXPORT
void pakfire_package_add_suggests(PakfirePackage pkg
, PakfireRelation relation
) {
631 pakfire_package_add_relation(pkg
, SOLVABLE_SUGGESTS
, relation
);
634 PAKFIRE_EXPORT PakfireRepo
pakfire_package_get_repo(PakfirePackage pkg
) {
635 Solvable
* s
= get_solvable(pkg
);
637 return pakfire_repo_create_from_repo(pkg
->pakfire
, s
->repo
);
640 PAKFIRE_EXPORT
void pakfire_package_set_repo(PakfirePackage pkg
, PakfireRepo repo
) {
641 Solvable
* s
= get_solvable(pkg
);
643 s
->repo
= pakfire_repo_get_repo(repo
);
646 PAKFIRE_EXPORT
char* pakfire_package_get_location(PakfirePackage pkg
) {
647 pakfire_package_internalize_repo(pkg
);
649 Solvable
* s
= get_solvable(pkg
);
651 const char* location
= solvable_get_location(s
, NULL
);
652 return pakfire_strdup(location
);
655 static void pakfire_package_dump_add_line(char** str
, const char* key
, const char* val
) {
657 asprintf(str
, "%s%-15s: %s\n", *str
, key
? key
: "", val
);
660 static void pakfire_package_dump_add_lines(char** str
, const char* key
, const char* val
) {
661 const char* string
= val
;
664 char line
[STRING_SIZE
];
668 if (*string
== '\n') {
673 line
[counter
++] = *string
++;
675 line
[counter
] = '\0';
678 pakfire_package_dump_add_line(str
, key
, line
);
684 static void pakfire_package_dump_add_line_date(char** str
, const char* key
, unsigned long long date
) {
685 // Convert from integer to tm struct.
686 struct tm
* timer
= gmtime((time_t *)&date
);
688 char val
[STRING_SIZE
];
689 strftime(val
, STRING_SIZE
, "%a, %d %b %Y %T %z", timer
);
691 pakfire_package_dump_add_line(str
, key
, val
);
694 static void pakfire_package_dump_add_line_relations(char** str
, const char* key
, PakfireRelationList deps
) {
695 int count
= pakfire_relationlist_count(deps
);
696 for (int i
= 0; i
< count
; i
++) {
697 PakfireRelation relation
= pakfire_relationlist_get_clone(deps
, i
);
700 char* dep
= pakfire_relation_str(relation
);
701 pakfire_relation_unref(relation
);
703 // Stop here and don't list any files.
704 if (strcmp(PAKFIRE_SOLVABLE_FILEMARKER
, dep
) == 0)
708 pakfire_package_dump_add_line(str
, (i
== 0) ? key
: "", dep
);
715 static void pakfire_package_dump_add_line_size(char** str
, const char* key
, unsigned long long size
) {
716 char* val
= pakfire_format_size(size
);
719 pakfire_package_dump_add_line(str
, key
, val
);
724 PAKFIRE_EXPORT
char* pakfire_package_dump(PakfirePackage pkg
, int flags
) {
728 const char* name
= pakfire_package_get_name(pkg
);
729 pakfire_package_dump_add_line(&string
, _("Name"), name
);
732 const char* version
= pakfire_package_get_version(pkg
);
733 pakfire_package_dump_add_line(&string
, _("Version"), version
);
736 const char* release
= pakfire_package_get_release(pkg
);
737 pakfire_package_dump_add_line(&string
, _("Release"), release
);
740 unsigned long long size
= pakfire_package_get_size(pkg
);
741 pakfire_package_dump_add_line_size(&string
, _("Size"), size
);
744 if (pakfire_package_is_installed(pkg
)) {
745 unsigned long long installsize
= pakfire_package_get_installsize(pkg
);
746 pakfire_package_dump_add_line_size(&string
, _("Installed size"), installsize
);
750 unsigned long long downloadsize
= pakfire_package_get_downloadsize(pkg
);
751 pakfire_package_dump_add_line_size(&string
, _("Download size"), downloadsize
);
754 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
756 const char* repo_name
= pakfire_repo_get_name(repo
);
757 pakfire_package_dump_add_line(&string
, _("Repo"), repo_name
);
759 pakfire_repo_unref(repo
);
763 const char* summary
= pakfire_package_get_summary(pkg
);
764 pakfire_package_dump_add_line(&string
, _("Summary"), summary
);
767 const char* description
= pakfire_package_get_description(pkg
);
768 pakfire_package_dump_add_lines(&string
, _("Description"), description
);
774 const char* url
= pakfire_package_get_url(pkg
);
775 pakfire_package_dump_add_line(&string
, _("URL"), url
);
778 const char* license
= pakfire_package_get_license(pkg
);
779 pakfire_package_dump_add_line(&string
, _("License"), license
);
781 if (flags
& PAKFIRE_PKG_DUMP_LONG
) {
783 const char* maintainer
= pakfire_package_get_maintainer(pkg
);
784 pakfire_package_dump_add_line(&string
, _("Maintainer"), maintainer
);
787 const char* vendor
= pakfire_package_get_vendor(pkg
);
788 pakfire_package_dump_add_line(&string
, _("Vendor"), vendor
);
791 const char* uuid
= pakfire_package_get_uuid(pkg
);
792 pakfire_package_dump_add_line(&string
, _("UUID"), uuid
);
795 unsigned long long buildtime
= pakfire_package_get_buildtime(pkg
);
796 pakfire_package_dump_add_line_date(&string
, _("Build date"), buildtime
);
799 const char* buildhost
= pakfire_package_get_buildhost(pkg
);
800 pakfire_package_dump_add_line(&string
, _("Build host"), buildhost
);
802 PakfireRelationList provides
= pakfire_package_get_provides(pkg
);
804 pakfire_package_dump_add_line_relations(&string
, _("Provides"), provides
);
805 pakfire_relationlist_unref(provides
);
808 PakfireRelationList requires
= pakfire_package_get_requires(pkg
);
810 pakfire_package_dump_add_line_relations(&string
, _("Requires"), requires
);
811 pakfire_relationlist_unref(requires
);
814 PakfireRelationList conflicts
= pakfire_package_get_conflicts(pkg
);
816 pakfire_package_dump_add_line_relations(&string
, _("Conflicts"), conflicts
);
817 pakfire_relationlist_unref(conflicts
);
820 PakfireRelationList obsoletes
= pakfire_package_get_obsoletes(pkg
);
822 pakfire_package_dump_add_line_relations(&string
, _("Obsoletes"), obsoletes
);
823 pakfire_relationlist_unref(obsoletes
);
826 PakfireRelationList recommends
= pakfire_package_get_recommends(pkg
);
828 pakfire_package_dump_add_line_relations(&string
, _("Recommends"), recommends
);
829 pakfire_relationlist_unref(recommends
);
832 PakfireRelationList suggests
= pakfire_package_get_suggests(pkg
);
834 pakfire_package_dump_add_line_relations(&string
, _("Suggests"), suggests
);
835 pakfire_relationlist_unref(suggests
);
839 if (flags
& PAKFIRE_PKG_DUMP_FILELIST
) {
840 PakfireFile file
= pakfire_package_get_filelist(pkg
);
842 char* prefix
= _("Filelist");
844 const char* name
= pakfire_file_get_name(file
);
845 pakfire_package_dump_add_line(&string
, prefix
, name
);
847 file
= pakfire_file_get_next(file
);
849 // Only prefix the first line.
857 PAKFIRE_EXPORT
int pakfire_package_is_cached(PakfirePackage pkg
) {
858 char* path
= pakfire_package_get_cache_path(pkg
);
860 // Check if the file is readable
861 int r
= pakfire_access(path
, NULL
, R_OK
);
867 PAKFIRE_EXPORT
char* pakfire_package_get_cache_path(PakfirePackage pkg
) {
868 char buffer
[STRING_SIZE
] = "";
870 const char* filename
= pakfire_package_get_filename(pkg
);
871 const char* checksum
= pakfire_package_get_checksum(pkg
);
873 if (strlen(checksum
) < 3)
876 snprintf(buffer
, sizeof(buffer
), "%c%c/%s/%s", checksum
[0], checksum
[1],
877 checksum
+ 2, filename
);
879 return pakfire_get_cache_path(pkg
->pakfire
, buffer
);
882 PAKFIRE_EXPORT PakfireArchive
pakfire_package_get_archive(PakfirePackage pkg
) {
883 // Return the package if it has already been opened
885 return pakfire_archive_ref(pkg
->archive
);
887 // Otherwise open the archive from the cache
888 char* path
= pakfire_package_get_cache_path(pkg
);
889 PakfireArchive archive
= pakfire_archive_open(pkg
->pakfire
, path
);
897 static PakfireFile
pakfire_package_fetch_legacy_filelist(PakfirePackage pkg
) {
898 pakfire_package_internalize_repo(pkg
);
900 PakfireFile file
= NULL
;
901 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
902 Solvable
* s
= get_solvable(pkg
);
903 Pool
* p
= pakfire_package_get_solv_pool(pkg
);
904 Repo
* r
= pakfire_repo_get_repo(repo
);
906 int found_marker
= 0;
909 ids
= r
->idarraydata
+ s
->provides
;
910 while((id
= *ids
++) != 0) {
911 const char* filename
= pool_dep2str(p
, id
);
915 file
= pakfire_file_append(file
);
917 file
= pakfire_file_create();
920 pakfire_file_set_name(file
, filename
);
924 if (strcmp(filename
, PAKFIRE_SOLVABLE_FILEMARKER
) == 0)
929 file
= pakfire_file_get_first(file
);
932 file
= pakfire_file_sort(file
);
935 pakfire_repo_unref(repo
);
940 static PakfireFile
pakfire_package_fetch_filelist(PakfirePackage pkg
) {
941 pakfire_package_internalize_repo(pkg
);
943 PakfireFile file
= NULL
;
944 Pool
* pool
= pakfire_package_get_solv_pool(pkg
);
945 Repo
* repo
= pakfire_package_solv_repo(pkg
);
946 Id handle
= pakfire_package_get_handle(pkg
);
949 dataiterator_init(&di
, pool
, repo
, handle
,
950 SOLVABLE_FILELIST
, NULL
, SEARCH_FILES
| SEARCH_COMPLETE_FILELIST
);
951 while (dataiterator_step(&di
)) {
953 file
= pakfire_file_append(file
);
955 file
= pakfire_file_create();
958 pakfire_file_set_name(file
, di
.kv
.str
);
960 dataiterator_free(&di
);
963 file
= pakfire_file_get_first(file
);
966 file
= pakfire_file_sort(file
);
969 // If the file list is empty, we fall back to read files
970 // in the older format.
972 file
= pakfire_package_fetch_legacy_filelist(pkg
);
977 PAKFIRE_EXPORT PakfireFile
pakfire_package_get_filelist(PakfirePackage pkg
) {
978 if (!pkg
->filelist
) {
979 pkg
->filelist
= pakfire_package_fetch_filelist(pkg
);
982 return pkg
->filelist
;
985 PAKFIRE_EXPORT PakfireFile
pakfire_package_filelist_append(PakfirePackage pkg
, const char* filename
) {
986 PakfireRepo repo
= pakfire_package_get_repo(pkg
);
987 Repodata
* repodata
= pakfire_repo_get_repodata(repo
);
989 Id handle
= pakfire_package_get_handle(pkg
);
991 char* dirname
= pakfire_dirname(filename
);
992 char* basename
= pakfire_basename(filename
);
994 Id did
= repodata_str2dir(repodata
, dirname
, 1);
996 did
= repodata_str2dir(repodata
, "/", 1);
998 repodata_add_dirstr(repodata
, handle
,
999 SOLVABLE_FILELIST
, did
, basename
);
1001 pakfire_repo_unref(repo
);
1007 PakfireFile
pakfire_package_filelist_append(PakfirePackage pkg
) {
1008 if (pkg
->filelist
) {
1009 return pakfire_file_append(pkg
->filelist
);
1012 PakfireFile file
= pakfire_file_create();
1013 pkg
->filelist
= file
;
1019 PAKFIRE_EXPORT
void pakfire_package_filelist_remove(PakfirePackage pkg
) {
1021 pakfire_file_free_all(pkg
->filelist
);