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