]>
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 | 27 | |
b59c9fa2 MT |
28 | #include <json.h> |
29 | ||
221cc3ce MT |
30 | #include <solv/evr.h> |
31 | #include <solv/pool.h> | |
221cc3ce MT |
32 | #include <solv/repo.h> |
33 | #include <solv/solvable.h> | |
34 | ||
517708c8 MT |
35 | // Enable legacy logging |
36 | #define PAKFIRE_LEGACY_LOGGING | |
37 | ||
cbed1552 | 38 | #include <pakfire/archive.h> |
221cc3ce | 39 | #include <pakfire/constants.h> |
484b2077 | 40 | #include <pakfire/ctx.h> |
2a623cf8 | 41 | #include <pakfire/dependencies.h> |
c52e0148 | 42 | #include <pakfire/digest.h> |
221cc3ce | 43 | #include <pakfire/file.h> |
5e9463ec | 44 | #include <pakfire/filelist.h> |
221cc3ce | 45 | #include <pakfire/i18n.h> |
6cdfb9dd | 46 | #include <pakfire/logging.h> |
221cc3ce | 47 | #include <pakfire/package.h> |
cbed1552 | 48 | #include <pakfire/pakfire.h> |
b4ae14b2 | 49 | #include <pakfire/path.h> |
9f953e68 | 50 | #include <pakfire/private.h> |
221cc3ce | 51 | #include <pakfire/repo.h> |
d973a13d | 52 | #include <pakfire/string.h> |
2f269d34 | 53 | #include <pakfire/transaction.h> |
221cc3ce MT |
54 | #include <pakfire/util.h> |
55 | ||
31480bee | 56 | struct pakfire_package { |
484b2077 | 57 | struct pakfire_ctx* ctx; |
ac4c607b | 58 | struct pakfire* pakfire; |
7847efcd | 59 | int nrefs; |
e9d9eadc | 60 | |
8b088877 MT |
61 | // Reference to this package in the SOLV pool |
62 | Id id; | |
4651122b | 63 | struct pakfire_repo* repo; |
8b088877 | 64 | |
40fcf5ff | 65 | char nevra[NAME_MAX]; |
571539a7 | 66 | char source_nevra[NAME_MAX]; |
40fcf5ff | 67 | |
b12a5d7d MT |
68 | char filename[NAME_MAX]; |
69 | char path[PATH_MAX]; | |
6c0217d3 | 70 | char cache_path[PATH_MAX]; |
7847efcd MT |
71 | }; |
72 | ||
39d1a3d3 MT |
73 | static Solvable* get_solvable(struct pakfire_package* pkg) { |
74 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
75 | ||
76 | return pool_id2solvable(pool, pkg->id); | |
77 | } | |
78 | ||
79 | static int pakfire_package_dep2id(const enum pakfire_package_key key, | |
80 | Id* id, Id* marker) { | |
81 | switch (key) { | |
82 | case PAKFIRE_PKG_PROVIDES: | |
83 | *id = SOLVABLE_PROVIDES; | |
84 | *marker = -SOLVABLE_FILEMARKER; | |
85 | break; | |
86 | ||
87 | case PAKFIRE_PKG_PREREQUIRES: | |
88 | *id = SOLVABLE_REQUIRES; | |
89 | *marker = SOLVABLE_PREREQMARKER; | |
90 | break; | |
91 | ||
92 | case PAKFIRE_PKG_REQUIRES: | |
93 | *id = SOLVABLE_REQUIRES; | |
94 | *marker = -SOLVABLE_PREREQMARKER; | |
95 | break; | |
96 | ||
97 | case PAKFIRE_PKG_CONFLICTS: | |
98 | *id = SOLVABLE_CONFLICTS; | |
99 | break; | |
100 | ||
101 | case PAKFIRE_PKG_OBSOLETES: | |
102 | *id = SOLVABLE_OBSOLETES; | |
103 | break; | |
104 | ||
105 | case PAKFIRE_PKG_RECOMMENDS: | |
106 | *id = SOLVABLE_RECOMMENDS; | |
107 | break; | |
108 | ||
109 | case PAKFIRE_PKG_SUGGESTS: | |
110 | *id = SOLVABLE_SUGGESTS; | |
111 | break; | |
112 | ||
113 | case PAKFIRE_PKG_SUPPLEMENTS: | |
114 | *id = SOLVABLE_SUPPLEMENTS; | |
115 | break; | |
116 | ||
117 | case PAKFIRE_PKG_ENHANCES: | |
118 | *id = SOLVABLE_ENHANCES; | |
119 | break; | |
120 | ||
121 | // This operation is not possible for any other types | |
122 | default: | |
123 | errno = EINVAL; | |
124 | return 1; | |
125 | } | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
130 | static int pakfire_package_add_depid(struct pakfire_package* pkg, | |
131 | const enum pakfire_package_key key, Id dep) { | |
132 | Solvable* s = get_solvable(pkg); | |
6a648bd4 MT |
133 | int r; |
134 | ||
39d1a3d3 MT |
135 | Id id = ID_NULL; |
136 | Id marker = ID_NULL; | |
137 | ||
138 | // Translate the dependency type | |
139 | r = pakfire_package_dep2id(key, &id, &marker); | |
140 | if (r) | |
6a648bd4 MT |
141 | return r; |
142 | ||
39d1a3d3 MT |
143 | // Append to the dependency array |
144 | solvable_add_deparray(s, id, dep, marker); | |
6a648bd4 | 145 | |
39d1a3d3 MT |
146 | return 0; |
147 | } | |
6a648bd4 | 148 | |
39d1a3d3 MT |
149 | static int pakfire_package_add_self_provides(struct pakfire_package* pkg) { |
150 | // Fetch the solvable | |
151 | Solvable* s = get_solvable(pkg); | |
152 | if (!s) | |
153 | return 1; | |
154 | ||
155 | // Get the self-provides ID | |
156 | Id dep = solvable_selfprovidedep(s); | |
157 | ||
158 | // Add it to the package | |
159 | return pakfire_package_add_depid(pkg, PAKFIRE_PKG_PROVIDES, dep); | |
6a648bd4 MT |
160 | } |
161 | ||
33ad2a01 MT |
162 | int pakfire_package_create_from_solvable(struct pakfire_package** package, |
163 | struct pakfire* pakfire, Id id) { | |
31480bee | 164 | struct pakfire_package* pkg = calloc(1, sizeof(*pkg)); |
e9d9eadc | 165 | if (!pkg) |
33ad2a01 | 166 | return 1; |
6cdfb9dd | 167 | |
484b2077 MT |
168 | // Store a reference to the context |
169 | pkg->ctx = pakfire_ctx(pakfire); | |
170 | ||
e9d9eadc | 171 | pkg->pakfire = pakfire_ref(pakfire); |
e9d9eadc | 172 | pkg->nrefs = 1; |
221cc3ce | 173 | |
33ad2a01 MT |
174 | // Store the ID |
175 | pkg->id = id; | |
176 | ||
177 | // Success | |
178 | *package = pkg; | |
179 | return 0; | |
221cc3ce MT |
180 | } |
181 | ||
33ad2a01 | 182 | PAKFIRE_EXPORT int pakfire_package_create(struct pakfire_package** package, |
32136e0c MT |
183 | struct pakfire* pakfire, struct pakfire_repo* repo, |
184 | const char* name, const char* evr, const char* arch) { | |
32136e0c | 185 | struct pakfire_repo* dummy = NULL; |
33ad2a01 MT |
186 | int r; |
187 | ||
188 | // Check for some valid input | |
189 | if (!name || !evr || !arch) { | |
190 | errno = EINVAL; | |
191 | return 1; | |
192 | } | |
32136e0c MT |
193 | |
194 | // Default to dummy repository | |
195 | if (!repo) { | |
196 | dummy = pakfire_get_repo(pakfire, PAKFIRE_REPO_DUMMY); | |
197 | if (!dummy) { | |
198 | errno = ENOENT; | |
33ad2a01 | 199 | return 1; |
32136e0c MT |
200 | } |
201 | ||
202 | repo = dummy; | |
203 | } | |
204 | ||
205 | // Allocate a new solvable | |
e9d9eadc | 206 | Id id = pakfire_repo_add_solvable(repo); |
33ad2a01 MT |
207 | if (!id) { |
208 | ERROR(pakfire, "Could not allocate a solvable: %m\n"); | |
209 | r = 1; | |
32136e0c | 210 | goto ERROR; |
33ad2a01 | 211 | } |
e9d9eadc | 212 | |
32136e0c | 213 | // Create a new package object |
33ad2a01 MT |
214 | r = pakfire_package_create_from_solvable(package, pakfire, id); |
215 | if (r) | |
32136e0c | 216 | goto ERROR; |
221cc3ce | 217 | |
33ad2a01 MT |
218 | // Reference the repository |
219 | (*package)->repo = pakfire_repo_ref(repo); | |
e9d9eadc | 220 | |
33ad2a01 MT |
221 | // Set the name |
222 | r = pakfire_package_set_string(*package, PAKFIRE_PKG_NAME, name); | |
223 | if (r) { | |
224 | ERROR(pakfire, "Could not set package name '%s': %m\n", name); | |
225 | goto ERROR; | |
226 | } | |
227 | ||
228 | // Set EVR | |
229 | r = pakfire_package_set_string(*package, PAKFIRE_PKG_EVR, evr); | |
230 | if (r) { | |
231 | ERROR(pakfire, "Could not set package EVR '%s': %m\n", evr); | |
232 | goto ERROR; | |
233 | } | |
234 | ||
235 | // Set arch | |
236 | r = pakfire_package_set_string(*package, PAKFIRE_PKG_ARCH, arch); | |
237 | if (r) { | |
238 | ERROR(pakfire, "Could not set package arch '%s': %m\n", arch); | |
239 | goto ERROR; | |
240 | } | |
221cc3ce | 241 | |
6a648bd4 | 242 | // Add self-provides |
39d1a3d3 | 243 | r = pakfire_package_add_self_provides(*package); |
6a648bd4 MT |
244 | if (r) { |
245 | ERROR(pakfire, "Could not create self-provides: %m\n"); | |
246 | goto ERROR; | |
247 | } | |
248 | ||
32136e0c MT |
249 | ERROR: |
250 | if (dummy) | |
251 | pakfire_repo_unref(dummy); | |
252 | ||
33ad2a01 | 253 | return r; |
221cc3ce MT |
254 | } |
255 | ||
31480bee | 256 | static void pakfire_package_free(struct pakfire_package* pkg) { |
e9d9eadc MT |
257 | if (pkg->repo) |
258 | pakfire_repo_unref(pkg->repo); | |
484b2077 MT |
259 | if (pkg->pakfire) |
260 | pakfire_unref(pkg->pakfire); | |
261 | if (pkg->ctx) | |
262 | pakfire_ctx_unref(pkg->ctx); | |
f0d6233d | 263 | free(pkg); |
221cc3ce MT |
264 | } |
265 | ||
31480bee | 266 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_ref(struct pakfire_package* pkg) { |
a4e3894f MT |
267 | pkg->nrefs++; |
268 | ||
269 | return pkg; | |
270 | } | |
271 | ||
31480bee | 272 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_unref(struct pakfire_package* pkg) { |
a4e3894f MT |
273 | if (--pkg->nrefs > 0) |
274 | return pkg; | |
275 | ||
276 | pakfire_package_free(pkg); | |
277 | return NULL; | |
278 | } | |
279 | ||
ac4c607b | 280 | PAKFIRE_EXPORT struct pakfire* pakfire_package_get_pakfire(struct pakfire_package* pkg) { |
178a4506 MT |
281 | return pakfire_ref(pkg->pakfire); |
282 | } | |
283 | ||
31480bee | 284 | PAKFIRE_EXPORT int pakfire_package_eq(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
221cc3ce MT |
285 | return pkg1->id == pkg2->id; |
286 | } | |
287 | ||
31480bee | 288 | PAKFIRE_EXPORT int pakfire_package_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
0defa23e | 289 | Pool* pool = pakfire_get_solv_pool(pkg1->pakfire); |
221cc3ce MT |
290 | |
291 | Solvable* s1 = get_solvable(pkg1); | |
292 | Solvable* s2 = get_solvable(pkg2); | |
293 | ||
294 | // Check names | |
295 | const char* str1 = pool_id2str(pool, s1->name); | |
296 | const char* str2 = pool_id2str(pool, s2->name); | |
297 | ||
298 | int ret = strcmp(str1, str2); | |
299 | if (ret) | |
300 | return ret; | |
301 | ||
302 | // Check the version string | |
303 | ret = pakfire_package_evr_cmp(pkg1, pkg2); | |
304 | if (ret) | |
305 | return ret; | |
306 | ||
307 | // Check repositories | |
4651122b MT |
308 | struct pakfire_repo* repo1 = pakfire_package_get_repo(pkg1); |
309 | struct pakfire_repo* repo2 = pakfire_package_get_repo(pkg2); | |
221cc3ce MT |
310 | |
311 | if (repo1 && repo2) { | |
312 | ret = pakfire_repo_cmp(repo1, repo2); | |
3ff6aee6 | 313 | } |
221cc3ce | 314 | |
3ff6aee6 MT |
315 | pakfire_repo_unref(repo1); |
316 | pakfire_repo_unref(repo2); | |
221cc3ce | 317 | |
3ff6aee6 MT |
318 | if (ret) |
319 | return ret; | |
221cc3ce MT |
320 | |
321 | // Check package architectures | |
322 | str1 = pool_id2str(pool, s1->arch); | |
323 | str2 = pool_id2str(pool, s2->arch); | |
324 | ||
325 | return strcmp(str1, str2); | |
326 | } | |
327 | ||
31480bee | 328 | PAKFIRE_EXPORT int pakfire_package_evr_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
0defa23e | 329 | Pool* pool = pakfire_get_solv_pool(pkg1->pakfire); |
221cc3ce MT |
330 | |
331 | Solvable* s1 = get_solvable(pkg1); | |
332 | Solvable* s2 = get_solvable(pkg2); | |
333 | ||
334 | return pool_evrcmp(pool, s1->evr, s2->evr, EVRCMP_COMPARE); | |
335 | } | |
336 | ||
d99f530b | 337 | PAKFIRE_EXPORT unsigned int pakfire_package_id(struct pakfire_package* pkg) { |
221cc3ce MT |
338 | return pkg->id; |
339 | } | |
340 | ||
e42b5960 MT |
341 | char* pakfire_package_join_evr(const char* e, const char* v, const char* r) { |
342 | char* buffer = NULL; | |
312fd26f | 343 | |
e42b5960 MT |
344 | // Check for valid input |
345 | if (!e || !v || !r) { | |
346 | errno = EINVAL; | |
347 | return NULL; | |
312fd26f MT |
348 | } |
349 | ||
e42b5960 MT |
350 | // Skip any zeroes in epoch |
351 | while (*e && *e == '0') | |
352 | e++; | |
353 | ||
354 | // Format string with epoch | |
355 | if (*e) { | |
356 | if (asprintf(&buffer, "%s:%s-%s", e, v, r) < 0) | |
357 | return NULL; | |
358 | ||
359 | // Or format it without epoch | |
360 | } else { | |
361 | if (asprintf(&buffer, "%s-%s", v, r) < 0) | |
362 | return NULL; | |
363 | } | |
312fd26f MT |
364 | |
365 | return buffer; | |
366 | } | |
367 | ||
31480bee | 368 | int pakfire_package_is_source(struct pakfire_package* pkg) { |
74468e4f | 369 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH); |
af14aefb MT |
370 | if (!arch) |
371 | return 1; | |
372 | ||
373 | return (strcmp(arch, "src") == 0); | |
374 | } | |
375 | ||
31480bee | 376 | static void pakfire_package_internalize_repo(struct pakfire_package* pkg) { |
4651122b | 377 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
221cc3ce | 378 | if (repo) { |
9eba3d65 | 379 | pakfire_repo_internalize(repo, 0); |
3ff6aee6 | 380 | pakfire_repo_unref(repo); |
221cc3ce | 381 | } |
becf17ca | 382 | } |
221cc3ce | 383 | |
becf17ca MT |
384 | static void pakfire_package_has_changed(struct pakfire_package* pkg) { |
385 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); | |
386 | if (repo) { | |
387 | pakfire_repo_has_changed(repo); | |
388 | pakfire_repo_unref(repo); | |
389 | } | |
7fbede3a MT |
390 | } |
391 | ||
0aade652 MT |
392 | // Removes epoch |
393 | static const char* evr2vr(const char* evr) { | |
394 | const char* p = evr; | |
395 | ||
396 | // Skip any leading digits | |
397 | for (; *p >= '0' && *p <= '9'; p++); | |
398 | ||
399 | // If after the leading digits, we found :, we return the rest of the string | |
400 | if (p != evr && *p == ':') | |
401 | return ++p; | |
402 | ||
403 | return evr; | |
404 | } | |
405 | ||
406 | static const char* pakfire_package_make_filename(struct pakfire_package* pkg) { | |
407 | int r; | |
408 | ||
409 | if (!*pkg->filename) { | |
410 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME); | |
411 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR); | |
412 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH); | |
413 | ||
414 | if (!name || !evr || !arch) | |
415 | return NULL; | |
416 | ||
417 | const char* vr = evr2vr(evr); | |
418 | if (!vr) | |
419 | return NULL; | |
420 | ||
421 | r = pakfire_string_format(pkg->filename, "%s-%s.%s.pfm", name, vr, arch); | |
422 | if (r) | |
423 | return NULL; | |
424 | } | |
425 | ||
426 | return pkg->filename; | |
427 | } | |
428 | ||
b1743459 | 429 | static int pakfire_package_make_cache_path(struct pakfire_package* pkg) { |
6c0217d3 | 430 | const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA); |
b1743459 | 431 | |
6c0217d3 MT |
432 | // Fetch the filename |
433 | const char* filename = pakfire_package_get_string(pkg, PAKFIRE_PKG_FILENAME); | |
434 | if (!filename) { | |
435 | ERROR(pkg->pakfire, "Could not fetch filename for %s: %m\n", nevra); | |
436 | return 1; | |
437 | } | |
b1743459 | 438 | |
6c0217d3 MT |
439 | // Fetch UUID |
440 | const char* uuid = pakfire_package_get_string(pkg, PAKFIRE_PKG_UUID); | |
441 | if (!uuid) { | |
442 | ERROR(pkg->pakfire, "Could not fetch UUID for %s: %m\n", nevra); | |
443 | return 1; | |
444 | } | |
b1743459 | 445 | |
5f4d8a0b | 446 | return pakfire_cache_path(pkg->pakfire, pkg->cache_path, "%s/%s", uuid, filename); |
b1743459 MT |
447 | } |
448 | ||
314e2310 MT |
449 | PAKFIRE_EXPORT void pakfire_package_unset(struct pakfire_package* pkg, |
450 | const enum pakfire_package_key key) { | |
451 | Id id = ID_NULL; | |
452 | ||
453 | Solvable* s = get_solvable(pkg); | |
454 | ||
455 | switch (key) { | |
456 | // Some keys cannot be unset | |
457 | case PAKFIRE_PKG_NAME: | |
458 | case PAKFIRE_PKG_EVR: | |
459 | case PAKFIRE_PKG_ARCH: | |
460 | return; | |
461 | ||
462 | case PAKFIRE_PKG_NEVRA: | |
463 | break; | |
464 | ||
465 | case PAKFIRE_PKG_UUID: | |
466 | id = SOLVABLE_PKGID; | |
467 | break; | |
468 | ||
469 | case PAKFIRE_PKG_SUMMARY: | |
470 | id = SOLVABLE_SUMMARY; | |
471 | break; | |
472 | ||
473 | case PAKFIRE_PKG_DESCRIPTION: | |
474 | id = SOLVABLE_DESCRIPTION; | |
475 | break; | |
476 | ||
477 | case PAKFIRE_PKG_LICENSE: | |
478 | id = SOLVABLE_LICENSE; | |
479 | break; | |
480 | ||
481 | case PAKFIRE_PKG_URL: | |
482 | id = SOLVABLE_URL; | |
483 | break; | |
484 | ||
485 | case PAKFIRE_PKG_GROUPS: | |
486 | id = SOLVABLE_GROUP; | |
487 | break; | |
488 | ||
489 | case PAKFIRE_PKG_VENDOR: | |
490 | id = SOLVABLE_VENDOR; | |
491 | break; | |
492 | ||
493 | case PAKFIRE_PKG_DISTRO: | |
494 | id = SOLVABLE_DISTRIBUTION; | |
495 | break; | |
496 | ||
497 | case PAKFIRE_PKG_PACKAGER: | |
498 | id = SOLVABLE_PACKAGER; | |
499 | break; | |
500 | ||
501 | case PAKFIRE_PKG_PATH: | |
502 | id = SOLVABLE_MEDIADIR; | |
503 | ||
504 | // Unset the filename, too | |
505 | pakfire_package_unset(pkg, PAKFIRE_PKG_FILENAME); | |
506 | ||
507 | // Invalidate the cache | |
508 | *pkg->path = '\0'; | |
509 | break; | |
510 | ||
511 | case PAKFIRE_PKG_FILENAME: | |
512 | id = SOLVABLE_MEDIAFILE; | |
513 | break; | |
514 | ||
515 | case PAKFIRE_PKG_CACHE_PATH: | |
516 | *pkg->cache_path = '\0'; | |
517 | break; | |
518 | ||
519 | case PAKFIRE_PKG_BUILD_HOST: | |
520 | id = SOLVABLE_BUILDHOST; | |
521 | break; | |
522 | ||
523 | case PAKFIRE_PKG_BUILD_ID: | |
524 | id = SOLVABLE_BUILDVERSION; | |
525 | break; | |
526 | ||
527 | case PAKFIRE_PKG_BUILD_TIME: | |
528 | id = SOLVABLE_BUILDTIME; | |
529 | break; | |
530 | ||
531 | case PAKFIRE_PKG_BUILD_ARCHES: | |
532 | id = SOLVABLE_BUILDFLAVOR; | |
533 | break; | |
534 | ||
535 | case PAKFIRE_PKG_SOURCE_PKG: | |
536 | pakfire_package_unset(pkg, PAKFIRE_PKG_SOURCE_NAME); | |
537 | pakfire_package_unset(pkg, PAKFIRE_PKG_SOURCE_EVR); | |
538 | pakfire_package_unset(pkg, PAKFIRE_PKG_SOURCE_ARCH); | |
539 | ||
540 | // Invalidate cache | |
541 | *pkg->source_nevra = '\0'; | |
542 | break; | |
543 | ||
544 | case PAKFIRE_PKG_SOURCE_NAME: | |
545 | id = SOLVABLE_SOURCENAME; | |
546 | break; | |
547 | ||
548 | case PAKFIRE_PKG_SOURCE_EVR: | |
549 | id = SOLVABLE_SOURCEEVR; | |
550 | break; | |
551 | ||
552 | case PAKFIRE_PKG_SOURCE_ARCH: | |
553 | id = SOLVABLE_SOURCEARCH; | |
554 | break; | |
555 | ||
556 | case PAKFIRE_PKG_DOWNLOADSIZE: | |
557 | id = SOLVABLE_DOWNLOADSIZE; | |
558 | break; | |
559 | ||
560 | case PAKFIRE_PKG_INSTALLSIZE: | |
561 | id = SOLVABLE_INSTALLSIZE; | |
562 | break; | |
563 | ||
564 | case PAKFIRE_PKG_INSTALLTIME: | |
565 | id = SOLVABLE_INSTALLTIME; | |
566 | break; | |
567 | ||
568 | // Cannot unset dependencies here | |
569 | case PAKFIRE_PKG_PROVIDES: | |
570 | case PAKFIRE_PKG_PREREQUIRES: | |
571 | case PAKFIRE_PKG_REQUIRES: | |
572 | case PAKFIRE_PKG_CONFLICTS: | |
573 | case PAKFIRE_PKG_OBSOLETES: | |
574 | case PAKFIRE_PKG_RECOMMENDS: | |
575 | case PAKFIRE_PKG_SUGGESTS: | |
576 | case PAKFIRE_PKG_SUPPLEMENTS: | |
577 | case PAKFIRE_PKG_ENHANCES: | |
578 | return; | |
579 | ||
580 | case PAKFIRE_PKG_DBID: | |
581 | return; | |
582 | } | |
583 | ||
584 | // Unset any values | |
585 | solvable_unset(s, id); | |
586 | } | |
587 | ||
10211c67 | 588 | PAKFIRE_EXPORT char** pakfire_package_get_strings( |
314e2310 | 589 | struct pakfire_package* pkg, const enum pakfire_package_key key) { |
10211c67 MT |
590 | char** ret = NULL; |
591 | const char* str = NULL; | |
314e2310 MT |
592 | Queue strings; |
593 | Id id = ID_NULL; | |
594 | ||
595 | pakfire_package_internalize_repo(pkg); | |
596 | ||
597 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
598 | Solvable* s = get_solvable(pkg); | |
599 | ||
600 | switch (key) { | |
d333480c MT |
601 | case PAKFIRE_PKG_GROUPS: |
602 | id = SOLVABLE_GROUP; | |
603 | break; | |
604 | ||
314e2310 MT |
605 | case PAKFIRE_PKG_BUILD_ARCHES: |
606 | id = SOLVABLE_BUILDFLAVOR; | |
607 | break; | |
608 | ||
609 | default: | |
610 | errno = EINVAL; | |
611 | return NULL; | |
612 | } | |
613 | ||
614 | // Setup a queue | |
615 | queue_init(&strings); | |
616 | ||
617 | // Fetch the strings | |
618 | solvable_lookup_idarray(s, id, &strings); | |
619 | ||
620 | if (strings.count) { | |
621 | // Allocate an array | |
622 | ret = calloc(strings.count + 1, sizeof(*ret)); | |
623 | if (!ret) | |
624 | goto ERROR; | |
625 | ||
626 | // Fetch the strings | |
10211c67 MT |
627 | for (int i = 0; i < strings.count; i++) { |
628 | str = pool_id2str(pool, strings.elements[i]); | |
629 | if (!str) | |
630 | goto ERROR; | |
631 | ||
632 | // Copy string to heap | |
633 | ret[i] = strdup(str); | |
634 | } | |
314e2310 MT |
635 | } |
636 | ||
637 | ERROR: | |
638 | // Free the queue | |
639 | queue_free(&strings); | |
640 | ||
641 | return ret; | |
642 | } | |
643 | ||
644 | PAKFIRE_EXPORT int pakfire_package_set_strings(struct pakfire_package* pkg, | |
645 | const enum pakfire_package_key key, const char** values) { | |
646 | int r; | |
647 | ||
648 | // Drop any previous values | |
649 | pakfire_package_unset(pkg, key); | |
650 | ||
651 | // End without error if values is empty | |
652 | if (!values) | |
653 | return 0; | |
654 | ||
655 | // Add all new values | |
656 | for (const char** value = values; *value; value++) { | |
657 | r = pakfire_package_add_string(pkg, key, *value); | |
658 | if (r) | |
659 | return r; | |
660 | } | |
661 | ||
662 | return 0; | |
663 | } | |
664 | ||
665 | int pakfire_package_set_strings_from_string(struct pakfire_package* pkg, | |
666 | const enum pakfire_package_key key, const char* value) { | |
667 | char* buffer = NULL; | |
668 | char* p = NULL; | |
669 | int r; | |
670 | ||
671 | // Drop any previous values | |
672 | pakfire_package_unset(pkg, key); | |
673 | ||
674 | // End without error if value is empty | |
675 | if (!value || !*value) | |
676 | return 0; | |
677 | ||
678 | // Copy the string to the heap to change it | |
679 | buffer = strdup(value); | |
680 | if (!buffer) { | |
681 | r = -errno; | |
682 | goto ERROR; | |
683 | } | |
684 | ||
685 | // Split the string | |
686 | char* s = strtok_r(buffer, " ", &p); | |
687 | ||
688 | // Add each part individually | |
689 | while (s) { | |
690 | r = pakfire_package_add_string(pkg, key, s); | |
691 | if (r) | |
692 | goto ERROR; | |
693 | ||
694 | // Move on to the next part | |
695 | s = strtok_r(NULL, " ", &p); | |
696 | } | |
697 | ||
698 | ERROR: | |
699 | if (buffer) | |
700 | free(buffer); | |
701 | ||
702 | return r; | |
703 | } | |
704 | ||
7fbede3a MT |
705 | PAKFIRE_EXPORT const char* pakfire_package_get_string( |
706 | struct pakfire_package* pkg, const enum pakfire_package_key key) { | |
707 | const char* ret = NULL; | |
708 | int r; | |
709 | ||
ac71886a MT |
710 | pakfire_package_internalize_repo(pkg); |
711 | ||
7fbede3a | 712 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
ac71886a | 713 | Solvable* s = get_solvable(pkg); |
ac71886a | 714 | |
7fbede3a MT |
715 | switch (key) { |
716 | case PAKFIRE_PKG_NAME: | |
717 | return pool_id2str(pool, s->name); | |
ac71886a | 718 | |
7fbede3a MT |
719 | case PAKFIRE_PKG_EVR: |
720 | return pool_id2str(pool, s->evr); | |
ac71886a | 721 | |
7fbede3a MT |
722 | case PAKFIRE_PKG_ARCH: |
723 | return pool_id2str(pool, s->arch); | |
221cc3ce | 724 | |
7fbede3a | 725 | case PAKFIRE_PKG_NEVRA: |
064b177e | 726 | if (!*pkg->nevra) { |
7fbede3a MT |
727 | r = pakfire_string_set(pkg->nevra, pool_solvable2str(pool, s)); |
728 | if (r) | |
729 | return NULL; | |
730 | } | |
221cc3ce | 731 | |
7fbede3a MT |
732 | return pkg->nevra; |
733 | ||
734 | case PAKFIRE_PKG_UUID: | |
735 | ret = solvable_lookup_str(s, SOLVABLE_PKGID); | |
8ceacfa4 MT |
736 | if (!ret) |
737 | return NULL; | |
7189e532 MT |
738 | |
739 | // Validate the UUID | |
740 | if (!pakfire_uuid_is_valid(ret)) { | |
741 | errno = EINVAL; | |
742 | return NULL; | |
743 | } | |
744 | ||
7fbede3a MT |
745 | break; |
746 | ||
747 | case PAKFIRE_PKG_SUMMARY: | |
748 | ret = solvable_lookup_str(s, SOLVABLE_SUMMARY); | |
749 | break; | |
750 | ||
751 | case PAKFIRE_PKG_DESCRIPTION: | |
752 | ret = solvable_lookup_str(s, SOLVABLE_DESCRIPTION); | |
753 | break; | |
754 | ||
755 | case PAKFIRE_PKG_LICENSE: | |
756 | ret = solvable_lookup_str(s, SOLVABLE_LICENSE); | |
757 | break; | |
758 | ||
759 | case PAKFIRE_PKG_URL: | |
760 | ret = solvable_lookup_str(s, SOLVABLE_URL); | |
761 | break; | |
762 | ||
7fbede3a MT |
763 | case PAKFIRE_PKG_VENDOR: |
764 | ret = solvable_lookup_str(s, SOLVABLE_VENDOR); | |
765 | break; | |
221cc3ce | 766 | |
7fbede3a MT |
767 | case PAKFIRE_PKG_DISTRO: |
768 | ret = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION); | |
769 | break; | |
770 | ||
145d0efe | 771 | case PAKFIRE_PKG_PACKAGER: |
7fbede3a MT |
772 | ret = solvable_lookup_str(s, SOLVABLE_PACKAGER); |
773 | break; | |
0aade652 | 774 | |
b1743459 MT |
775 | case PAKFIRE_PKG_PATH: |
776 | if (!*pkg->path) { | |
6c0217d3 MT |
777 | const char* filename = pakfire_package_get_string(pkg, PAKFIRE_PKG_FILENAME); |
778 | if (!filename) | |
779 | return NULL; | |
b1743459 | 780 | |
a98600fb | 781 | const char* dir = solvable_lookup_str(s, SOLVABLE_MEDIADIR); |
6c0217d3 MT |
782 | if (dir) { |
783 | r = pakfire_string_format(pkg->path, "%s/%s", dir, filename); | |
784 | if (r) | |
785 | return NULL; | |
b1743459 | 786 | } else { |
6c0217d3 | 787 | r = pakfire_string_set(pkg->path, filename); |
b1743459 MT |
788 | if (r) |
789 | return NULL; | |
790 | } | |
791 | } | |
792 | ||
793 | return pkg->path; | |
794 | ||
0aade652 MT |
795 | case PAKFIRE_PKG_FILENAME: |
796 | ret = solvable_lookup_str(s, SOLVABLE_MEDIAFILE); | |
797 | ||
798 | // Generate the filename if not set | |
799 | if (!ret) | |
800 | ret = pakfire_package_make_filename(pkg); | |
801 | break; | |
1f669e88 | 802 | |
6c0217d3 MT |
803 | case PAKFIRE_PKG_CACHE_PATH: |
804 | if (!*pkg->cache_path) { | |
805 | r = pakfire_package_make_cache_path(pkg); | |
806 | if (r) | |
807 | return NULL; | |
808 | } | |
809 | ||
810 | return pkg->cache_path; | |
811 | ||
1f669e88 MT |
812 | case PAKFIRE_PKG_BUILD_HOST: |
813 | ret = solvable_lookup_str(s, SOLVABLE_BUILDHOST); | |
814 | break; | |
70f6900d MT |
815 | |
816 | case PAKFIRE_PKG_BUILD_ID: | |
817 | ret = solvable_lookup_str(s, SOLVABLE_BUILDVERSION); | |
818 | break; | |
73ff505b MT |
819 | |
820 | case PAKFIRE_PKG_SOURCE_PKG: | |
821 | if (!*pkg->source_nevra) { | |
988ce1bc MT |
822 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_NAME); |
823 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_EVR); | |
824 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_ARCH); | |
73ff505b MT |
825 | |
826 | // Return nothing if we don't have all information | |
827 | if (!name || !evr || !arch) | |
828 | return NULL; | |
829 | ||
830 | // Format package name | |
831 | r = pakfire_string_format(pkg->source_nevra, "%s-%s.%s", name, evr, arch); | |
832 | if (r) | |
833 | return NULL; | |
834 | } | |
835 | ||
836 | return pkg->source_nevra; | |
988ce1bc MT |
837 | |
838 | case PAKFIRE_PKG_SOURCE_NAME: | |
839 | ret = solvable_lookup_str(s, SOLVABLE_SOURCENAME); | |
840 | break; | |
841 | ||
842 | case PAKFIRE_PKG_SOURCE_EVR: | |
843 | ret = solvable_lookup_str(s, SOLVABLE_SOURCEEVR); | |
844 | break; | |
845 | ||
846 | case PAKFIRE_PKG_SOURCE_ARCH: | |
847 | ret = solvable_lookup_str(s, SOLVABLE_SOURCEARCH); | |
848 | break; | |
3f327c3c MT |
849 | |
850 | default: | |
851 | break; | |
7fbede3a MT |
852 | } |
853 | ||
854 | return ret; | |
221cc3ce MT |
855 | } |
856 | ||
74468e4f | 857 | PAKFIRE_EXPORT int pakfire_package_set_string( |
7fbede3a | 858 | struct pakfire_package* pkg, const enum pakfire_package_key key, const char* value) { |
f54eb6e7 MT |
859 | char basename[PATH_MAX]; |
860 | char dirname[PATH_MAX]; | |
7fbede3a | 861 | Id id = ID_NULL; |
f54eb6e7 | 862 | int r; |
7fbede3a | 863 | |
74468e4f MT |
864 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
865 | Solvable* s = get_solvable(pkg); | |
866 | ||
7fbede3a MT |
867 | switch (key) { |
868 | // Do not allow to change name, evr, or arch | |
869 | case PAKFIRE_PKG_NAME: | |
74468e4f MT |
870 | // Reset nevra & filename |
871 | *pkg->nevra = *pkg->filename = '\0'; | |
872 | ||
873 | s->name = pool_str2id(pool, value, 1); | |
874 | return 0; | |
875 | ||
7fbede3a | 876 | case PAKFIRE_PKG_EVR: |
74468e4f MT |
877 | // Reset nevra & filename |
878 | *pkg->nevra = *pkg->filename = '\0'; | |
879 | ||
880 | // Skip empty epoch | |
881 | if (pakfire_string_startswith(value, "0:")) | |
882 | value += 2; | |
883 | ||
884 | s->evr = pool_str2id(pool, value, 1); | |
885 | return 0; | |
886 | ||
7fbede3a | 887 | case PAKFIRE_PKG_ARCH: |
74468e4f MT |
888 | // Reset nevra & filename |
889 | *pkg->nevra = *pkg->filename = '\0'; | |
890 | ||
891 | s->arch = pool_str2id(pool, value, 1); | |
892 | return 0; | |
893 | ||
7fbede3a MT |
894 | case PAKFIRE_PKG_NEVRA: |
895 | errno = EINVAL; | |
896 | return 1; | |
897 | ||
898 | case PAKFIRE_PKG_UUID: | |
899 | id = SOLVABLE_PKGID; | |
7189e532 MT |
900 | |
901 | // Validate the UUID | |
902 | if (!pakfire_uuid_is_valid(value)) | |
903 | return -EINVAL; | |
904 | ||
7fbede3a MT |
905 | break; |
906 | ||
907 | case PAKFIRE_PKG_SUMMARY: | |
908 | id = SOLVABLE_SUMMARY; | |
909 | break; | |
910 | ||
911 | case PAKFIRE_PKG_DESCRIPTION: | |
912 | id = SOLVABLE_DESCRIPTION; | |
913 | break; | |
914 | ||
915 | case PAKFIRE_PKG_LICENSE: | |
916 | id = SOLVABLE_LICENSE; | |
917 | break; | |
918 | ||
919 | case PAKFIRE_PKG_URL: | |
920 | id = SOLVABLE_URL; | |
921 | break; | |
922 | ||
7fbede3a MT |
923 | case PAKFIRE_PKG_VENDOR: |
924 | id = SOLVABLE_VENDOR; | |
925 | break; | |
926 | ||
927 | case PAKFIRE_PKG_DISTRO: | |
928 | id = SOLVABLE_DISTRIBUTION; | |
929 | break; | |
930 | ||
145d0efe | 931 | case PAKFIRE_PKG_PACKAGER: |
7fbede3a MT |
932 | id = SOLVABLE_PACKAGER; |
933 | break; | |
0aade652 | 934 | |
b1743459 MT |
935 | case PAKFIRE_PKG_PATH: |
936 | if (value) { | |
67497686 | 937 | r = pakfire_path_basename(basename, value); |
f54eb6e7 MT |
938 | if (r) |
939 | return r; | |
940 | ||
b4ae14b2 | 941 | r = pakfire_path_dirname(dirname, value); |
f54eb6e7 MT |
942 | if (r) |
943 | return r; | |
b1743459 MT |
944 | } |
945 | ||
f54eb6e7 | 946 | if (*basename) |
b1743459 MT |
947 | solvable_set_str(s, SOLVABLE_MEDIAFILE, basename); |
948 | else | |
949 | solvable_unset(s, SOLVABLE_MEDIAFILE); | |
950 | ||
f54eb6e7 | 951 | if (*dirname) |
a98600fb | 952 | solvable_set_str(s, SOLVABLE_MEDIADIR, dirname); |
b1743459 | 953 | else |
a98600fb | 954 | solvable_unset(s, SOLVABLE_MEDIADIR); |
b1743459 MT |
955 | |
956 | // Cache the path | |
957 | pakfire_string_set(pkg->path, value); | |
958 | ||
959 | // Mark the package as changed | |
960 | pakfire_package_has_changed(pkg); | |
961 | ||
962 | return 0; | |
963 | ||
0aade652 MT |
964 | case PAKFIRE_PKG_FILENAME: |
965 | id = SOLVABLE_MEDIAFILE; | |
966 | break; | |
1f669e88 | 967 | |
6c0217d3 MT |
968 | case PAKFIRE_PKG_CACHE_PATH: |
969 | return pakfire_string_set(pkg->cache_path, value); | |
970 | ||
1f669e88 MT |
971 | case PAKFIRE_PKG_BUILD_HOST: |
972 | id = SOLVABLE_BUILDHOST; | |
973 | break; | |
70f6900d MT |
974 | |
975 | case PAKFIRE_PKG_BUILD_ID: | |
976 | id = SOLVABLE_BUILDVERSION; | |
977 | break; | |
73ff505b MT |
978 | |
979 | case PAKFIRE_PKG_SOURCE_PKG: | |
980 | // The source package name cannot be set | |
981 | break; | |
988ce1bc MT |
982 | |
983 | case PAKFIRE_PKG_SOURCE_NAME: | |
984 | id = SOLVABLE_SOURCENAME; | |
985 | break; | |
986 | ||
987 | case PAKFIRE_PKG_SOURCE_EVR: | |
988 | // Skip empty epoch | |
989 | if (pakfire_string_startswith(value, "0:")) | |
990 | value += 2; | |
991 | ||
992 | id = SOLVABLE_SOURCEEVR; | |
993 | break; | |
994 | ||
995 | case PAKFIRE_PKG_SOURCE_ARCH: | |
996 | id = SOLVABLE_SOURCEARCH; | |
997 | break; | |
3f327c3c | 998 | |
314e2310 MT |
999 | // Compat which splits a string and stores it as an array |
1000 | case PAKFIRE_PKG_BUILD_ARCHES: | |
d333480c | 1001 | case PAKFIRE_PKG_GROUPS: |
314e2310 MT |
1002 | return pakfire_package_set_strings_from_string(pkg, key, value); |
1003 | ||
3f327c3c MT |
1004 | default: |
1005 | break; | |
7fbede3a MT |
1006 | } |
1007 | ||
1008 | // Check if we have found a valid ID | |
1009 | if (id == ID_NULL) { | |
1010 | errno = EINVAL; | |
1011 | return 1; | |
1012 | } | |
1013 | ||
51c47a9a | 1014 | // Unset on empty string |
ba1229cc | 1015 | if (!value) |
7fbede3a | 1016 | solvable_unset(s, id); |
221cc3ce | 1017 | |
51c47a9a | 1018 | // Store string |
ba1229cc MT |
1019 | else |
1020 | solvable_set_str(s, id, value); | |
7fbede3a MT |
1021 | |
1022 | // Mark the package as changed | |
1023 | pakfire_package_has_changed(pkg); | |
1024 | ||
1025 | return 0; | |
1026 | } | |
1027 | ||
314e2310 MT |
1028 | PAKFIRE_EXPORT int pakfire_package_add_string(struct pakfire_package* pkg, |
1029 | const enum pakfire_package_key key, const char* value) { | |
1030 | Id key_id = ID_NULL; | |
1031 | Id value_id = ID_NULL; | |
1032 | ||
1033 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
1034 | Solvable* s = get_solvable(pkg); | |
1035 | ||
1036 | switch (key) { | |
d333480c MT |
1037 | case PAKFIRE_PKG_GROUPS: |
1038 | key_id = SOLVABLE_GROUP; | |
1039 | break; | |
1040 | ||
314e2310 MT |
1041 | case PAKFIRE_PKG_BUILD_ARCHES: |
1042 | key_id = SOLVABLE_BUILDFLAVOR; | |
314e2310 MT |
1043 | break; |
1044 | ||
1045 | default: | |
1046 | errno = EINVAL; | |
1047 | return 1; | |
1048 | } | |
1049 | ||
d333480c MT |
1050 | // Convert value |
1051 | value_id = pool_str2id(pool, value, 1); | |
1052 | ||
314e2310 MT |
1053 | // Append the string to the ID array |
1054 | solvable_add_idarray(s, key_id, value_id); | |
1055 | ||
1056 | // Mark the package as changed | |
1057 | pakfire_package_has_changed(pkg); | |
1058 | ||
1059 | return 0; | |
1060 | } | |
1061 | ||
3bea955d MT |
1062 | PAKFIRE_EXPORT int pakfire_package_get_uuid(struct pakfire_package* pkg, |
1063 | const enum pakfire_package_key key, uuid_t uuid) { | |
1064 | const char* buffer = NULL; | |
1065 | int r; | |
1066 | ||
1067 | switch (key) { | |
1068 | case PAKFIRE_PKG_UUID: | |
1069 | case PAKFIRE_PKG_BUILD_ID: | |
1070 | // Clear the UUID | |
1071 | uuid_clear(uuid); | |
1072 | ||
1073 | // Fetch the value | |
1074 | buffer = pakfire_package_get_string(pkg, key); | |
1075 | if (!buffer) | |
1076 | return 1; | |
1077 | ||
1078 | // Read buffer into the output | |
1079 | r = uuid_parse(buffer, uuid); | |
1080 | if (r) | |
1081 | return r; | |
1082 | ||
1083 | return 0; | |
1084 | ||
1085 | default: | |
1086 | errno = EINVAL; | |
1087 | return 1; | |
1088 | } | |
1089 | } | |
1090 | ||
1091 | PAKFIRE_EXPORT int pakfire_package_set_uuid(struct pakfire_package* pkg, | |
1092 | const enum pakfire_package_key key, const uuid_t uuid) { | |
1093 | char buffer[UUID_STR_LEN]; | |
1094 | ||
1095 | switch (key) { | |
1096 | case PAKFIRE_PKG_UUID: | |
1097 | case PAKFIRE_PKG_BUILD_ID: | |
1098 | // Convert the UUID to string | |
1099 | uuid_unparse_lower(uuid, buffer); | |
1100 | ||
1101 | // Store the UUID as string | |
1102 | return pakfire_package_set_string(pkg, key, buffer); | |
1103 | ||
1104 | default: | |
1105 | errno = EINVAL; | |
1106 | return 1; | |
1107 | } | |
1108 | } | |
1109 | ||
3f327c3c MT |
1110 | PAKFIRE_EXPORT unsigned long long pakfire_package_get_num(struct pakfire_package* pkg, |
1111 | const enum pakfire_package_key key, unsigned long long notfound) { | |
1112 | Id id = ID_NULL; | |
7fbede3a | 1113 | |
3f327c3c | 1114 | switch (key) { |
20b898e3 MT |
1115 | case PAKFIRE_PKG_DBID: |
1116 | id = RPM_RPMDBID; | |
1117 | break; | |
1118 | ||
3f327c3c MT |
1119 | case PAKFIRE_PKG_DOWNLOADSIZE: |
1120 | id = SOLVABLE_DOWNLOADSIZE; | |
1121 | break; | |
1122 | ||
1123 | case PAKFIRE_PKG_INSTALLSIZE: | |
1124 | id = SOLVABLE_INSTALLSIZE; | |
1125 | break; | |
1126 | ||
1127 | case PAKFIRE_PKG_BUILD_TIME: | |
1128 | id = SOLVABLE_BUILDTIME; | |
1129 | break; | |
1130 | ||
1131 | case PAKFIRE_PKG_INSTALLTIME: | |
1132 | id = SOLVABLE_INSTALLTIME; | |
1133 | break; | |
1134 | ||
1135 | // Return zero for all unhandled keys | |
1136 | default: | |
1137 | errno = EINVAL; | |
1138 | return 1; | |
1139 | } | |
7fbede3a | 1140 | |
7fbede3a MT |
1141 | Solvable* s = get_solvable(pkg); |
1142 | ||
4ab9fd79 MT |
1143 | pakfire_package_internalize_repo(pkg); |
1144 | ||
3f327c3c | 1145 | return solvable_lookup_num(s, id, notfound); |
7ccc9d74 MT |
1146 | } |
1147 | ||
3f327c3c MT |
1148 | PAKFIRE_EXPORT int pakfire_package_set_num(struct pakfire_package* pkg, |
1149 | const enum pakfire_package_key key, unsigned long long num) { | |
1150 | Id id = ID_NULL; | |
1151 | ||
1152 | switch (key) { | |
20b898e3 MT |
1153 | case PAKFIRE_PKG_DBID: |
1154 | id = RPM_RPMDBID; | |
1155 | break; | |
1156 | ||
3f327c3c MT |
1157 | case PAKFIRE_PKG_DOWNLOADSIZE: |
1158 | id = SOLVABLE_DOWNLOADSIZE; | |
1159 | break; | |
ac71886a | 1160 | |
3f327c3c MT |
1161 | case PAKFIRE_PKG_INSTALLSIZE: |
1162 | id = SOLVABLE_INSTALLSIZE; | |
1163 | break; | |
1164 | ||
1165 | case PAKFIRE_PKG_BUILD_TIME: | |
1166 | id = SOLVABLE_BUILDTIME; | |
1167 | break; | |
1168 | ||
1169 | case PAKFIRE_PKG_INSTALLTIME: | |
1170 | id = SOLVABLE_INSTALLTIME; | |
1171 | break; | |
1172 | ||
1173 | // Return zero for all unhandled keys | |
1174 | default: | |
1175 | errno = EINVAL; | |
1176 | return 1; | |
1177 | } | |
1178 | ||
1179 | Solvable* s = get_solvable(pkg); | |
1180 | ||
4ab9fd79 | 1181 | // Store the number |
3f327c3c MT |
1182 | solvable_set_num(s, id, num); |
1183 | ||
4ab9fd79 MT |
1184 | // Mark the package as changed |
1185 | pakfire_package_has_changed(pkg); | |
1186 | ||
3f327c3c | 1187 | return 0; |
ac71886a MT |
1188 | } |
1189 | ||
c52e0148 | 1190 | static enum pakfire_digest_types pakfire_package_id2digest(Id id) { |
e61716e4 MT |
1191 | switch (id) { |
1192 | case REPOKEY_TYPE_SHA512: | |
4500ed0a | 1193 | return PAKFIRE_DIGEST_SHA2_512; |
b28af23a | 1194 | |
e61716e4 | 1195 | case REPOKEY_TYPE_SHA256: |
4500ed0a | 1196 | return PAKFIRE_DIGEST_SHA2_256; |
b28af23a MT |
1197 | } |
1198 | ||
9802aaf6 | 1199 | return 0; |
b28af23a MT |
1200 | } |
1201 | ||
1202 | PAKFIRE_EXPORT const unsigned char* pakfire_package_get_digest( | |
e082fb85 | 1203 | struct pakfire_package* pkg, enum pakfire_digest_types* type, size_t* length) { |
b28af23a | 1204 | Solvable* s = get_solvable(pkg); |
e082fb85 | 1205 | Id id = 0; |
b28af23a | 1206 | |
e61716e4 | 1207 | const unsigned char* checksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id); |
b28af23a | 1208 | |
e61716e4 MT |
1209 | // Convert ID to digest type |
1210 | *type = pakfire_package_id2digest(id); | |
1211 | if (!*type) { | |
1212 | errno = ENOTSUP; | |
1213 | checksum = NULL; | |
1214 | } | |
1215 | ||
e082fb85 MT |
1216 | // Store the length (if requested) |
1217 | if (length) | |
1218 | *length = pakfire_digest_length(*type); | |
e61716e4 MT |
1219 | |
1220 | return checksum; | |
b28af23a MT |
1221 | } |
1222 | ||
1223 | PAKFIRE_EXPORT int pakfire_package_set_digest(struct pakfire_package* pkg, | |
e082fb85 | 1224 | enum pakfire_digest_types type, const unsigned char* digest, const size_t length) { |
b28af23a MT |
1225 | Solvable* s = get_solvable(pkg); |
1226 | Pool* pool = s->repo->pool; | |
e61716e4 | 1227 | Id id; |
b28af23a MT |
1228 | int r = 1; |
1229 | ||
e61716e4 | 1230 | switch (type) { |
4500ed0a | 1231 | case PAKFIRE_DIGEST_SHA2_256: |
e61716e4 MT |
1232 | id = REPOKEY_TYPE_SHA256; |
1233 | break; | |
1234 | ||
4500ed0a | 1235 | case PAKFIRE_DIGEST_SHA2_512: |
e61716e4 MT |
1236 | id = REPOKEY_TYPE_SHA512; |
1237 | break; | |
1238 | ||
1239 | default: | |
1240 | errno = ENOTSUP; | |
1241 | return 1; | |
1242 | } | |
b28af23a | 1243 | |
e082fb85 MT |
1244 | // Check if the digest length matches |
1245 | if (pakfire_digest_length(type) != length) { | |
1246 | errno = EINVAL; | |
1247 | return 1; | |
1248 | } | |
1249 | ||
b28af23a MT |
1250 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
1251 | ||
1252 | Repodata* data = pakfire_repo_get_repodata(repo); | |
1253 | if (!data) | |
1254 | goto ERROR; | |
1255 | ||
1256 | repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, id, digest); | |
1257 | ||
1258 | // Success | |
1259 | r = 0; | |
1260 | ||
1261 | ERROR: | |
1262 | pakfire_repo_unref(repo); | |
1263 | ||
1264 | return r; | |
1265 | } | |
1266 | ||
f3320724 | 1267 | int pakfire_package_is_installed(struct pakfire_package* pkg) { |
0defa23e | 1268 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
1269 | Solvable* s = get_solvable(pkg); |
1270 | ||
1271 | return pool->installed == s->repo; | |
1272 | } | |
1273 | ||
27116707 | 1274 | PAKFIRE_EXPORT size_t pakfire_package_get_size(struct pakfire_package* pkg) { |
221cc3ce | 1275 | if (pakfire_package_is_installed(pkg)) |
3f327c3c | 1276 | return pakfire_package_get_num(pkg, PAKFIRE_PKG_INSTALLSIZE, 0); |
221cc3ce | 1277 | |
3f327c3c | 1278 | return pakfire_package_get_num(pkg, PAKFIRE_PKG_DOWNLOADSIZE, 0); |
af647c55 MT |
1279 | } |
1280 | ||
be3f4199 MT |
1281 | // Build |
1282 | ||
1283 | int pakfire_package_supports_build_arch(struct pakfire_package* pkg, const char* arch) { | |
1284 | int r; | |
1285 | ||
1286 | char** supported_arches = pakfire_package_get_strings(pkg, PAKFIRE_PKG_BUILD_ARCHES); | |
1287 | ||
1288 | // If no build arches are configured, this package supports all arches | |
1289 | if (!supported_arches) | |
1290 | return 1; | |
1291 | ||
1292 | for (char** supported_arch = supported_arches; *supported_arch; supported_arch++) { | |
1293 | if (strcmp(arch, *supported_arch) == 0) { | |
1294 | r = 1; | |
1295 | goto END; | |
1296 | } | |
1297 | } | |
1298 | ||
1299 | // No match found | |
1300 | r = 0; | |
1301 | ||
1302 | END: | |
1303 | // Cleanup | |
1304 | if (supported_arches) | |
1305 | pakfire_strings_free(supported_arches); | |
1306 | ||
1307 | return r; | |
1308 | } | |
1309 | ||
6f3fad3b | 1310 | // Dependencies |
452d3833 | 1311 | |
6f3fad3b MT |
1312 | PAKFIRE_EXPORT char** pakfire_package_get_deps(struct pakfire_package* pkg, |
1313 | const enum pakfire_package_key key) { | |
1314 | Solvable* s = get_solvable(pkg); | |
1315 | char** ret = NULL; | |
1316 | int r; | |
221cc3ce | 1317 | |
6f3fad3b MT |
1318 | Queue q; |
1319 | Id id = ID_NULL; | |
1320 | Id marker = ID_NULL; | |
1321 | const char* dep = NULL; | |
221cc3ce | 1322 | |
6f3fad3b MT |
1323 | r = pakfire_package_dep2id(key, &id, &marker); |
1324 | if (r) | |
1325 | return NULL; | |
221cc3ce | 1326 | |
6f3fad3b MT |
1327 | // Initialize the output queue |
1328 | queue_init(&q); | |
452d3833 | 1329 | |
6f3fad3b MT |
1330 | // Fetch all deps |
1331 | solvable_lookup_deparray(s, id, &q, marker); | |
221cc3ce | 1332 | |
6f3fad3b MT |
1333 | // Allocate array |
1334 | ret = calloc(q.count + 1, sizeof(*ret)); | |
1335 | if (!ret) | |
1336 | goto ERROR; | |
221cc3ce | 1337 | |
6f3fad3b MT |
1338 | for (int i = 0; i < q.count; i++) { |
1339 | dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); | |
1340 | if (!dep) | |
1341 | goto ERROR; | |
221cc3ce | 1342 | |
6f3fad3b MT |
1343 | ret[i] = strdup(dep); |
1344 | if (!ret[i]) | |
1345 | goto ERROR; | |
1346 | } | |
221cc3ce | 1347 | |
6f3fad3b MT |
1348 | // All good! |
1349 | goto SUCCESS; | |
221cc3ce | 1350 | |
6f3fad3b MT |
1351 | ERROR: |
1352 | if (ret) { | |
15360ad7 | 1353 | pakfire_strings_free(ret); |
6f3fad3b MT |
1354 | ret = NULL; |
1355 | } | |
221cc3ce | 1356 | |
6f3fad3b MT |
1357 | SUCCESS: |
1358 | queue_free(&q); | |
221cc3ce | 1359 | |
6f3fad3b | 1360 | return ret; |
221cc3ce MT |
1361 | } |
1362 | ||
6f3fad3b MT |
1363 | int pakfire_package_add_dep(struct pakfire_package* pkg, |
1364 | const enum pakfire_package_key key, const char* dep) { | |
6f3fad3b | 1365 | // Parse the dependency |
39d1a3d3 | 1366 | Id id = pakfire_str2dep(pkg->pakfire, dep); |
ca66e095 MT |
1367 | |
1368 | // Silently ignore any invalid dependencies | |
39d1a3d3 | 1369 | if (!id) |
ca66e095 | 1370 | return 0; |
8fe2e4ba | 1371 | |
39d1a3d3 | 1372 | return pakfire_package_add_depid(pkg, key, id); |
452d3833 MT |
1373 | } |
1374 | ||
31480bee | 1375 | PAKFIRE_EXPORT int pakfire_package_get_reverse_requires(struct pakfire_package* pkg, |
4a25eca3 | 1376 | struct pakfire_packagelist* list) { |
e1d77c57 MT |
1377 | Queue matches; |
1378 | queue_init(&matches); | |
1379 | ||
4a25eca3 MT |
1380 | // Get the pool ready |
1381 | pakfire_pool_internalize(pkg->pakfire); | |
e1d77c57 MT |
1382 | |
1383 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
1384 | ||
1385 | // Search for any matches | |
1386 | pool_whatmatchessolvable(pool, SOLVABLE_REQUIRES, pkg->id, &matches, 0); | |
1387 | ||
4a25eca3 | 1388 | // Import the result to the package list |
460ce205 | 1389 | int r = pakfire_packagelist_import_solvables(list, pkg->pakfire, &matches); |
e1d77c57 MT |
1390 | if (r) |
1391 | goto ERROR; | |
1392 | ||
1393 | ERROR: | |
1394 | queue_free(&matches); | |
1395 | ||
1396 | return r; | |
1397 | } | |
1398 | ||
555b6dd2 MT |
1399 | static int pakfire_package_has_rich_deps_in_deparray( |
1400 | struct pakfire_package* pkg, Id type) { | |
1401 | int r = 0; | |
1402 | ||
1403 | Solvable* s = get_solvable(pkg); | |
1404 | ||
1405 | Queue q; | |
1406 | queue_init(&q); | |
1407 | ||
1408 | // Fetch all deps | |
1409 | solvable_lookup_deparray(s, type, &q, 0); | |
1410 | ||
1411 | // Nothing to do if the array was empty | |
1412 | if (!q.count) | |
1413 | goto ERROR; | |
1414 | ||
1415 | for (int i = 0; i < q.count; i++) { | |
1416 | const char* dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); | |
1417 | ||
1418 | // Is this a rich dependency? | |
1419 | if (dep && *dep == '(') { | |
1420 | r = 1; | |
1421 | break; | |
1422 | } | |
1423 | } | |
1424 | ||
1425 | ERROR: | |
1426 | queue_free(&q); | |
1427 | ||
1428 | return r; | |
1429 | } | |
1430 | ||
1431 | int pakfire_package_has_rich_deps(struct pakfire_package* pkg) { | |
3bf61f1d | 1432 | const Id types[] = { |
555b6dd2 MT |
1433 | // Requires (includes pre-requires) |
1434 | SOLVABLE_REQUIRES, | |
1435 | SOLVABLE_PROVIDES, | |
1436 | SOLVABLE_CONFLICTS, | |
1437 | SOLVABLE_OBSOLETES, | |
1438 | SOLVABLE_RECOMMENDS, | |
1439 | SOLVABLE_SUGGESTS, | |
1440 | SOLVABLE_SUPPLEMENTS, | |
1441 | SOLVABLE_ENHANCES, | |
1442 | 0, | |
1443 | }; | |
1444 | ||
1445 | for (const Id* type = types; *type; type++) { | |
1446 | int r = pakfire_package_has_rich_deps_in_deparray(pkg, *type); | |
1447 | if (r) | |
1448 | return r; | |
1449 | } | |
1450 | ||
1451 | // No match | |
1452 | return 0; | |
1453 | } | |
1454 | ||
f35eadab MT |
1455 | int pakfire_package_matches_dep(struct pakfire_package* pkg, |
1456 | const enum pakfire_package_key key, const char* dep) { | |
1457 | int r; | |
1458 | ||
1459 | Id id = ID_NULL; | |
1460 | int marker = 0; | |
1461 | ||
1462 | // Translate the dependency type | |
1463 | r = pakfire_package_dep2id(key, &id, &marker); | |
1464 | if (r) | |
1465 | return r; | |
1466 | ||
1467 | // Get the dependency | |
1468 | Id depid = pakfire_str2dep(pkg->pakfire, dep); | |
1469 | if (!depid) | |
56281312 | 1470 | return -1; |
f35eadab MT |
1471 | |
1472 | // Fetch the solvable | |
1473 | Solvable* s = get_solvable(pkg); | |
1474 | ||
1475 | // Check whether this solvable matches the requested dependency | |
061bcc69 | 1476 | return solvable_matchesdep(s, id, depid, marker); |
f35eadab MT |
1477 | } |
1478 | ||
4651122b | 1479 | PAKFIRE_EXPORT struct pakfire_repo* pakfire_package_get_repo(struct pakfire_package* pkg) { |
e9d9eadc MT |
1480 | if (!pkg->repo) { |
1481 | Solvable* s = get_solvable(pkg); | |
1482 | ||
1483 | pkg->repo = pakfire_repo_create_from_repo(pkg->pakfire, s->repo); | |
1484 | } | |
221cc3ce | 1485 | |
e9d9eadc | 1486 | return pakfire_repo_ref(pkg->repo); |
221cc3ce MT |
1487 | } |
1488 | ||
221cc3ce MT |
1489 | static void pakfire_package_dump_add_line(char** str, const char* key, const char* val) { |
1490 | if (val) | |
2932624b | 1491 | asprintf(str, "%s%-15s: %s\n", (*str) ? *str : "", key ? key : "", val); |
221cc3ce MT |
1492 | } |
1493 | ||
d333480c MT |
1494 | static void pakfire_package_dump_add_lines(char** str, const char* key, char** lines) { |
1495 | for (; *lines; lines++) { | |
1496 | pakfire_package_dump_add_line(str, key, *lines); | |
1497 | ||
1498 | // Reset the key after the first line | |
1499 | key = NULL; | |
1500 | } | |
1501 | } | |
1502 | ||
1503 | static void pakfire_package_dump_add_long_line(char** str, const char* key, const char* val) { | |
45f9e649 MT |
1504 | char* p = NULL; |
1505 | ||
1506 | // Copy the string onto the heap | |
1507 | char* buffer = strdupa(val); | |
1508 | if (!buffer) | |
7500066c | 1509 | return; |
221cc3ce | 1510 | |
45f9e649 MT |
1511 | const char* line = strtok_r(buffer, "\n", &p); |
1512 | ||
1513 | while (line) { | |
1514 | pakfire_package_dump_add_line(str, key, line); | |
1515 | ||
1516 | // Reset the key | |
1517 | key = NULL; | |
1518 | ||
1519 | // Go to the next line | |
1520 | line = strtok_r(NULL, "\n", &p); | |
1521 | } | |
221cc3ce MT |
1522 | } |
1523 | ||
5cf4a7a1 MT |
1524 | static void pakfire_package_dump_add_line_date(char** str, const char* key, time_t date) { |
1525 | char buffer[1024]; | |
1526 | int r; | |
221cc3ce | 1527 | |
5cf4a7a1 MT |
1528 | // Format time |
1529 | r = pakfire_strftime(buffer, "%a, %d %b %Y %T %z", date); | |
1530 | if (r) | |
1531 | return; | |
221cc3ce | 1532 | |
5cf4a7a1 | 1533 | pakfire_package_dump_add_line(str, key, buffer); |
221cc3ce MT |
1534 | } |
1535 | ||
e0b28592 MT |
1536 | static void pakfire_package_dump_add_line_hex(char** str, |
1537 | const char* key, const unsigned char* buffer, const size_t length) { | |
1538 | char* hex = __pakfire_hexlify(buffer, length); | |
1539 | if (!hex) | |
1540 | return; | |
1541 | ||
1542 | pakfire_package_dump_add_line(str, key, hex); | |
1543 | free(hex); | |
1544 | } | |
1545 | ||
27116707 | 1546 | static void pakfire_package_dump_add_line_size(char** str, const char* key, size_t size) { |
cc90545a | 1547 | char buffer[128]; |
9b0e3d52 MT |
1548 | |
1549 | // Format size in human-readable format | |
1550 | int r = pakfire_format_size(buffer, size); | |
1551 | if (r < 0) | |
1552 | return; | |
221cc3ce | 1553 | |
cc90545a | 1554 | pakfire_package_dump_add_line(str, key, buffer); |
221cc3ce MT |
1555 | } |
1556 | ||
7db0d073 MT |
1557 | static int pakfire_sort_dependencies(const void* p1, const void* p2) { |
1558 | const char* dep1 = *(const char**)p1; | |
1559 | const char* dep2 = *(const char**)p2; | |
1560 | ||
1561 | return strcmp(dep1, dep2); | |
1562 | } | |
1563 | ||
31480bee | 1564 | PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags) { |
2932624b | 1565 | char* string = NULL; |
221cc3ce MT |
1566 | |
1567 | // Name | |
74468e4f MT |
1568 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME); |
1569 | if (name) | |
1570 | pakfire_package_dump_add_line(&string, _("Name"), name); | |
221cc3ce | 1571 | |
6ed66687 | 1572 | // EVR |
74468e4f MT |
1573 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR); |
1574 | if (evr) | |
1575 | pakfire_package_dump_add_line(&string, _("Version"), evr); | |
221cc3ce | 1576 | |
6ed66687 | 1577 | // Arch |
74468e4f MT |
1578 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH); |
1579 | if (arch) | |
1580 | pakfire_package_dump_add_line(&string, _("Arch"), arch); | |
221cc3ce MT |
1581 | |
1582 | // Size | |
27116707 | 1583 | size_t size = pakfire_package_get_size(pkg); |
c2737936 MT |
1584 | if (size) |
1585 | pakfire_package_dump_add_line_size(&string, _("Size"), size); | |
221cc3ce | 1586 | |
d0f0d507 | 1587 | // Installed Size |
221cc3ce | 1588 | if (pakfire_package_is_installed(pkg)) { |
8fde67b2 | 1589 | unsigned long long installsize = pakfire_package_get_num(pkg, PAKFIRE_PKG_INSTALLSIZE, 0); |
d0f0d507 MT |
1590 | if (installsize) |
1591 | pakfire_package_dump_add_line_size(&string, _("Installed Size"), installsize); | |
221cc3ce | 1592 | |
d0f0d507 | 1593 | // Download Size |
221cc3ce | 1594 | } else { |
3f327c3c | 1595 | size_t downloadsize = pakfire_package_get_num(pkg, PAKFIRE_PKG_DOWNLOADSIZE, 0); |
d0f0d507 MT |
1596 | if (downloadsize) |
1597 | pakfire_package_dump_add_line_size(&string, _("Download Size"), downloadsize); | |
221cc3ce MT |
1598 | } |
1599 | ||
d0f0d507 | 1600 | // Repository |
4651122b | 1601 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
221cc3ce | 1602 | if (repo) { |
866aa605 | 1603 | if (!pakfire_repo_name_equals(repo, PAKFIRE_REPO_DUMMY)) { |
a4292569 MT |
1604 | const char* repo_name = pakfire_repo_get_name(repo); |
1605 | pakfire_package_dump_add_line(&string, _("Repo"), repo_name); | |
1606 | } | |
221cc3ce | 1607 | |
3ff6aee6 | 1608 | pakfire_repo_unref(repo); |
221cc3ce MT |
1609 | } |
1610 | ||
1611 | // Summary | |
74468e4f MT |
1612 | const char* summary = pakfire_package_get_string(pkg, PAKFIRE_PKG_SUMMARY); |
1613 | if (summary) | |
1614 | pakfire_package_dump_add_line(&string, _("Summary"), summary); | |
221cc3ce MT |
1615 | |
1616 | // Description | |
74468e4f | 1617 | const char* description = pakfire_package_get_string(pkg, PAKFIRE_PKG_DESCRIPTION); |
1b99c676 | 1618 | if (description) |
d333480c | 1619 | pakfire_package_dump_add_long_line(&string, _("Description"), description); |
221cc3ce MT |
1620 | |
1621 | // Groups | |
d333480c MT |
1622 | char** groups = pakfire_package_get_strings(pkg, PAKFIRE_PKG_GROUPS); |
1623 | if (groups) { | |
7ccc9d74 | 1624 | pakfire_package_dump_add_lines(&string, _("Groups"), groups); |
d333480c MT |
1625 | pakfire_strings_free(groups); |
1626 | } | |
221cc3ce MT |
1627 | |
1628 | // URL | |
74468e4f MT |
1629 | const char* url = pakfire_package_get_string(pkg, PAKFIRE_PKG_URL); |
1630 | if (url) | |
1631 | pakfire_package_dump_add_line(&string, _("URL"), url); | |
221cc3ce MT |
1632 | |
1633 | // License | |
74468e4f MT |
1634 | const char* license = pakfire_package_get_string(pkg, PAKFIRE_PKG_LICENSE); |
1635 | if (license) | |
1636 | pakfire_package_dump_add_line(&string, _("License"), license); | |
221cc3ce MT |
1637 | |
1638 | if (flags & PAKFIRE_PKG_DUMP_LONG) { | |
af647c55 | 1639 | // Install Time |
3f327c3c MT |
1640 | time_t install_time = pakfire_package_get_num(pkg, PAKFIRE_PKG_INSTALLTIME, 0); |
1641 | if (install_time) | |
af647c55 | 1642 | pakfire_package_dump_add_line_date(&string, _("Install Time"), install_time); |
af647c55 | 1643 | |
cb9b4eba | 1644 | // Distribution |
74468e4f | 1645 | const char* distro = pakfire_package_get_string(pkg, PAKFIRE_PKG_DISTRO); |
cb9b4eba MT |
1646 | if (distro) |
1647 | pakfire_package_dump_add_line(&string, _("Distribution"), distro); | |
1648 | ||
145d0efe MT |
1649 | // Packager |
1650 | const char* packager = pakfire_package_get_string(pkg, PAKFIRE_PKG_PACKAGER); | |
1651 | if (packager) | |
1652 | pakfire_package_dump_add_line(&string, _("Packager"), packager); | |
221cc3ce MT |
1653 | |
1654 | // Vendor | |
74468e4f MT |
1655 | const char* vendor = pakfire_package_get_string(pkg, PAKFIRE_PKG_VENDOR); |
1656 | if (vendor) | |
1657 | pakfire_package_dump_add_line(&string, _("Vendor"), vendor); | |
221cc3ce MT |
1658 | |
1659 | // UUID | |
74468e4f MT |
1660 | const char* uuid = pakfire_package_get_string(pkg, PAKFIRE_PKG_UUID); |
1661 | if (uuid) | |
1662 | pakfire_package_dump_add_line(&string, _("UUID"), uuid); | |
221cc3ce | 1663 | |
7996020a | 1664 | // Build ID |
70f6900d | 1665 | const char* build_id = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_ID); |
7996020a MT |
1666 | if (build_id) |
1667 | pakfire_package_dump_add_line(&string, _("Build ID"), build_id); | |
1668 | ||
314e2310 | 1669 | // Build Arches |
10211c67 | 1670 | char** build_arches = pakfire_package_get_strings(pkg, PAKFIRE_PKG_BUILD_ARCHES); |
314e2310 | 1671 | if (build_arches) { |
d333480c | 1672 | pakfire_package_dump_add_lines(&string, _("Build Arch"), build_arches); |
15360ad7 | 1673 | pakfire_strings_free(build_arches); |
314e2310 MT |
1674 | } |
1675 | ||
e0b28592 MT |
1676 | enum pakfire_digest_types digest_type = PAKFIRE_DIGEST_UNDEFINED; |
1677 | size_t digest_length = 0; | |
e61716e4 MT |
1678 | |
1679 | // Digest | |
e0b28592 MT |
1680 | const unsigned char* digest = pakfire_package_get_digest(pkg, |
1681 | &digest_type, &digest_length); | |
1682 | if (digest) { | |
1683 | switch (digest_type) { | |
1684 | case PAKFIRE_DIGEST_SHA2_512: | |
1685 | pakfire_package_dump_add_line_hex(&string, | |
1686 | _("SHA2-512 Digest"), digest, digest_length); | |
1687 | break; | |
1688 | ||
1689 | case PAKFIRE_DIGEST_SHA2_256: | |
1690 | pakfire_package_dump_add_line_hex(&string, | |
1691 | _("SHA2-256 Digest"), digest, digest_length); | |
1692 | break; | |
1693 | ||
1694 | case PAKFIRE_DIGEST_SHA3_512: | |
1695 | case PAKFIRE_DIGEST_SHA3_256: | |
1696 | case PAKFIRE_DIGEST_BLAKE2B512: | |
1697 | case PAKFIRE_DIGEST_BLAKE2S256: | |
1698 | case PAKFIRE_DIGEST_UNDEFINED: | |
1699 | break; | |
1700 | } | |
e61716e4 | 1701 | } |
b28af23a | 1702 | |
571539a7 | 1703 | // Source package |
73ff505b | 1704 | const char* source_package = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_PKG); |
571539a7 MT |
1705 | if (source_package) |
1706 | pakfire_package_dump_add_line(&string, _("Source Package"), source_package); | |
1707 | ||
221cc3ce | 1708 | // Build time |
3f327c3c MT |
1709 | time_t build_time = pakfire_package_get_num(pkg, PAKFIRE_PKG_BUILD_TIME, 0); |
1710 | if (build_time) | |
1711 | pakfire_package_dump_add_line_date(&string, _("Build Time"), build_time); | |
221cc3ce MT |
1712 | |
1713 | // Build host | |
1f669e88 MT |
1714 | const char* build_host = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_HOST); |
1715 | if (build_host) | |
1716 | pakfire_package_dump_add_line(&string, _("Build Host"), build_host); | |
221cc3ce | 1717 | |
2f873877 | 1718 | // Dependencies |
6f3fad3b MT |
1719 | for (const struct pakfire_dep* dep = pakfire_deps; dep->key; dep++) { |
1720 | char** deps = pakfire_package_get_deps(pkg, dep->key); | |
7db0d073 MT |
1721 | if (deps) { |
1722 | size_t count = 0; | |
1723 | ||
1724 | // Count elements in the list | |
6f3fad3b | 1725 | for (char** d = deps; *d; d++) |
7db0d073 MT |
1726 | count++; |
1727 | ||
1728 | // Sort the list | |
1729 | qsort(deps, count, sizeof(*deps), pakfire_sort_dependencies); | |
1730 | ||
6f3fad3b MT |
1731 | switch (dep->key) { |
1732 | case PAKFIRE_PKG_PROVIDES: | |
1733 | name = _("Provides"); | |
1734 | break; | |
1735 | ||
1736 | case PAKFIRE_PKG_PREREQUIRES: | |
1737 | name = _("Pre-Requires"); | |
1738 | break; | |
1739 | ||
1740 | case PAKFIRE_PKG_REQUIRES: | |
1741 | name = _("Requires"); | |
1742 | break; | |
1743 | ||
1744 | case PAKFIRE_PKG_CONFLICTS: | |
1745 | name = _("Conflicts"); | |
1746 | break; | |
1747 | ||
1748 | case PAKFIRE_PKG_OBSOLETES: | |
1749 | name = _("Obsoletes"); | |
1750 | break; | |
1751 | ||
1752 | case PAKFIRE_PKG_RECOMMENDS: | |
1753 | name = _("Recommends"); | |
1754 | break; | |
1755 | ||
1756 | case PAKFIRE_PKG_SUGGESTS: | |
1757 | name = _("Suggests"); | |
1758 | break; | |
1759 | ||
1760 | case PAKFIRE_PKG_SUPPLEMENTS: | |
1761 | name = _("Supplements"); | |
1762 | break; | |
1763 | ||
1764 | case PAKFIRE_PKG_ENHANCES: | |
1765 | name = _("Enhances"); | |
1766 | break; | |
1767 | ||
1768 | default: | |
1769 | name = NULL; | |
1770 | break; | |
1771 | } | |
1772 | ||
7db0d073 | 1773 | // Write it to the console |
e3a6f5d2 MT |
1774 | pakfire_package_dump_add_lines(&string, name, deps); |
1775 | pakfire_strings_free(deps); | |
2f873877 | 1776 | } |
221cc3ce MT |
1777 | } |
1778 | } | |
1779 | ||
1780 | if (flags & PAKFIRE_PKG_DUMP_FILELIST) { | |
1bbbfb9e | 1781 | struct pakfire_filelist* filelist = pakfire_package_get_filelist(pkg); |
5e9463ec MT |
1782 | |
1783 | const char* prefix = _("Filelist"); | |
1784 | ||
94ff3014 | 1785 | for (unsigned int i = 0; i < pakfire_filelist_length(filelist); i++) { |
5803b5f6 | 1786 | struct pakfire_file* file = pakfire_filelist_get(filelist, i); |
221cc3ce | 1787 | |
32485f6c MT |
1788 | const char* path = pakfire_file_get_path(file); |
1789 | pakfire_package_dump_add_line(&string, prefix, path); | |
221cc3ce | 1790 | |
5e9463ec | 1791 | pakfire_file_unref(file); |
221cc3ce | 1792 | |
5e9463ec | 1793 | // Only prefix the first line |
221cc3ce MT |
1794 | prefix = NULL; |
1795 | } | |
5e9463ec MT |
1796 | |
1797 | pakfire_filelist_unref(filelist); | |
221cc3ce MT |
1798 | } |
1799 | ||
1800 | return string; | |
1801 | } | |
1802 | ||
900faa2f | 1803 | PAKFIRE_EXPORT struct pakfire_archive* pakfire_package_get_archive(struct pakfire_package* pkg) { |
9686a82a | 1804 | struct pakfire_archive* archive = NULL; |
6c0217d3 MT |
1805 | struct pakfire_repo* repo = NULL; |
1806 | const char* path = NULL; | |
1807 | int r; | |
1808 | ||
1809 | // Fetch the repository | |
1810 | repo = pakfire_package_get_repo(pkg); | |
1811 | if (repo) { | |
1812 | if (pakfire_repo_is_local(repo)) { | |
1813 | path = pakfire_package_get_string(pkg, PAKFIRE_PKG_PATH); | |
1814 | if (!path) | |
1815 | goto ERROR; | |
1816 | } | |
1817 | } | |
b12a5d7d | 1818 | |
cbed1552 | 1819 | // Otherwise open the archive from the cache |
641cab18 | 1820 | if (!path) |
6c0217d3 | 1821 | path = pakfire_package_get_string(pkg, PAKFIRE_PKG_CACHE_PATH); |
cbed1552 | 1822 | |
641cab18 | 1823 | // Open archive |
6c0217d3 MT |
1824 | r = pakfire_archive_open(&archive, pkg->pakfire, path); |
1825 | if (r) { | |
1826 | ERROR(pkg->pakfire, "Could not open archive for %s (at %s): %m\n", | |
1827 | pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA), path); | |
1828 | goto ERROR; | |
1829 | } | |
1830 | ||
1831 | ERROR: | |
1832 | if (repo) | |
1833 | pakfire_repo_unref(repo); | |
cbed1552 | 1834 | |
9686a82a | 1835 | return archive; |
cbed1552 MT |
1836 | } |
1837 | ||
843fa803 MT |
1838 | struct pakfire_package_filelist_search { |
1839 | struct pakfire* pakfire; | |
1840 | struct pakfire_filelist* filelist; | |
1841 | int r; | |
1842 | }; | |
1843 | ||
1844 | static int __pakfire_package_fetch_filelist(void* data, Solvable* s, Repodata* repodata, | |
1845 | Repokey* key, struct s_KeyValue* kv) { | |
1846 | struct pakfire_package_filelist_search* search = (struct pakfire_package_filelist_search*)data; | |
1847 | ||
a83d9e9f | 1848 | struct pakfire_file* file = NULL; |
843fa803 | 1849 | int r; |
5e9463ec | 1850 | |
843fa803 MT |
1851 | // Skip any results of the wrong type |
1852 | if (key->type != REPOKEY_TYPE_DIRSTRARRAY) | |
1853 | return 0; | |
221cc3ce | 1854 | |
843fa803 MT |
1855 | // Fetch the path |
1856 | const char* path = repodata_dir2str(repodata, kv->id, kv->str); | |
1857 | if (!path) { | |
1858 | r = 1; | |
1859 | goto ERROR; | |
1860 | } | |
221cc3ce | 1861 | |
843fa803 MT |
1862 | // Create a new file entry |
1863 | r = pakfire_file_create(&file, search->pakfire); | |
1864 | if (r) | |
1865 | goto ERROR; | |
5e9463ec | 1866 | |
843fa803 MT |
1867 | // Set path |
1868 | r = pakfire_file_set_path(file, path); | |
1869 | if (r) | |
1870 | goto ERROR; | |
221cc3ce | 1871 | |
843fa803 | 1872 | // Append the file to the filelist |
2f88682d | 1873 | r = pakfire_filelist_add(search->filelist, file); |
843fa803 MT |
1874 | if (r) |
1875 | goto ERROR; | |
1876 | ||
1877 | ERROR: | |
1878 | // Store the error code | |
1879 | search->r = r; | |
221cc3ce | 1880 | |
843fa803 | 1881 | if (file) |
5e9463ec | 1882 | pakfire_file_unref(file); |
221cc3ce | 1883 | |
843fa803 MT |
1884 | return r; |
1885 | } | |
1886 | ||
1887 | static int pakfire_package_fetch_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) { | |
1888 | struct pakfire_package_filelist_search search = { | |
1889 | .pakfire = pkg->pakfire, | |
1890 | .filelist = filelist, | |
1891 | .r = 0, | |
1892 | }; | |
5e9463ec | 1893 | |
843fa803 MT |
1894 | pakfire_package_internalize_repo(pkg); |
1895 | ||
1896 | Solvable* s = get_solvable(pkg); | |
1897 | ||
1898 | Repodata* repodata = repo_last_repodata(s->repo); | |
1899 | ||
1900 | // Search for all files | |
1901 | repodata_search(repodata, pkg->id, SOLVABLE_FILELIST, SEARCH_FILES, | |
1902 | __pakfire_package_fetch_filelist, &search); | |
1903 | ||
1904 | // Break on any error | |
1905 | if (search.r) | |
1906 | return search.r; | |
1907 | ||
843fa803 | 1908 | return search.r; |
221cc3ce MT |
1909 | } |
1910 | ||
1bbbfb9e | 1911 | PAKFIRE_EXPORT struct pakfire_filelist* pakfire_package_get_filelist(struct pakfire_package* pkg) { |
f78f6159 | 1912 | struct pakfire_filelist* filelist = NULL; |
5e9463ec | 1913 | |
f78f6159 | 1914 | // Create a new filelist |
883b3be9 | 1915 | int r = pakfire_filelist_create(&filelist, pkg->pakfire); |
f4560c3f | 1916 | if (r) |
f78f6159 | 1917 | goto ERROR; |
5e9463ec | 1918 | |
f78f6159 | 1919 | // Fetch all entries from the repository database |
f4560c3f | 1920 | r = pakfire_package_fetch_filelist(pkg, filelist); |
f78f6159 MT |
1921 | if (r) |
1922 | goto ERROR; | |
221cc3ce | 1923 | |
f4560c3f | 1924 | return filelist; |
f78f6159 MT |
1925 | |
1926 | ERROR: | |
1927 | if (filelist) | |
1928 | pakfire_filelist_unref(filelist); | |
1929 | ||
1930 | return NULL; | |
221cc3ce MT |
1931 | } |
1932 | ||
9da8ddfc | 1933 | int pakfire_package_append_file(struct pakfire_package* pkg, const char* path) { |
f54eb6e7 MT |
1934 | char basename[PATH_MAX]; |
1935 | char dirname[PATH_MAX]; | |
1936 | int r; | |
1937 | ||
5e9463ec | 1938 | // Fetch repodata |
4651122b | 1939 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
0384da25 MT |
1940 | if (!repo) { |
1941 | ERROR(pkg->pakfire, "Could not find repository for %s: %m\n", | |
74468e4f | 1942 | pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA)); |
0384da25 MT |
1943 | return 1; |
1944 | } | |
1945 | ||
3ff6aee6 | 1946 | Repodata* repodata = pakfire_repo_get_repodata(repo); |
221cc3ce | 1947 | |
f54eb6e7 | 1948 | // Get filename part |
67497686 | 1949 | r = pakfire_path_basename(basename, path); |
f54eb6e7 MT |
1950 | if (r) |
1951 | return r; | |
1952 | ||
1953 | // Get directory part | |
b4ae14b2 | 1954 | r = pakfire_path_dirname(dirname, path); |
f54eb6e7 MT |
1955 | if (r) |
1956 | return r; | |
d995f7fc MT |
1957 | |
1958 | // Convert directory into ID | |
1959 | Id did = repodata_str2dir(repodata, dirname, 1); | |
1960 | if (!did) | |
1961 | did = repodata_str2dir(repodata, "/", 1); | |
1962 | ||
1963 | // Add data to list | |
94db84fc | 1964 | repodata_add_dirstr(repodata, pkg->id, |
d995f7fc MT |
1965 | SOLVABLE_FILELIST, did, basename); |
1966 | ||
0384da25 MT |
1967 | pakfire_repo_unref(repo); |
1968 | ||
843fa803 MT |
1969 | // This package has changed |
1970 | pakfire_package_has_changed(pkg); | |
1971 | ||
d995f7fc MT |
1972 | return 0; |
1973 | } | |
1974 | ||
30ab941e MT |
1975 | static int __pakfire_package_set_filelist(struct pakfire* pakfire, |
1976 | struct pakfire_file* file, void* data) { | |
1977 | struct pakfire_package* pkg = (struct pakfire_package*)data; | |
221cc3ce | 1978 | |
30ab941e MT |
1979 | // Fetch the path |
1980 | const char* path = pakfire_file_get_path(file); | |
d995f7fc | 1981 | |
30ab941e MT |
1982 | return pakfire_package_append_file(pkg, path); |
1983 | } | |
d995f7fc | 1984 | |
30ab941e MT |
1985 | PAKFIRE_EXPORT int pakfire_package_set_filelist( |
1986 | struct pakfire_package* pkg, struct pakfire_filelist* filelist) { | |
a3f3c077 | 1987 | return pakfire_filelist_walk(filelist, __pakfire_package_set_filelist, pkg, 0); |
d995f7fc | 1988 | } |
221cc3ce | 1989 | |
31480bee | 1990 | int pakfire_package_set_filelist_from_string(struct pakfire_package* pkg, const char* files) { |
731f1d42 MT |
1991 | char* p = NULL; |
1992 | int r = 0; | |
d995f7fc | 1993 | |
731f1d42 MT |
1994 | // Copy files |
1995 | char* buffer = strdup(files); | |
1996 | if (!buffer) | |
1997 | goto ERROR; | |
d995f7fc | 1998 | |
731f1d42 MT |
1999 | // Walk through all files |
2000 | char* path = strtok_r(buffer, "\n", &p); | |
2001 | while (path) { | |
2002 | r = pakfire_package_append_file(pkg, path); | |
d995f7fc | 2003 | if (r) |
731f1d42 | 2004 | goto ERROR; |
d995f7fc | 2005 | |
731f1d42 | 2006 | path = strtok_r(NULL, "\n", &p); |
5e9463ec | 2007 | } |
221cc3ce | 2008 | |
731f1d42 MT |
2009 | ERROR: |
2010 | if (buffer) | |
2011 | free(buffer); | |
2012 | ||
2013 | return r; | |
221cc3ce | 2014 | } |
b59c9fa2 MT |
2015 | |
2016 | static int _pakfire_package_add_json_dependencies( | |
2017 | struct pakfire_package* pkg, | |
2018 | struct json_object* json, | |
2019 | const char* name, | |
6f3fad3b | 2020 | const enum pakfire_package_key key) { |
b59c9fa2 | 2021 | // Fetch dependencies |
6f3fad3b | 2022 | char** dependencies = pakfire_package_get_deps(pkg, key); |
b59c9fa2 | 2023 | if (!dependencies) |
6f3fad3b | 2024 | return 1; |
b59c9fa2 MT |
2025 | |
2026 | // Add dependencies | |
10211c67 | 2027 | int r = pakfire_json_add_string_array(pkg->pakfire, json, name, dependencies); |
b59c9fa2 MT |
2028 | if (r) |
2029 | goto ERROR; | |
2030 | ||
2031 | ERROR: | |
15360ad7 MT |
2032 | if (dependencies) |
2033 | pakfire_strings_free(dependencies); | |
b59c9fa2 MT |
2034 | |
2035 | return r; | |
2036 | } | |
2037 | ||
2038 | static int pakfire_package_add_json_dependencies( | |
2039 | struct pakfire_package* pkg, struct json_object* md) { | |
2040 | int r = 0; | |
2041 | ||
2042 | // Create new dependencies object | |
2043 | struct json_object* object = json_object_new_object(); | |
2044 | if (!object) | |
2045 | return 1; | |
2046 | ||
2047 | // Pre-requires | |
2048 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2049 | "prerequires", PAKFIRE_PKG_PREREQUIRES); |
b59c9fa2 MT |
2050 | if (r) |
2051 | goto ERROR; | |
2052 | ||
2053 | // Requires | |
2054 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2055 | "requires", PAKFIRE_PKG_REQUIRES); |
b59c9fa2 MT |
2056 | if (r) |
2057 | goto ERROR; | |
2058 | ||
2059 | // Provides | |
2060 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2061 | "provides", PAKFIRE_PKG_PROVIDES); |
b59c9fa2 MT |
2062 | if (r) |
2063 | goto ERROR; | |
2064 | ||
2065 | // Conflicts | |
2066 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2067 | "conflicts", PAKFIRE_PKG_CONFLICTS); |
b59c9fa2 MT |
2068 | if (r) |
2069 | goto ERROR; | |
2070 | ||
2071 | // Obsoletes | |
2072 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2073 | "obsoletes", PAKFIRE_PKG_OBSOLETES); |
b59c9fa2 MT |
2074 | if (r) |
2075 | goto ERROR; | |
2076 | ||
2077 | // Recommends | |
2078 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2079 | "recommends", PAKFIRE_PKG_RECOMMENDS); |
b59c9fa2 MT |
2080 | if (r) |
2081 | goto ERROR; | |
2082 | ||
2083 | // Suggests | |
2084 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2085 | "suggests", PAKFIRE_PKG_SUGGESTS); |
b59c9fa2 MT |
2086 | if (r) |
2087 | goto ERROR; | |
2088 | ||
2089 | // Supplements | |
2090 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2091 | "supplements", PAKFIRE_PKG_SUPPLEMENTS); |
b59c9fa2 MT |
2092 | if (r) |
2093 | goto ERROR; | |
2094 | ||
2095 | // Enhances | |
2096 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
6f3fad3b | 2097 | "enhances", PAKFIRE_PKG_ENHANCES); |
b59c9fa2 MT |
2098 | if (r) |
2099 | goto ERROR; | |
2100 | ||
2101 | // Add object | |
2102 | r = json_object_object_add(md, "dependencies", object); | |
2103 | if (r) | |
2104 | goto ERROR; | |
2105 | ||
2106 | ERROR: | |
2107 | if (r) | |
2108 | json_object_put(object); | |
2109 | ||
2110 | return r; | |
2111 | } | |
2112 | ||
ee292522 MT |
2113 | static int __pakfire_package_add_json_filelist(struct pakfire* pakfire, |
2114 | struct pakfire_file* file, void* data) { | |
2115 | struct json_object* filelist = (struct json_object*)data; | |
2116 | int r = 1; | |
2117 | ||
2118 | // Fetch the file path | |
2119 | const char* path = pakfire_file_get_path(file); | |
2120 | ||
2121 | // Create a new JSON string | |
2122 | struct json_object* object = json_object_new_string(path); | |
2123 | if (!object) | |
2124 | goto ERROR; | |
2125 | ||
2126 | // Append the string | |
2127 | r = json_object_array_add(filelist, object); | |
2128 | if (r) | |
2129 | goto ERROR; | |
2130 | ||
2131 | return 0; | |
2132 | ||
2133 | ERROR: | |
2134 | // Free JSON string | |
2135 | if (object) | |
2136 | json_object_put(object); | |
2137 | ||
2138 | return r; | |
2139 | } | |
2140 | ||
2141 | static int pakfire_package_add_json_filelist( | |
2142 | struct pakfire_package* pkg, struct json_object* md) { | |
2143 | struct pakfire_filelist* filelist = NULL; | |
2144 | struct json_object* object = NULL; | |
2145 | int r; | |
2146 | ||
2147 | // Fetch the filelist | |
2148 | filelist = pakfire_package_get_filelist(pkg); | |
2149 | if (!filelist) { | |
2150 | ERROR(pkg->pakfire, "Could not fetch package filelist\n"); | |
2151 | r = 1; | |
2152 | goto ERROR; | |
2153 | } | |
2154 | ||
2155 | // Create a new JSON array | |
2156 | object = json_object_new_array(); | |
2157 | if (!object) { | |
2158 | ERROR(pkg->pakfire, "Could not create a JSON array\n"); | |
2159 | r = 1; | |
2160 | goto ERROR; | |
2161 | } | |
2162 | ||
2163 | // Walk through the filelist | |
a3f3c077 | 2164 | r = pakfire_filelist_walk(filelist, __pakfire_package_add_json_filelist, object, 0); |
ee292522 MT |
2165 | if (r) |
2166 | goto ERROR; | |
2167 | ||
2168 | // Add object | |
2169 | r = json_object_object_add(md, "filelist", object); | |
2170 | if (r) | |
2171 | goto ERROR; | |
2172 | ||
2173 | ERROR: | |
2174 | // Free JSON object on error | |
2175 | if (r) | |
2176 | json_object_put(object); | |
2177 | if (filelist) | |
2178 | pakfire_filelist_unref(filelist); | |
2179 | ||
2180 | return r; | |
2181 | } | |
2182 | ||
460ce205 | 2183 | static int __pakfire_package_add_build_packages(struct pakfire_ctx* ctx, |
1cb9c3bf MT |
2184 | struct pakfire_package* pkg, void* p) { |
2185 | struct json_object* object = (struct json_object*)p; | |
2186 | int r; | |
2187 | ||
2188 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME); | |
2189 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR); | |
2190 | ||
2191 | if (!name || !evr) { | |
460ce205 | 2192 | CTX_ERROR(ctx, "Could not fetch package information: %m\n"); |
1cb9c3bf MT |
2193 | return 1; |
2194 | } | |
2195 | ||
2196 | // Add package information to the list | |
460ce205 | 2197 | r = pakfire_json_add_string(pkg->pakfire, object, name, evr); |
1cb9c3bf | 2198 | if (r) { |
460ce205 | 2199 | CTX_ERROR(ctx, "Could not add package to packages list: %m\n"); |
1cb9c3bf MT |
2200 | return r; |
2201 | } | |
2202 | ||
2203 | return 0; | |
2204 | } | |
2205 | ||
2206 | static int pakfire_package_add_build_packages(struct pakfire_package* pkg, | |
2207 | struct json_object* md) { | |
2208 | struct pakfire_repo* repo = NULL; | |
2209 | struct pakfire_packagelist* packages = NULL; | |
2210 | struct json_object* object = NULL; | |
2211 | int r; | |
2212 | ||
2213 | // Create a new JSON array | |
2214 | object = json_object_new_object(); | |
2215 | if (!object) { | |
2216 | ERROR(pkg->pakfire, "Could not create a new JSON object: %m\n"); | |
2217 | r = 1; | |
2218 | goto ERROR; | |
2219 | } | |
2220 | ||
2221 | // Fetch the installed repository | |
2222 | repo = pakfire_get_installed_repo(pkg->pakfire); | |
2223 | if (!repo) { | |
2224 | ERROR(pkg->pakfire, "Could not fetch the installed repository: %m\n"); | |
2225 | r = 1; | |
2226 | goto ERROR; | |
2227 | } | |
2228 | ||
d789a72a | 2229 | // Create a new list |
460ce205 | 2230 | r = pakfire_packagelist_create(&packages, pkg->ctx); |
d789a72a MT |
2231 | if (r) |
2232 | goto ERROR; | |
2233 | ||
1cb9c3bf | 2234 | // Fetch all installed packages |
d789a72a | 2235 | r = pakfire_repo_to_packagelist(repo, packages); |
1cb9c3bf MT |
2236 | if (r) { |
2237 | ERROR(pkg->pakfire, "Could not fetch packages from installed repository: %m\n"); | |
2238 | goto ERROR; | |
2239 | } | |
2240 | ||
2241 | // Add all packages to the array | |
2242 | r = pakfire_packagelist_walk(packages, __pakfire_package_add_build_packages, object); | |
2243 | if (r) | |
2244 | goto ERROR; | |
2245 | ||
2246 | // Add object | |
2247 | r = json_object_object_add(md, "packages", json_object_get(object)); | |
2248 | if (r) | |
2249 | goto ERROR; | |
2250 | ||
2251 | ERROR: | |
2252 | if (packages) | |
2253 | pakfire_packagelist_unref(packages); | |
2254 | if (repo) | |
2255 | pakfire_repo_unref(repo); | |
2256 | if (object) | |
2257 | json_object_put(object); | |
2258 | ||
2259 | return r; | |
2260 | } | |
2261 | ||
b59c9fa2 MT |
2262 | static int pakfire_package_add_build_metadata(struct pakfire_package* pkg, |
2263 | struct json_object* md) { | |
2264 | int r; | |
2265 | ||
2266 | // Create a new JSON object | |
2267 | struct json_object* object = json_object_new_object(); | |
2268 | if (!object) | |
2269 | return 1; | |
2270 | ||
2271 | // Add pakfire version that generated this metadata | |
2272 | r = pakfire_json_add_string(pkg->pakfire, object, "pakfire", PACKAGE_VERSION); | |
2273 | if (r) | |
2274 | goto ERROR; | |
2275 | ||
2276 | // Write build host | |
1f669e88 | 2277 | const char* build_host = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_HOST); |
b59c9fa2 MT |
2278 | if (build_host) { |
2279 | r = pakfire_json_add_string(pkg->pakfire, object, "host", build_host); | |
2280 | if (r) | |
2281 | goto ERROR; | |
2282 | } | |
2283 | ||
2284 | // Write build id | |
70f6900d | 2285 | const char* build_id = pakfire_package_get_string(pkg, PAKFIRE_PKG_BUILD_ID); |
b59c9fa2 MT |
2286 | if (build_id) { |
2287 | r = pakfire_json_add_string(pkg->pakfire, object, "id", build_id); | |
2288 | if (r) | |
2289 | goto ERROR; | |
2290 | } | |
2291 | ||
2292 | // Write build host | |
3f327c3c | 2293 | time_t build_time = pakfire_package_get_num(pkg, PAKFIRE_PKG_BUILD_TIME, 0); |
b59c9fa2 MT |
2294 | if (build_time) { |
2295 | r = pakfire_json_add_integer(pkg->pakfire, object, "time", build_time); | |
2296 | if (r) | |
2297 | goto ERROR; | |
2298 | } | |
2299 | ||
314e2310 | 2300 | // Write build arches |
10211c67 | 2301 | char** build_arches = pakfire_package_get_strings(pkg, PAKFIRE_PKG_BUILD_ARCHES); |
314e2310 MT |
2302 | if (build_arches) { |
2303 | r = pakfire_json_add_string_array(pkg->pakfire, object, "arches", build_arches); | |
10211c67 MT |
2304 | |
2305 | // Cleanup | |
15360ad7 | 2306 | pakfire_strings_free(build_arches); |
314e2310 MT |
2307 | |
2308 | if (r) | |
2309 | goto ERROR; | |
2310 | } | |
2311 | ||
571539a7 | 2312 | // Source package name |
988ce1bc | 2313 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_NAME); |
571539a7 MT |
2314 | if (name) { |
2315 | r = pakfire_json_add_string(pkg->pakfire, object, "source-name", name); | |
2316 | if (r) | |
2317 | goto ERROR; | |
2318 | } | |
2319 | ||
2320 | // Source package EVR | |
988ce1bc | 2321 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_EVR); |
571539a7 MT |
2322 | if (evr) { |
2323 | r = pakfire_json_add_string(pkg->pakfire, object, "source-evr", evr); | |
2324 | if (r) | |
2325 | goto ERROR; | |
2326 | } | |
2327 | ||
2328 | // Source package arch | |
988ce1bc | 2329 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_SOURCE_ARCH); |
571539a7 MT |
2330 | if (arch) { |
2331 | r = pakfire_json_add_string(pkg->pakfire, object, "source-arch", arch); | |
2332 | if (r) | |
2333 | goto ERROR; | |
2334 | } | |
2335 | ||
1cb9c3bf MT |
2336 | // Build Packages |
2337 | if (!pakfire_package_is_source(pkg)) { | |
2338 | r = pakfire_package_add_build_packages(pkg, object); | |
2339 | if (r) | |
2340 | goto ERROR; | |
2341 | } | |
2342 | ||
b59c9fa2 MT |
2343 | // Add object |
2344 | r = json_object_object_add(md, "build", object); | |
2345 | if (r) | |
2346 | goto ERROR; | |
2347 | ||
2348 | ERROR: | |
2349 | if (r) | |
2350 | json_object_put(object); | |
2351 | ||
2352 | return r; | |
2353 | } | |
2354 | ||
2355 | struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) { | |
2356 | struct json_object* md = json_object_new_object(); | |
2357 | int r = 0; | |
2358 | ||
2359 | // Name | |
74468e4f | 2360 | const char* name = pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME); |
b59c9fa2 MT |
2361 | if (name) { |
2362 | r = pakfire_json_add_string(pkg->pakfire, md, "name", name); | |
2363 | if (r) | |
2364 | goto ERROR; | |
2365 | } | |
2366 | ||
2367 | // EVR | |
74468e4f | 2368 | const char* evr = pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR); |
b59c9fa2 MT |
2369 | if (evr) { |
2370 | r = pakfire_json_add_string(pkg->pakfire, md, "evr", evr); | |
2371 | if (r) | |
2372 | goto ERROR; | |
2373 | } | |
2374 | ||
2375 | // Arch | |
74468e4f | 2376 | const char* arch = pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH); |
b59c9fa2 MT |
2377 | if (arch) { |
2378 | r = pakfire_json_add_string(pkg->pakfire, md, "arch", arch); | |
2379 | if (r) | |
2380 | goto ERROR; | |
2381 | } | |
2382 | ||
d9475a74 | 2383 | // Vendor |
74468e4f | 2384 | const char* vendor = pakfire_package_get_string(pkg, PAKFIRE_PKG_VENDOR); |
d9475a74 MT |
2385 | if (vendor) { |
2386 | r = pakfire_json_add_string(pkg->pakfire, md, "vendor", vendor); | |
2387 | if (r) | |
2388 | goto ERROR; | |
2389 | } | |
2390 | ||
ca002cae | 2391 | // Distribution |
74468e4f | 2392 | const char* distribution = pakfire_package_get_string(pkg, PAKFIRE_PKG_DISTRO); |
ca002cae MT |
2393 | if (distribution) { |
2394 | r = pakfire_json_add_string(pkg->pakfire, md, "distribution", distribution); | |
2395 | if (r) | |
2396 | goto ERROR; | |
2397 | } | |
2398 | ||
b59c9fa2 | 2399 | // UUID |
74468e4f | 2400 | const char* uuid = pakfire_package_get_string(pkg, PAKFIRE_PKG_UUID); |
b59c9fa2 MT |
2401 | if (uuid) { |
2402 | r = pakfire_json_add_string(pkg->pakfire, md, "uuid", uuid); | |
2403 | if (r) | |
2404 | goto ERROR; | |
2405 | } | |
2406 | ||
2407 | // Groups | |
d333480c | 2408 | char** groups = pakfire_package_get_strings(pkg, PAKFIRE_PKG_GROUPS); |
b59c9fa2 | 2409 | if (groups) { |
d333480c MT |
2410 | r = pakfire_json_add_string_array(pkg->pakfire, md, "groups", groups); |
2411 | ||
2412 | // Cleanup | |
2413 | pakfire_strings_free(groups); | |
2414 | ||
cb9b4eba MT |
2415 | if (r) |
2416 | goto ERROR; | |
2417 | } | |
2418 | ||
145d0efe MT |
2419 | // Packager |
2420 | const char* packager = pakfire_package_get_string(pkg, PAKFIRE_PKG_PACKAGER); | |
2421 | if (packager) { | |
2422 | r = pakfire_json_add_string(pkg->pakfire, md, "packager", packager); | |
b59c9fa2 MT |
2423 | if (r) |
2424 | goto ERROR; | |
2425 | } | |
2426 | ||
2427 | // URL | |
74468e4f | 2428 | const char* url = pakfire_package_get_string(pkg, PAKFIRE_PKG_URL); |
b59c9fa2 MT |
2429 | if (url) { |
2430 | r = pakfire_json_add_string(pkg->pakfire, md, "url", url); | |
2431 | if (r) | |
2432 | goto ERROR; | |
2433 | } | |
2434 | ||
2435 | // License | |
74468e4f | 2436 | const char* license = pakfire_package_get_string(pkg, PAKFIRE_PKG_LICENSE); |
b59c9fa2 MT |
2437 | if (license) { |
2438 | r = pakfire_json_add_string(pkg->pakfire, md, "license", license); | |
2439 | if (r) | |
2440 | goto ERROR; | |
2441 | } | |
2442 | ||
2443 | // Summary | |
74468e4f | 2444 | const char* summary = pakfire_package_get_string(pkg, PAKFIRE_PKG_SUMMARY); |
b59c9fa2 MT |
2445 | if (summary) { |
2446 | r = pakfire_json_add_string(pkg->pakfire, md, "summary", summary); | |
2447 | if (r) | |
2448 | goto ERROR; | |
2449 | } | |
2450 | ||
2451 | // Description | |
74468e4f | 2452 | const char* description = pakfire_package_get_string(pkg, PAKFIRE_PKG_DESCRIPTION); |
b59c9fa2 MT |
2453 | if (description) { |
2454 | r = pakfire_json_add_string(pkg->pakfire, md, "description", description); | |
2455 | if (r) | |
2456 | goto ERROR; | |
2457 | } | |
2458 | ||
2459 | // Installed package size | |
8fde67b2 | 2460 | unsigned long long installsize = pakfire_package_get_num(pkg, PAKFIRE_PKG_INSTALLSIZE, 0); |
3f327c3c | 2461 | |
8fde67b2 | 2462 | r = pakfire_json_add_integer(pkg->pakfire, md, "size", (uint64_t)installsize); |
b59c9fa2 MT |
2463 | if (r) |
2464 | goto ERROR; | |
2465 | ||
2466 | // Generate dependency metadata | |
2467 | r = pakfire_package_add_json_dependencies(pkg, md); | |
2468 | if (r) | |
2469 | goto ERROR; | |
2470 | ||
ee292522 MT |
2471 | // Generate filelist |
2472 | r = pakfire_package_add_json_filelist(pkg, md); | |
2473 | if (r) | |
2474 | goto ERROR; | |
2475 | ||
b59c9fa2 MT |
2476 | // Generate build metadata |
2477 | r = pakfire_package_add_build_metadata(pkg, md); | |
2478 | if (r) | |
2479 | goto ERROR; | |
2480 | ||
2481 | ERROR: | |
2482 | if (r) | |
2483 | json_object_put(md); | |
2484 | ||
2485 | return md; | |
2486 | } | |
4df7e8d8 | 2487 | |
2f269d34 MT |
2488 | PAKFIRE_EXPORT int pakfire_package_installcheck(struct pakfire_package* pkg, |
2489 | char** problem, int flags) { | |
2490 | struct pakfire_transaction* transaction = NULL; | |
2491 | char* p = NULL; | |
4df7e8d8 MT |
2492 | int r; |
2493 | ||
2494 | const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA); | |
2495 | ||
2f269d34 MT |
2496 | // Create a new transaction |
2497 | r = pakfire_transaction_create(&transaction, pkg->pakfire, flags); | |
4df7e8d8 MT |
2498 | if (r) |
2499 | goto ERROR; | |
2500 | ||
2501 | // Install the package | |
2f269d34 MT |
2502 | r = pakfire_transaction_request_package(transaction, |
2503 | PAKFIRE_JOB_INSTALL, pkg, PAKFIRE_JOB_ESSENTIAL); | |
4df7e8d8 MT |
2504 | if (r) { |
2505 | ERROR(pkg->pakfire, "Could not add package %s to the request\n", nevra); | |
2506 | goto ERROR; | |
2507 | } | |
2508 | ||
2f269d34 | 2509 | // Solve the transaction |
94427e38 | 2510 | r = pakfire_transaction_solve(transaction, PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED, &p); |
4df7e8d8 | 2511 | if (r) { |
2f269d34 | 2512 | DEBUG(pkg->pakfire, "Could not install %s:\n%s\n", nevra, p); |
4df7e8d8 | 2513 | |
2f269d34 MT |
2514 | // Copy the problem string |
2515 | if (p) | |
2516 | *problem = strdup(p); | |
4df7e8d8 MT |
2517 | } |
2518 | ||
2519 | ERROR: | |
2f269d34 MT |
2520 | if (p) |
2521 | free(p); | |
2522 | if (transaction) | |
2523 | pakfire_transaction_unref(transaction); | |
4df7e8d8 MT |
2524 | |
2525 | return r; | |
2526 | } |