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