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