From: Michael Tremer Date: Tue, 23 Mar 2021 10:46:41 +0000 (+0000) Subject: libpakfire: Make common function that creates an archive reader X-Git-Tag: 0.9.28~1285^2~485 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bd0311109435e53105514fe1f5fd44c78038532;p=pakfire.git libpakfire: Make common function that creates an archive reader Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 5bdd2c691..2f35f6f6a 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -92,6 +92,9 @@ void pakfire_pool_apply_changes(Pakfire pakfire); Pool* pakfire_get_solv_pool(Pakfire pakfire); Queue* pakfire_get_installonly_queue(Pakfire pakfire); +// Archive helpers +struct archive* pakfire_make_archive_disk_reader(Pakfire pakfire, int internal); + #endif #endif /* PAKFIRE_PAKFIRE_H */ diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index aed630998..1daf0251c 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -901,3 +902,66 @@ PAKFIRE_EXPORT void pakfire_log(Pakfire pakfire, int priority, const char* file, // Restore errno errno = saved_errno; } + +static const char* pakfire_user_lookup(void* data, la_int64_t uid) { + Pakfire pakfire = (Pakfire)data; + + // Fast path for "root" + if (uid == 0) + return "root"; + + // Find a matching entry in /etc/passwd + struct passwd* entry = pakfire_getpwuid(pakfire, uid); + if (!entry) { + ERROR(pakfire, "Could not retrieve uname for %ld: %s\n", uid, strerror(errno)); + return 0; + } + + DEBUG(pakfire, "Mapping UID %ld to %s\n", uid, entry->pw_name); + + return entry->pw_name; +} + +static const char* pakfire_group_lookup(void* data, la_int64_t gid) { + Pakfire pakfire = (Pakfire)data; + + // Fast path for "root" + if (gid == 0) + return "root"; + + // Find a matching entry in /etc/group + struct group* entry = pakfire_getgrgid(pakfire, gid); + if (!entry) { + ERROR(pakfire, "Could not retrieve gname for %ld: %s\n", gid, strerror(errno)); + return 0; + } + + DEBUG(pakfire, "Mapping GID %ld to %s\n", gid, entry->gr_name); + + return entry->gr_name; +} + +struct archive* pakfire_make_archive_disk_reader(Pakfire pakfire, int internal) { + struct archive* archive = archive_read_disk_new(); + if (!archive) + return NULL; + + // Do not read fflags + int r = archive_read_disk_set_behavior(archive, ARCHIVE_READDISK_NO_FFLAGS); + if (r) { + ERROR(pakfire, "Could not change behavior of reader: %s\n", + archive_error_string(archive)); + archive_read_free(archive); + return NULL; + } + + // Install user/group lookups + if (internal) { + archive_read_disk_set_uname_lookup(archive, pakfire, pakfire_user_lookup, NULL); + archive_read_disk_set_gname_lookup(archive, pakfire, pakfire_group_lookup, NULL); + } else { + archive_read_disk_set_standard_lookup(archive); + } + + return archive; +}