]> git.ipfire.org Git - people/ms/pakfire.git/blame - src/libpakfire/packager.c
logging: Make the legacy logger configurable
[people/ms/pakfire.git] / src / libpakfire / packager.c
CommitLineData
6aeb48e6
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2021 Pakfire development team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
11# This program is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
20
21#include <errno.h>
1ea1f35b
MT
22#include <fcntl.h>
23#include <linux/limits.h>
6aeb48e6 24#include <stdlib.h>
da08f989
MT
25#include <sys/stat.h>
26#include <sys/types.h>
05cfc2c9 27#include <time.h>
da08f989 28#include <unistd.h>
6aeb48e6 29
1ea1f35b 30#include <archive.h>
da08f989 31#include <archive_entry.h>
1ea1f35b 32
b59c9fa2
MT
33#include <json.h>
34
517708c8
MT
35// Enable legacy logging
36#define PAKFIRE_LEGACY_LOGGING
37
2adc4a4a 38#include <pakfire/archive.h>
6bf9841b 39#include <pakfire/compress.h>
436677a3 40#include <pakfire/constants.h>
1ea1f35b 41#include <pakfire/logging.h>
6aeb48e6
MT
42#include <pakfire/package.h>
43#include <pakfire/packager.h>
44#include <pakfire/pakfire.h>
677e9e5b 45#include <pakfire/pwd.h>
d973a13d 46#include <pakfire/string.h>
f57ad279 47#include <pakfire/util.h>
6aeb48e6
MT
48
49struct pakfire_packager {
ac4c607b 50 struct pakfire* pakfire;
6aeb48e6 51 int nrefs;
05cfc2c9 52 time_t time_created;
6aeb48e6 53
31480bee 54 struct pakfire_package* pkg;
bb06d548 55 char filename[PATH_MAX];
1ea1f35b 56
738b3582
MT
57 // Reader
58 struct archive* reader;
59
60 // Payload
6bf9841b 61 struct pakfire_filelist* filelist;
106d2edd 62
9ca45f4f 63 // Scriptlets
106d2edd
MT
64 struct pakfire_scriptlet** scriptlets;
65 unsigned int num_scriptlets;
9ca45f4f
MT
66
67 // Digests
68 unsigned int digests;
6aeb48e6
MT
69};
70
1ea1f35b 71static void pakfire_packager_free(struct pakfire_packager* packager) {
106d2edd
MT
72 // Scriptlets
73 if (packager->scriptlets) {
74 for (unsigned int i = 0; i < packager->num_scriptlets; i++)
9dd7b1aa 75 pakfire_scriptlet_unref(packager->scriptlets[i]);
106d2edd
MT
76 free(packager->scriptlets);
77 }
78
738b3582 79 if (packager->reader)
66817062 80 archive_read_free(packager->reader);
738b3582 81
6bf9841b
MT
82 if (packager->filelist)
83 pakfire_filelist_unref(packager->filelist);
1ea1f35b
MT
84 pakfire_package_unref(packager->pkg);
85 pakfire_unref(packager->pakfire);
51105783 86 free(packager);
1ea1f35b
MT
87}
88
22b8e37b 89int pakfire_packager_create(struct pakfire_packager** packager,
5d7a93ec 90 struct pakfire* pakfire, struct pakfire_package* pkg) {
53a87249
MT
91 struct pakfire_packager* p = NULL;
92 char hostname[HOST_NAME_MAX];
e282863a
MT
93 int r = 1;
94
53a87249
MT
95 // Allocate the packager object
96 p = calloc(1, sizeof(*p));
97 if (!p)
98 return -errno;
99
05cfc2c9
MT
100 // Save creation time
101 p->time_created = time(NULL);
102
6aeb48e6
MT
103 // Initialize reference counting
104 p->nrefs = 1;
105
106 // Store a reference to Pakfire
5d7a93ec 107 p->pakfire = pakfire_ref(pakfire);
6aeb48e6
MT
108
109 // Store a reference to the package
110 p->pkg = pakfire_package_ref(pkg);
111
9ca45f4f
MT
112 // Use the default digests
113 p->digests = PAKFIRE_PACKAGER_DIGESTS;
114
cb9b4eba
MT
115 // Set distribution
116 const char* tag = pakfire_get_distro_tag(p->pakfire);
117 if (!tag) {
118 ERROR(p->pakfire, "Distribution tag is not configured: %m\n");
119 goto ERROR;
120 }
121
74468e4f 122 pakfire_package_set_string(pkg, PAKFIRE_PKG_DISTRO, tag);
cb9b4eba 123
53a87249
MT
124 // Fetch the hostname
125 r = gethostname(hostname, sizeof(hostname));
126 if (r) {
127 ERROR(p->pakfire, "Could not determine the hostname: %m\n");
128 goto ERROR;
129 }
130
cd2c2cfb 131 // Set build host
53a87249
MT
132 r = pakfire_package_set_string(pkg, PAKFIRE_PKG_BUILD_HOST, hostname);
133 if (r) {
134 ERROR_ERRNO(p->pakfire, r, "Could not set the hostname: %m\n");
135 goto ERROR;
136 }
cd2c2cfb
MT
137
138 // Set build time
3f327c3c 139 pakfire_package_set_num(pkg, PAKFIRE_PKG_BUILD_TIME, p->time_created);
cd2c2cfb 140
0682aeb3 141 // Create reader
66817062
MT
142 p->reader = pakfire_make_archive_disk_reader(p->pakfire, 1);
143 if (!p->reader)
1ba1869e 144 goto ERROR;
1ea1f35b 145
6bf9841b
MT
146 // Create filelist
147 r = pakfire_filelist_create(&p->filelist, p->pakfire);
0682aeb3 148 if (r)
738b3582 149 goto ERROR;
738b3582 150
6bf9841b 151 // Add a requirement for the cryptographic algorithms we are using
6f3fad3b
MT
152 if (p->digests & PAKFIRE_DIGEST_SHA3_512) {
153 r = pakfire_package_add_dep(p->pkg,
154 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-512)");
155 if (r)
156 goto ERROR;
157 }
158 if (p->digests & PAKFIRE_DIGEST_SHA3_256) {
159 r = pakfire_package_add_dep(p->pkg,
160 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA3-256)");
161 if (r)
162 goto ERROR;
163 }
164 if (p->digests & PAKFIRE_DIGEST_BLAKE2B512) {
165 r = pakfire_package_add_dep(p->pkg,
166 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2b512)");
167 if (r)
168 goto ERROR;
169 }
170 if (p->digests & PAKFIRE_DIGEST_BLAKE2S256) {
171 r = pakfire_package_add_dep(p->pkg,
172 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-BLAKE2s256)");
173 if (r)
174 goto ERROR;
175 }
176 if (p->digests & PAKFIRE_DIGEST_SHA2_512) {
177 r = pakfire_package_add_dep(p->pkg,
178 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-512)");
179 if (r)
180 goto ERROR;
181 }
182 if (p->digests & PAKFIRE_DIGEST_SHA2_256) {
183 r = pakfire_package_add_dep(p->pkg,
184 PAKFIRE_PKG_REQUIRES, "pakfire(Digest-SHA2-256)");
185 if (r)
186 goto ERROR;
187 }
6bf9841b 188
53a87249
MT
189 // Return a reference
190 *packager = pakfire_packager_ref(p);
1ba1869e
MT
191
192ERROR:
53a87249
MT
193 if (p)
194 pakfire_packager_unref(p);
1ba1869e
MT
195
196 return r;
6aeb48e6
MT
197}
198
22b8e37b 199struct pakfire_packager* pakfire_packager_ref(
6aeb48e6
MT
200 struct pakfire_packager* packager) {
201 ++packager->nrefs;
202
203 return packager;
204}
205
22b8e37b 206struct pakfire_packager* pakfire_packager_unref(
6aeb48e6
MT
207 struct pakfire_packager* packager) {
208 if (--packager->nrefs > 0)
209 return packager;
210
211 pakfire_packager_free(packager);
6aeb48e6
MT
212 return NULL;
213}
da08f989 214
22b8e37b 215const char* pakfire_packager_filename(struct pakfire_packager* packager) {
bb06d548 216 if (!*packager->filename) {
0aade652 217 const char* filename = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_FILENAME);
bb06d548
MT
218
219 // Add arch
220 if (pakfire_package_is_source(packager->pkg))
221 pakfire_string_set(packager->filename, filename);
222 else {
74468e4f 223 const char* arch = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_ARCH);
bb06d548
MT
224
225 pakfire_string_format(packager->filename, "%s/%s", arch, filename);
226 }
227 }
228
229 return packager->filename;
96d2c7bc
MT
230}
231
28700a5b 232static struct archive_entry* pakfire_packager_create_file(
95b81a98 233 struct pakfire_packager* packager, const char* filename, size_t size, mode_t mode) {
98e85f1c
MT
234 // Create a new file entry
235 struct archive_entry* entry = archive_entry_new();
236 if (!entry)
28700a5b 237 return NULL;
98e85f1c
MT
238
239 // Set filename
240 archive_entry_set_pathname(entry, filename);
241
242 // This is a regular file
243 archive_entry_set_filetype(entry, AE_IFREG);
95b81a98 244 archive_entry_set_perm(entry, mode);
98e85f1c 245
28700a5b
MT
246 // Set size
247 archive_entry_set_size(entry, size);
248
05cfc2c9
MT
249 // Set ownership
250 archive_entry_set_uname(entry, "root");
251 archive_entry_set_uid(entry, 0);
252 archive_entry_set_gname(entry, "root");
253 archive_entry_set_gid(entry, 0);
254
255 // Set times
256 archive_entry_set_birthtime(entry, packager->time_created, 0);
257 archive_entry_set_ctime(entry, packager->time_created, 0);
258 archive_entry_set_mtime(entry, packager->time_created, 0);
259 archive_entry_set_atime(entry, packager->time_created, 0);
260
28700a5b
MT
261 return entry;
262}
263
264static int pakfire_packager_write_file_from_buffer(struct pakfire_packager* packager,
bfdad796 265 struct archive* a, const char* filename, mode_t mode, const char* buffer) {
28700a5b
MT
266 size_t size = strlen(buffer);
267
268 // Create a new file
7e346194
MT
269 struct archive_entry* entry = pakfire_packager_create_file(packager, filename, size, mode);
270 if (!entry) {
271 ERROR(packager->pakfire, "Could not create file '%s'\n", filename);
28700a5b 272 return 1;
7e346194 273 }
98e85f1c
MT
274
275 // This is the end of the header
276 int r = archive_write_header(a, entry);
277 if (r) {
278 ERROR(packager->pakfire, "Error writing header: %s\n", archive_error_string(a));
265a7974 279 goto ERROR;
98e85f1c
MT
280 }
281
282 // Write content
283 r = archive_write_data(a, buffer, strlen(buffer));
284 if (r < 0) {
285 ERROR(packager->pakfire, "Error writing data: %s\n", archive_error_string(a));
265a7974 286 goto ERROR;
98e85f1c
MT
287 }
288
265a7974
MT
289 // Success
290 r = 0;
291
292ERROR:
98e85f1c
MT
293 archive_entry_free(entry);
294
265a7974 295 return r;
98e85f1c
MT
296}
297
436677a3
MT
298static int pakfire_packager_write_format(struct pakfire_packager* packager,
299 struct archive* a) {
300 const char buffer[] = TO_STRING(PACKAGE_FORMAT) "\n";
301
7e346194
MT
302 DEBUG(packager->pakfire, "Writing package format\n");
303
bfdad796 304 int r = pakfire_packager_write_file_from_buffer(packager, a,
0dbfb5e1 305 "pakfire-format", 0444, buffer);
a6dd151e
MT
306 if (r)
307 return r;
308
309 // Add package format marker
6f3fad3b 310 r = pakfire_package_add_dep(packager->pkg, PAKFIRE_PKG_REQUIRES,
a6dd151e 311 "pakfire(PackageFormat-" TO_STRING(PACKAGE_FORMAT) ")");
6f3fad3b
MT
312 if (r)
313 return r;
a6dd151e
MT
314
315 return 0;
436677a3
MT
316}
317
b59c9fa2
MT
318static char* pakfire_packager_make_metadata(struct pakfire_packager* packager) {
319 char* result = NULL;
98e85f1c 320
b59c9fa2
MT
321 // Convert all package metadata to JSON
322 struct json_object* md = pakfire_package_to_json(packager->pkg);
323 if (!md)
98e85f1c
MT
324 goto ERROR;
325
b59c9fa2 326 // Serialize JSON to file
ef4a2e77 327 const char* s = json_object_to_json_string_ext(md, 0);
b59c9fa2 328 if (!s)
98e85f1c
MT
329 goto ERROR;
330
b59c9fa2
MT
331 // Copy result onto heap
332 result = strdup(s);
333 if (!result)
98e85f1c 334 goto ERROR;
98e85f1c
MT
335
336ERROR:
b59c9fa2
MT
337 // Free metadata
338 if (md)
339 json_object_put(md);
98e85f1c 340
b59c9fa2 341 return result;
98e85f1c
MT
342}
343
344static int pakfire_packager_write_metadata(struct pakfire_packager* packager,
bfdad796 345 struct archive* a) {
98e85f1c 346 // Make metadata
b59c9fa2 347 char* buffer = pakfire_packager_make_metadata(packager);
98e85f1c
MT
348 if (!buffer)
349 return 1;
350
b59c9fa2 351 DEBUG(packager->pakfire, "Generated package metadata:\n%s\n", buffer);
98e85f1c
MT
352
353 // Write buffer
bfdad796 354 int r = pakfire_packager_write_file_from_buffer(packager, a,
9f6b177b 355 ".PKGINFO", 0444, buffer);
98e85f1c
MT
356
357 free(buffer);
358
359 return r;
360}
361
106d2edd 362static int pakfire_packager_write_scriptlet(struct pakfire_packager* packager,
bfdad796 363 struct archive* a, struct pakfire_scriptlet* scriptlet) {
106d2edd
MT
364 char filename[PATH_MAX];
365 size_t size;
366 int r;
367
368 // Fetch type
369 const char* type = pakfire_scriptlet_get_type(scriptlet);
370
371 DEBUG(packager->pakfire, "Writing scriptlet '%s' to package\n", type);
372
373 // Make filename
9f6b177b 374 r = pakfire_string_format(filename, ".scriptlets/%s", type);
a60955af 375 if (r)
106d2edd
MT
376 return r;
377
378 // Fetch scriptlet
379 const char* data = pakfire_scriptlet_get_data(scriptlet, &size);
380
381 // Write file
bfdad796 382 return pakfire_packager_write_file_from_buffer(packager, a, filename, 0544, data);
106d2edd
MT
383}
384
436677a3
MT
385/*
386 This function is being called at the end when all data has been added to the package.
387
388 It will create a new archive and write the package to the given file descriptor.
389*/
22b8e37b 390int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f) {
1b4e7c7b 391 struct archive* a = NULL;
cec1458f 392 unsigned int level;
96d2c7bc 393 int r = 1;
436677a3 394
74468e4f 395 const char* nevra = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_NEVRA);
1b4e7c7b 396
555b6dd2 397 // Add requires feature markers
6f3fad3b
MT
398 if (pakfire_package_has_rich_deps(packager->pkg)) {
399 r = pakfire_package_add_dep(packager->pkg,
400 PAKFIRE_PKG_REQUIRES, "pakfire(RichDependencies)");
401 if (r)
402 goto ERROR;
403 }
555b6dd2 404
260006f2
MT
405 // Add filelist
406 r = pakfire_package_set_filelist(packager->pkg, packager->filelist);
407 if (r)
408 goto ERROR;
409
6bf9841b
MT
410 const size_t installsize = pakfire_filelist_total_size(packager->filelist);
411
508e2030 412 // Store total install size
3f327c3c
MT
413 r = pakfire_package_set_num(packager->pkg, PAKFIRE_PKG_INSTALLSIZE, installsize);
414 if (r)
415 goto ERROR;
fafe383d 416
a3151996
MT
417 // Select compression level
418 if (pakfire_package_is_source(packager->pkg))
e66c6bbc 419 level = 1;
a3151996 420 else
e66c6bbc 421 level = 22;
a3151996 422
e66c6bbc
MT
423 // Create a new archive that is being compressed as fast as possible
424 r = pakfire_compress_create_archive(packager->pakfire, &a, f,
425 PAKFIRE_COMPRESS_ZSTD, level);
426 if (r)
427 goto ERROR;
63476763
MT
428
429 // Add feature marker
6f3fad3b
MT
430 pakfire_package_add_dep(packager->pkg,
431 PAKFIRE_PKG_REQUIRES, "pakfire(Compress-Zstandard)");
63476763 432
436677a3
MT
433 // Start with the format file
434 r = pakfire_packager_write_format(packager, a);
265a7974
MT
435 if (r) {
436 ERROR(packager->pakfire, "Could not add format file to archive: %s\n",
437 archive_error_string(a));
436677a3 438 goto ERROR;
265a7974 439 }
436677a3 440
98e85f1c 441 // Write the metadata
bfdad796 442 r = pakfire_packager_write_metadata(packager, a);
265a7974
MT
443 if (r) {
444 ERROR(packager->pakfire, "Could not add metadata file to archive: %s\n",
445 archive_error_string(a));
98e85f1c 446 goto ERROR;
265a7974 447 }
98e85f1c 448
d8856104
MT
449 // Write scriptlets
450 for (unsigned int i = 0; i < packager->num_scriptlets; i++) {
451 r = pakfire_packager_write_scriptlet(packager, a, packager->scriptlets[i]);
452 if (r) {
453 ERROR(packager->pakfire, "Could not add scriptlet to the archive: %m\n");
454 goto ERROR;
455 }
456 }
457
bfdad796 458 // Write the payload
6bf9841b
MT
459 r = pakfire_compress(packager->pakfire, a, packager->filelist, nevra,
460 PAKFIRE_COMPRESS_SHOW_THROUGHPUT, PAKFIRE_PACKAGER_DIGESTS);
131c1449
MT
461 if (r)
462 goto ERROR;
265a7974 463
2013270b
MT
464 // Flush all buffers to disk
465 fflush(f);
466
96d2c7bc
MT
467 // Success
468 r = 0;
436677a3
MT
469
470ERROR:
471 if (a)
265a7974 472 archive_write_free(a);
436677a3 473
96d2c7bc 474 return r;
436677a3
MT
475}
476
22b8e37b 477int pakfire_packager_finish_to_directory(struct pakfire_packager* packager,
45448dbd 478 const char* target, char** result) {
48c6f2e7 479 char path[PATH_MAX];
bb06d548 480 char tmppath[PATH_MAX];
131c1449 481 FILE* f = NULL;
48c6f2e7
MT
482 int r = 1;
483
484 // target cannot be empty
485 if (!target) {
486 errno = EINVAL;
487 return 1;
488 }
489
bb06d548
MT
490 // Get the filename of the package
491 const char* filename = pakfire_packager_filename(packager);
492 if (!filename) {
b1772bfb 493 ERROR(packager->pakfire, "Could not generate filename for package: %m\n");
bb06d548
MT
494 r = 1;
495 goto ERROR;
496 }
497
498 // Make the package path
499 r = pakfire_string_format(path, "%s/%s", target, filename);
a60955af 500 if (r)
bb06d548
MT
501 goto ERROR;
502
503 // Create the parent directory
520ce66c 504 r = pakfire_mkparentdir(path, 0755);
bb06d548
MT
505 if (r)
506 goto ERROR;
507
48c6f2e7 508 // Create a temporary file in the target directory
bb06d548 509 r = pakfire_string_format(tmppath, "%s.XXXXXX", path);
a60955af 510 if (r)
bb06d548 511 goto ERROR;
48c6f2e7
MT
512
513 // Create a temporary result file
a87004ed 514 f = pakfire_mktemp(tmppath, 0);
48c6f2e7
MT
515 if (!f)
516 goto ERROR;
517
518 // Write the finished package
519 r = pakfire_packager_finish(packager, f);
520 if (r) {
b1772bfb 521 ERROR(packager->pakfire, "pakfire_packager_finish() failed: %m\n");
48c6f2e7
MT
522 goto ERROR;
523 }
524
48c6f2e7 525 // Move the temporary file to destination
bb06d548
MT
526 r = rename(tmppath, path);
527 if (r) {
b1772bfb 528 ERROR(packager->pakfire, "Could not move %s to %s: %m\n", tmppath, path);
48c6f2e7 529 goto ERROR;
bb06d548 530 }
48c6f2e7 531
3ddc473d 532 DEBUG(packager->pakfire, "Package written to %s\n", path);
48c6f2e7 533
45448dbd
MT
534 // Store result path if requested
535 if (result) {
536 *result = strdup(path);
537 if (!*result) {
538 r = 1;
539 goto ERROR;
540 }
541 }
542
48c6f2e7
MT
543 // Success
544 r = 0;
545
546ERROR:
131c1449
MT
547 if (f)
548 fclose(f);
549
48c6f2e7 550 // Remove temporary file
bb06d548
MT
551 if (r && *tmppath)
552 unlink(tmppath);
48c6f2e7 553
bb06d548 554 return r;
48c6f2e7
MT
555}
556
80a108bf 557int pakfire_packager_add_file(struct pakfire_packager* packager, struct pakfire_file* file) {
210aabe9
MT
558 int r;
559
85b59296
MT
560 // Check input
561 if (!file) {
255d4488
MT
562 errno = EINVAL;
563 return 1;
564 }
da08f989 565
85b59296
MT
566 // Fetch path
567 const char* path = pakfire_file_get_path(file);
da08f989 568
85b59296 569 // Files cannot have an empty path
37c5d873 570 if (!path || !*path) {
85b59296
MT
571 ERROR(packager->pakfire, "Cannot add a file with an empty path\n");
572 errno = EPERM;
573 return 1;
da08f989 574
85b59296
MT
575 // Hidden files cannot be added
576 } else if (*path == '.') {
577 ERROR(packager->pakfire, "Hidden files cannot be added to a package: %s\n", path);
578 errno = EPERM;
579 return 1;
738b3582 580 }
da08f989 581
85b59296
MT
582 DEBUG(packager->pakfire, "Adding file to payload: %s\n", path);
583
210aabe9
MT
584 // Detect the MIME type
585 r = pakfire_file_detect_mimetype(file);
586 if (r)
587 return r;
588
2ed2b519
MT
589 // Overwrite a couple of things for source archives
590 if (pakfire_package_is_source(packager->pkg)) {
591 // Reset permissions
85b59296 592 pakfire_file_set_perms(file, 0644);
2ed2b519
MT
593
594 // Reset file ownership
302e3253
MT
595 pakfire_file_set_uname(file, "root");
596 pakfire_file_set_gname(file, "root");
2ed2b519
MT
597 }
598
88f4d6e6
MT
599 // Handle systemd sysusers
600 if (pakfire_file_matches(file, "/usr/lib/sysusers.d/*.conf")) {
601 pakfire_package_add_dep(packager->pkg,
602 PAKFIRE_PKG_REQUIRES, "pakfire(systemd-sysusers)");
603
604 // Ask to pre-install /usr/bin/systemd-sysusers
605 pakfire_package_add_dep(packager->pkg,
606 PAKFIRE_PKG_PREREQUIRES, "/usr/bin/systemd-sysusers");
607 }
608
609 // Handle systemd tmpfiles
f7ffbb93
MT
610 if (pakfire_file_matches(file, "/usr/lib/tmpfiles.d/*.conf")) {
611 pakfire_package_add_dep(packager->pkg,
612 PAKFIRE_PKG_REQUIRES, "pakfire(systemd-tmpfiles)");
613
614 // Ask to pre-install systemd
615 pakfire_package_add_dep(packager->pkg,
616 PAKFIRE_PKG_PREREQUIRES, "systemd");
617 }
618
6bf9841b 619 // Append the file to the filelist
2f88682d 620 return pakfire_filelist_add(packager->filelist, file);
da08f989 621}
106d2edd 622
85b59296
MT
623int pakfire_packager_add(struct pakfire_packager* packager,
624 const char* sourcepath, const char* path) {
625 struct pakfire_file* file = NULL;
37c5d873
MT
626 int r;
627
628 // Create a new file object
629 r = pakfire_file_create(&file, packager->pakfire);
630 if (r)
631 goto ERROR;
85b59296 632
37c5d873
MT
633 // Read the meta information
634 r = pakfire_file_read(file, packager->reader, sourcepath);
85b59296
MT
635 if (r)
636 goto ERROR;
637
15128e65
MT
638 if (!path)
639 path = sourcepath;
640
61b0856b 641 // Assign a new path for inside the archive
15128e65
MT
642 r = pakfire_file_set_path(file, path);
643 if (r)
644 goto ERROR;
61b0856b 645
85b59296
MT
646 // Call the main function
647 r = pakfire_packager_add_file(packager, file);
648
649ERROR:
650 if (file)
651 pakfire_file_unref(file);
652
653 return r;
654}
655
5d5da764
MT
656static int __pakfire_packager_add_files(struct pakfire* pakfire,
657 struct pakfire_file* file, void* p) {
658 struct pakfire_packager* packager = (struct pakfire_packager*)p;
814b7fee 659
5d5da764
MT
660 return pakfire_packager_add_file(packager, file);
661}
814b7fee 662
5d5da764
MT
663int pakfire_packager_add_files(
664 struct pakfire_packager* packager, struct pakfire_filelist* filelist) {
665 // Add all files on the filelist
a3f3c077 666 return pakfire_filelist_walk(filelist, __pakfire_packager_add_files, packager, 0);
814b7fee
MT
667}
668
106d2edd
MT
669int pakfire_packager_add_scriptlet(struct pakfire_packager* packager,
670 struct pakfire_scriptlet* scriptlet) {
671 if (!scriptlet) {
672 errno = EINVAL;
673 return 1;
674 }
675
676 // Extend array
677 packager->scriptlets = reallocarray(packager->scriptlets,
678 packager->num_scriptlets + 1, sizeof(*packager->scriptlets));
679 if (!packager->scriptlets)
680 return 1;
681
682 // Append scriptlet
683 packager->scriptlets[packager->num_scriptlets++] = pakfire_scriptlet_ref(scriptlet);
684
685 return 0;
686}
2a838122
MT
687
688/*
689 Removes all files on the filelist
690*/
691int pakfire_packager_cleanup(struct pakfire_packager* packager) {
692 // Delete all files on the filelist
9274236e 693 return pakfire_filelist_cleanup(packager->filelist, PAKFIRE_FILE_CLEANUP_TIDY);
2a838122 694}