]> git.ipfire.org Git - pakfire.git/blame - src/libpakfire/package.c
libpakfire: Fix dumping empty packages
[pakfire.git] / src / libpakfire / package.c
CommitLineData
221cc3ce
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2013 Pakfire development team #
5# #
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. #
10# #
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. #
15# #
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/>. #
18# #
19#############################################################################*/
20
21#include <assert.h>
22#include <stdlib.h>
23#include <string.h>
24#include <time.h>
25
26#include <solv/evr.h>
27#include <solv/pool.h>
28#include <solv/pooltypes.h>
29#include <solv/repo.h>
30#include <solv/solvable.h>
31
cbed1552 32#include <pakfire/archive.h>
221cc3ce
MT
33#include <pakfire/constants.h>
34#include <pakfire/file.h>
35#include <pakfire/i18n.h>
6cdfb9dd 36#include <pakfire/logging.h>
221cc3ce 37#include <pakfire/package.h>
cbed1552 38#include <pakfire/pakfire.h>
9f953e68 39#include <pakfire/private.h>
221cc3ce
MT
40#include <pakfire/relation.h>
41#include <pakfire/relationlist.h>
42#include <pakfire/repo.h>
221cc3ce
MT
43#include <pakfire/util.h>
44
7847efcd 45struct _PakfirePackage {
cbed1552 46 Pakfire pakfire;
7847efcd
MT
47 Id id;
48 PakfireFile filelist;
cbed1552 49 PakfireArchive archive;
7847efcd
MT
50 int nrefs;
51};
52
f1c7996e 53static Pool* pakfire_package_get_solv_pool(PakfirePackage pkg) {
44b27b6f 54 return pakfire_get_solv_pool(pkg->pakfire);
f1c7996e
MT
55}
56
cbed1552 57static void pakfire_package_add_self_provides(Pakfire pakfire, PakfirePackage pkg, const char* name, const char* evr) {
1a497776 58 PakfireRelation relation = pakfire_relation_create(pakfire, name, PAKFIRE_EQ, evr);
cbed1552 59
221cc3ce
MT
60 pakfire_package_add_provides(pkg, relation);
61
1a497776 62 pakfire_relation_unref(relation);
221cc3ce
MT
63}
64
cbed1552 65PAKFIRE_EXPORT PakfirePackage pakfire_package_create(Pakfire pakfire, Id id) {
221cc3ce 66 PakfirePackage pkg = pakfire_calloc(1, sizeof(*pkg));
221cc3ce 67 if (pkg) {
12656820 68 DEBUG(pakfire, "Allocated Package at %p\n", pkg);
6cdfb9dd 69
cbed1552 70 pkg->pakfire = pakfire_ref(pakfire);
221cc3ce
MT
71 pkg->id = id;
72
73 // Initialize reference counter
74 pkg->nrefs = 1;
75 }
76
77 return pkg;
78}
79
cbed1552 80PAKFIRE_EXPORT PakfirePackage pakfire_package_create2(Pakfire pakfire, PakfireRepo repo, const char* name, const char* evr, const char* arch) {
221cc3ce
MT
81 PakfirePackage pkg = pakfire_repo_add_package(repo);
82
83 pakfire_package_set_name(pkg, name);
84 pakfire_package_set_evr(pkg, evr);
85 pakfire_package_set_arch(pkg, arch);
86
cbed1552 87 pakfire_package_add_self_provides(pakfire, pkg, name, evr);
221cc3ce
MT
88
89 return pkg;
90}
91
a4e3894f 92static void pakfire_package_free(PakfirePackage pkg) {
12656820
MT
93 DEBUG(pkg->pakfire, "Releasing Package at %p\n", pkg);
94 pakfire_unref(pkg->pakfire);
95
cbed1552 96 pakfire_archive_unref(pkg->archive);
221cc3ce
MT
97 pakfire_package_filelist_remove(pkg);
98 pakfire_free(pkg);
99}
100
a4e3894f
MT
101PAKFIRE_EXPORT PakfirePackage pakfire_package_ref(PakfirePackage pkg) {
102 pkg->nrefs++;
103
104 return pkg;
105}
106
107PAKFIRE_EXPORT PakfirePackage pakfire_package_unref(PakfirePackage pkg) {
108 if (!pkg)
109 return NULL;
110
111 if (--pkg->nrefs > 0)
112 return pkg;
113
114 pakfire_package_free(pkg);
115 return NULL;
116}
117
178a4506
MT
118PAKFIRE_EXPORT Pakfire pakfire_package_get_pakfire(PakfirePackage pkg) {
119 return pakfire_ref(pkg->pakfire);
120}
121
221cc3ce 122static Solvable* get_solvable(PakfirePackage pkg) {
f1c7996e 123 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce 124
f1c7996e 125 return pool_id2solvable(pool, pkg->id);
221cc3ce
MT
126}
127
128static Repo* pakfire_package_solv_repo(PakfirePackage pkg) {
129 Solvable* s = get_solvable(pkg);
130
131 return s->repo;
132}
133
134static Id pakfire_package_get_handle(PakfirePackage pkg) {
f1c7996e 135 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
136 Solvable* s = get_solvable(pkg);
137
138 return s - pool->solvables;
139}
140
9f953e68 141PAKFIRE_EXPORT int pakfire_package_identical(PakfirePackage pkg1, PakfirePackage pkg2) {
221cc3ce
MT
142 return pkg1->id == pkg2->id;
143}
144
9f953e68 145PAKFIRE_EXPORT int pakfire_package_cmp(PakfirePackage pkg1, PakfirePackage pkg2) {
f1c7996e 146 Pool* pool = pakfire_package_get_solv_pool(pkg1);
221cc3ce
MT
147
148 Solvable* s1 = get_solvable(pkg1);
149 Solvable* s2 = get_solvable(pkg2);
150
151 // Check names
152 const char* str1 = pool_id2str(pool, s1->name);
153 const char* str2 = pool_id2str(pool, s2->name);
154
155 int ret = strcmp(str1, str2);
156 if (ret)
157 return ret;
158
159 // Check the version string
160 ret = pakfire_package_evr_cmp(pkg1, pkg2);
161 if (ret)
162 return ret;
163
164 // Check repositories
165 PakfireRepo repo1 = pakfire_package_get_repo(pkg1);
166 PakfireRepo repo2 = pakfire_package_get_repo(pkg2);
167
168 if (repo1 && repo2) {
169 ret = pakfire_repo_cmp(repo1, repo2);
3ff6aee6 170 }
221cc3ce 171
3ff6aee6
MT
172 pakfire_repo_unref(repo1);
173 pakfire_repo_unref(repo2);
221cc3ce 174
3ff6aee6
MT
175 if (ret)
176 return ret;
221cc3ce
MT
177
178 // Check package architectures
179 str1 = pool_id2str(pool, s1->arch);
180 str2 = pool_id2str(pool, s2->arch);
181
182 return strcmp(str1, str2);
183}
184
9f953e68 185PAKFIRE_EXPORT int pakfire_package_evr_cmp(PakfirePackage pkg1, PakfirePackage pkg2) {
f1c7996e 186 Pool* pool = pakfire_package_get_solv_pool(pkg1);
221cc3ce
MT
187
188 Solvable* s1 = get_solvable(pkg1);
189 Solvable* s2 = get_solvable(pkg2);
190
191 return pool_evrcmp(pool, s1->evr, s2->evr, EVRCMP_COMPARE);
192}
193
9f953e68 194PAKFIRE_EXPORT Id pakfire_package_id(PakfirePackage pkg) {
221cc3ce
MT
195 return pkg->id;
196}
197
9f953e68 198PAKFIRE_EXPORT char* pakfire_package_get_nevra(PakfirePackage pkg) {
f1c7996e 199 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
200 Solvable* s = get_solvable(pkg);
201
202 const char* nevra = pool_solvable2str(pool, s);
203
204 return pakfire_strdup(nevra);
205}
206
9f953e68 207PAKFIRE_EXPORT const char* pakfire_package_get_name(PakfirePackage pkg) {
f1c7996e 208 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
209 Solvable* s = get_solvable(pkg);
210
211 return pool_id2str(pool, s->name);
212}
213
9f953e68 214PAKFIRE_EXPORT void pakfire_package_set_name(PakfirePackage pkg, const char* name) {
f1c7996e 215 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
216 Solvable* s = get_solvable(pkg);
217
218 s->name = pool_str2id(pool, name, 1);
219}
220
9f953e68 221PAKFIRE_EXPORT const char* pakfire_package_get_evr(PakfirePackage pkg) {
f1c7996e 222 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
223 Solvable* s = get_solvable(pkg);
224
225 return pool_id2str(pool, s->evr);
226}
227
9f953e68 228PAKFIRE_EXPORT void pakfire_package_set_evr(PakfirePackage pkg, const char* evr) {
f1c7996e 229 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
230 Solvable* s = get_solvable(pkg);
231
232 s->evr = pool_str2id(pool, evr, 1);
233}
234
235static void split_evr(Pool* pool, const char* evr_c, char** epoch, char** version, char** release) {
221cc3ce
MT
236 char *e, *v, *r;
237
464c8ecc
MT
238 char* evr = pool_alloctmpspace(pool, strlen(evr_c) + 1);
239 strcpy(evr, evr_c);
240
221cc3ce
MT
241 for (e = evr + 1; *e != ':' && *e != '-'; ++e)
242 ;
243
244 if (*e == '-') {
245 *e = '\0';
246 v = evr;
247 r = e + 1;
248 e = NULL;
249 } else { /* *e == ':' */
250 *e = '\0';
251 v = e + 1;
252 e = evr;
253 for (r = v + 1; *r != '-'; ++r)
254 ;
255 *r = '\0';
256 r++;
257 }
258
259 *epoch = e;
260 *version = v;
261 *release = r;
262}
263
9f953e68 264PAKFIRE_EXPORT unsigned long pakfire_package_get_epoch(PakfirePackage pkg) {
f1c7996e 265 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
266 char *e, *v, *r, *endptr;
267
268 unsigned long epoch = 0;
269
270 split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
271
272 if (e) {
273 long int converted = strtol(e, &endptr, 10);
274 assert(converted > 0);
275 assert(*endptr == '\0');
276 epoch = converted;
277 }
278
279 return epoch;
280}
281
9f953e68 282PAKFIRE_EXPORT const char* pakfire_package_get_version(PakfirePackage pkg) {
f1c7996e 283 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
284 char *e, *v, *r;
285
286 split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
287 return pakfire_strdup(v);
288}
289
9f953e68 290PAKFIRE_EXPORT const char* pakfire_package_get_release(PakfirePackage pkg) {
f1c7996e 291 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
292 char *e, *v, *r;
293
294 split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
295 return pakfire_strdup(r);
296}
297
9f953e68 298PAKFIRE_EXPORT const char* pakfire_package_get_arch(PakfirePackage pkg) {
f1c7996e 299 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
300 Solvable* s = get_solvable(pkg);
301
302 return pool_id2str(pool, s->arch);
303}
304
9f953e68 305PAKFIRE_EXPORT void pakfire_package_set_arch(PakfirePackage pkg, const char* arch) {
f1c7996e 306 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
307 Solvable* s = get_solvable(pkg);
308
309 s->arch = pool_str2id(pool, arch, 1);
310}
311
312static void pakfire_package_internalize_repo(PakfirePackage pkg) {
313 PakfireRepo repo = pakfire_package_get_repo(pkg);
314 if (repo) {
315 pakfire_repo_internalize(repo);
3ff6aee6 316 pakfire_repo_unref(repo);
221cc3ce
MT
317 }
318}
319
320static const char* pakfire_package_get_string(PakfirePackage pkg, int key) {
321 pakfire_package_internalize_repo(pkg);
322
323 Solvable* s = get_solvable(pkg);
324 const char* str = solvable_lookup_str(s, key);
325
326 if (!str)
327 return NULL;
328
329 if (strlen(str) == 0)
330 return NULL;
331
332 return str;
333}
334
335static void pakfire_package_set_string(PakfirePackage pkg, int key, const char* value) {
336 Solvable* s = get_solvable(pkg);
337
338 if (!value)
339 value = "";
340
341 solvable_set_str(s, key, value);
342}
343
9f953e68 344PAKFIRE_EXPORT const char* pakfire_package_get_uuid(PakfirePackage pkg) {
221cc3ce
MT
345 return pakfire_package_get_string(pkg, SOLVABLE_PKGID);
346}
347
9f953e68 348PAKFIRE_EXPORT void pakfire_package_set_uuid(PakfirePackage pkg, const char* uuid) {
221cc3ce
MT
349 pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid);
350}
351
9f953e68 352PAKFIRE_EXPORT const char* pakfire_package_get_checksum(PakfirePackage pkg) {
221cc3ce
MT
353 return pakfire_package_get_string(pkg, SOLVABLE_CHECKSUM);
354}
355
9f953e68 356PAKFIRE_EXPORT void pakfire_package_set_checksum(PakfirePackage pkg, const char* checksum) {
221cc3ce
MT
357 pakfire_package_set_string(pkg, SOLVABLE_CHECKSUM, checksum);
358}
359
9f953e68 360PAKFIRE_EXPORT const char* pakfire_package_get_summary(PakfirePackage pkg) {
221cc3ce
MT
361 return pakfire_package_get_string(pkg, SOLVABLE_SUMMARY);
362}
363
9f953e68 364PAKFIRE_EXPORT void pakfire_package_set_summary(PakfirePackage pkg, const char* summary) {
221cc3ce
MT
365 pakfire_package_set_string(pkg, SOLVABLE_SUMMARY, summary);
366}
367
9f953e68 368PAKFIRE_EXPORT const char* pakfire_package_get_description(PakfirePackage pkg) {
221cc3ce
MT
369 return pakfire_package_get_string(pkg, SOLVABLE_DESCRIPTION);
370}
371
9f953e68 372PAKFIRE_EXPORT void pakfire_package_set_description(PakfirePackage pkg, const char* description) {
221cc3ce
MT
373 pakfire_package_set_string(pkg, SOLVABLE_DESCRIPTION, description);
374}
375
9f953e68 376PAKFIRE_EXPORT const char* pakfire_package_get_license(PakfirePackage pkg) {
221cc3ce
MT
377 return pakfire_package_get_string(pkg, SOLVABLE_LICENSE);
378}
379
9f953e68 380PAKFIRE_EXPORT void pakfire_package_set_license(PakfirePackage pkg, const char* license) {
221cc3ce
MT
381 pakfire_package_set_string(pkg, SOLVABLE_LICENSE, license);
382}
383
9f953e68 384PAKFIRE_EXPORT const char* pakfire_package_get_url(PakfirePackage pkg) {
221cc3ce
MT
385 return pakfire_package_get_string(pkg, SOLVABLE_URL);
386}
387
9f953e68 388PAKFIRE_EXPORT void pakfire_package_set_url(PakfirePackage pkg, const char* url) {
221cc3ce
MT
389 pakfire_package_set_string(pkg, SOLVABLE_URL, url);
390}
391
8ad0a954 392PAKFIRE_EXPORT char** pakfire_package_get_groups(PakfirePackage pkg) {
221cc3ce
MT
393 const char* groups = pakfire_package_get_string(pkg, SOLVABLE_GROUP);
394
2141b578
MT
395 // Return nothing when the string is empty
396 if (!groups)
397 return NULL;
398
399 // Copy string to stack and count spaces
400 char buffer[strlen(groups) + 2];
221cc3ce 401
2141b578
MT
402 size_t count = 1;
403 for (unsigned int i = 0; i < strlen(groups) + 1; i++) {
404 buffer[i] = groups[i];
221cc3ce 405
2141b578
MT
406 if (groups[i] == ' ') {
407 buffer[i] = '\0';
408 count++;
409 }
221cc3ce 410 }
2141b578
MT
411
412 // Allocate an array of sufficient size
8ad0a954 413 char** grouplist = pakfire_malloc(sizeof(*grouplist) * (count + 1));
2141b578
MT
414
415 // Copy strings to heap one by one
416 unsigned int i = 0;
417 char* p = buffer;
418 while (*p) {
419 grouplist[i++] = pakfire_strdup(p);
420
421 // Move pointer to the next string
422 p += strlen(p) + 1;
423 }
424
425 // Terminate array
426 grouplist[count] = NULL;
221cc3ce
MT
427
428 return grouplist;
429}
430
2141b578
MT
431static char* pakfire_package_make_group_string(const char** grouplist) {
432 char* s = NULL;
221cc3ce 433
2141b578
MT
434 while (grouplist && *grouplist) {
435 if (s)
436 asprintf(&s, "%s %s", s, *grouplist);
437 else
438 asprintf(&s, "%s", *grouplist);
221cc3ce 439
2141b578
MT
440 // Move pointer forward
441 grouplist++;
442 }
443
444 return s;
445}
446
447PAKFIRE_EXPORT void pakfire_package_set_groups(PakfirePackage pkg, const char** grouplist) {
448 char* s = pakfire_package_make_group_string(grouplist);
221cc3ce 449
2141b578
MT
450 pakfire_package_set_string(pkg, SOLVABLE_GROUP, s);
451 pakfire_free(s);
221cc3ce
MT
452}
453
8ad0a954
MT
454PAKFIRE_EXPORT int pakfire_package_is_in_group(PakfirePackage pkg, const char* group) {
455 char** grouplist = pakfire_package_get_groups(pkg);
456 if (!grouplist)
457 return -1;
458
459 int ret = 1;
460
461 // Walk through all groups
462 while (*grouplist) {
463 // Check if the group name matches
464 if (strcmp(*grouplist, group) == 0) {
465 ret = 0;
466 }
467
468 // Free the element in the group list
469 pakfire_free(*grouplist);
470 grouplist++;
471 }
472
473 pakfire_free(grouplist);
474
475 return ret;
476}
477
9f953e68 478PAKFIRE_EXPORT const char* pakfire_package_get_vendor(PakfirePackage pkg) {
221cc3ce
MT
479 return pakfire_package_get_string(pkg, SOLVABLE_VENDOR);
480}
481
9f953e68 482PAKFIRE_EXPORT void pakfire_package_set_vendor(PakfirePackage pkg, const char* vendor) {
221cc3ce
MT
483 pakfire_package_set_string(pkg, SOLVABLE_VENDOR, vendor);
484}
485
9f953e68 486PAKFIRE_EXPORT const char* pakfire_package_get_maintainer(PakfirePackage pkg) {
221cc3ce
MT
487 return pakfire_package_get_string(pkg, SOLVABLE_PACKAGER);
488}
489
9f953e68 490PAKFIRE_EXPORT void pakfire_package_set_maintainer(PakfirePackage pkg, const char* maintainer) {
221cc3ce
MT
491 pakfire_package_set_string(pkg, SOLVABLE_PACKAGER, maintainer);
492}
493
9f953e68 494PAKFIRE_EXPORT const char* pakfire_package_get_filename(PakfirePackage pkg) {
221cc3ce
MT
495 return pakfire_package_get_string(pkg, SOLVABLE_MEDIAFILE);
496}
497
9f953e68 498PAKFIRE_EXPORT void pakfire_package_set_filename(PakfirePackage pkg, const char* filename) {
221cc3ce
MT
499 pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, filename);
500}
501
9f953e68 502PAKFIRE_EXPORT int pakfire_package_is_installed(PakfirePackage pkg) {
f1c7996e 503 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
504 Solvable* s = get_solvable(pkg);
505
506 return pool->installed == s->repo;
507}
508
509static unsigned long long pakfire_package_get_num(PakfirePackage pkg, Id type) {
510 pakfire_package_internalize_repo(pkg);
511
512 Solvable* s = get_solvable(pkg);
513 return solvable_lookup_num(s, type, 0);
514}
515
516static void pakfire_package_set_num(PakfirePackage pkg, Id type, unsigned long long value) {
517 Solvable* s = get_solvable(pkg);
518
519 solvable_set_num(s, type, value);
520}
521
9f953e68 522PAKFIRE_EXPORT unsigned long long pakfire_package_get_downloadsize(PakfirePackage pkg) {
221cc3ce
MT
523 return pakfire_package_get_num(pkg, SOLVABLE_DOWNLOADSIZE);
524}
525
9f953e68 526PAKFIRE_EXPORT void pakfire_package_set_downloadsize(PakfirePackage pkg, unsigned long long downloadsize) {
221cc3ce
MT
527 return pakfire_package_set_num(pkg, SOLVABLE_DOWNLOADSIZE, downloadsize);
528}
529
9f953e68 530PAKFIRE_EXPORT unsigned long long pakfire_package_get_installsize(PakfirePackage pkg) {
221cc3ce
MT
531 return pakfire_package_get_num(pkg, SOLVABLE_INSTALLSIZE);
532}
533
9f953e68 534PAKFIRE_EXPORT void pakfire_package_set_installsize(PakfirePackage pkg, unsigned long long installsize) {
221cc3ce
MT
535 return pakfire_package_set_num(pkg, SOLVABLE_INSTALLSIZE, installsize);
536}
537
9f953e68 538PAKFIRE_EXPORT unsigned long long pakfire_package_get_size(PakfirePackage pkg) {
221cc3ce
MT
539 if (pakfire_package_is_installed(pkg))
540 return pakfire_package_get_installsize(pkg);
541
542 return pakfire_package_get_downloadsize(pkg);
543}
544
9f953e68 545PAKFIRE_EXPORT const char* pakfire_package_get_buildhost(PakfirePackage pkg) {
221cc3ce
MT
546 return pakfire_package_get_string(pkg, SOLVABLE_BUILDHOST);
547}
548
9f953e68 549PAKFIRE_EXPORT void pakfire_package_set_buildhost(PakfirePackage pkg, const char* buildhost) {
221cc3ce
MT
550 pakfire_package_set_string(pkg, SOLVABLE_BUILDHOST, buildhost);
551}
552
9f953e68 553PAKFIRE_EXPORT unsigned long long pakfire_package_get_buildtime(PakfirePackage pkg) {
221cc3ce
MT
554 return pakfire_package_get_num(pkg, SOLVABLE_BUILDTIME);
555}
556
9f953e68 557PAKFIRE_EXPORT void pakfire_package_set_buildtime(PakfirePackage pkg, unsigned long long buildtime) {
221cc3ce
MT
558 pakfire_package_set_num(pkg, SOLVABLE_BUILDTIME, buildtime);
559}
560
9f953e68 561PAKFIRE_EXPORT unsigned long long pakfire_package_get_installtime(PakfirePackage pkg) {
221cc3ce
MT
562 return pakfire_package_get_num(pkg, SOLVABLE_INSTALLTIME);
563}
564
565static PakfireRelationList pakfire_package_get_relationlist(PakfirePackage pkg, Id type) {
566 Queue q;
567 queue_init(&q);
568
569 Solvable* s = get_solvable(pkg);
570 solvable_lookup_idarray(s, type, &q);
571
1a497776 572 PakfireRelationList relationlist = pakfire_relationlist_from_queue(pkg->pakfire, q);
221cc3ce
MT
573 queue_free(&q);
574
575 return relationlist;
576}
577
578static void pakfire_package_set_relationlist(PakfirePackage pkg, Id type, PakfireRelationList relationlist) {
579#if 0
580 // This implemention should be the fastest, but unfortunately does not work.
581 Queue q;
582 pakfire_relationlist_clone_to_queue(relationlist, &q);
583
584 Solvable* s = get_solvable(pkg);
585 solvable_set_idarray(s, type, &q);
586
587 queue_free(&q);
588#endif
589
590 Solvable* s = get_solvable(pkg);
591 solvable_unset(s, type);
592
593 int count = pakfire_relationlist_count(relationlist);
594 for (int i = 0; i < count; i++) {
595 PakfireRelation relation = pakfire_relationlist_get_clone(relationlist, i);
1a497776 596 solvable_add_idarray(s, type, pakfire_relation_get_id(relation));
221cc3ce 597
1a497776 598 pakfire_relation_unref(relation);
221cc3ce
MT
599 }
600}
601
602static void pakfire_package_add_relation(PakfirePackage pkg, Id type, PakfireRelation relation) {
603 Solvable* s = get_solvable(pkg);
604
1a497776 605 solvable_add_idarray(s, type, pakfire_relation_get_id(relation));
221cc3ce
MT
606}
607
9f953e68 608PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_provides(PakfirePackage pkg) {
221cc3ce
MT
609 return pakfire_package_get_relationlist(pkg, SOLVABLE_PROVIDES);
610}
611
9f953e68 612PAKFIRE_EXPORT void pakfire_package_set_provides(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
613 pakfire_package_set_relationlist(pkg, SOLVABLE_PROVIDES, relationlist);
614}
615
9f953e68 616PAKFIRE_EXPORT void pakfire_package_add_provides(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
617 pakfire_package_add_relation(pkg, SOLVABLE_PROVIDES, relation);
618}
619
9f953e68 620PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_prerequires(PakfirePackage pkg) {
221cc3ce
MT
621 #warning TODO
622 return NULL;
623}
624
9f953e68 625PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_requires(PakfirePackage pkg) {
221cc3ce
MT
626 return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES);
627}
628
9f953e68 629PAKFIRE_EXPORT void pakfire_package_set_requires(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
630 pakfire_package_set_relationlist(pkg, SOLVABLE_REQUIRES, relationlist);
631}
632
9f953e68 633PAKFIRE_EXPORT void pakfire_package_add_requires(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
634 pakfire_package_add_relation(pkg, SOLVABLE_REQUIRES, relation);
635}
636
9f953e68 637PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_conflicts(PakfirePackage pkg) {
221cc3ce
MT
638 return pakfire_package_get_relationlist(pkg, SOLVABLE_CONFLICTS);
639}
640
9f953e68 641PAKFIRE_EXPORT void pakfire_package_set_conflicts(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
642 pakfire_package_set_relationlist(pkg, SOLVABLE_CONFLICTS, relationlist);
643}
644
9f953e68 645PAKFIRE_EXPORT void pakfire_package_add_conflicts(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
646 pakfire_package_add_relation(pkg, SOLVABLE_CONFLICTS, relation);
647}
648
9f953e68 649PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_obsoletes(PakfirePackage pkg) {
221cc3ce
MT
650 return pakfire_package_get_relationlist(pkg, SOLVABLE_OBSOLETES);
651}
652
9f953e68 653PAKFIRE_EXPORT void pakfire_package_set_obsoletes(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
654 pakfire_package_set_relationlist(pkg, SOLVABLE_OBSOLETES, relationlist);
655}
656
9f953e68 657PAKFIRE_EXPORT void pakfire_package_add_obsoletes(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
658 pakfire_package_add_relation(pkg, SOLVABLE_OBSOLETES, relation);
659}
660
9f953e68 661PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_recommends(PakfirePackage pkg) {
221cc3ce
MT
662 return pakfire_package_get_relationlist(pkg, SOLVABLE_RECOMMENDS);
663}
664
9f953e68 665PAKFIRE_EXPORT void pakfire_package_set_recommends(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
666 pakfire_package_set_relationlist(pkg, SOLVABLE_RECOMMENDS, relationlist);
667}
668
9f953e68 669PAKFIRE_EXPORT void pakfire_package_add_recommends(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
670 pakfire_package_add_relation(pkg, SOLVABLE_RECOMMENDS, relation);
671}
672
9f953e68 673PAKFIRE_EXPORT PakfireRelationList pakfire_package_get_suggests(PakfirePackage pkg) {
221cc3ce
MT
674 return pakfire_package_get_relationlist(pkg, SOLVABLE_SUGGESTS);
675}
676
9f953e68 677PAKFIRE_EXPORT void pakfire_package_set_suggests(PakfirePackage pkg, PakfireRelationList relationlist) {
221cc3ce
MT
678 pakfire_package_set_relationlist(pkg, SOLVABLE_SUGGESTS, relationlist);
679}
680
9f953e68 681PAKFIRE_EXPORT void pakfire_package_add_suggests(PakfirePackage pkg, PakfireRelation relation) {
221cc3ce
MT
682 pakfire_package_add_relation(pkg, SOLVABLE_SUGGESTS, relation);
683}
684
9f953e68 685PAKFIRE_EXPORT PakfireRepo pakfire_package_get_repo(PakfirePackage pkg) {
221cc3ce
MT
686 Solvable* s = get_solvable(pkg);
687
cbed1552 688 return pakfire_repo_create_from_repo(pkg->pakfire, s->repo);
221cc3ce
MT
689}
690
9f953e68 691PAKFIRE_EXPORT void pakfire_package_set_repo(PakfirePackage pkg, PakfireRepo repo) {
221cc3ce
MT
692 Solvable* s = get_solvable(pkg);
693
3ff6aee6 694 s->repo = pakfire_repo_get_repo(repo);
221cc3ce
MT
695}
696
9f953e68 697PAKFIRE_EXPORT char* pakfire_package_get_location(PakfirePackage pkg) {
221cc3ce
MT
698 pakfire_package_internalize_repo(pkg);
699
700 Solvable* s = get_solvable(pkg);
701
702 const char* location = solvable_get_location(s, NULL);
703 return pakfire_strdup(location);
704}
705
706static void pakfire_package_dump_add_line(char** str, const char* key, const char* val) {
707 if (val)
708 asprintf(str, "%s%-15s: %s\n", *str, key ? key : "", val);
709}
710
711static void pakfire_package_dump_add_lines(char** str, const char* key, const char* val) {
712 const char* string = val;
713
714 while (*string) {
715 char line[STRING_SIZE];
716 int counter = 0;
717
718 while (*string) {
719 if (*string == '\n') {
720 string++;
721 break;
722 }
723
724 line[counter++] = *string++;
725 }
726 line[counter] = '\0';
727
728 if (*line) {
729 pakfire_package_dump_add_line(str, key, line);
730 key = NULL;
731 }
732 }
733}
734
735static void pakfire_package_dump_add_line_date(char** str, const char* key, unsigned long long date) {
736 // Convert from integer to tm struct.
737 struct tm* timer = gmtime((time_t *)&date);
738
739 char val[STRING_SIZE];
740 strftime(val, STRING_SIZE, "%a, %d %b %Y %T %z", timer);
741
742 pakfire_package_dump_add_line(str, key, val);
743}
744
745static void pakfire_package_dump_add_line_relations(char** str, const char* key, PakfireRelationList deps) {
746 int count = pakfire_relationlist_count(deps);
747 for (int i = 0; i < count; i++) {
748 PakfireRelation relation = pakfire_relationlist_get_clone(deps, i);
749
750 if (relation) {
751 char* dep = pakfire_relation_str(relation);
1a497776 752 pakfire_relation_unref(relation);
221cc3ce
MT
753
754 // Stop here and don't list any files.
755 if (strcmp(PAKFIRE_SOLVABLE_FILEMARKER, dep) == 0)
756 break;
757
758 if (dep) {
759 pakfire_package_dump_add_line(str, (i == 0) ? key : "", dep);
760 pakfire_free(dep);
761 }
762 }
763 }
764}
765
766static void pakfire_package_dump_add_line_size(char** str, const char* key, unsigned long long size) {
767 char* val = pakfire_format_size(size);
768
769 if (val) {
770 pakfire_package_dump_add_line(str, key, val);
771 pakfire_free(val);
772 }
773}
774
9f953e68 775PAKFIRE_EXPORT char* pakfire_package_dump(PakfirePackage pkg, int flags) {
221cc3ce
MT
776 char* string = "";
777
778 // Name
779 const char* name = pakfire_package_get_name(pkg);
780 pakfire_package_dump_add_line(&string, _("Name"), name);
781
782 // Version
783 const char* version = pakfire_package_get_version(pkg);
784 pakfire_package_dump_add_line(&string, _("Version"), version);
785
786 // Release
787 const char* release = pakfire_package_get_release(pkg);
788 pakfire_package_dump_add_line(&string, _("Release"), release);
789
790 // Size
791 unsigned long long size = pakfire_package_get_size(pkg);
792 pakfire_package_dump_add_line_size(&string, _("Size"), size);
793
794 // Installed size
795 if (pakfire_package_is_installed(pkg)) {
796 unsigned long long installsize = pakfire_package_get_installsize(pkg);
797 pakfire_package_dump_add_line_size(&string, _("Installed size"), installsize);
798
799 // Downloadsize
800 } else {
801 unsigned long long downloadsize = pakfire_package_get_downloadsize(pkg);
802 pakfire_package_dump_add_line_size(&string, _("Download size"), downloadsize);
803 }
804
805 PakfireRepo repo = pakfire_package_get_repo(pkg);
806 if (repo) {
807 const char* repo_name = pakfire_repo_get_name(repo);
808 pakfire_package_dump_add_line(&string, _("Repo"), repo_name);
809
3ff6aee6 810 pakfire_repo_unref(repo);
221cc3ce
MT
811 }
812
813 // Summary
814 const char* summary = pakfire_package_get_summary(pkg);
815 pakfire_package_dump_add_line(&string, _("Summary"), summary);
816
817 // Description
818 const char* description = pakfire_package_get_description(pkg);
1b99c676
MT
819 if (description)
820 pakfire_package_dump_add_lines(&string, _("Description"), description);
221cc3ce
MT
821
822 // Groups
8ad0a954 823 char** groups = pakfire_package_get_groups(pkg);
2141b578 824 if (groups) {
8ad0a954 825 char* s = pakfire_package_make_group_string((const char**)groups);
1b99c676
MT
826
827 if (s) {
828 pakfire_package_dump_add_lines(&string, _("Groups"), s);
829 pakfire_free(s);
830 }
2141b578 831 }
221cc3ce
MT
832
833 // URL
834 const char* url = pakfire_package_get_url(pkg);
835 pakfire_package_dump_add_line(&string, _("URL"), url);
836
837 // License
838 const char* license = pakfire_package_get_license(pkg);
839 pakfire_package_dump_add_line(&string, _("License"), license);
840
841 if (flags & PAKFIRE_PKG_DUMP_LONG) {
842 // Maintainer
843 const char* maintainer = pakfire_package_get_maintainer(pkg);
844 pakfire_package_dump_add_line(&string, _("Maintainer"), maintainer);
845
846 // Vendor
847 const char* vendor = pakfire_package_get_vendor(pkg);
848 pakfire_package_dump_add_line(&string, _("Vendor"), vendor);
849
850 // UUID
851 const char* uuid = pakfire_package_get_uuid(pkg);
852 pakfire_package_dump_add_line(&string, _("UUID"), uuid);
853
854 // Build time
855 unsigned long long buildtime = pakfire_package_get_buildtime(pkg);
856 pakfire_package_dump_add_line_date(&string, _("Build date"), buildtime);
857
858 // Build host
859 const char* buildhost = pakfire_package_get_buildhost(pkg);
860 pakfire_package_dump_add_line(&string, _("Build host"), buildhost);
861
862 PakfireRelationList provides = pakfire_package_get_provides(pkg);
863 if (provides) {
864 pakfire_package_dump_add_line_relations(&string, _("Provides"), provides);
1a497776 865 pakfire_relationlist_unref(provides);
221cc3ce
MT
866 }
867
868 PakfireRelationList requires = pakfire_package_get_requires(pkg);
869 if (requires) {
870 pakfire_package_dump_add_line_relations(&string, _("Requires"), requires);
1a497776 871 pakfire_relationlist_unref(requires);
221cc3ce
MT
872 }
873
874 PakfireRelationList conflicts = pakfire_package_get_conflicts(pkg);
875 if (conflicts) {
876 pakfire_package_dump_add_line_relations(&string, _("Conflicts"), conflicts);
1a497776 877 pakfire_relationlist_unref(conflicts);
221cc3ce
MT
878 }
879
880 PakfireRelationList obsoletes = pakfire_package_get_obsoletes(pkg);
881 if (obsoletes) {
882 pakfire_package_dump_add_line_relations(&string, _("Obsoletes"), obsoletes);
1a497776 883 pakfire_relationlist_unref(obsoletes);
221cc3ce
MT
884 }
885
886 PakfireRelationList recommends = pakfire_package_get_recommends(pkg);
887 if (recommends) {
888 pakfire_package_dump_add_line_relations(&string, _("Recommends"), recommends);
1a497776 889 pakfire_relationlist_unref(recommends);
221cc3ce
MT
890 }
891
892 PakfireRelationList suggests = pakfire_package_get_suggests(pkg);
893 if (suggests) {
894 pakfire_package_dump_add_line_relations(&string, _("Suggests"), suggests);
1a497776 895 pakfire_relationlist_unref(suggests);
221cc3ce
MT
896 }
897 }
898
899 if (flags & PAKFIRE_PKG_DUMP_FILELIST) {
900 PakfireFile file = pakfire_package_get_filelist(pkg);
901
902 char* prefix = _("Filelist");
903 while (file) {
904 const char* name = pakfire_file_get_name(file);
905 pakfire_package_dump_add_line(&string, prefix, name);
906
907 file = pakfire_file_get_next(file);
908
909 // Only prefix the first line.
910 prefix = NULL;
911 }
912 }
913
914 return string;
915}
916
9f953e68 917PAKFIRE_EXPORT int pakfire_package_is_cached(PakfirePackage pkg) {
3f7bcbc4 918 char* path = pakfire_package_get_cache_path(pkg);
cbed1552 919
3f7bcbc4 920 // Check if the file is readable
12656820 921 int r = pakfire_access(pkg->pakfire, path, NULL, R_OK);
3f7bcbc4 922 pakfire_free(path);
221cc3ce 923
cf27dd9c 924 return (r == 0);
221cc3ce
MT
925}
926
9f953e68 927PAKFIRE_EXPORT char* pakfire_package_get_cache_path(PakfirePackage pkg) {
3f7bcbc4 928 char buffer[STRING_SIZE] = "";
221cc3ce 929
3f7bcbc4
MT
930 const char* filename = pakfire_package_get_filename(pkg);
931 const char* checksum = pakfire_package_get_checksum(pkg);
221cc3ce 932
3f7bcbc4 933 if (strlen(checksum) < 3)
221cc3ce
MT
934 return NULL;
935
3f7bcbc4
MT
936 snprintf(buffer, sizeof(buffer), "%c%c/%s/%s", checksum[0], checksum[1],
937 checksum + 2, filename);
221cc3ce 938
3f7bcbc4 939 return pakfire_get_cache_path(pkg->pakfire, buffer);
221cc3ce
MT
940}
941
cbed1552
MT
942PAKFIRE_EXPORT PakfireArchive pakfire_package_get_archive(PakfirePackage pkg) {
943 // Return the package if it has already been opened
944 if (pkg->archive)
945 return pakfire_archive_ref(pkg->archive);
946
947 // Otherwise open the archive from the cache
3f7bcbc4 948 char* path = pakfire_package_get_cache_path(pkg);
cbed1552
MT
949 PakfireArchive archive = pakfire_archive_open(pkg->pakfire, path);
950
951 // Free resources
952 pakfire_free(path);
953
954 return archive;
955}
956
221cc3ce
MT
957static PakfireFile pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
958 pakfire_package_internalize_repo(pkg);
959
960 PakfireFile file = NULL;
961 PakfireRepo repo = pakfire_package_get_repo(pkg);
962 Solvable* s = get_solvable(pkg);
f1c7996e 963 Pool* p = pakfire_package_get_solv_pool(pkg);
3ff6aee6 964 Repo* r = pakfire_repo_get_repo(repo);
221cc3ce
MT
965
966 int found_marker = 0;
967
968 Id id, *ids;
969 ids = r->idarraydata + s->provides;
970 while((id = *ids++) != 0) {
971 const char* filename = pool_dep2str(p, id);
972
973 if (found_marker) {
974 if (file) {
975 file = pakfire_file_append(file);
976 } else {
977 file = pakfire_file_create();
978 }
979
980 pakfire_file_set_name(file, filename);
981 continue;
982 }
983
984 if (strcmp(filename, PAKFIRE_SOLVABLE_FILEMARKER) == 0)
985 ++found_marker;
986 }
987
988 if (file) {
989 file = pakfire_file_get_first(file);
990
991 // Sort the output
992 file = pakfire_file_sort(file);
993 }
994
3ff6aee6
MT
995 pakfire_repo_unref(repo);
996
221cc3ce
MT
997 return file;
998}
999
1000static PakfireFile pakfire_package_fetch_filelist(PakfirePackage pkg) {
1001 pakfire_package_internalize_repo(pkg);
1002
1003 PakfireFile file = NULL;
f1c7996e 1004 Pool* pool = pakfire_package_get_solv_pool(pkg);
221cc3ce
MT
1005 Repo* repo = pakfire_package_solv_repo(pkg);
1006 Id handle = pakfire_package_get_handle(pkg);
1007
1008 Dataiterator di;
1009 dataiterator_init(&di, pool, repo, handle,
1010 SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
1011 while (dataiterator_step(&di)) {
1012 if (file) {
1013 file = pakfire_file_append(file);
1014 } else {
1015 file = pakfire_file_create();
1016 }
1017
1018 pakfire_file_set_name(file, di.kv.str);
1019 }
1020 dataiterator_free(&di);
1021
1022 if (file) {
1023 file = pakfire_file_get_first(file);
1024
1025 // Sort the result.
1026 file = pakfire_file_sort(file);
1027 }
1028
1029 // If the file list is empty, we fall back to read files
1030 // in the older format.
1031 if (!file)
1032 file = pakfire_package_fetch_legacy_filelist(pkg);
1033
1034 return file;
1035}
1036
9f953e68 1037PAKFIRE_EXPORT PakfireFile pakfire_package_get_filelist(PakfirePackage pkg) {
221cc3ce
MT
1038 if (!pkg->filelist) {
1039 pkg->filelist = pakfire_package_fetch_filelist(pkg);
1040 }
1041
1042 return pkg->filelist;
1043}
1044
9f953e68 1045PAKFIRE_EXPORT PakfireFile pakfire_package_filelist_append(PakfirePackage pkg, const char* filename) {
221cc3ce 1046 PakfireRepo repo = pakfire_package_get_repo(pkg);
3ff6aee6 1047 Repodata* repodata = pakfire_repo_get_repodata(repo);
221cc3ce
MT
1048
1049 Id handle = pakfire_package_get_handle(pkg);
1050
1051 char* dirname = pakfire_dirname(filename);
1052 char* basename = pakfire_basename(filename);
1053
3ff6aee6 1054 Id did = repodata_str2dir(repodata, dirname, 1);
221cc3ce 1055 if (!did)
3ff6aee6 1056 did = repodata_str2dir(repodata, "/", 1);
221cc3ce 1057
3ff6aee6 1058 repodata_add_dirstr(repodata, handle,
221cc3ce
MT
1059 SOLVABLE_FILELIST, did, basename);
1060
3ff6aee6
MT
1061 pakfire_repo_unref(repo);
1062
221cc3ce
MT
1063 return NULL;
1064}
1065
1066#if 0
1067PakfireFile pakfire_package_filelist_append(PakfirePackage pkg) {
1068 if (pkg->filelist) {
1069 return pakfire_file_append(pkg->filelist);
1070 }
1071
1072 PakfireFile file = pakfire_file_create();
1073 pkg->filelist = file;
1074
1075 return file;
1076}
1077#endif
1078
9f953e68 1079PAKFIRE_EXPORT void pakfire_package_filelist_remove(PakfirePackage pkg) {
221cc3ce
MT
1080 if (pkg->filelist)
1081 pakfire_file_free_all(pkg->filelist);
1082}