return entry->pw_uid;
}
+static la_int64_t archive_group_lookup(void* data, const char* name, la_int64_t uid) {
+ Pakfire pakfire = (Pakfire)data;
+
+ // Fast path for "root"
+ if (strcmp(name, "root") == 0)
+ return 0;
+
+ // Find a matching entry in /etc/group
+ struct group* entry = pakfire_getgrnam(pakfire, name);
+ if (!entry) {
+ ERROR(pakfire, "Could not retrieve GID for '%s': %s\n", name, strerror(errno));
+ return 0;
+ }
+
+ DEBUG(pakfire, "Mapping %s to GID %d\n", name, entry->gr_gid);
+
+ return entry->gr_gid;
+}
+
static int archive_extract(PakfireArchive archive, struct archive* a, const char* prefix) {
struct archive_entry* entry;
int r;
flags |= ARCHIVE_EXTRACT_XATTR;
archive_write_disk_set_options(ext, flags);
- archive_write_disk_set_standard_lookup(ext);
- // Install our own routine for user lookups
+ // Install our own routine for user/group lookups
archive_write_disk_set_user_lookup(ext, archive->pakfire, archive_user_lookup, NULL);
+ archive_write_disk_set_group_lookup(ext, archive->pakfire, archive_group_lookup, NULL);
for (;;) {
r = archive_read_next_header(a, &entry);
#ifdef PAKFIRE_PRIVATE
+#include <grp.h>
#include <pwd.h>
#include <pakfire/types.h>
struct passwd* pakfire_getpwnam(Pakfire pakfire, const char* name);
struct passwd* pakfire_getpwuid(Pakfire pakfire, uid_t uid);
+struct group* pakfire_getgrnam(Pakfire pakfire, const char* name);
+struct group* pakfire_getgruid(Pakfire pakfire, gid_t gid);
+
#endif
#endif /* PAKFIRE_PWD_H */
# #
#############################################################################*/
+#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
struct passwd* pakfire_getpwuid(Pakfire pakfire, uid_t uid) {
return pakfire_getpwent(pakfire, __pakfire_getpwuid, &uid);
}
+
+static struct group* pakfire_getgrent(Pakfire pakfire,
+ int(*cmp)(struct group* entry, const void* value), const void* value) {
+ struct group* entry = NULL;
+
+ // Get path to /etc/group
+ char* path = pakfire_make_path(pakfire, "/etc/group");
+ if (!path)
+ return NULL;
+
+ FILE* f = fopen(path, "r");
+ if (!f)
+ goto END;
+
+ for (;;) {
+ // Parse entry
+ entry = fgetgrent(f);
+ if (!entry)
+ goto END;
+
+ // Check if this is what we are looking for
+ if (cmp(entry, value))
+ break;
+ else
+ entry = NULL;
+ }
+
+END:
+ free(path);
+
+ if (f)
+ fclose(f);
+
+ return entry;
+}
+
+static int __pakfire_getgrnam(struct group* entry, const void* value) {
+ const char* name = (const char*)value;
+
+ if (strcmp(entry->gr_name, name) == 0)
+ return 1;
+
+ return 0;
+}
+
+struct group* pakfire_getgrnam(Pakfire pakfire, const char* name) {
+ return pakfire_getgrent(pakfire, __pakfire_getgrnam, name);
+}
+
+static int __pakfire_getgrgid(struct group* entry, const void* value) {
+ gid_t* gid = (gid_t*)value;
+
+ if (entry->gr_gid == *gid)
+ return 1;
+
+ return 0;
+}
+
+struct group* pakfire_getgruid(Pakfire pakfire, gid_t gid) {
+ return pakfire_getgrent(pakfire, __pakfire_getgrgid, &gid);
+}