]> git.ipfire.org Git - pakfire.git/blame - src/libpakfire/package.c
packager: Dump metadata of written package
[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
e42b5960 21#include <errno.h>
4a81ff85 22#include <linux/limits.h>
221cc3ce
MT
23#include <stdlib.h>
24#include <string.h>
25#include <time.h>
57e2cf99 26#include <uuid/uuid.h>
221cc3ce
MT
27
28#include <solv/evr.h>
29#include <solv/pool.h>
221cc3ce
MT
30#include <solv/repo.h>
31#include <solv/solvable.h>
32
cbed1552 33#include <pakfire/archive.h>
221cc3ce
MT
34#include <pakfire/constants.h>
35#include <pakfire/file.h>
5e9463ec 36#include <pakfire/filelist.h>
221cc3ce 37#include <pakfire/i18n.h>
6cdfb9dd 38#include <pakfire/logging.h>
221cc3ce 39#include <pakfire/package.h>
cbed1552 40#include <pakfire/pakfire.h>
9f953e68 41#include <pakfire/private.h>
221cc3ce 42#include <pakfire/repo.h>
221cc3ce
MT
43#include <pakfire/util.h>
44
31480bee 45struct pakfire_package {
ac4c607b 46 struct pakfire* pakfire;
7847efcd 47 int nrefs;
e9d9eadc 48
8b088877
MT
49 // Reference to this package in the SOLV pool
50 Id id;
4651122b 51 struct pakfire_repo* repo;
8b088877 52
40fcf5ff
MT
53 char nevra[NAME_MAX];
54
b12a5d7d
MT
55 char filename[NAME_MAX];
56 char path[PATH_MAX];
7847efcd
MT
57};
58
ac4c607b 59static void pakfire_package_add_self_provides(struct pakfire* pakfire, struct pakfire_package* pkg, const char* name, const char* evr) {
452d3833
MT
60 char buffer[1024];
61 pakfire_string_format(buffer, "%s = %s", name, evr);
62
63 pakfire_package_add_provides(pkg, buffer);
221cc3ce
MT
64}
65
ac4c607b 66struct pakfire_package* pakfire_package_create_from_solvable(struct pakfire* pakfire, Id id) {
31480bee 67 struct pakfire_package* pkg = calloc(1, sizeof(*pkg));
e9d9eadc
MT
68 if (!pkg)
69 return NULL;
6cdfb9dd 70
e9d9eadc
MT
71 pkg->pakfire = pakfire_ref(pakfire);
72 pkg->id = id;
73
74 // Initialize reference counter
75 pkg->nrefs = 1;
221cc3ce
MT
76
77 return pkg;
78}
79
ac4c607b 80PAKFIRE_EXPORT struct pakfire_package* pakfire_package_create(struct pakfire* pakfire, struct pakfire_repo* repo, const char* name, const char* evr, const char* arch) {
e9d9eadc
MT
81 Id id = pakfire_repo_add_solvable(repo);
82 if (!id)
83 return NULL;
84
31480bee 85 struct pakfire_package* pkg = pakfire_package_create_from_solvable(pakfire, id);
e9d9eadc
MT
86 if (!pkg)
87 return NULL;
221cc3ce 88
e9d9eadc
MT
89 pkg->repo = pakfire_repo_ref(repo);
90
91 // Set the given attributes
221cc3ce
MT
92 pakfire_package_set_name(pkg, name);
93 pakfire_package_set_evr(pkg, evr);
94 pakfire_package_set_arch(pkg, arch);
95
e9d9eadc 96 // Add self-provides
cbed1552 97 pakfire_package_add_self_provides(pakfire, pkg, name, evr);
221cc3ce
MT
98
99 return pkg;
100}
101
31480bee 102static void pakfire_package_free(struct pakfire_package* pkg) {
e9d9eadc
MT
103 if (pkg->repo)
104 pakfire_repo_unref(pkg->repo);
105
5e9463ec 106 pakfire_unref(pkg->pakfire);
f0d6233d 107 free(pkg);
221cc3ce
MT
108}
109
31480bee 110PAKFIRE_EXPORT struct pakfire_package* pakfire_package_ref(struct pakfire_package* pkg) {
a4e3894f
MT
111 pkg->nrefs++;
112
113 return pkg;
114}
115
31480bee 116PAKFIRE_EXPORT struct pakfire_package* pakfire_package_unref(struct pakfire_package* pkg) {
a4e3894f
MT
117 if (--pkg->nrefs > 0)
118 return pkg;
119
120 pakfire_package_free(pkg);
121 return NULL;
122}
123
ac4c607b 124PAKFIRE_EXPORT struct pakfire* pakfire_package_get_pakfire(struct pakfire_package* pkg) {
178a4506
MT
125 return pakfire_ref(pkg->pakfire);
126}
127
31480bee 128static Solvable* get_solvable(struct pakfire_package* pkg) {
0defa23e 129 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce 130
f1c7996e 131 return pool_id2solvable(pool, pkg->id);
221cc3ce
MT
132}
133
31480bee 134PAKFIRE_EXPORT int pakfire_package_eq(struct pakfire_package* pkg1, struct pakfire_package* pkg2) {
221cc3ce
MT
135 return pkg1->id == pkg2->id;
136}
137
31480bee 138PAKFIRE_EXPORT int pakfire_package_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) {
0defa23e 139 Pool* pool = pakfire_get_solv_pool(pkg1->pakfire);
221cc3ce
MT
140
141 Solvable* s1 = get_solvable(pkg1);
142 Solvable* s2 = get_solvable(pkg2);
143
144 // Check names
145 const char* str1 = pool_id2str(pool, s1->name);
146 const char* str2 = pool_id2str(pool, s2->name);
147
148 int ret = strcmp(str1, str2);
149 if (ret)
150 return ret;
151
152 // Check the version string
153 ret = pakfire_package_evr_cmp(pkg1, pkg2);
154 if (ret)
155 return ret;
156
157 // Check repositories
4651122b
MT
158 struct pakfire_repo* repo1 = pakfire_package_get_repo(pkg1);
159 struct pakfire_repo* repo2 = pakfire_package_get_repo(pkg2);
221cc3ce
MT
160
161 if (repo1 && repo2) {
162 ret = pakfire_repo_cmp(repo1, repo2);
3ff6aee6 163 }
221cc3ce 164
3ff6aee6
MT
165 pakfire_repo_unref(repo1);
166 pakfire_repo_unref(repo2);
221cc3ce 167
3ff6aee6
MT
168 if (ret)
169 return ret;
221cc3ce
MT
170
171 // Check package architectures
172 str1 = pool_id2str(pool, s1->arch);
173 str2 = pool_id2str(pool, s2->arch);
174
175 return strcmp(str1, str2);
176}
177
31480bee 178PAKFIRE_EXPORT int pakfire_package_evr_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) {
0defa23e 179 Pool* pool = pakfire_get_solv_pool(pkg1->pakfire);
221cc3ce
MT
180
181 Solvable* s1 = get_solvable(pkg1);
182 Solvable* s2 = get_solvable(pkg2);
183
184 return pool_evrcmp(pool, s1->evr, s2->evr, EVRCMP_COMPARE);
185}
186
31480bee 187Id pakfire_package_id(struct pakfire_package* pkg) {
221cc3ce
MT
188 return pkg->id;
189}
190
31480bee 191PAKFIRE_EXPORT const char* pakfire_package_get_nevra(struct pakfire_package* pkg) {
40fcf5ff
MT
192 if (!*pkg->nevra) {
193 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
194 Solvable* s = get_solvable(pkg);
221cc3ce 195
40fcf5ff
MT
196 pakfire_string_set(pkg->nevra, pool_solvable2str(pool, s));
197 }
221cc3ce 198
40fcf5ff 199 return pkg->nevra;
221cc3ce
MT
200}
201
31480bee 202PAKFIRE_EXPORT const char* pakfire_package_get_name(struct pakfire_package* pkg) {
0defa23e 203 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
204 Solvable* s = get_solvable(pkg);
205
206 return pool_id2str(pool, s->name);
207}
208
31480bee 209PAKFIRE_EXPORT void pakfire_package_set_name(struct pakfire_package* pkg, const char* name) {
0defa23e 210 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
211 Solvable* s = get_solvable(pkg);
212
213 s->name = pool_str2id(pool, name, 1);
214}
215
31480bee 216PAKFIRE_EXPORT const char* pakfire_package_get_evr(struct pakfire_package* pkg) {
0defa23e 217 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
218 Solvable* s = get_solvable(pkg);
219
220 return pool_id2str(pool, s->evr);
221}
222
31480bee 223PAKFIRE_EXPORT void pakfire_package_set_evr(struct pakfire_package* pkg, const char* evr) {
0defa23e 224 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
225 Solvable* s = get_solvable(pkg);
226
227 s->evr = pool_str2id(pool, evr, 1);
228}
229
e42b5960
MT
230char* pakfire_package_join_evr(const char* e, const char* v, const char* r) {
231 char* buffer = NULL;
312fd26f 232
e42b5960
MT
233 // Check for valid input
234 if (!e || !v || !r) {
235 errno = EINVAL;
236 return NULL;
312fd26f
MT
237 }
238
e42b5960
MT
239 // Skip any zeroes in epoch
240 while (*e && *e == '0')
241 e++;
242
243 // Format string with epoch
244 if (*e) {
245 if (asprintf(&buffer, "%s:%s-%s", e, v, r) < 0)
246 return NULL;
247
248 // Or format it without epoch
249 } else {
250 if (asprintf(&buffer, "%s-%s", v, r) < 0)
251 return NULL;
252 }
312fd26f
MT
253
254 return buffer;
255}
256
31480bee 257PAKFIRE_EXPORT const char* pakfire_package_get_arch(struct pakfire_package* pkg) {
0defa23e 258 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
259 Solvable* s = get_solvable(pkg);
260
261 return pool_id2str(pool, s->arch);
262}
263
31480bee 264PAKFIRE_EXPORT void pakfire_package_set_arch(struct pakfire_package* pkg, const char* arch) {
0defa23e 265 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
266 Solvable* s = get_solvable(pkg);
267
268 s->arch = pool_str2id(pool, arch, 1);
269}
270
31480bee 271int pakfire_package_is_source(struct pakfire_package* pkg) {
af14aefb
MT
272 const char* arch = pakfire_package_get_arch(pkg);
273 if (!arch)
274 return 1;
275
276 return (strcmp(arch, "src") == 0);
277}
278
31480bee 279static void pakfire_package_internalize_repo(struct pakfire_package* pkg) {
4651122b 280 struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
221cc3ce
MT
281 if (repo) {
282 pakfire_repo_internalize(repo);
3ff6aee6 283 pakfire_repo_unref(repo);
221cc3ce
MT
284 }
285}
286
31480bee 287static unsigned long long pakfire_package_get_num(struct pakfire_package* pkg, Id type) {
ac71886a
MT
288 pakfire_package_internalize_repo(pkg);
289
290 Solvable* s = get_solvable(pkg);
291 return solvable_lookup_num(s, type, 0);
292}
293
31480bee 294static void pakfire_package_set_num(struct pakfire_package* pkg, Id type, unsigned long long value) {
ac71886a
MT
295 Solvable* s = get_solvable(pkg);
296
297 solvable_set_num(s, type, value);
298}
299
31480bee 300static const char* pakfire_package_get_string(struct pakfire_package* pkg, int key) {
221cc3ce
MT
301 pakfire_package_internalize_repo(pkg);
302
303 Solvable* s = get_solvable(pkg);
304 const char* str = solvable_lookup_str(s, key);
305
306 if (!str)
307 return NULL;
308
309 if (strlen(str) == 0)
310 return NULL;
311
312 return str;
313}
314
31480bee 315static void pakfire_package_set_string(struct pakfire_package* pkg, int key, const char* value) {
221cc3ce
MT
316 Solvable* s = get_solvable(pkg);
317
318 if (!value)
319 value = "";
320
7ccc9d74
MT
321 solvable_set_poolstr(s, key, value);
322}
323
31480bee 324static char** pakfire_package_get_string_array(struct pakfire_package* pkg, Id key) {
1eb7f40b
MT
325 char** strings = NULL;
326
327 Queue ids;
328 queue_init(&ids);
329
0defa23e 330 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
7ccc9d74 331 Solvable* s = get_solvable(pkg);
1eb7f40b
MT
332 solvable_lookup_idarray(s, key, &ids);
333
334 if (ids.count > 0) {
335 strings = calloc(ids.count + 1, sizeof(*strings));
336 if (!strings) {
337 queue_free(&ids);
338 return NULL;
339 }
340
341 for (int i = 0; i < ids.count; i++) {
342 const char* value = pool_id2str(pool, ids.elements[i]);
343 strings[i] = strdup(value);
344 }
7ccc9d74 345
1eb7f40b
MT
346 strings[ids.count] = NULL;
347 }
348
349 queue_free(&ids);
350
351 return strings;
352}
353
31480bee 354static void pakfire_package_add_string_array(struct pakfire_package* pkg, Id key, const char* value) {
7ccc9d74
MT
355 if (!value)
356 return;
357
1eb7f40b 358 Solvable* s = get_solvable(pkg);
7ccc9d74 359 solvable_add_poolstr_array(s, key, value);
221cc3ce
MT
360}
361
31480bee 362uint64_t pakfire_package_get_dbid(struct pakfire_package* pkg) {
ac71886a
MT
363 return pakfire_package_get_num(pkg, RPM_RPMDBID);
364}
365
31480bee 366void pakfire_package_set_dbid(struct pakfire_package* pkg, uint64_t id) {
ac71886a
MT
367 pakfire_package_set_num(pkg, RPM_RPMDBID, id);
368}
369
31480bee 370PAKFIRE_EXPORT const char* pakfire_package_get_uuid(struct pakfire_package* pkg) {
221cc3ce
MT
371 return pakfire_package_get_string(pkg, SOLVABLE_PKGID);
372}
373
31480bee 374PAKFIRE_EXPORT void pakfire_package_set_uuid(struct pakfire_package* pkg, const char* uuid) {
221cc3ce
MT
375 pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid);
376}
377
31480bee 378PAKFIRE_EXPORT const char* pakfire_package_get_checksum(struct pakfire_package* pkg) {
221cc3ce
MT
379 return pakfire_package_get_string(pkg, SOLVABLE_CHECKSUM);
380}
381
31480bee 382PAKFIRE_EXPORT void pakfire_package_set_checksum(struct pakfire_package* pkg, const char* checksum) {
221cc3ce
MT
383 pakfire_package_set_string(pkg, SOLVABLE_CHECKSUM, checksum);
384}
385
31480bee 386PAKFIRE_EXPORT const char* pakfire_package_get_summary(struct pakfire_package* pkg) {
221cc3ce
MT
387 return pakfire_package_get_string(pkg, SOLVABLE_SUMMARY);
388}
389
31480bee 390PAKFIRE_EXPORT void pakfire_package_set_summary(struct pakfire_package* pkg, const char* summary) {
221cc3ce
MT
391 pakfire_package_set_string(pkg, SOLVABLE_SUMMARY, summary);
392}
393
31480bee 394PAKFIRE_EXPORT const char* pakfire_package_get_description(struct pakfire_package* pkg) {
221cc3ce
MT
395 return pakfire_package_get_string(pkg, SOLVABLE_DESCRIPTION);
396}
397
31480bee 398PAKFIRE_EXPORT void pakfire_package_set_description(struct pakfire_package* pkg, const char* description) {
221cc3ce
MT
399 pakfire_package_set_string(pkg, SOLVABLE_DESCRIPTION, description);
400}
401
31480bee 402PAKFIRE_EXPORT const char* pakfire_package_get_license(struct pakfire_package* pkg) {
221cc3ce
MT
403 return pakfire_package_get_string(pkg, SOLVABLE_LICENSE);
404}
405
31480bee 406PAKFIRE_EXPORT void pakfire_package_set_license(struct pakfire_package* pkg, const char* license) {
221cc3ce
MT
407 pakfire_package_set_string(pkg, SOLVABLE_LICENSE, license);
408}
409
31480bee 410PAKFIRE_EXPORT const char* pakfire_package_get_url(struct pakfire_package* pkg) {
221cc3ce
MT
411 return pakfire_package_get_string(pkg, SOLVABLE_URL);
412}
413
31480bee 414PAKFIRE_EXPORT void pakfire_package_set_url(struct pakfire_package* pkg, const char* url) {
221cc3ce
MT
415 pakfire_package_set_string(pkg, SOLVABLE_URL, url);
416}
417
31480bee 418PAKFIRE_EXPORT char* pakfire_package_get_groups(struct pakfire_package* pkg) {
1eb7f40b
MT
419 char** groups = pakfire_package_get_string_array(pkg, SOLVABLE_GROUP);
420 if (!groups)
421 return NULL;
422
423 char* string = pakfire_string_join(groups, " ");
424
425 // Free array
426 for (char** group = groups; *group; group++)
427 free(*group);
428 free(groups);
429
430 return string;
221cc3ce
MT
431}
432
31480bee 433PAKFIRE_EXPORT void pakfire_package_set_groups(struct pakfire_package* pkg, const char* groups) {
7ccc9d74 434 char** list = pakfire_split_string(groups, ' ');
1eb7f40b
MT
435 if (!list)
436 return;
221cc3ce 437
1eb7f40b
MT
438 for (char** group = list; *group; group++) {
439 pakfire_package_add_string_array(pkg, SOLVABLE_GROUP, *group);
440 free(*group);
2141b578 441 }
1eb7f40b
MT
442
443 free(list);
8ad0a954
MT
444}
445
31480bee 446PAKFIRE_EXPORT const char* pakfire_package_get_vendor(struct pakfire_package* pkg) {
221cc3ce
MT
447 return pakfire_package_get_string(pkg, SOLVABLE_VENDOR);
448}
449
31480bee 450PAKFIRE_EXPORT void pakfire_package_set_vendor(struct pakfire_package* pkg, const char* vendor) {
221cc3ce
MT
451 pakfire_package_set_string(pkg, SOLVABLE_VENDOR, vendor);
452}
453
31480bee 454PAKFIRE_EXPORT const char* pakfire_package_get_maintainer(struct pakfire_package* pkg) {
221cc3ce
MT
455 return pakfire_package_get_string(pkg, SOLVABLE_PACKAGER);
456}
457
31480bee 458PAKFIRE_EXPORT void pakfire_package_set_maintainer(struct pakfire_package* pkg, const char* maintainer) {
221cc3ce
MT
459 pakfire_package_set_string(pkg, SOLVABLE_PACKAGER, maintainer);
460}
461
31480bee 462static int pakfire_package_make_cache_path(struct pakfire_package* pkg) {
b12a5d7d
MT
463 const char* filename = pakfire_package_get_filename(pkg);
464 const char* checksum = pakfire_package_get_checksum(pkg);
465
466 if (strlen(checksum) < 3)
467 return 1;
468
469 return pakfire_make_cache_path(pkg->pakfire, pkg->path,
470 "%c%c/%s/%s", checksum[0], checksum[1], checksum + 2, filename);
471}
472
31480bee 473PAKFIRE_EXPORT const char* pakfire_package_get_path(struct pakfire_package* pkg) {
b12a5d7d
MT
474 int r;
475
476 if (!*pkg->path) {
477 const char* base = pakfire_package_get_string(pkg, SOLVABLE_MEDIABASE);
478 if (base) {
479 const char* filename = pakfire_package_get_filename(pkg);
480 if (!filename)
481 return NULL;
482
483 pakfire_string_format(pkg->path, "%s/%s", base, filename);
484 } else {
485 r = pakfire_package_make_cache_path(pkg);
486 if (r)
487 return NULL;
488 }
489 }
490
491 return pkg->path;
492}
493
31480bee 494PAKFIRE_EXPORT void pakfire_package_set_path(struct pakfire_package* pkg, const char* path) {
b12a5d7d
MT
495 char* basename = pakfire_basename(path);
496 char* dirname = pakfire_dirname(path);
497
498 if (basename) {
499 pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, basename);
500 free(basename);
501 }
502
503 if (dirname) {
504 pakfire_package_set_string(pkg, SOLVABLE_MEDIABASE, dirname);
505 free(dirname);
506 }
507
508 pakfire_string_set(pkg->path, path);
509}
510
511// Removes epoch
512static const char* evr2vr(const char* evr) {
513 const char* p = evr;
514
515 // Skip any leading digits
516 for (; *p >= '0' && *p <= '9'; p++);
517
518 // If after the leading digits, we found :, we return the rest of the string
519 if (p != evr && *p == ':')
520 return ++p;
521
522 return evr;
523}
524
31480bee 525static const char* pakfire_package_make_filename(struct pakfire_package* pkg) {
b12a5d7d
MT
526 if (!*pkg->filename) {
527 const char* name = pakfire_package_get_name(pkg);
528 const char* evr = pakfire_package_get_evr(pkg);
529 const char* arch = pakfire_package_get_arch(pkg);
530
531 if (!name || !evr || !arch)
532 return NULL;
533
534 const char* vr = evr2vr(evr);
535
536 pakfire_string_format(pkg->filename, "%s-%s.%s.pfm", name, vr, arch);
537 }
538
539 return pkg->filename;
540}
541
31480bee 542PAKFIRE_EXPORT const char* pakfire_package_get_filename(struct pakfire_package* pkg) {
b12a5d7d
MT
543 const char* filename = pakfire_package_get_string(pkg, SOLVABLE_MEDIAFILE);
544
545 // Generate the filename if not set
546 if (!filename)
547 filename = pakfire_package_make_filename(pkg);
548
549 return filename;
221cc3ce
MT
550}
551
31480bee 552PAKFIRE_EXPORT void pakfire_package_set_filename(struct pakfire_package* pkg, const char* filename) {
221cc3ce
MT
553 pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, filename);
554}
555
31480bee 556PAKFIRE_EXPORT int pakfire_package_is_installed(struct pakfire_package* pkg) {
0defa23e 557 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce
MT
558 Solvable* s = get_solvable(pkg);
559
560 return pool->installed == s->repo;
561}
562
31480bee 563PAKFIRE_EXPORT unsigned long long pakfire_package_get_downloadsize(struct pakfire_package* pkg) {
221cc3ce
MT
564 return pakfire_package_get_num(pkg, SOLVABLE_DOWNLOADSIZE);
565}
566
31480bee 567PAKFIRE_EXPORT void pakfire_package_set_downloadsize(struct pakfire_package* pkg, unsigned long long downloadsize) {
221cc3ce
MT
568 return pakfire_package_set_num(pkg, SOLVABLE_DOWNLOADSIZE, downloadsize);
569}
570
31480bee 571PAKFIRE_EXPORT unsigned long long pakfire_package_get_installsize(struct pakfire_package* pkg) {
221cc3ce
MT
572 return pakfire_package_get_num(pkg, SOLVABLE_INSTALLSIZE);
573}
574
31480bee 575PAKFIRE_EXPORT void pakfire_package_set_installsize(struct pakfire_package* pkg, unsigned long long installsize) {
221cc3ce
MT
576 return pakfire_package_set_num(pkg, SOLVABLE_INSTALLSIZE, installsize);
577}
578
31480bee 579PAKFIRE_EXPORT unsigned long long pakfire_package_get_size(struct pakfire_package* pkg) {
221cc3ce
MT
580 if (pakfire_package_is_installed(pkg))
581 return pakfire_package_get_installsize(pkg);
582
583 return pakfire_package_get_downloadsize(pkg);
584}
585
31480bee 586PAKFIRE_EXPORT const char* pakfire_package_get_build_host(struct pakfire_package* pkg) {
221cc3ce
MT
587 return pakfire_package_get_string(pkg, SOLVABLE_BUILDHOST);
588}
589
31480bee 590PAKFIRE_EXPORT void pakfire_package_set_build_host(struct pakfire_package* pkg, const char* build_host) {
2ffc704d 591 pakfire_package_set_string(pkg, SOLVABLE_BUILDHOST, build_host);
221cc3ce
MT
592}
593
31480bee 594PAKFIRE_EXPORT const char* pakfire_package_get_build_id(struct pakfire_package* pkg) {
7996020a
MT
595 return pakfire_package_get_string(pkg, SOLVABLE_BUILDVERSION);
596}
597
31480bee 598PAKFIRE_EXPORT void pakfire_package_set_build_id(struct pakfire_package* pkg, const char* build_id) {
7996020a
MT
599 pakfire_package_set_string(pkg, SOLVABLE_BUILDVERSION, build_id);
600}
601
57e2cf99
MT
602void pakfire_package_set_build_id_from_uuid(struct pakfire_package* pkg, uuid_t* build_id) {
603 char buffer[UUID_STR_LEN];
604
605 // Convert the UUID to string
606 uuid_unparse_lower(*build_id, buffer);
607
608 pakfire_package_set_build_id(pkg, buffer);
609}
610
31480bee 611PAKFIRE_EXPORT time_t pakfire_package_get_build_time(struct pakfire_package* pkg) {
221cc3ce
MT
612 return pakfire_package_get_num(pkg, SOLVABLE_BUILDTIME);
613}
614
31480bee 615PAKFIRE_EXPORT void pakfire_package_set_build_time(struct pakfire_package* pkg, time_t build_time) {
2ffc704d 616 pakfire_package_set_num(pkg, SOLVABLE_BUILDTIME, build_time);
221cc3ce
MT
617}
618
31480bee 619PAKFIRE_EXPORT time_t pakfire_package_get_install_time(struct pakfire_package* pkg) {
221cc3ce
MT
620 return pakfire_package_get_num(pkg, SOLVABLE_INSTALLTIME);
621}
622
31480bee 623PAKFIRE_EXPORT void pakfire_package_set_install_time(struct pakfire_package* pkg, time_t install_time) {
af647c55
MT
624 pakfire_package_set_num(pkg, SOLVABLE_INSTALLTIME, install_time);
625}
626
452d3833 627static char** pakfire_package_get_relationlist(
31480bee 628 struct pakfire_package* pkg, Id type, Id marker) {
452d3833
MT
629 char** array = NULL;
630
221cc3ce
MT
631 Queue q;
632 queue_init(&q);
633
634 Solvable* s = get_solvable(pkg);
452d3833
MT
635
636 // Fetch all deps
a9659851 637 solvable_lookup_deparray(s, type, &q, marker);
221cc3ce 638
452d3833
MT
639 // Nothing to do if the array was empty
640 if (!q.count)
641 goto ERROR;
d6ea32df 642
452d3833 643 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
221cc3ce 644
452d3833
MT
645 // Allocate array
646 array = calloc(q.count + 1, sizeof(*array));
647 if (!array)
648 goto ERROR;
649
650 for (int i = 0; i < q.count; i++) {
651 const char* dep = pool_dep2str(pool, q.elements[i]);
d6ea32df 652
452d3833
MT
653 array[i] = strdup(dep);
654 }
655
656ERROR:
657 queue_free(&q);
658
659 return array;
221cc3ce
MT
660}
661
31480bee 662static void pakfire_package_add_dep(struct pakfire_package* pkg, Id type,
452d3833 663 const char* dep, Id marker) {
221cc3ce
MT
664 Solvable* s = get_solvable(pkg);
665
452d3833
MT
666 // Parse the dependency
667 Id id = pakfire_parse_dep(pkg->pakfire, dep);
668 if (!id)
669 return;
670
671 solvable_add_deparray(s, type, id, marker);
221cc3ce
MT
672}
673
31480bee 674PAKFIRE_EXPORT char** pakfire_package_get_provides(struct pakfire_package* pkg) {
063ca10f 675 return pakfire_package_get_relationlist(pkg, SOLVABLE_PROVIDES, -SOLVABLE_FILEMARKER);
221cc3ce
MT
676}
677
31480bee 678void pakfire_package_add_provides(struct pakfire_package* pkg, const char* dep) {
452d3833 679 pakfire_package_add_dep(pkg, SOLVABLE_PROVIDES, dep, -SOLVABLE_FILEMARKER);
221cc3ce
MT
680}
681
31480bee 682PAKFIRE_EXPORT char** pakfire_package_get_prerequires(struct pakfire_package* pkg) {
063ca10f 683 return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, SOLVABLE_PREREQMARKER);
221cc3ce
MT
684}
685
31480bee 686void pakfire_package_add_prerequires(struct pakfire_package* pkg, const char* dep) {
452d3833
MT
687 pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, SOLVABLE_PREREQMARKER);
688}
689
31480bee 690PAKFIRE_EXPORT char** pakfire_package_get_requires(struct pakfire_package* pkg) {
063ca10f 691 return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, -SOLVABLE_PREREQMARKER);
221cc3ce
MT
692}
693
31480bee 694void pakfire_package_add_requires(struct pakfire_package* pkg, const char* dep) {
452d3833 695 pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, -SOLVABLE_PREREQMARKER);
221cc3ce
MT
696}
697
31480bee 698PAKFIRE_EXPORT char** pakfire_package_get_conflicts(struct pakfire_package* pkg) {
a9659851 699 return pakfire_package_get_relationlist(pkg, SOLVABLE_CONFLICTS, 0);
221cc3ce
MT
700}
701
31480bee 702void pakfire_package_add_conflicts(struct pakfire_package* pkg, const char* dep) {
452d3833 703 pakfire_package_add_dep(pkg, SOLVABLE_CONFLICTS, dep, 0);
221cc3ce
MT
704}
705
31480bee 706PAKFIRE_EXPORT char** pakfire_package_get_obsoletes(struct pakfire_package* pkg) {
a9659851 707 return pakfire_package_get_relationlist(pkg, SOLVABLE_OBSOLETES, 0);
221cc3ce
MT
708}
709
31480bee 710void pakfire_package_add_obsoletes(struct pakfire_package* pkg, const char* dep) {
452d3833 711 pakfire_package_add_dep(pkg, SOLVABLE_OBSOLETES, dep, 0);
221cc3ce
MT
712}
713
31480bee 714PAKFIRE_EXPORT char** pakfire_package_get_recommends(struct pakfire_package* pkg) {
a9659851 715 return pakfire_package_get_relationlist(pkg, SOLVABLE_RECOMMENDS, 0);
221cc3ce
MT
716}
717
31480bee 718void pakfire_package_add_recommends(struct pakfire_package* pkg, const char* dep) {
452d3833 719 pakfire_package_add_dep(pkg, SOLVABLE_RECOMMENDS, dep, 0);
221cc3ce
MT
720}
721
31480bee 722PAKFIRE_EXPORT char** pakfire_package_get_suggests(struct pakfire_package* pkg) {
a9659851 723 return pakfire_package_get_relationlist(pkg, SOLVABLE_SUGGESTS, 0);
221cc3ce
MT
724}
725
31480bee 726void pakfire_package_add_suggests(struct pakfire_package* pkg, const char* dep) {
452d3833 727 pakfire_package_add_dep(pkg, SOLVABLE_SUGGESTS, dep, 0);
221cc3ce
MT
728}
729
31480bee 730PAKFIRE_EXPORT char** pakfire_package_get_supplements(struct pakfire_package* pkg) {
8fe2e4ba
MT
731 return pakfire_package_get_relationlist(pkg, SOLVABLE_SUPPLEMENTS, 0);
732}
733
31480bee 734void pakfire_package_add_supplements(struct pakfire_package* pkg, const char* dep) {
452d3833
MT
735 pakfire_package_add_dep(pkg, SOLVABLE_SUPPLEMENTS, dep, 0);
736}
737
31480bee 738PAKFIRE_EXPORT char** pakfire_package_get_enhances(struct pakfire_package* pkg) {
8fe2e4ba
MT
739 return pakfire_package_get_relationlist(pkg, SOLVABLE_ENHANCES, 0);
740}
741
31480bee 742void pakfire_package_add_enhances(struct pakfire_package* pkg, const char* dep) {
452d3833
MT
743 pakfire_package_add_dep(pkg, SOLVABLE_ENHANCES, dep, 0);
744}
745
31480bee 746PAKFIRE_EXPORT int pakfire_package_get_reverse_requires(struct pakfire_package* pkg,
e1d77c57
MT
747 struct pakfire_packagelist** list) {
748 Queue matches;
749 queue_init(&matches);
750
751 // Reset pointer
752 *list = NULL;
753
754 Pool* pool = pakfire_get_solv_pool(pkg->pakfire);
755
756 // Search for any matches
757 pool_whatmatchessolvable(pool, SOLVABLE_REQUIRES, pkg->id, &matches, 0);
758
759 // Create a new package list
760 int r = pakfire_packagelist_create_from_queue(list, pkg->pakfire, &matches);
761 if (r)
762 goto ERROR;
763
764ERROR:
765 queue_free(&matches);
766
767 return r;
768}
769
4651122b 770PAKFIRE_EXPORT struct pakfire_repo* pakfire_package_get_repo(struct pakfire_package* pkg) {
e9d9eadc
MT
771 if (!pkg->repo) {
772 Solvable* s = get_solvable(pkg);
773
774 pkg->repo = pakfire_repo_create_from_repo(pkg->pakfire, s->repo);
775 }
221cc3ce 776
e9d9eadc 777 return pakfire_repo_ref(pkg->repo);
221cc3ce
MT
778}
779
221cc3ce
MT
780static void pakfire_package_dump_add_line(char** str, const char* key, const char* val) {
781 if (val)
782 asprintf(str, "%s%-15s: %s\n", *str, key ? key : "", val);
783}
784
785static void pakfire_package_dump_add_lines(char** str, const char* key, const char* val) {
7500066c
MT
786 char** lines = pakfire_split_string(val, '\n');
787 if (!lines)
788 return;
221cc3ce 789
7500066c
MT
790 while (*lines) {
791 pakfire_package_dump_add_line(str, key, *lines);
792 lines++;
221cc3ce
MT
793 }
794}
795
796static void pakfire_package_dump_add_line_date(char** str, const char* key, unsigned long long date) {
797 // Convert from integer to tm struct.
798 struct tm* timer = gmtime((time_t *)&date);
799
7500066c
MT
800 char val[128];
801 strftime(val, sizeof(val) - 1, "%a, %d %b %Y %T %z", timer);
221cc3ce
MT
802
803 pakfire_package_dump_add_line(str, key, val);
804}
805
221cc3ce 806static void pakfire_package_dump_add_line_size(char** str, const char* key, unsigned long long size) {
cc90545a
MT
807 char buffer[128];
808 pakfire_format_size(buffer, sizeof(buffer) - 1, size);
221cc3ce 809
cc90545a 810 pakfire_package_dump_add_line(str, key, buffer);
221cc3ce
MT
811}
812
7db0d073
MT
813static int pakfire_sort_dependencies(const void* p1, const void* p2) {
814 const char* dep1 = *(const char**)p1;
815 const char* dep2 = *(const char**)p2;
816
817 return strcmp(dep1, dep2);
818}
819
31480bee 820PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags) {
221cc3ce
MT
821 char* string = "";
822
823 // Name
824 const char* name = pakfire_package_get_name(pkg);
825 pakfire_package_dump_add_line(&string, _("Name"), name);
826
6ed66687
MT
827 // EVR
828 const char* evr = pakfire_package_get_evr(pkg);
829 pakfire_package_dump_add_line(&string, _("Version"), evr);
221cc3ce 830
6ed66687
MT
831 // Arch
832 const char* arch = pakfire_package_get_arch(pkg);
833 pakfire_package_dump_add_line(&string, _("Arch"), arch);
221cc3ce
MT
834
835 // Size
836 unsigned long long size = pakfire_package_get_size(pkg);
837 pakfire_package_dump_add_line_size(&string, _("Size"), size);
838
839 // Installed size
840 if (pakfire_package_is_installed(pkg)) {
841 unsigned long long installsize = pakfire_package_get_installsize(pkg);
842 pakfire_package_dump_add_line_size(&string, _("Installed size"), installsize);
843
844 // Downloadsize
845 } else {
846 unsigned long long downloadsize = pakfire_package_get_downloadsize(pkg);
847 pakfire_package_dump_add_line_size(&string, _("Download size"), downloadsize);
848 }
849
4651122b 850 struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
221cc3ce
MT
851 if (repo) {
852 const char* repo_name = pakfire_repo_get_name(repo);
853 pakfire_package_dump_add_line(&string, _("Repo"), repo_name);
854
3ff6aee6 855 pakfire_repo_unref(repo);
221cc3ce
MT
856 }
857
858 // Summary
859 const char* summary = pakfire_package_get_summary(pkg);
860 pakfire_package_dump_add_line(&string, _("Summary"), summary);
861
862 // Description
863 const char* description = pakfire_package_get_description(pkg);
1b99c676
MT
864 if (description)
865 pakfire_package_dump_add_lines(&string, _("Description"), description);
221cc3ce
MT
866
867 // Groups
7ccc9d74 868 const char* groups = pakfire_package_get_groups(pkg);
2141b578 869 if (groups) {
7ccc9d74 870 pakfire_package_dump_add_lines(&string, _("Groups"), groups);
2141b578 871 }
221cc3ce
MT
872
873 // URL
874 const char* url = pakfire_package_get_url(pkg);
875 pakfire_package_dump_add_line(&string, _("URL"), url);
876
877 // License
878 const char* license = pakfire_package_get_license(pkg);
879 pakfire_package_dump_add_line(&string, _("License"), license);
880
881 if (flags & PAKFIRE_PKG_DUMP_LONG) {
af647c55
MT
882 // Install Time
883 time_t install_time = pakfire_package_get_install_time(pkg);
884 if (install_time) {
885 pakfire_package_dump_add_line_date(&string, _("Install Time"), install_time);
886 }
887
221cc3ce
MT
888 // Maintainer
889 const char* maintainer = pakfire_package_get_maintainer(pkg);
890 pakfire_package_dump_add_line(&string, _("Maintainer"), maintainer);
891
892 // Vendor
893 const char* vendor = pakfire_package_get_vendor(pkg);
894 pakfire_package_dump_add_line(&string, _("Vendor"), vendor);
895
896 // UUID
897 const char* uuid = pakfire_package_get_uuid(pkg);
898 pakfire_package_dump_add_line(&string, _("UUID"), uuid);
899
7996020a
MT
900 // Build ID
901 const char* build_id = pakfire_package_get_build_id(pkg);
902 if (build_id)
903 pakfire_package_dump_add_line(&string, _("Build ID"), build_id);
904
221cc3ce 905 // Build time
2ffc704d
MT
906 time_t build_time = pakfire_package_get_build_time(pkg);
907 pakfire_package_dump_add_line_date(&string, _("Build Time"), build_time);
221cc3ce
MT
908
909 // Build host
2ffc704d
MT
910 const char* build_host = pakfire_package_get_build_host(pkg);
911 pakfire_package_dump_add_line(&string, _("Build Host"), build_host);
221cc3ce 912
2f873877
MT
913 // Dependencies
914
915 const struct relation {
916 const char* name;
31480bee 917 char** (*get)(struct pakfire_package* pkg);
2f873877
MT
918 } relations[] = {
919 { _("Provides"), pakfire_package_get_provides, },
920 { _("Pre-Requires"), pakfire_package_get_prerequires, },
921 { _("Requires"), pakfire_package_get_requires, },
922 { _("Conflicts"), pakfire_package_get_conflicts, },
923 { _("Obsoletes"), pakfire_package_get_obsoletes, },
924 { _("Recommends"), pakfire_package_get_recommends, },
925 { _("Suggests"), pakfire_package_get_suggests, },
8fe2e4ba
MT
926 { _("Supplements"), pakfire_package_get_supplements, },
927 { _("Enhances"), pakfire_package_get_enhances, },
2f873877
MT
928 { NULL, NULL},
929 };
930
931 for (const struct relation* relation = relations; relation->name; relation++) {
7db0d073
MT
932 char** deps = relation->get(pkg);
933 if (deps) {
e650b3ee 934 const char* name = relation->name;
7db0d073
MT
935 size_t count = 0;
936
937 // Count elements in the list
938 for (char** dep = deps; *dep; dep++)
939 count++;
940
941 // Sort the list
942 qsort(deps, count, sizeof(*deps), pakfire_sort_dependencies);
943
944 // Write it to the console
945 for (char** dep = deps; *dep; dep++) {
e650b3ee 946 pakfire_package_dump_add_line(&string, name, *dep);
452d3833 947 free(*dep);
e650b3ee
MT
948
949 // Clear name after first line
950 name = NULL;
452d3833 951 }
7db0d073 952 free(deps);
2f873877 953 }
221cc3ce
MT
954 }
955 }
956
957 if (flags & PAKFIRE_PKG_DUMP_FILELIST) {
1bbbfb9e 958 struct pakfire_filelist* filelist = pakfire_package_get_filelist(pkg);
5e9463ec
MT
959
960 const char* prefix = _("Filelist");
961
962 for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
5803b5f6 963 struct pakfire_file* file = pakfire_filelist_get(filelist, i);
221cc3ce 964
32485f6c
MT
965 const char* path = pakfire_file_get_path(file);
966 pakfire_package_dump_add_line(&string, prefix, path);
221cc3ce 967
5e9463ec 968 pakfire_file_unref(file);
221cc3ce 969
5e9463ec 970 // Only prefix the first line
221cc3ce
MT
971 prefix = NULL;
972 }
5e9463ec
MT
973
974 pakfire_filelist_unref(filelist);
221cc3ce
MT
975 }
976
977 return string;
978}
979
900faa2f
MT
980PAKFIRE_EXPORT struct pakfire_archive* pakfire_package_get_archive(struct pakfire_package* pkg) {
981 struct pakfire_archive* archive;
b12a5d7d 982
cbed1552 983 // Otherwise open the archive from the cache
b12a5d7d 984 const char* path = pakfire_package_get_path(pkg);
641cab18
MT
985 if (!path)
986 return NULL;
cbed1552 987
641cab18 988 // Open archive
cf3e773a 989 int r = pakfire_archive_open(&archive, pkg->pakfire, path);
cbed1552 990
cf3e773a
MT
991 if (r == 0)
992 return archive;
993
994 return NULL;
cbed1552
MT
995}
996
1bbbfb9e 997static int pakfire_package_fetch_legacy_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) {
221cc3ce
MT
998 pakfire_package_internalize_repo(pkg);
999
4651122b 1000 struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
221cc3ce 1001 Solvable* s = get_solvable(pkg);
0defa23e 1002 Pool* p = pakfire_get_solv_pool(pkg->pakfire);
3ff6aee6 1003 Repo* r = pakfire_repo_get_repo(repo);
5e9463ec 1004 pakfire_repo_unref(repo);
221cc3ce
MT
1005
1006 int found_marker = 0;
1007
1008 Id id, *ids;
1009 ids = r->idarraydata + s->provides;
1010 while((id = *ids++) != 0) {
32485f6c 1011 const char* path = pool_dep2str(p, id);
221cc3ce
MT
1012
1013 if (found_marker) {
5803b5f6 1014 struct pakfire_file* file;
221cc3ce 1015
883b3be9 1016 int r = pakfire_file_create(&file, pkg->pakfire);
5e9463ec
MT
1017 if (r)
1018 return r;
1019
32485f6c
MT
1020 // Set path
1021 pakfire_file_set_path(file, path);
5e9463ec 1022
f4560c3f 1023 r = pakfire_filelist_append(filelist, file);
5e9463ec
MT
1024 if (r)
1025 return r;
1026
1027 pakfire_file_unref(file);
221cc3ce
MT
1028 continue;
1029 }
1030
614a3dc8 1031 if (strcmp(path, "solvable:filemarker") == 0)
221cc3ce
MT
1032 ++found_marker;
1033 }
1034
5e9463ec 1035 return 0;
221cc3ce
MT
1036}
1037
1bbbfb9e 1038static int pakfire_package_fetch_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) {
5e9463ec
MT
1039 int r;
1040
221cc3ce
MT
1041 pakfire_package_internalize_repo(pkg);
1042
96c6c8f6 1043 Solvable* s = get_solvable(pkg);
221cc3ce
MT
1044
1045 Dataiterator di;
96c6c8f6 1046 dataiterator_init(&di, s->repo->pool, s->repo, pkg->id,
221cc3ce 1047 SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
5e9463ec 1048
221cc3ce 1049 while (dataiterator_step(&di)) {
5803b5f6 1050 struct pakfire_file* file;
221cc3ce 1051
883b3be9 1052 r = pakfire_file_create(&file, pkg->pakfire);
5e9463ec
MT
1053 if (r)
1054 return r;
221cc3ce 1055
32485f6c 1056 pakfire_file_set_path(file, di.kv.str);
221cc3ce 1057
5e9463ec 1058 // Append to filelist
f4560c3f 1059 pakfire_filelist_append(filelist, file);
5e9463ec 1060 pakfire_file_unref(file);
221cc3ce 1061 }
5e9463ec 1062 dataiterator_free(&di);
221cc3ce
MT
1063
1064 // If the file list is empty, we fall back to read files
1065 // in the older format.
f4560c3f
MT
1066 if (pakfire_filelist_is_empty(filelist)) {
1067 r = pakfire_package_fetch_legacy_filelist(pkg, filelist);
5e9463ec
MT
1068 if (r)
1069 return r;
1070 }
1071
1072 // Sort the list
f4560c3f 1073 pakfire_filelist_sort(filelist);
221cc3ce 1074
5e9463ec 1075 return 0;
221cc3ce
MT
1076}
1077
1bbbfb9e
MT
1078PAKFIRE_EXPORT struct pakfire_filelist* pakfire_package_get_filelist(struct pakfire_package* pkg) {
1079 struct pakfire_filelist* filelist;
5e9463ec 1080
883b3be9 1081 int r = pakfire_filelist_create(&filelist, pkg->pakfire);
f4560c3f
MT
1082 if (r)
1083 return NULL;
5e9463ec 1084
f4560c3f
MT
1085 r = pakfire_package_fetch_filelist(pkg, filelist);
1086 if (r) {
1087 pakfire_filelist_unref(filelist);
1088 return NULL;
221cc3ce
MT
1089 }
1090
f4560c3f 1091 return filelist;
221cc3ce
MT
1092}
1093
31480bee 1094static int pakfire_package_append_file(struct pakfire_package* pkg, const char* path) {
5e9463ec 1095 // Fetch repodata
4651122b 1096 struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
3ff6aee6 1097 Repodata* repodata = pakfire_repo_get_repodata(repo);
5e9463ec 1098 pakfire_repo_unref(repo);
221cc3ce 1099
d995f7fc
MT
1100 char* basename = pakfire_basename(path);
1101 char* dirname = pakfire_dirname(path);
1102
1103 // Convert directory into ID
1104 Id did = repodata_str2dir(repodata, dirname, 1);
1105 if (!did)
1106 did = repodata_str2dir(repodata, "/", 1);
1107
1108 // Add data to list
94db84fc 1109 repodata_add_dirstr(repodata, pkg->id,
d995f7fc
MT
1110 SOLVABLE_FILELIST, did, basename);
1111
1112 free(basename);
1113 free(dirname);
1114
1115 return 0;
1116}
1117
1bbbfb9e 1118PAKFIRE_EXPORT int pakfire_package_set_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) {
d995f7fc
MT
1119 int r;
1120
5e9463ec 1121 for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) {
5803b5f6 1122 struct pakfire_file* file = pakfire_filelist_get(filelist, i);
221cc3ce 1123
32485f6c
MT
1124 const char* path = pakfire_file_get_path(file);
1125 if (path) {
1126 r = pakfire_package_append_file(pkg, path);
d995f7fc
MT
1127 if (r) {
1128 pakfire_file_unref(file);
1129 return r;
1130 }
1131 }
1132
1133 pakfire_file_unref(file);
d995f7fc
MT
1134 }
1135
1136 return 0;
1137}
221cc3ce 1138
31480bee 1139int pakfire_package_set_filelist_from_string(struct pakfire_package* pkg, const char* files) {
d995f7fc
MT
1140 // Total length of the input string
1141 size_t size = strlen(files);
221cc3ce 1142
d995f7fc
MT
1143 // Copy files to the stack to be able to modify it
1144 char* buffer = alloca(size + 1);
3ff6aee6 1145
d995f7fc
MT
1146 // Copy the content
1147 memcpy(buffer, files, size);
1148
1149 // Replace all line breaks with NUL
1150 for (unsigned int i = 0; i < size; i++) {
1151 if (buffer[i] == '\n')
1152 buffer[i] = '\0';
1153 }
1154
1155 size_t p = 0;
1156 while (p < size) {
1157 const char* name = &buffer[p];
1158
1159 int r = pakfire_package_append_file(pkg, name);
1160 if (r)
1161 return r;
1162
1163 p += strlen(name) + 1;
5e9463ec 1164 }
221cc3ce 1165
5e9463ec 1166 return 0;
221cc3ce 1167}