]>
Commit | Line | Data |
---|---|---|
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 | 45 | struct 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 | 59 | static 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 | 66 | struct 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 | 80 | PAKFIRE_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 | 102 | static 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 | 110 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_ref(struct pakfire_package* pkg) { |
a4e3894f MT |
111 | pkg->nrefs++; |
112 | ||
113 | return pkg; | |
114 | } | |
115 | ||
31480bee | 116 | PAKFIRE_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 | 124 | PAKFIRE_EXPORT struct pakfire* pakfire_package_get_pakfire(struct pakfire_package* pkg) { |
178a4506 MT |
125 | return pakfire_ref(pkg->pakfire); |
126 | } | |
127 | ||
31480bee | 128 | static 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 | 134 | PAKFIRE_EXPORT int pakfire_package_eq(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
221cc3ce MT |
135 | return pkg1->id == pkg2->id; |
136 | } | |
137 | ||
31480bee | 138 | PAKFIRE_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 | 178 | PAKFIRE_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 | 187 | Id pakfire_package_id(struct pakfire_package* pkg) { |
221cc3ce MT |
188 | return pkg->id; |
189 | } | |
190 | ||
31480bee | 191 | PAKFIRE_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 | 202 | PAKFIRE_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 | 209 | PAKFIRE_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 | 216 | PAKFIRE_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 | 223 | PAKFIRE_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 |
230 | char* 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 | 257 | PAKFIRE_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 | 264 | PAKFIRE_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 | 271 | int 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 | 279 | static 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 | 287 | static 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 | 294 | static 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 | 300 | static 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 | 315 | static 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 | 324 | static 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 | 354 | static 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 | 362 | uint64_t pakfire_package_get_dbid(struct pakfire_package* pkg) { |
ac71886a MT |
363 | return pakfire_package_get_num(pkg, RPM_RPMDBID); |
364 | } | |
365 | ||
31480bee | 366 | void 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 | 370 | PAKFIRE_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 | 374 | PAKFIRE_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 | 378 | PAKFIRE_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 | 382 | PAKFIRE_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 | 386 | PAKFIRE_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 | 390 | PAKFIRE_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 | 394 | PAKFIRE_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 | 398 | PAKFIRE_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 | 402 | PAKFIRE_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 | 406 | PAKFIRE_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 | 410 | PAKFIRE_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 | 414 | PAKFIRE_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 | 418 | PAKFIRE_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 | 433 | PAKFIRE_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 | 446 | PAKFIRE_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 | 450 | PAKFIRE_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 | 454 | PAKFIRE_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 | 458 | PAKFIRE_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 | 462 | static 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 | 473 | PAKFIRE_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 | 494 | PAKFIRE_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 | |
512 | static 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 | 525 | static 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 | 542 | PAKFIRE_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 | 552 | PAKFIRE_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 | 556 | PAKFIRE_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 | 563 | PAKFIRE_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 | 567 | PAKFIRE_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 | 571 | PAKFIRE_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 | 575 | PAKFIRE_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 | 579 | PAKFIRE_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 | 586 | PAKFIRE_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 | 590 | PAKFIRE_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 | 594 | PAKFIRE_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 | 598 | PAKFIRE_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 |
602 | void 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 | 611 | PAKFIRE_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 | 615 | PAKFIRE_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 | 619 | PAKFIRE_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 | 623 | PAKFIRE_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 | 627 | static 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 | ||
656 | ERROR: | |
657 | queue_free(&q); | |
658 | ||
659 | return array; | |
221cc3ce MT |
660 | } |
661 | ||
31480bee | 662 | static 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 | 674 | PAKFIRE_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 | 678 | void 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 | 682 | PAKFIRE_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 | 686 | void 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 | 690 | PAKFIRE_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 | 694 | void 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 | 698 | PAKFIRE_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 | 702 | void 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 | 706 | PAKFIRE_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 | 710 | void 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 | 714 | PAKFIRE_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 | 718 | void 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 | 722 | PAKFIRE_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 | 726 | void 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 | 730 | PAKFIRE_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 | 734 | void 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 | 738 | PAKFIRE_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 | 742 | void 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 | 746 | PAKFIRE_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 | ||
764 | ERROR: | |
765 | queue_free(&matches); | |
766 | ||
767 | return r; | |
768 | } | |
769 | ||
4651122b | 770 | PAKFIRE_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 |
780 | static 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 | ||
785 | static 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 | ||
796 | static 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 | 806 | static 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 |
813 | static 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 | 820 | PAKFIRE_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 |
980 | PAKFIRE_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 | 997 | static 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 | 1038 | static 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 |
1078 | PAKFIRE_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 | 1094 | static 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 | 1118 | PAKFIRE_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 | 1139 | int 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 | } |