]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: Make common function that creates an archive reader
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 23 Mar 2021 10:46:41 +0000 (10:46 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 23 Mar 2021 10:46:41 +0000 (10:46 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/pakfire.c

index 5bdd2c69169b70451c4cfbe0d5a8c80835656097..2f35f6f6a91c1f2badb6f8ca52040fc38bc153f7 100644 (file)
@@ -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 */
index aed630998a1e73f925fcd057a9880160214080e9..1daf0251c5ed907a6df6de0696dd8c120baa3c56 100644 (file)
@@ -48,6 +48,7 @@
 #include <pakfire/pakfire.h>
 #include <pakfire/parser.h>
 #include <pakfire/private.h>
+#include <pakfire/pwd.h>
 #include <pakfire/repo.h>
 #include <pakfire/types.h>
 #include <pakfire/util.h>
@@ -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;
+}