#include <pakfire/file.h>
#include <pakfire/filelist.h>
#include <pakfire/i18n.h>
+#include <pakfire/jail.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
#include <pakfire/pakfire.h>
return NULL;
}
+
+/*
+ systemd sysusers
+*/
+static int __pakfire_archive_filter_systemd_sysusers(struct pakfire* pakfire,
+ struct archive* a, struct archive_entry* e, void* data) {
+ const char* path = archive_entry_pathname(e);
+
+ if (!pakfire_path_match("/usr/lib/sysusers.d/*.conf", path))
+ return PAKFIRE_WALK_SKIP;
+
+ return PAKFIRE_WALK_OK;
+}
+
+static int pakfire_archive_stream_payload(struct pakfire* pakfire, void* data, int fd) {
+ char buffer[1024];
+
+ struct archive* a = (struct archive*)data;
+
+ // Read a block from the input archive
+ ssize_t bytes_read = archive_read_data(a, buffer, sizeof(buffer));
+ if (bytes_read < 0) {
+ ERROR(pakfire, "Could not read from archive: %s\n", archive_error_string(a));
+ return 1;
+ }
+
+ // We have consumed everything
+ if (bytes_read == 0)
+ return EOF;
+
+ // Write the data to the output file descriptor
+ ssize_t bytes_written = write(fd, buffer, bytes_read);
+ if (bytes_written < 0) {
+ ERROR(pakfire, "Could not stream output: %m\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int __pakfire_archive_handle_systemd_sysusers(struct pakfire* pakfire,
+ struct archive* a, struct archive_entry* e, void* data) {
+ struct pakfire_jail* jail = NULL;
+ char replace[PATH_MAX];
+ int r;
+
+ // Fetch path
+ const char* path = archive_entry_pathname(e);
+
+ // Format --replace
+ r = pakfire_string_format(replace, "--replace=/%s", path);
+ if (r)
+ goto ERROR;
+
+ const char* argv[] = { "/usr/bin/systemd-sysusers", replace, "-", NULL };
+
+ // Create a new jail
+ r = pakfire_jail_create(&jail, pakfire, 0);
+ if (r)
+ goto ERROR;
+
+ r = pakfire_jail_exec(jail, argv, pakfire_archive_stream_payload, NULL, a);
+ switch (r) {
+ // If the command does not exist, we silently ignore this error
+ case 127:
+ r = 0;
+ break;
+
+ default:
+ goto ERROR;
+ }
+
+ERROR:
+ if (jail)
+ pakfire_jail_unref(jail);
+
+ return r;
+}
+
+int pakfire_archive_apply_systemd_sysusers(struct pakfire_archive* archive) {
+ pakfire_archive_walk(archive,
+ __pakfire_archive_filter_systemd_sysusers, __pakfire_archive_handle_systemd_sysusers, NULL);
+
+ return 0;
+}
pakfire_file_set_gname(file, "root");
}
+ // Handle systemd sysusers
+ if (pakfire_file_matches(file, "/usr/lib/sysusers.d/*.conf")) {
+ pakfire_package_add_dep(packager->pkg,
+ PAKFIRE_PKG_REQUIRES, "pakfire(systemd-sysusers)");
+
+ // Ask to pre-install /usr/bin/systemd-sysusers
+ pakfire_package_add_dep(packager->pkg,
+ PAKFIRE_PKG_PREREQUIRES, "/usr/bin/systemd-sysusers");
+ }
+
+ // Handle systemd tmpfiles
if (pakfire_file_matches(file, "/usr/lib/tmpfiles.d/*.conf")) {
pakfire_package_add_dep(packager->pkg,
PAKFIRE_PKG_REQUIRES, "pakfire(systemd-tmpfiles)");
return 0;
}
+static int pakfire_transaction_apply_systemd_sysusers(struct pakfire_transaction* transaction,
+ struct pakfire_package* pkg, struct pakfire_archive* archive) {
+ // Walk through the archive and find all sysuser files
+ if (pakfire_package_matches_dep(pkg, PAKFIRE_PKG_REQUIRES, "pakfire(systemd-sysusers)"))
+ return pakfire_archive_apply_systemd_sysusers(archive);
+
+ return 0;
+}
+
static int pakfire_transaction_apply_systemd_tmpfiles(
struct pakfire_transaction* transaction, struct pakfire_package* pkg) {
// Apply any tmpfiles (ignore any errors)
switch (type) {
case PAKFIRE_STEP_INSTALL:
case PAKFIRE_STEP_REINSTALL:
+ // Apply systemd sysusers
+ r = pakfire_transaction_apply_systemd_sysusers(transaction, pkg, archive);
+ if (r)
+ break;
+
r = pakfire_transaction_run_script(transaction, db,
"prein", pkg, archive);
if (r)
case PAKFIRE_STEP_UPGRADE:
case PAKFIRE_STEP_DOWNGRADE:
+ // Apply systemd sysusers
+ r = pakfire_transaction_apply_systemd_sysusers(transaction, pkg, archive);
+ if (r)
+ break;
+
r = pakfire_transaction_run_script(transaction, db,
"preup", pkg, archive);
if (r)