]>
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 | ||
cbed1552 | 35 | #include <pakfire/archive.h> |
221cc3ce | 36 | #include <pakfire/constants.h> |
2a623cf8 | 37 | #include <pakfire/dependencies.h> |
c52e0148 | 38 | #include <pakfire/digest.h> |
221cc3ce | 39 | #include <pakfire/file.h> |
5e9463ec | 40 | #include <pakfire/filelist.h> |
221cc3ce | 41 | #include <pakfire/i18n.h> |
6cdfb9dd | 42 | #include <pakfire/logging.h> |
221cc3ce | 43 | #include <pakfire/package.h> |
cbed1552 | 44 | #include <pakfire/pakfire.h> |
9f953e68 | 45 | #include <pakfire/private.h> |
221cc3ce | 46 | #include <pakfire/repo.h> |
d973a13d | 47 | #include <pakfire/string.h> |
221cc3ce MT |
48 | #include <pakfire/util.h> |
49 | ||
31480bee | 50 | struct pakfire_package { |
ac4c607b | 51 | struct pakfire* pakfire; |
7847efcd | 52 | int nrefs; |
e9d9eadc | 53 | |
8b088877 MT |
54 | // Reference to this package in the SOLV pool |
55 | Id id; | |
4651122b | 56 | struct pakfire_repo* repo; |
8b088877 | 57 | |
40fcf5ff | 58 | char nevra[NAME_MAX]; |
571539a7 | 59 | char source_nevra[NAME_MAX]; |
40fcf5ff | 60 | |
b12a5d7d MT |
61 | char filename[NAME_MAX]; |
62 | char path[PATH_MAX]; | |
7847efcd MT |
63 | }; |
64 | ||
ac4c607b | 65 | struct pakfire_package* pakfire_package_create_from_solvable(struct pakfire* pakfire, Id id) { |
31480bee | 66 | struct pakfire_package* pkg = calloc(1, sizeof(*pkg)); |
e9d9eadc MT |
67 | if (!pkg) |
68 | return NULL; | |
6cdfb9dd | 69 | |
e9d9eadc MT |
70 | pkg->pakfire = pakfire_ref(pakfire); |
71 | pkg->id = id; | |
72 | ||
73 | // Initialize reference counter | |
74 | pkg->nrefs = 1; | |
221cc3ce MT |
75 | |
76 | return pkg; | |
77 | } | |
78 | ||
32136e0c MT |
79 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_create( |
80 | struct pakfire* pakfire, struct pakfire_repo* repo, | |
81 | const char* name, const char* evr, const char* arch) { | |
82 | struct pakfire_package* pkg = NULL; | |
83 | struct pakfire_repo* dummy = NULL; | |
84 | ||
85 | // Default to dummy repository | |
86 | if (!repo) { | |
87 | dummy = pakfire_get_repo(pakfire, PAKFIRE_REPO_DUMMY); | |
88 | if (!dummy) { | |
89 | errno = ENOENT; | |
90 | return NULL; | |
91 | } | |
92 | ||
93 | repo = dummy; | |
94 | } | |
95 | ||
96 | // Allocate a new solvable | |
e9d9eadc MT |
97 | Id id = pakfire_repo_add_solvable(repo); |
98 | if (!id) | |
32136e0c | 99 | goto ERROR; |
e9d9eadc | 100 | |
32136e0c MT |
101 | // Create a new package object |
102 | pkg = pakfire_package_create_from_solvable(pakfire, id); | |
e9d9eadc | 103 | if (!pkg) |
32136e0c | 104 | goto ERROR; |
221cc3ce | 105 | |
e9d9eadc MT |
106 | pkg->repo = pakfire_repo_ref(repo); |
107 | ||
108 | // Set the given attributes | |
221cc3ce MT |
109 | pakfire_package_set_name(pkg, name); |
110 | pakfire_package_set_evr(pkg, evr); | |
111 | pakfire_package_set_arch(pkg, arch); | |
112 | ||
32136e0c MT |
113 | ERROR: |
114 | if (dummy) | |
115 | pakfire_repo_unref(dummy); | |
116 | ||
221cc3ce MT |
117 | return pkg; |
118 | } | |
119 | ||
31480bee | 120 | static void pakfire_package_free(struct pakfire_package* pkg) { |
e9d9eadc MT |
121 | if (pkg->repo) |
122 | pakfire_repo_unref(pkg->repo); | |
123 | ||
5e9463ec | 124 | pakfire_unref(pkg->pakfire); |
f0d6233d | 125 | free(pkg); |
221cc3ce MT |
126 | } |
127 | ||
31480bee | 128 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_ref(struct pakfire_package* pkg) { |
a4e3894f MT |
129 | pkg->nrefs++; |
130 | ||
131 | return pkg; | |
132 | } | |
133 | ||
31480bee | 134 | PAKFIRE_EXPORT struct pakfire_package* pakfire_package_unref(struct pakfire_package* pkg) { |
a4e3894f MT |
135 | if (--pkg->nrefs > 0) |
136 | return pkg; | |
137 | ||
138 | pakfire_package_free(pkg); | |
139 | return NULL; | |
140 | } | |
141 | ||
ac4c607b | 142 | PAKFIRE_EXPORT struct pakfire* pakfire_package_get_pakfire(struct pakfire_package* pkg) { |
178a4506 MT |
143 | return pakfire_ref(pkg->pakfire); |
144 | } | |
145 | ||
31480bee | 146 | static Solvable* get_solvable(struct pakfire_package* pkg) { |
0defa23e | 147 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce | 148 | |
f1c7996e | 149 | return pool_id2solvable(pool, pkg->id); |
221cc3ce MT |
150 | } |
151 | ||
31480bee | 152 | PAKFIRE_EXPORT int pakfire_package_eq(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
221cc3ce MT |
153 | return pkg1->id == pkg2->id; |
154 | } | |
155 | ||
31480bee | 156 | PAKFIRE_EXPORT int pakfire_package_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
0defa23e | 157 | Pool* pool = pakfire_get_solv_pool(pkg1->pakfire); |
221cc3ce MT |
158 | |
159 | Solvable* s1 = get_solvable(pkg1); | |
160 | Solvable* s2 = get_solvable(pkg2); | |
161 | ||
162 | // Check names | |
163 | const char* str1 = pool_id2str(pool, s1->name); | |
164 | const char* str2 = pool_id2str(pool, s2->name); | |
165 | ||
166 | int ret = strcmp(str1, str2); | |
167 | if (ret) | |
168 | return ret; | |
169 | ||
170 | // Check the version string | |
171 | ret = pakfire_package_evr_cmp(pkg1, pkg2); | |
172 | if (ret) | |
173 | return ret; | |
174 | ||
175 | // Check repositories | |
4651122b MT |
176 | struct pakfire_repo* repo1 = pakfire_package_get_repo(pkg1); |
177 | struct pakfire_repo* repo2 = pakfire_package_get_repo(pkg2); | |
221cc3ce MT |
178 | |
179 | if (repo1 && repo2) { | |
180 | ret = pakfire_repo_cmp(repo1, repo2); | |
3ff6aee6 | 181 | } |
221cc3ce | 182 | |
3ff6aee6 MT |
183 | pakfire_repo_unref(repo1); |
184 | pakfire_repo_unref(repo2); | |
221cc3ce | 185 | |
3ff6aee6 MT |
186 | if (ret) |
187 | return ret; | |
221cc3ce MT |
188 | |
189 | // Check package architectures | |
190 | str1 = pool_id2str(pool, s1->arch); | |
191 | str2 = pool_id2str(pool, s2->arch); | |
192 | ||
193 | return strcmp(str1, str2); | |
194 | } | |
195 | ||
31480bee | 196 | PAKFIRE_EXPORT int pakfire_package_evr_cmp(struct pakfire_package* pkg1, struct pakfire_package* pkg2) { |
0defa23e | 197 | Pool* pool = pakfire_get_solv_pool(pkg1->pakfire); |
221cc3ce MT |
198 | |
199 | Solvable* s1 = get_solvable(pkg1); | |
200 | Solvable* s2 = get_solvable(pkg2); | |
201 | ||
202 | return pool_evrcmp(pool, s1->evr, s2->evr, EVRCMP_COMPARE); | |
203 | } | |
204 | ||
31480bee | 205 | Id pakfire_package_id(struct pakfire_package* pkg) { |
221cc3ce MT |
206 | return pkg->id; |
207 | } | |
208 | ||
31480bee | 209 | PAKFIRE_EXPORT const char* pakfire_package_get_nevra(struct pakfire_package* pkg) { |
40fcf5ff MT |
210 | if (!*pkg->nevra) { |
211 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
212 | Solvable* s = get_solvable(pkg); | |
221cc3ce | 213 | |
40fcf5ff MT |
214 | pakfire_string_set(pkg->nevra, pool_solvable2str(pool, s)); |
215 | } | |
221cc3ce | 216 | |
40fcf5ff | 217 | return pkg->nevra; |
221cc3ce MT |
218 | } |
219 | ||
31480bee | 220 | PAKFIRE_EXPORT const char* pakfire_package_get_name(struct pakfire_package* pkg) { |
0defa23e | 221 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
222 | Solvable* s = get_solvable(pkg); |
223 | ||
224 | return pool_id2str(pool, s->name); | |
225 | } | |
226 | ||
31480bee | 227 | PAKFIRE_EXPORT void pakfire_package_set_name(struct pakfire_package* pkg, const char* name) { |
0defa23e | 228 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
229 | Solvable* s = get_solvable(pkg); |
230 | ||
231 | s->name = pool_str2id(pool, name, 1); | |
232 | } | |
233 | ||
31480bee | 234 | PAKFIRE_EXPORT const char* pakfire_package_get_evr(struct pakfire_package* pkg) { |
0defa23e | 235 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
236 | Solvable* s = get_solvable(pkg); |
237 | ||
238 | return pool_id2str(pool, s->evr); | |
239 | } | |
240 | ||
31480bee | 241 | PAKFIRE_EXPORT void pakfire_package_set_evr(struct pakfire_package* pkg, const char* evr) { |
0defa23e | 242 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
243 | Solvable* s = get_solvable(pkg); |
244 | ||
85b75c7b MT |
245 | // Skip empty epoch |
246 | if (pakfire_string_startswith(evr, "0:")) | |
247 | evr += 2; | |
248 | ||
221cc3ce MT |
249 | s->evr = pool_str2id(pool, evr, 1); |
250 | } | |
251 | ||
e42b5960 MT |
252 | char* pakfire_package_join_evr(const char* e, const char* v, const char* r) { |
253 | char* buffer = NULL; | |
312fd26f | 254 | |
e42b5960 MT |
255 | // Check for valid input |
256 | if (!e || !v || !r) { | |
257 | errno = EINVAL; | |
258 | return NULL; | |
312fd26f MT |
259 | } |
260 | ||
e42b5960 MT |
261 | // Skip any zeroes in epoch |
262 | while (*e && *e == '0') | |
263 | e++; | |
264 | ||
265 | // Format string with epoch | |
266 | if (*e) { | |
267 | if (asprintf(&buffer, "%s:%s-%s", e, v, r) < 0) | |
268 | return NULL; | |
269 | ||
270 | // Or format it without epoch | |
271 | } else { | |
272 | if (asprintf(&buffer, "%s-%s", v, r) < 0) | |
273 | return NULL; | |
274 | } | |
312fd26f MT |
275 | |
276 | return buffer; | |
277 | } | |
278 | ||
31480bee | 279 | PAKFIRE_EXPORT const char* pakfire_package_get_arch(struct pakfire_package* pkg) { |
0defa23e | 280 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
281 | Solvable* s = get_solvable(pkg); |
282 | ||
283 | return pool_id2str(pool, s->arch); | |
284 | } | |
285 | ||
31480bee | 286 | PAKFIRE_EXPORT void pakfire_package_set_arch(struct pakfire_package* pkg, const char* arch) { |
0defa23e | 287 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
288 | Solvable* s = get_solvable(pkg); |
289 | ||
290 | s->arch = pool_str2id(pool, arch, 1); | |
291 | } | |
292 | ||
31480bee | 293 | int pakfire_package_is_source(struct pakfire_package* pkg) { |
af14aefb MT |
294 | const char* arch = pakfire_package_get_arch(pkg); |
295 | if (!arch) | |
296 | return 1; | |
297 | ||
298 | return (strcmp(arch, "src") == 0); | |
299 | } | |
300 | ||
31480bee | 301 | static void pakfire_package_internalize_repo(struct pakfire_package* pkg) { |
4651122b | 302 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
221cc3ce | 303 | if (repo) { |
9eba3d65 | 304 | pakfire_repo_internalize(repo, 0); |
3ff6aee6 | 305 | pakfire_repo_unref(repo); |
221cc3ce MT |
306 | } |
307 | } | |
308 | ||
31480bee | 309 | static unsigned long long pakfire_package_get_num(struct pakfire_package* pkg, Id type) { |
ac71886a MT |
310 | pakfire_package_internalize_repo(pkg); |
311 | ||
312 | Solvable* s = get_solvable(pkg); | |
313 | return solvable_lookup_num(s, type, 0); | |
314 | } | |
315 | ||
31480bee | 316 | static void pakfire_package_set_num(struct pakfire_package* pkg, Id type, unsigned long long value) { |
ac71886a MT |
317 | Solvable* s = get_solvable(pkg); |
318 | ||
319 | solvable_set_num(s, type, value); | |
320 | } | |
321 | ||
8e76ebe1 | 322 | static const char* pakfire_package_get_string(struct pakfire_package* pkg, Id key) { |
221cc3ce MT |
323 | pakfire_package_internalize_repo(pkg); |
324 | ||
325 | Solvable* s = get_solvable(pkg); | |
221cc3ce | 326 | |
8e76ebe1 MT |
327 | const char* str = solvable_lookup_str(s, key); |
328 | if (!str || !*str) | |
221cc3ce MT |
329 | return NULL; |
330 | ||
331 | return str; | |
332 | } | |
333 | ||
31480bee | 334 | static void pakfire_package_set_string(struct pakfire_package* pkg, int key, const char* value) { |
221cc3ce MT |
335 | Solvable* s = get_solvable(pkg); |
336 | ||
51c47a9a MT |
337 | // Unset on empty string |
338 | if (!value || !*value) | |
339 | solvable_unset(s, key); | |
221cc3ce | 340 | |
51c47a9a MT |
341 | // Store string |
342 | solvable_set_str(s, key, value); | |
7ccc9d74 MT |
343 | } |
344 | ||
31480bee | 345 | static char** pakfire_package_get_string_array(struct pakfire_package* pkg, Id key) { |
1eb7f40b MT |
346 | char** strings = NULL; |
347 | ||
348 | Queue ids; | |
349 | queue_init(&ids); | |
350 | ||
0defa23e | 351 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
7ccc9d74 | 352 | Solvable* s = get_solvable(pkg); |
1eb7f40b MT |
353 | solvable_lookup_idarray(s, key, &ids); |
354 | ||
355 | if (ids.count > 0) { | |
356 | strings = calloc(ids.count + 1, sizeof(*strings)); | |
357 | if (!strings) { | |
358 | queue_free(&ids); | |
359 | return NULL; | |
360 | } | |
361 | ||
362 | for (int i = 0; i < ids.count; i++) { | |
363 | const char* value = pool_id2str(pool, ids.elements[i]); | |
364 | strings[i] = strdup(value); | |
365 | } | |
7ccc9d74 | 366 | |
1eb7f40b MT |
367 | strings[ids.count] = NULL; |
368 | } | |
369 | ||
370 | queue_free(&ids); | |
371 | ||
372 | return strings; | |
373 | } | |
374 | ||
31480bee | 375 | static void pakfire_package_add_string_array(struct pakfire_package* pkg, Id key, const char* value) { |
7ccc9d74 MT |
376 | if (!value) |
377 | return; | |
378 | ||
1eb7f40b | 379 | Solvable* s = get_solvable(pkg); |
7ccc9d74 | 380 | solvable_add_poolstr_array(s, key, value); |
221cc3ce MT |
381 | } |
382 | ||
31480bee | 383 | uint64_t pakfire_package_get_dbid(struct pakfire_package* pkg) { |
ac71886a MT |
384 | return pakfire_package_get_num(pkg, RPM_RPMDBID); |
385 | } | |
386 | ||
31480bee | 387 | void pakfire_package_set_dbid(struct pakfire_package* pkg, uint64_t id) { |
ac71886a MT |
388 | pakfire_package_set_num(pkg, RPM_RPMDBID, id); |
389 | } | |
390 | ||
31480bee | 391 | PAKFIRE_EXPORT const char* pakfire_package_get_uuid(struct pakfire_package* pkg) { |
221cc3ce MT |
392 | return pakfire_package_get_string(pkg, SOLVABLE_PKGID); |
393 | } | |
394 | ||
31480bee | 395 | PAKFIRE_EXPORT void pakfire_package_set_uuid(struct pakfire_package* pkg, const char* uuid) { |
221cc3ce MT |
396 | pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid); |
397 | } | |
398 | ||
c52e0148 | 399 | static enum pakfire_digest_types pakfire_package_id2digest(Id id) { |
e61716e4 MT |
400 | switch (id) { |
401 | case REPOKEY_TYPE_SHA512: | |
4500ed0a | 402 | return PAKFIRE_DIGEST_SHA2_512; |
b28af23a | 403 | |
e61716e4 | 404 | case REPOKEY_TYPE_SHA256: |
4500ed0a | 405 | return PAKFIRE_DIGEST_SHA2_256; |
b28af23a MT |
406 | } |
407 | ||
9802aaf6 | 408 | return 0; |
b28af23a MT |
409 | } |
410 | ||
411 | PAKFIRE_EXPORT const unsigned char* pakfire_package_get_digest( | |
c52e0148 | 412 | struct pakfire_package* pkg, enum pakfire_digest_types* type) { |
b28af23a | 413 | Solvable* s = get_solvable(pkg); |
e61716e4 | 414 | Id id; |
b28af23a | 415 | |
e61716e4 | 416 | const unsigned char* checksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &id); |
b28af23a | 417 | |
e61716e4 MT |
418 | // Convert ID to digest type |
419 | *type = pakfire_package_id2digest(id); | |
420 | if (!*type) { | |
421 | errno = ENOTSUP; | |
422 | checksum = NULL; | |
423 | } | |
424 | ||
425 | return checksum; | |
b28af23a MT |
426 | } |
427 | ||
428 | PAKFIRE_EXPORT const char* pakfire_package_get_hexdigest( | |
c52e0148 | 429 | struct pakfire_package* pkg, enum pakfire_digest_types* type) { |
b28af23a | 430 | Solvable* s = get_solvable(pkg); |
e61716e4 | 431 | Id id; |
b28af23a | 432 | |
e61716e4 | 433 | const char* checksum = solvable_lookup_checksum(s, SOLVABLE_CHECKSUM, &id); |
b28af23a | 434 | |
e61716e4 MT |
435 | // Convert ID to digest type |
436 | *type = pakfire_package_id2digest(id); | |
437 | if (!*type) { | |
438 | errno = ENOTSUP; | |
439 | checksum = NULL; | |
440 | } | |
441 | ||
442 | return checksum; | |
b28af23a MT |
443 | } |
444 | ||
445 | PAKFIRE_EXPORT int pakfire_package_set_digest(struct pakfire_package* pkg, | |
c52e0148 | 446 | enum pakfire_digest_types type, const unsigned char* digest) { |
b28af23a MT |
447 | Solvable* s = get_solvable(pkg); |
448 | Pool* pool = s->repo->pool; | |
e61716e4 | 449 | Id id; |
b28af23a MT |
450 | int r = 1; |
451 | ||
e61716e4 | 452 | switch (type) { |
4500ed0a | 453 | case PAKFIRE_DIGEST_SHA2_256: |
e61716e4 MT |
454 | id = REPOKEY_TYPE_SHA256; |
455 | break; | |
456 | ||
4500ed0a | 457 | case PAKFIRE_DIGEST_SHA2_512: |
e61716e4 MT |
458 | id = REPOKEY_TYPE_SHA512; |
459 | break; | |
460 | ||
461 | default: | |
462 | errno = ENOTSUP; | |
463 | return 1; | |
464 | } | |
b28af23a MT |
465 | |
466 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); | |
467 | ||
468 | Repodata* data = pakfire_repo_get_repodata(repo); | |
469 | if (!data) | |
470 | goto ERROR; | |
471 | ||
472 | repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, id, digest); | |
473 | ||
474 | // Success | |
475 | r = 0; | |
476 | ||
477 | ERROR: | |
478 | pakfire_repo_unref(repo); | |
479 | ||
480 | return r; | |
481 | } | |
482 | ||
b28af23a | 483 | PAKFIRE_EXPORT int pakfire_package_set_hexdigest(struct pakfire_package* pkg, |
c52e0148 | 484 | enum pakfire_digest_types type, const char* hexdigest) { |
7cea394c | 485 | const size_t digest_length = pakfire_digest_length(type); |
b28af23a MT |
486 | |
487 | if (!digest_length) { | |
488 | errno = EINVAL; | |
489 | return 1; | |
490 | } | |
491 | ||
492 | // Allocate a buffer for the binary representation of the digest | |
493 | unsigned char* digest = alloca(digest_length); | |
494 | if (!digest) | |
495 | return 1; | |
496 | ||
497 | // Convert from hex to binary | |
498 | __pakfire_unhexlify(digest, digest_length, hexdigest); | |
499 | ||
500 | return pakfire_package_set_digest(pkg, type, digest); | |
221cc3ce MT |
501 | } |
502 | ||
31480bee | 503 | PAKFIRE_EXPORT const char* pakfire_package_get_summary(struct pakfire_package* pkg) { |
221cc3ce MT |
504 | return pakfire_package_get_string(pkg, SOLVABLE_SUMMARY); |
505 | } | |
506 | ||
31480bee | 507 | PAKFIRE_EXPORT void pakfire_package_set_summary(struct pakfire_package* pkg, const char* summary) { |
221cc3ce MT |
508 | pakfire_package_set_string(pkg, SOLVABLE_SUMMARY, summary); |
509 | } | |
510 | ||
31480bee | 511 | PAKFIRE_EXPORT const char* pakfire_package_get_description(struct pakfire_package* pkg) { |
221cc3ce MT |
512 | return pakfire_package_get_string(pkg, SOLVABLE_DESCRIPTION); |
513 | } | |
514 | ||
31480bee | 515 | PAKFIRE_EXPORT void pakfire_package_set_description(struct pakfire_package* pkg, const char* description) { |
221cc3ce MT |
516 | pakfire_package_set_string(pkg, SOLVABLE_DESCRIPTION, description); |
517 | } | |
518 | ||
31480bee | 519 | PAKFIRE_EXPORT const char* pakfire_package_get_license(struct pakfire_package* pkg) { |
221cc3ce MT |
520 | return pakfire_package_get_string(pkg, SOLVABLE_LICENSE); |
521 | } | |
522 | ||
31480bee | 523 | PAKFIRE_EXPORT void pakfire_package_set_license(struct pakfire_package* pkg, const char* license) { |
221cc3ce MT |
524 | pakfire_package_set_string(pkg, SOLVABLE_LICENSE, license); |
525 | } | |
526 | ||
31480bee | 527 | PAKFIRE_EXPORT const char* pakfire_package_get_url(struct pakfire_package* pkg) { |
221cc3ce MT |
528 | return pakfire_package_get_string(pkg, SOLVABLE_URL); |
529 | } | |
530 | ||
31480bee | 531 | PAKFIRE_EXPORT void pakfire_package_set_url(struct pakfire_package* pkg, const char* url) { |
221cc3ce MT |
532 | pakfire_package_set_string(pkg, SOLVABLE_URL, url); |
533 | } | |
534 | ||
31480bee | 535 | PAKFIRE_EXPORT char* pakfire_package_get_groups(struct pakfire_package* pkg) { |
1eb7f40b MT |
536 | char** groups = pakfire_package_get_string_array(pkg, SOLVABLE_GROUP); |
537 | if (!groups) | |
538 | return NULL; | |
539 | ||
540 | char* string = pakfire_string_join(groups, " "); | |
541 | ||
542 | // Free array | |
543 | for (char** group = groups; *group; group++) | |
544 | free(*group); | |
545 | free(groups); | |
546 | ||
547 | return string; | |
221cc3ce MT |
548 | } |
549 | ||
31480bee | 550 | PAKFIRE_EXPORT void pakfire_package_set_groups(struct pakfire_package* pkg, const char* groups) { |
d973a13d | 551 | char** list = pakfire_string_split(groups, ' '); |
1eb7f40b MT |
552 | if (!list) |
553 | return; | |
221cc3ce | 554 | |
1eb7f40b MT |
555 | for (char** group = list; *group; group++) { |
556 | pakfire_package_add_string_array(pkg, SOLVABLE_GROUP, *group); | |
557 | free(*group); | |
2141b578 | 558 | } |
1eb7f40b MT |
559 | |
560 | free(list); | |
8ad0a954 MT |
561 | } |
562 | ||
31480bee | 563 | PAKFIRE_EXPORT const char* pakfire_package_get_vendor(struct pakfire_package* pkg) { |
221cc3ce MT |
564 | return pakfire_package_get_string(pkg, SOLVABLE_VENDOR); |
565 | } | |
566 | ||
31480bee | 567 | PAKFIRE_EXPORT void pakfire_package_set_vendor(struct pakfire_package* pkg, const char* vendor) { |
221cc3ce MT |
568 | pakfire_package_set_string(pkg, SOLVABLE_VENDOR, vendor); |
569 | } | |
570 | ||
ca002cae MT |
571 | PAKFIRE_EXPORT const char* pakfire_package_get_distribution(struct pakfire_package* pkg) { |
572 | return pakfire_package_get_string(pkg, SOLVABLE_DISTRIBUTION); | |
573 | } | |
574 | ||
575 | PAKFIRE_EXPORT void pakfire_package_set_distribution(struct pakfire_package* pkg, const char* distribution) { | |
576 | pakfire_package_set_string(pkg, SOLVABLE_DISTRIBUTION, distribution); | |
577 | } | |
578 | ||
31480bee | 579 | PAKFIRE_EXPORT const char* pakfire_package_get_maintainer(struct pakfire_package* pkg) { |
221cc3ce MT |
580 | return pakfire_package_get_string(pkg, SOLVABLE_PACKAGER); |
581 | } | |
582 | ||
31480bee | 583 | PAKFIRE_EXPORT void pakfire_package_set_maintainer(struct pakfire_package* pkg, const char* maintainer) { |
221cc3ce MT |
584 | pakfire_package_set_string(pkg, SOLVABLE_PACKAGER, maintainer); |
585 | } | |
586 | ||
31480bee | 587 | static int pakfire_package_make_cache_path(struct pakfire_package* pkg) { |
b12a5d7d | 588 | const char* filename = pakfire_package_get_filename(pkg); |
b12a5d7d | 589 | |
c52e0148 | 590 | enum pakfire_digest_types digest; |
e61716e4 MT |
591 | const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest); |
592 | ||
126037d1 | 593 | if (hexdigest && strlen(hexdigest) >= 3) |
df1409ef | 594 | return pakfire_cache_path(pkg->pakfire, pkg->path, |
126037d1 | 595 | "%c%c/%s/%s", hexdigest[0], hexdigest[1], hexdigest + 2, filename); |
b12a5d7d | 596 | |
df1409ef | 597 | return pakfire_cache_path(pkg->pakfire, pkg->path, "%s", filename); |
b12a5d7d MT |
598 | } |
599 | ||
31480bee | 600 | PAKFIRE_EXPORT const char* pakfire_package_get_path(struct pakfire_package* pkg) { |
b12a5d7d MT |
601 | int r; |
602 | ||
603 | if (!*pkg->path) { | |
604 | const char* base = pakfire_package_get_string(pkg, SOLVABLE_MEDIABASE); | |
605 | if (base) { | |
606 | const char* filename = pakfire_package_get_filename(pkg); | |
607 | if (!filename) | |
608 | return NULL; | |
609 | ||
610 | pakfire_string_format(pkg->path, "%s/%s", base, filename); | |
611 | } else { | |
612 | r = pakfire_package_make_cache_path(pkg); | |
613 | if (r) | |
614 | return NULL; | |
615 | } | |
616 | } | |
617 | ||
618 | return pkg->path; | |
619 | } | |
620 | ||
31480bee | 621 | PAKFIRE_EXPORT void pakfire_package_set_path(struct pakfire_package* pkg, const char* path) { |
bbbc9842 MT |
622 | const char* basename = pakfire_basename(path); |
623 | const char* dirname = pakfire_dirname(path); | |
b12a5d7d | 624 | |
bbbc9842 | 625 | if (basename) |
b12a5d7d | 626 | pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, basename); |
b12a5d7d | 627 | |
bbbc9842 | 628 | if (dirname) |
b12a5d7d | 629 | pakfire_package_set_string(pkg, SOLVABLE_MEDIABASE, dirname); |
b12a5d7d MT |
630 | |
631 | pakfire_string_set(pkg->path, path); | |
632 | } | |
633 | ||
634 | // Removes epoch | |
635 | static const char* evr2vr(const char* evr) { | |
636 | const char* p = evr; | |
637 | ||
638 | // Skip any leading digits | |
639 | for (; *p >= '0' && *p <= '9'; p++); | |
640 | ||
641 | // If after the leading digits, we found :, we return the rest of the string | |
642 | if (p != evr && *p == ':') | |
643 | return ++p; | |
644 | ||
645 | return evr; | |
646 | } | |
647 | ||
31480bee | 648 | static const char* pakfire_package_make_filename(struct pakfire_package* pkg) { |
b12a5d7d MT |
649 | if (!*pkg->filename) { |
650 | const char* name = pakfire_package_get_name(pkg); | |
651 | const char* evr = pakfire_package_get_evr(pkg); | |
652 | const char* arch = pakfire_package_get_arch(pkg); | |
653 | ||
654 | if (!name || !evr || !arch) | |
655 | return NULL; | |
656 | ||
657 | const char* vr = evr2vr(evr); | |
658 | ||
659 | pakfire_string_format(pkg->filename, "%s-%s.%s.pfm", name, vr, arch); | |
660 | } | |
661 | ||
662 | return pkg->filename; | |
663 | } | |
664 | ||
31480bee | 665 | PAKFIRE_EXPORT const char* pakfire_package_get_filename(struct pakfire_package* pkg) { |
b12a5d7d MT |
666 | const char* filename = pakfire_package_get_string(pkg, SOLVABLE_MEDIAFILE); |
667 | ||
668 | // Generate the filename if not set | |
669 | if (!filename) | |
670 | filename = pakfire_package_make_filename(pkg); | |
671 | ||
672 | return filename; | |
221cc3ce MT |
673 | } |
674 | ||
31480bee | 675 | PAKFIRE_EXPORT void pakfire_package_set_filename(struct pakfire_package* pkg, const char* filename) { |
221cc3ce MT |
676 | pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, filename); |
677 | } | |
678 | ||
31480bee | 679 | PAKFIRE_EXPORT int pakfire_package_is_installed(struct pakfire_package* pkg) { |
0defa23e | 680 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); |
221cc3ce MT |
681 | Solvable* s = get_solvable(pkg); |
682 | ||
683 | return pool->installed == s->repo; | |
684 | } | |
685 | ||
27116707 | 686 | PAKFIRE_EXPORT size_t pakfire_package_get_downloadsize(struct pakfire_package* pkg) { |
221cc3ce MT |
687 | return pakfire_package_get_num(pkg, SOLVABLE_DOWNLOADSIZE); |
688 | } | |
689 | ||
27116707 | 690 | PAKFIRE_EXPORT void pakfire_package_set_downloadsize(struct pakfire_package* pkg, size_t downloadsize) { |
47b7aebd | 691 | pakfire_package_set_num(pkg, SOLVABLE_DOWNLOADSIZE, downloadsize); |
221cc3ce MT |
692 | } |
693 | ||
27116707 | 694 | PAKFIRE_EXPORT size_t pakfire_package_get_installsize(struct pakfire_package* pkg) { |
221cc3ce MT |
695 | return pakfire_package_get_num(pkg, SOLVABLE_INSTALLSIZE); |
696 | } | |
697 | ||
27116707 | 698 | PAKFIRE_EXPORT void pakfire_package_set_installsize(struct pakfire_package* pkg, size_t installsize) { |
47b7aebd | 699 | pakfire_package_set_num(pkg, SOLVABLE_INSTALLSIZE, installsize); |
221cc3ce MT |
700 | } |
701 | ||
27116707 | 702 | PAKFIRE_EXPORT size_t pakfire_package_get_size(struct pakfire_package* pkg) { |
221cc3ce MT |
703 | if (pakfire_package_is_installed(pkg)) |
704 | return pakfire_package_get_installsize(pkg); | |
705 | ||
706 | return pakfire_package_get_downloadsize(pkg); | |
707 | } | |
708 | ||
31480bee | 709 | PAKFIRE_EXPORT const char* pakfire_package_get_build_host(struct pakfire_package* pkg) { |
221cc3ce MT |
710 | return pakfire_package_get_string(pkg, SOLVABLE_BUILDHOST); |
711 | } | |
712 | ||
31480bee | 713 | PAKFIRE_EXPORT void pakfire_package_set_build_host(struct pakfire_package* pkg, const char* build_host) { |
2ffc704d | 714 | pakfire_package_set_string(pkg, SOLVABLE_BUILDHOST, build_host); |
221cc3ce MT |
715 | } |
716 | ||
31480bee | 717 | PAKFIRE_EXPORT const char* pakfire_package_get_build_id(struct pakfire_package* pkg) { |
7996020a MT |
718 | return pakfire_package_get_string(pkg, SOLVABLE_BUILDVERSION); |
719 | } | |
720 | ||
31480bee | 721 | PAKFIRE_EXPORT void pakfire_package_set_build_id(struct pakfire_package* pkg, const char* build_id) { |
7996020a MT |
722 | pakfire_package_set_string(pkg, SOLVABLE_BUILDVERSION, build_id); |
723 | } | |
724 | ||
57e2cf99 MT |
725 | void pakfire_package_set_build_id_from_uuid(struct pakfire_package* pkg, uuid_t* build_id) { |
726 | char buffer[UUID_STR_LEN]; | |
727 | ||
728 | // Convert the UUID to string | |
729 | uuid_unparse_lower(*build_id, buffer); | |
730 | ||
731 | pakfire_package_set_build_id(pkg, buffer); | |
732 | } | |
733 | ||
31480bee | 734 | PAKFIRE_EXPORT time_t pakfire_package_get_build_time(struct pakfire_package* pkg) { |
221cc3ce MT |
735 | return pakfire_package_get_num(pkg, SOLVABLE_BUILDTIME); |
736 | } | |
737 | ||
31480bee | 738 | PAKFIRE_EXPORT void pakfire_package_set_build_time(struct pakfire_package* pkg, time_t build_time) { |
2ffc704d | 739 | pakfire_package_set_num(pkg, SOLVABLE_BUILDTIME, build_time); |
221cc3ce MT |
740 | } |
741 | ||
31480bee | 742 | PAKFIRE_EXPORT time_t pakfire_package_get_install_time(struct pakfire_package* pkg) { |
221cc3ce MT |
743 | return pakfire_package_get_num(pkg, SOLVABLE_INSTALLTIME); |
744 | } | |
745 | ||
31480bee | 746 | PAKFIRE_EXPORT void pakfire_package_set_install_time(struct pakfire_package* pkg, time_t install_time) { |
af647c55 MT |
747 | pakfire_package_set_num(pkg, SOLVABLE_INSTALLTIME, install_time); |
748 | } | |
749 | ||
571539a7 MT |
750 | PAKFIRE_EXPORT const char* pakfire_package_get_source_package(struct pakfire_package* pkg) { |
751 | if (!*pkg->source_nevra) { | |
752 | const char* name = pakfire_package_get_source_name(pkg); | |
753 | const char* evr = pakfire_package_get_source_evr(pkg); | |
754 | const char* arch = pakfire_package_get_source_arch(pkg); | |
755 | ||
756 | // Return nothing if we don't have all information | |
757 | if (!name || !evr || !arch) | |
758 | return NULL; | |
759 | ||
760 | // Format package name | |
761 | pakfire_string_format(pkg->source_nevra, "%s-%s.%s", name, evr, arch); | |
762 | } | |
763 | ||
764 | return pkg->source_nevra; | |
765 | } | |
766 | ||
767 | PAKFIRE_EXPORT const char* pakfire_package_get_source_name(struct pakfire_package* pkg) { | |
768 | return pakfire_package_get_string(pkg, SOLVABLE_SOURCENAME); | |
769 | } | |
770 | ||
771 | PAKFIRE_EXPORT void pakfire_package_set_source_name(struct pakfire_package* pkg, const char* name) { | |
772 | pakfire_package_set_string(pkg, SOLVABLE_SOURCENAME, name); | |
773 | } | |
774 | ||
775 | PAKFIRE_EXPORT const char* pakfire_package_get_source_evr(struct pakfire_package* pkg) { | |
776 | return pakfire_package_get_string(pkg, SOLVABLE_SOURCEEVR); | |
777 | } | |
778 | ||
779 | PAKFIRE_EXPORT void pakfire_package_set_source_evr(struct pakfire_package* pkg, const char* evr) { | |
780 | // Skip empty epoch | |
781 | if (pakfire_string_startswith(evr, "0:")) | |
782 | evr += 2; | |
783 | ||
784 | pakfire_package_set_string(pkg, SOLVABLE_SOURCEEVR, evr); | |
785 | } | |
786 | ||
787 | PAKFIRE_EXPORT const char* pakfire_package_get_source_arch(struct pakfire_package* pkg) { | |
788 | return pakfire_package_get_string(pkg, SOLVABLE_SOURCEARCH); | |
789 | } | |
790 | ||
791 | PAKFIRE_EXPORT void pakfire_package_set_source_arch(struct pakfire_package* pkg, const char* arch) { | |
792 | pakfire_package_set_string(pkg, SOLVABLE_SOURCEARCH, arch); | |
793 | } | |
794 | ||
452d3833 | 795 | static char** pakfire_package_get_relationlist( |
31480bee | 796 | struct pakfire_package* pkg, Id type, Id marker) { |
452d3833 MT |
797 | char** array = NULL; |
798 | ||
221cc3ce MT |
799 | Queue q; |
800 | queue_init(&q); | |
801 | ||
802 | Solvable* s = get_solvable(pkg); | |
452d3833 MT |
803 | |
804 | // Fetch all deps | |
a9659851 | 805 | solvable_lookup_deparray(s, type, &q, marker); |
221cc3ce | 806 | |
452d3833 MT |
807 | // Nothing to do if the array was empty |
808 | if (!q.count) | |
809 | goto ERROR; | |
d6ea32df | 810 | |
452d3833 MT |
811 | // Allocate array |
812 | array = calloc(q.count + 1, sizeof(*array)); | |
813 | if (!array) | |
814 | goto ERROR; | |
815 | ||
816 | for (int i = 0; i < q.count; i++) { | |
b1171f6a | 817 | const char* dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); |
d6ea32df | 818 | |
452d3833 MT |
819 | array[i] = strdup(dep); |
820 | } | |
821 | ||
822 | ERROR: | |
823 | queue_free(&q); | |
824 | ||
825 | return array; | |
221cc3ce MT |
826 | } |
827 | ||
31480bee | 828 | static void pakfire_package_add_dep(struct pakfire_package* pkg, Id type, |
452d3833 | 829 | const char* dep, Id marker) { |
221cc3ce MT |
830 | Solvable* s = get_solvable(pkg); |
831 | ||
452d3833 | 832 | // Parse the dependency |
4abdf39d | 833 | Id id = pakfire_str2dep(pkg->pakfire, dep); |
452d3833 MT |
834 | if (!id) |
835 | return; | |
836 | ||
837 | solvable_add_deparray(s, type, id, marker); | |
221cc3ce MT |
838 | } |
839 | ||
31480bee | 840 | PAKFIRE_EXPORT char** pakfire_package_get_provides(struct pakfire_package* pkg) { |
063ca10f | 841 | return pakfire_package_get_relationlist(pkg, SOLVABLE_PROVIDES, -SOLVABLE_FILEMARKER); |
221cc3ce MT |
842 | } |
843 | ||
31480bee | 844 | void pakfire_package_add_provides(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 845 | pakfire_package_add_dep(pkg, SOLVABLE_PROVIDES, dep, -SOLVABLE_FILEMARKER); |
221cc3ce MT |
846 | } |
847 | ||
31480bee | 848 | PAKFIRE_EXPORT char** pakfire_package_get_prerequires(struct pakfire_package* pkg) { |
063ca10f | 849 | return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, SOLVABLE_PREREQMARKER); |
221cc3ce MT |
850 | } |
851 | ||
31480bee | 852 | void pakfire_package_add_prerequires(struct pakfire_package* pkg, const char* dep) { |
452d3833 MT |
853 | pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, SOLVABLE_PREREQMARKER); |
854 | } | |
855 | ||
31480bee | 856 | PAKFIRE_EXPORT char** pakfire_package_get_requires(struct pakfire_package* pkg) { |
063ca10f | 857 | return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES, -SOLVABLE_PREREQMARKER); |
221cc3ce MT |
858 | } |
859 | ||
31480bee | 860 | void pakfire_package_add_requires(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 861 | pakfire_package_add_dep(pkg, SOLVABLE_REQUIRES, dep, -SOLVABLE_PREREQMARKER); |
221cc3ce MT |
862 | } |
863 | ||
31480bee | 864 | PAKFIRE_EXPORT char** pakfire_package_get_conflicts(struct pakfire_package* pkg) { |
a9659851 | 865 | return pakfire_package_get_relationlist(pkg, SOLVABLE_CONFLICTS, 0); |
221cc3ce MT |
866 | } |
867 | ||
31480bee | 868 | void pakfire_package_add_conflicts(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 869 | pakfire_package_add_dep(pkg, SOLVABLE_CONFLICTS, dep, 0); |
221cc3ce MT |
870 | } |
871 | ||
31480bee | 872 | PAKFIRE_EXPORT char** pakfire_package_get_obsoletes(struct pakfire_package* pkg) { |
a9659851 | 873 | return pakfire_package_get_relationlist(pkg, SOLVABLE_OBSOLETES, 0); |
221cc3ce MT |
874 | } |
875 | ||
31480bee | 876 | void pakfire_package_add_obsoletes(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 877 | pakfire_package_add_dep(pkg, SOLVABLE_OBSOLETES, dep, 0); |
221cc3ce MT |
878 | } |
879 | ||
31480bee | 880 | PAKFIRE_EXPORT char** pakfire_package_get_recommends(struct pakfire_package* pkg) { |
a9659851 | 881 | return pakfire_package_get_relationlist(pkg, SOLVABLE_RECOMMENDS, 0); |
221cc3ce MT |
882 | } |
883 | ||
31480bee | 884 | void pakfire_package_add_recommends(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 885 | pakfire_package_add_dep(pkg, SOLVABLE_RECOMMENDS, dep, 0); |
221cc3ce MT |
886 | } |
887 | ||
31480bee | 888 | PAKFIRE_EXPORT char** pakfire_package_get_suggests(struct pakfire_package* pkg) { |
a9659851 | 889 | return pakfire_package_get_relationlist(pkg, SOLVABLE_SUGGESTS, 0); |
221cc3ce MT |
890 | } |
891 | ||
31480bee | 892 | void pakfire_package_add_suggests(struct pakfire_package* pkg, const char* dep) { |
452d3833 | 893 | pakfire_package_add_dep(pkg, SOLVABLE_SUGGESTS, dep, 0); |
221cc3ce MT |
894 | } |
895 | ||
31480bee | 896 | PAKFIRE_EXPORT char** pakfire_package_get_supplements(struct pakfire_package* pkg) { |
8fe2e4ba MT |
897 | return pakfire_package_get_relationlist(pkg, SOLVABLE_SUPPLEMENTS, 0); |
898 | } | |
899 | ||
31480bee | 900 | void pakfire_package_add_supplements(struct pakfire_package* pkg, const char* dep) { |
452d3833 MT |
901 | pakfire_package_add_dep(pkg, SOLVABLE_SUPPLEMENTS, dep, 0); |
902 | } | |
903 | ||
31480bee | 904 | PAKFIRE_EXPORT char** pakfire_package_get_enhances(struct pakfire_package* pkg) { |
8fe2e4ba MT |
905 | return pakfire_package_get_relationlist(pkg, SOLVABLE_ENHANCES, 0); |
906 | } | |
907 | ||
31480bee | 908 | void pakfire_package_add_enhances(struct pakfire_package* pkg, const char* dep) { |
452d3833 MT |
909 | pakfire_package_add_dep(pkg, SOLVABLE_ENHANCES, dep, 0); |
910 | } | |
911 | ||
31480bee | 912 | PAKFIRE_EXPORT int pakfire_package_get_reverse_requires(struct pakfire_package* pkg, |
e1d77c57 MT |
913 | struct pakfire_packagelist** list) { |
914 | Queue matches; | |
915 | queue_init(&matches); | |
916 | ||
917 | // Reset pointer | |
918 | *list = NULL; | |
919 | ||
920 | Pool* pool = pakfire_get_solv_pool(pkg->pakfire); | |
921 | ||
922 | // Search for any matches | |
923 | pool_whatmatchessolvable(pool, SOLVABLE_REQUIRES, pkg->id, &matches, 0); | |
924 | ||
925 | // Create a new package list | |
926 | int r = pakfire_packagelist_create_from_queue(list, pkg->pakfire, &matches); | |
927 | if (r) | |
928 | goto ERROR; | |
929 | ||
930 | ERROR: | |
931 | queue_free(&matches); | |
932 | ||
933 | return r; | |
934 | } | |
935 | ||
555b6dd2 MT |
936 | static int pakfire_package_has_rich_deps_in_deparray( |
937 | struct pakfire_package* pkg, Id type) { | |
938 | int r = 0; | |
939 | ||
940 | Solvable* s = get_solvable(pkg); | |
941 | ||
942 | Queue q; | |
943 | queue_init(&q); | |
944 | ||
945 | // Fetch all deps | |
946 | solvable_lookup_deparray(s, type, &q, 0); | |
947 | ||
948 | // Nothing to do if the array was empty | |
949 | if (!q.count) | |
950 | goto ERROR; | |
951 | ||
952 | for (int i = 0; i < q.count; i++) { | |
953 | const char* dep = pakfire_dep2str(pkg->pakfire, q.elements[i]); | |
954 | ||
955 | // Is this a rich dependency? | |
956 | if (dep && *dep == '(') { | |
957 | r = 1; | |
958 | break; | |
959 | } | |
960 | } | |
961 | ||
962 | ERROR: | |
963 | queue_free(&q); | |
964 | ||
965 | return r; | |
966 | } | |
967 | ||
968 | int pakfire_package_has_rich_deps(struct pakfire_package* pkg) { | |
969 | static const Id types[] = { | |
970 | // Requires (includes pre-requires) | |
971 | SOLVABLE_REQUIRES, | |
972 | SOLVABLE_PROVIDES, | |
973 | SOLVABLE_CONFLICTS, | |
974 | SOLVABLE_OBSOLETES, | |
975 | SOLVABLE_RECOMMENDS, | |
976 | SOLVABLE_SUGGESTS, | |
977 | SOLVABLE_SUPPLEMENTS, | |
978 | SOLVABLE_ENHANCES, | |
979 | 0, | |
980 | }; | |
981 | ||
982 | for (const Id* type = types; *type; type++) { | |
983 | int r = pakfire_package_has_rich_deps_in_deparray(pkg, *type); | |
984 | if (r) | |
985 | return r; | |
986 | } | |
987 | ||
988 | // No match | |
989 | return 0; | |
990 | } | |
991 | ||
4651122b | 992 | PAKFIRE_EXPORT struct pakfire_repo* pakfire_package_get_repo(struct pakfire_package* pkg) { |
e9d9eadc MT |
993 | if (!pkg->repo) { |
994 | Solvable* s = get_solvable(pkg); | |
995 | ||
996 | pkg->repo = pakfire_repo_create_from_repo(pkg->pakfire, s->repo); | |
997 | } | |
221cc3ce | 998 | |
e9d9eadc | 999 | return pakfire_repo_ref(pkg->repo); |
221cc3ce MT |
1000 | } |
1001 | ||
221cc3ce MT |
1002 | static void pakfire_package_dump_add_line(char** str, const char* key, const char* val) { |
1003 | if (val) | |
1004 | asprintf(str, "%s%-15s: %s\n", *str, key ? key : "", val); | |
1005 | } | |
1006 | ||
1007 | static void pakfire_package_dump_add_lines(char** str, const char* key, const char* val) { | |
d973a13d | 1008 | char** lines = pakfire_string_split(val, '\n'); |
7500066c MT |
1009 | if (!lines) |
1010 | return; | |
221cc3ce | 1011 | |
7500066c MT |
1012 | while (*lines) { |
1013 | pakfire_package_dump_add_line(str, key, *lines); | |
1014 | lines++; | |
221cc3ce MT |
1015 | } |
1016 | } | |
1017 | ||
5cf4a7a1 MT |
1018 | static void pakfire_package_dump_add_line_date(char** str, const char* key, time_t date) { |
1019 | char buffer[1024]; | |
1020 | int r; | |
221cc3ce | 1021 | |
5cf4a7a1 MT |
1022 | // Format time |
1023 | r = pakfire_strftime(buffer, "%a, %d %b %Y %T %z", date); | |
1024 | if (r) | |
1025 | return; | |
221cc3ce | 1026 | |
5cf4a7a1 | 1027 | pakfire_package_dump_add_line(str, key, buffer); |
221cc3ce MT |
1028 | } |
1029 | ||
27116707 | 1030 | static void pakfire_package_dump_add_line_size(char** str, const char* key, size_t size) { |
cc90545a | 1031 | char buffer[128]; |
9b0e3d52 MT |
1032 | |
1033 | // Format size in human-readable format | |
1034 | int r = pakfire_format_size(buffer, size); | |
1035 | if (r < 0) | |
1036 | return; | |
221cc3ce | 1037 | |
cc90545a | 1038 | pakfire_package_dump_add_line(str, key, buffer); |
221cc3ce MT |
1039 | } |
1040 | ||
7db0d073 MT |
1041 | static int pakfire_sort_dependencies(const void* p1, const void* p2) { |
1042 | const char* dep1 = *(const char**)p1; | |
1043 | const char* dep2 = *(const char**)p2; | |
1044 | ||
1045 | return strcmp(dep1, dep2); | |
1046 | } | |
1047 | ||
31480bee | 1048 | PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags) { |
221cc3ce MT |
1049 | char* string = ""; |
1050 | ||
1051 | // Name | |
1052 | const char* name = pakfire_package_get_name(pkg); | |
1053 | pakfire_package_dump_add_line(&string, _("Name"), name); | |
1054 | ||
6ed66687 MT |
1055 | // EVR |
1056 | const char* evr = pakfire_package_get_evr(pkg); | |
1057 | pakfire_package_dump_add_line(&string, _("Version"), evr); | |
221cc3ce | 1058 | |
6ed66687 MT |
1059 | // Arch |
1060 | const char* arch = pakfire_package_get_arch(pkg); | |
1061 | pakfire_package_dump_add_line(&string, _("Arch"), arch); | |
221cc3ce MT |
1062 | |
1063 | // Size | |
27116707 | 1064 | size_t size = pakfire_package_get_size(pkg); |
c2737936 MT |
1065 | if (size) |
1066 | pakfire_package_dump_add_line_size(&string, _("Size"), size); | |
221cc3ce | 1067 | |
d0f0d507 | 1068 | // Installed Size |
221cc3ce | 1069 | if (pakfire_package_is_installed(pkg)) { |
27116707 | 1070 | size_t installsize = pakfire_package_get_installsize(pkg); |
d0f0d507 MT |
1071 | if (installsize) |
1072 | pakfire_package_dump_add_line_size(&string, _("Installed Size"), installsize); | |
221cc3ce | 1073 | |
d0f0d507 | 1074 | // Download Size |
221cc3ce | 1075 | } else { |
27116707 | 1076 | size_t downloadsize = pakfire_package_get_downloadsize(pkg); |
d0f0d507 MT |
1077 | if (downloadsize) |
1078 | pakfire_package_dump_add_line_size(&string, _("Download Size"), downloadsize); | |
221cc3ce MT |
1079 | } |
1080 | ||
d0f0d507 | 1081 | // Repository |
4651122b | 1082 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
221cc3ce | 1083 | if (repo) { |
866aa605 | 1084 | if (!pakfire_repo_name_equals(repo, PAKFIRE_REPO_DUMMY)) { |
a4292569 MT |
1085 | const char* repo_name = pakfire_repo_get_name(repo); |
1086 | pakfire_package_dump_add_line(&string, _("Repo"), repo_name); | |
1087 | } | |
221cc3ce | 1088 | |
3ff6aee6 | 1089 | pakfire_repo_unref(repo); |
221cc3ce MT |
1090 | } |
1091 | ||
1092 | // Summary | |
1093 | const char* summary = pakfire_package_get_summary(pkg); | |
1094 | pakfire_package_dump_add_line(&string, _("Summary"), summary); | |
1095 | ||
1096 | // Description | |
1097 | const char* description = pakfire_package_get_description(pkg); | |
1b99c676 MT |
1098 | if (description) |
1099 | pakfire_package_dump_add_lines(&string, _("Description"), description); | |
221cc3ce MT |
1100 | |
1101 | // Groups | |
7ccc9d74 | 1102 | const char* groups = pakfire_package_get_groups(pkg); |
2141b578 | 1103 | if (groups) { |
7ccc9d74 | 1104 | pakfire_package_dump_add_lines(&string, _("Groups"), groups); |
2141b578 | 1105 | } |
221cc3ce MT |
1106 | |
1107 | // URL | |
1108 | const char* url = pakfire_package_get_url(pkg); | |
1109 | pakfire_package_dump_add_line(&string, _("URL"), url); | |
1110 | ||
1111 | // License | |
1112 | const char* license = pakfire_package_get_license(pkg); | |
1113 | pakfire_package_dump_add_line(&string, _("License"), license); | |
1114 | ||
1115 | if (flags & PAKFIRE_PKG_DUMP_LONG) { | |
af647c55 MT |
1116 | // Install Time |
1117 | time_t install_time = pakfire_package_get_install_time(pkg); | |
1118 | if (install_time) { | |
1119 | pakfire_package_dump_add_line_date(&string, _("Install Time"), install_time); | |
1120 | } | |
1121 | ||
221cc3ce MT |
1122 | // Maintainer |
1123 | const char* maintainer = pakfire_package_get_maintainer(pkg); | |
1124 | pakfire_package_dump_add_line(&string, _("Maintainer"), maintainer); | |
1125 | ||
1126 | // Vendor | |
1127 | const char* vendor = pakfire_package_get_vendor(pkg); | |
1128 | pakfire_package_dump_add_line(&string, _("Vendor"), vendor); | |
1129 | ||
1130 | // UUID | |
1131 | const char* uuid = pakfire_package_get_uuid(pkg); | |
1132 | pakfire_package_dump_add_line(&string, _("UUID"), uuid); | |
1133 | ||
7996020a MT |
1134 | // Build ID |
1135 | const char* build_id = pakfire_package_get_build_id(pkg); | |
1136 | if (build_id) | |
1137 | pakfire_package_dump_add_line(&string, _("Build ID"), build_id); | |
1138 | ||
c52e0148 | 1139 | enum pakfire_digest_types digest = 0; |
e61716e4 MT |
1140 | |
1141 | // Digest | |
1142 | const char* hexdigest = pakfire_package_get_hexdigest(pkg, &digest); | |
1143 | switch (digest) { | |
4500ed0a | 1144 | case PAKFIRE_DIGEST_SHA2_512: |
e61716e4 MT |
1145 | pakfire_package_dump_add_line(&string, _("SHA512 Digest"), hexdigest); |
1146 | break; | |
b28af23a | 1147 | |
4500ed0a | 1148 | case PAKFIRE_DIGEST_SHA2_256: |
e61716e4 | 1149 | pakfire_package_dump_add_line(&string, _("SHA256 Digest"), hexdigest); |
5e8dfbeb | 1150 | break; |
2c4b4a02 | 1151 | |
d98740de MT |
1152 | case PAKFIRE_DIGEST_SHA3_512: |
1153 | case PAKFIRE_DIGEST_SHA3_256: | |
f1e6c5df MT |
1154 | case PAKFIRE_DIGEST_BLAKE2B512: |
1155 | case PAKFIRE_DIGEST_BLAKE2S256: | |
2c4b4a02 MT |
1156 | case PAKFIRE_DIGEST_UNDEFINED: |
1157 | break; | |
e61716e4 | 1158 | } |
b28af23a | 1159 | |
571539a7 MT |
1160 | // Source package |
1161 | const char* source_package = pakfire_package_get_source_package(pkg); | |
1162 | if (source_package) | |
1163 | pakfire_package_dump_add_line(&string, _("Source Package"), source_package); | |
1164 | ||
221cc3ce | 1165 | // Build time |
2ffc704d MT |
1166 | time_t build_time = pakfire_package_get_build_time(pkg); |
1167 | pakfire_package_dump_add_line_date(&string, _("Build Time"), build_time); | |
221cc3ce MT |
1168 | |
1169 | // Build host | |
2ffc704d MT |
1170 | const char* build_host = pakfire_package_get_build_host(pkg); |
1171 | pakfire_package_dump_add_line(&string, _("Build Host"), build_host); | |
221cc3ce | 1172 | |
2f873877 MT |
1173 | // Dependencies |
1174 | ||
1175 | const struct relation { | |
1176 | const char* name; | |
31480bee | 1177 | char** (*get)(struct pakfire_package* pkg); |
2f873877 MT |
1178 | } relations[] = { |
1179 | { _("Provides"), pakfire_package_get_provides, }, | |
1180 | { _("Pre-Requires"), pakfire_package_get_prerequires, }, | |
1181 | { _("Requires"), pakfire_package_get_requires, }, | |
1182 | { _("Conflicts"), pakfire_package_get_conflicts, }, | |
1183 | { _("Obsoletes"), pakfire_package_get_obsoletes, }, | |
1184 | { _("Recommends"), pakfire_package_get_recommends, }, | |
1185 | { _("Suggests"), pakfire_package_get_suggests, }, | |
8fe2e4ba MT |
1186 | { _("Supplements"), pakfire_package_get_supplements, }, |
1187 | { _("Enhances"), pakfire_package_get_enhances, }, | |
2f873877 MT |
1188 | { NULL, NULL}, |
1189 | }; | |
1190 | ||
1191 | for (const struct relation* relation = relations; relation->name; relation++) { | |
7db0d073 MT |
1192 | char** deps = relation->get(pkg); |
1193 | if (deps) { | |
23b93958 | 1194 | name = relation->name; |
7db0d073 MT |
1195 | size_t count = 0; |
1196 | ||
1197 | // Count elements in the list | |
1198 | for (char** dep = deps; *dep; dep++) | |
1199 | count++; | |
1200 | ||
1201 | // Sort the list | |
1202 | qsort(deps, count, sizeof(*deps), pakfire_sort_dependencies); | |
1203 | ||
1204 | // Write it to the console | |
1205 | for (char** dep = deps; *dep; dep++) { | |
e650b3ee | 1206 | pakfire_package_dump_add_line(&string, name, *dep); |
452d3833 | 1207 | free(*dep); |
e650b3ee MT |
1208 | |
1209 | // Clear name after first line | |
1210 | name = NULL; | |
452d3833 | 1211 | } |
7db0d073 | 1212 | free(deps); |
2f873877 | 1213 | } |
221cc3ce MT |
1214 | } |
1215 | } | |
1216 | ||
1217 | if (flags & PAKFIRE_PKG_DUMP_FILELIST) { | |
1bbbfb9e | 1218 | struct pakfire_filelist* filelist = pakfire_package_get_filelist(pkg); |
5e9463ec MT |
1219 | |
1220 | const char* prefix = _("Filelist"); | |
1221 | ||
1222 | for (unsigned int i = 0; i < pakfire_filelist_size(filelist); i++) { | |
5803b5f6 | 1223 | struct pakfire_file* file = pakfire_filelist_get(filelist, i); |
221cc3ce | 1224 | |
32485f6c MT |
1225 | const char* path = pakfire_file_get_path(file); |
1226 | pakfire_package_dump_add_line(&string, prefix, path); | |
221cc3ce | 1227 | |
5e9463ec | 1228 | pakfire_file_unref(file); |
221cc3ce | 1229 | |
5e9463ec | 1230 | // Only prefix the first line |
221cc3ce MT |
1231 | prefix = NULL; |
1232 | } | |
5e9463ec MT |
1233 | |
1234 | pakfire_filelist_unref(filelist); | |
221cc3ce MT |
1235 | } |
1236 | ||
1237 | return string; | |
1238 | } | |
1239 | ||
900faa2f | 1240 | PAKFIRE_EXPORT struct pakfire_archive* pakfire_package_get_archive(struct pakfire_package* pkg) { |
9686a82a | 1241 | struct pakfire_archive* archive = NULL; |
b12a5d7d | 1242 | |
cbed1552 | 1243 | // Otherwise open the archive from the cache |
b12a5d7d | 1244 | const char* path = pakfire_package_get_path(pkg); |
641cab18 MT |
1245 | if (!path) |
1246 | return NULL; | |
cbed1552 | 1247 | |
641cab18 | 1248 | // Open archive |
cf3e773a | 1249 | int r = pakfire_archive_open(&archive, pkg->pakfire, path); |
9686a82a MT |
1250 | if (r) |
1251 | return NULL; | |
cbed1552 | 1252 | |
9686a82a | 1253 | return archive; |
cbed1552 MT |
1254 | } |
1255 | ||
1bbbfb9e | 1256 | static int pakfire_package_fetch_legacy_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) { |
221cc3ce MT |
1257 | pakfire_package_internalize_repo(pkg); |
1258 | ||
4651122b | 1259 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
221cc3ce | 1260 | Solvable* s = get_solvable(pkg); |
23b93958 | 1261 | Repo* _repo = pakfire_repo_get_repo(repo); |
5e9463ec | 1262 | pakfire_repo_unref(repo); |
221cc3ce MT |
1263 | |
1264 | int found_marker = 0; | |
1265 | ||
1266 | Id id, *ids; | |
23b93958 | 1267 | ids = _repo->idarraydata + s->provides; |
221cc3ce | 1268 | while((id = *ids++) != 0) { |
b1171f6a | 1269 | const char* path = pakfire_dep2str(pkg->pakfire, id); |
221cc3ce MT |
1270 | |
1271 | if (found_marker) { | |
5803b5f6 | 1272 | struct pakfire_file* file; |
221cc3ce | 1273 | |
883b3be9 | 1274 | int r = pakfire_file_create(&file, pkg->pakfire); |
5e9463ec MT |
1275 | if (r) |
1276 | return r; | |
1277 | ||
32485f6c MT |
1278 | // Set path |
1279 | pakfire_file_set_path(file, path); | |
5e9463ec | 1280 | |
f4560c3f | 1281 | r = pakfire_filelist_append(filelist, file); |
5e9463ec MT |
1282 | if (r) |
1283 | return r; | |
1284 | ||
1285 | pakfire_file_unref(file); | |
221cc3ce MT |
1286 | continue; |
1287 | } | |
1288 | ||
614a3dc8 | 1289 | if (strcmp(path, "solvable:filemarker") == 0) |
221cc3ce MT |
1290 | ++found_marker; |
1291 | } | |
1292 | ||
5e9463ec | 1293 | return 0; |
221cc3ce MT |
1294 | } |
1295 | ||
1bbbfb9e | 1296 | static int pakfire_package_fetch_filelist(struct pakfire_package* pkg, struct pakfire_filelist* filelist) { |
5e9463ec MT |
1297 | int r; |
1298 | ||
221cc3ce MT |
1299 | pakfire_package_internalize_repo(pkg); |
1300 | ||
96c6c8f6 | 1301 | Solvable* s = get_solvable(pkg); |
221cc3ce MT |
1302 | |
1303 | Dataiterator di; | |
96c6c8f6 | 1304 | dataiterator_init(&di, s->repo->pool, s->repo, pkg->id, |
221cc3ce | 1305 | SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST); |
5e9463ec | 1306 | |
221cc3ce | 1307 | while (dataiterator_step(&di)) { |
5803b5f6 | 1308 | struct pakfire_file* file; |
221cc3ce | 1309 | |
883b3be9 | 1310 | r = pakfire_file_create(&file, pkg->pakfire); |
5e9463ec MT |
1311 | if (r) |
1312 | return r; | |
221cc3ce | 1313 | |
32485f6c | 1314 | pakfire_file_set_path(file, di.kv.str); |
221cc3ce | 1315 | |
5e9463ec | 1316 | // Append to filelist |
f4560c3f | 1317 | pakfire_filelist_append(filelist, file); |
5e9463ec | 1318 | pakfire_file_unref(file); |
221cc3ce | 1319 | } |
5e9463ec | 1320 | dataiterator_free(&di); |
221cc3ce MT |
1321 | |
1322 | // If the file list is empty, we fall back to read files | |
1323 | // in the older format. | |
f4560c3f MT |
1324 | if (pakfire_filelist_is_empty(filelist)) { |
1325 | r = pakfire_package_fetch_legacy_filelist(pkg, filelist); | |
5e9463ec MT |
1326 | if (r) |
1327 | return r; | |
1328 | } | |
1329 | ||
1330 | // Sort the list | |
f4560c3f | 1331 | pakfire_filelist_sort(filelist); |
221cc3ce | 1332 | |
5e9463ec | 1333 | return 0; |
221cc3ce MT |
1334 | } |
1335 | ||
1bbbfb9e | 1336 | PAKFIRE_EXPORT struct pakfire_filelist* pakfire_package_get_filelist(struct pakfire_package* pkg) { |
f78f6159 | 1337 | struct pakfire_filelist* filelist = NULL; |
5e9463ec | 1338 | |
f78f6159 | 1339 | // Create a new filelist |
883b3be9 | 1340 | int r = pakfire_filelist_create(&filelist, pkg->pakfire); |
f4560c3f | 1341 | if (r) |
f78f6159 | 1342 | goto ERROR; |
5e9463ec | 1343 | |
f78f6159 | 1344 | // Fetch all entries from the repository database |
f4560c3f | 1345 | r = pakfire_package_fetch_filelist(pkg, filelist); |
f78f6159 MT |
1346 | if (r) |
1347 | goto ERROR; | |
221cc3ce | 1348 | |
f4560c3f | 1349 | return filelist; |
f78f6159 MT |
1350 | |
1351 | ERROR: | |
1352 | if (filelist) | |
1353 | pakfire_filelist_unref(filelist); | |
1354 | ||
1355 | return NULL; | |
221cc3ce MT |
1356 | } |
1357 | ||
31480bee | 1358 | static int pakfire_package_append_file(struct pakfire_package* pkg, const char* path) { |
5e9463ec | 1359 | // Fetch repodata |
4651122b | 1360 | struct pakfire_repo* repo = pakfire_package_get_repo(pkg); |
3ff6aee6 | 1361 | Repodata* repodata = pakfire_repo_get_repodata(repo); |
5e9463ec | 1362 | pakfire_repo_unref(repo); |
221cc3ce | 1363 | |
bbbc9842 MT |
1364 | const char* basename = pakfire_basename(path); |
1365 | const char* dirname = pakfire_dirname(path); | |
d995f7fc MT |
1366 | |
1367 | // Convert directory into ID | |
1368 | Id did = repodata_str2dir(repodata, dirname, 1); | |
1369 | if (!did) | |
1370 | did = repodata_str2dir(repodata, "/", 1); | |
1371 | ||
1372 | // Add data to list | |
94db84fc | 1373 | repodata_add_dirstr(repodata, pkg->id, |
d995f7fc MT |
1374 | SOLVABLE_FILELIST, did, basename); |
1375 | ||
d995f7fc MT |
1376 | return 0; |
1377 | } | |
1378 | ||
30ab941e MT |
1379 | static int __pakfire_package_set_filelist(struct pakfire* pakfire, |
1380 | struct pakfire_file* file, void* data) { | |
1381 | struct pakfire_package* pkg = (struct pakfire_package*)data; | |
221cc3ce | 1382 | |
30ab941e MT |
1383 | // Fetch the path |
1384 | const char* path = pakfire_file_get_path(file); | |
d995f7fc | 1385 | |
30ab941e MT |
1386 | return pakfire_package_append_file(pkg, path); |
1387 | } | |
d995f7fc | 1388 | |
30ab941e MT |
1389 | PAKFIRE_EXPORT int pakfire_package_set_filelist( |
1390 | struct pakfire_package* pkg, struct pakfire_filelist* filelist) { | |
1391 | return pakfire_filelist_walk(filelist, __pakfire_package_set_filelist, pkg); | |
d995f7fc | 1392 | } |
221cc3ce | 1393 | |
31480bee | 1394 | int pakfire_package_set_filelist_from_string(struct pakfire_package* pkg, const char* files) { |
731f1d42 MT |
1395 | char* p = NULL; |
1396 | int r = 0; | |
d995f7fc | 1397 | |
731f1d42 MT |
1398 | // Copy files |
1399 | char* buffer = strdup(files); | |
1400 | if (!buffer) | |
1401 | goto ERROR; | |
d995f7fc | 1402 | |
731f1d42 MT |
1403 | // Walk through all files |
1404 | char* path = strtok_r(buffer, "\n", &p); | |
1405 | while (path) { | |
1406 | r = pakfire_package_append_file(pkg, path); | |
d995f7fc | 1407 | if (r) |
731f1d42 | 1408 | goto ERROR; |
d995f7fc | 1409 | |
731f1d42 | 1410 | path = strtok_r(NULL, "\n", &p); |
5e9463ec | 1411 | } |
221cc3ce | 1412 | |
731f1d42 MT |
1413 | ERROR: |
1414 | if (buffer) | |
1415 | free(buffer); | |
1416 | ||
1417 | return r; | |
221cc3ce | 1418 | } |
b59c9fa2 MT |
1419 | |
1420 | static int _pakfire_package_add_json_dependencies( | |
1421 | struct pakfire_package* pkg, | |
1422 | struct json_object* json, | |
1423 | const char* name, | |
1424 | char** (*func)(struct pakfire_package* pkg)) { | |
1425 | // Fetch dependencies | |
1426 | char** dependencies = func(pkg); | |
1427 | ||
1428 | // Nothing to do if there are no dependencies | |
1429 | if (!dependencies) | |
1430 | return 0; | |
1431 | ||
1432 | // Add dependencies | |
1433 | int r = pakfire_json_add_string_array(pkg->pakfire, json, name, dependencies); | |
1434 | if (r) | |
1435 | goto ERROR; | |
1436 | ||
1437 | ERROR: | |
1438 | if (dependencies) { | |
1439 | for (char** dep = dependencies; *dep; dep++) | |
1440 | free(*dep); | |
1441 | free(dependencies); | |
1442 | } | |
1443 | ||
1444 | return r; | |
1445 | } | |
1446 | ||
1447 | static int pakfire_package_add_json_dependencies( | |
1448 | struct pakfire_package* pkg, struct json_object* md) { | |
1449 | int r = 0; | |
1450 | ||
1451 | // Create new dependencies object | |
1452 | struct json_object* object = json_object_new_object(); | |
1453 | if (!object) | |
1454 | return 1; | |
1455 | ||
1456 | // Pre-requires | |
1457 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1458 | "prerequires", pakfire_package_get_prerequires); | |
1459 | if (r) | |
1460 | goto ERROR; | |
1461 | ||
1462 | // Requires | |
1463 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1464 | "requires", pakfire_package_get_requires); | |
1465 | if (r) | |
1466 | goto ERROR; | |
1467 | ||
1468 | // Provides | |
1469 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1470 | "provides", pakfire_package_get_provides); | |
1471 | if (r) | |
1472 | goto ERROR; | |
1473 | ||
1474 | // Conflicts | |
1475 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1476 | "conflicts", pakfire_package_get_conflicts); | |
1477 | if (r) | |
1478 | goto ERROR; | |
1479 | ||
1480 | // Obsoletes | |
1481 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1482 | "obsoletes", pakfire_package_get_obsoletes); | |
1483 | if (r) | |
1484 | goto ERROR; | |
1485 | ||
1486 | // Recommends | |
1487 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1488 | "recommends", pakfire_package_get_recommends); | |
1489 | if (r) | |
1490 | goto ERROR; | |
1491 | ||
1492 | // Suggests | |
1493 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1494 | "suggests", pakfire_package_get_suggests); | |
1495 | if (r) | |
1496 | goto ERROR; | |
1497 | ||
1498 | // Supplements | |
1499 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1500 | "supplements", pakfire_package_get_supplements); | |
1501 | if (r) | |
1502 | goto ERROR; | |
1503 | ||
1504 | // Enhances | |
1505 | r = _pakfire_package_add_json_dependencies(pkg, object, | |
1506 | "enhances", pakfire_package_get_enhances); | |
1507 | if (r) | |
1508 | goto ERROR; | |
1509 | ||
1510 | // Add object | |
1511 | r = json_object_object_add(md, "dependencies", object); | |
1512 | if (r) | |
1513 | goto ERROR; | |
1514 | ||
1515 | ERROR: | |
1516 | if (r) | |
1517 | json_object_put(object); | |
1518 | ||
1519 | return r; | |
1520 | } | |
1521 | ||
1522 | static int pakfire_package_add_build_metadata(struct pakfire_package* pkg, | |
1523 | struct json_object* md) { | |
1524 | int r; | |
1525 | ||
1526 | // Create a new JSON object | |
1527 | struct json_object* object = json_object_new_object(); | |
1528 | if (!object) | |
1529 | return 1; | |
1530 | ||
1531 | // Add pakfire version that generated this metadata | |
1532 | r = pakfire_json_add_string(pkg->pakfire, object, "pakfire", PACKAGE_VERSION); | |
1533 | if (r) | |
1534 | goto ERROR; | |
1535 | ||
1536 | // Write build host | |
1537 | const char* build_host = pakfire_package_get_build_host(pkg); | |
1538 | if (build_host) { | |
1539 | r = pakfire_json_add_string(pkg->pakfire, object, "host", build_host); | |
1540 | if (r) | |
1541 | goto ERROR; | |
1542 | } | |
1543 | ||
1544 | // Write build id | |
1545 | const char* build_id = pakfire_package_get_build_id(pkg); | |
1546 | if (build_id) { | |
1547 | r = pakfire_json_add_string(pkg->pakfire, object, "id", build_id); | |
1548 | if (r) | |
1549 | goto ERROR; | |
1550 | } | |
1551 | ||
1552 | // Write build host | |
1553 | time_t build_time = pakfire_package_get_build_time(pkg); | |
1554 | if (build_time) { | |
1555 | r = pakfire_json_add_integer(pkg->pakfire, object, "time", build_time); | |
1556 | if (r) | |
1557 | goto ERROR; | |
1558 | } | |
1559 | ||
571539a7 MT |
1560 | // Source package name |
1561 | const char* name = pakfire_package_get_source_name(pkg); | |
1562 | if (name) { | |
1563 | r = pakfire_json_add_string(pkg->pakfire, object, "source-name", name); | |
1564 | if (r) | |
1565 | goto ERROR; | |
1566 | } | |
1567 | ||
1568 | // Source package EVR | |
1569 | const char* evr = pakfire_package_get_source_evr(pkg); | |
1570 | if (evr) { | |
1571 | r = pakfire_json_add_string(pkg->pakfire, object, "source-evr", evr); | |
1572 | if (r) | |
1573 | goto ERROR; | |
1574 | } | |
1575 | ||
1576 | // Source package arch | |
1577 | const char* arch = pakfire_package_get_source_arch(pkg); | |
1578 | if (arch) { | |
1579 | r = pakfire_json_add_string(pkg->pakfire, object, "source-arch", arch); | |
1580 | if (r) | |
1581 | goto ERROR; | |
1582 | } | |
1583 | ||
b59c9fa2 MT |
1584 | // Add object |
1585 | r = json_object_object_add(md, "build", object); | |
1586 | if (r) | |
1587 | goto ERROR; | |
1588 | ||
1589 | ERROR: | |
1590 | if (r) | |
1591 | json_object_put(object); | |
1592 | ||
1593 | return r; | |
1594 | } | |
1595 | ||
1596 | struct json_object* pakfire_package_to_json(struct pakfire_package* pkg) { | |
1597 | struct json_object* md = json_object_new_object(); | |
1598 | int r = 0; | |
1599 | ||
1600 | // Name | |
1601 | const char* name = pakfire_package_get_name(pkg); | |
1602 | if (name) { | |
1603 | r = pakfire_json_add_string(pkg->pakfire, md, "name", name); | |
1604 | if (r) | |
1605 | goto ERROR; | |
1606 | } | |
1607 | ||
1608 | // EVR | |
1609 | const char* evr = pakfire_package_get_evr(pkg); | |
1610 | if (evr) { | |
1611 | r = pakfire_json_add_string(pkg->pakfire, md, "evr", evr); | |
1612 | if (r) | |
1613 | goto ERROR; | |
1614 | } | |
1615 | ||
1616 | // Arch | |
1617 | const char* arch = pakfire_package_get_arch(pkg); | |
1618 | if (arch) { | |
1619 | r = pakfire_json_add_string(pkg->pakfire, md, "arch", arch); | |
1620 | if (r) | |
1621 | goto ERROR; | |
1622 | } | |
1623 | ||
d9475a74 MT |
1624 | // Vendor |
1625 | const char* vendor = pakfire_package_get_vendor(pkg); | |
1626 | if (vendor) { | |
1627 | r = pakfire_json_add_string(pkg->pakfire, md, "vendor", vendor); | |
1628 | if (r) | |
1629 | goto ERROR; | |
1630 | } | |
1631 | ||
ca002cae MT |
1632 | // Distribution |
1633 | const char* distribution = pakfire_package_get_distribution(pkg); | |
1634 | if (distribution) { | |
1635 | r = pakfire_json_add_string(pkg->pakfire, md, "distribution", distribution); | |
1636 | if (r) | |
1637 | goto ERROR; | |
1638 | } | |
1639 | ||
b59c9fa2 MT |
1640 | // UUID |
1641 | const char* uuid = pakfire_package_get_uuid(pkg); | |
1642 | if (uuid) { | |
1643 | r = pakfire_json_add_string(pkg->pakfire, md, "uuid", uuid); | |
1644 | if (r) | |
1645 | goto ERROR; | |
1646 | } | |
1647 | ||
1648 | // Groups | |
1649 | char* groups = pakfire_package_get_groups(pkg); | |
1650 | if (groups) { | |
1651 | r = pakfire_json_add_string(pkg->pakfire, md, "groups", groups); | |
1652 | free(groups); | |
1653 | if (r) | |
1654 | goto ERROR; | |
1655 | } | |
1656 | ||
1657 | // Maintainer | |
1658 | const char* maintainer = pakfire_package_get_maintainer(pkg); | |
1659 | if (maintainer) { | |
1660 | r = pakfire_json_add_string(pkg->pakfire, md, "maintainer", maintainer); | |
1661 | if (r) | |
1662 | goto ERROR; | |
1663 | } | |
1664 | ||
1665 | // URL | |
1666 | const char* url = pakfire_package_get_url(pkg); | |
1667 | if (url) { | |
1668 | r = pakfire_json_add_string(pkg->pakfire, md, "url", url); | |
1669 | if (r) | |
1670 | goto ERROR; | |
1671 | } | |
1672 | ||
1673 | // License | |
1674 | const char* license = pakfire_package_get_license(pkg); | |
1675 | if (license) { | |
1676 | r = pakfire_json_add_string(pkg->pakfire, md, "license", license); | |
1677 | if (r) | |
1678 | goto ERROR; | |
1679 | } | |
1680 | ||
1681 | // Summary | |
1682 | const char* summary = pakfire_package_get_summary(pkg); | |
1683 | if (summary) { | |
1684 | r = pakfire_json_add_string(pkg->pakfire, md, "summary", summary); | |
1685 | if (r) | |
1686 | goto ERROR; | |
1687 | } | |
1688 | ||
1689 | // Description | |
1690 | const char* description = pakfire_package_get_description(pkg); | |
1691 | if (description) { | |
1692 | r = pakfire_json_add_string(pkg->pakfire, md, "description", description); | |
1693 | if (r) | |
1694 | goto ERROR; | |
1695 | } | |
1696 | ||
1697 | // Installed package size | |
1698 | size_t installsize = pakfire_package_get_installsize(pkg); | |
1699 | r = pakfire_json_add_integer(pkg->pakfire, md, "size", installsize); | |
1700 | if (r) | |
1701 | goto ERROR; | |
1702 | ||
1703 | // Generate dependency metadata | |
1704 | r = pakfire_package_add_json_dependencies(pkg, md); | |
1705 | if (r) | |
1706 | goto ERROR; | |
1707 | ||
1708 | // Generate build metadata | |
1709 | r = pakfire_package_add_build_metadata(pkg, md); | |
1710 | if (r) | |
1711 | goto ERROR; | |
1712 | ||
1713 | ERROR: | |
1714 | if (r) | |
1715 | json_object_put(md); | |
1716 | ||
1717 | return md; | |
1718 | } |