---
 lib/libalpm/add.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index f5c9a95..e40ce27 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -106,6 +106,31 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, 
alpm_pkg_t *pkg)
        return 0;
 }
 
+#include <pwd.h>
+static int64_t lookup_uid(UNUSED void *ctx, const char *uname, int64_t uid)
+{
+       struct passwd *ent = getpwnam(uname);
+       if(ent) {
+               return ent->pw_uid; /* uname exists, return assigned uid */
+       } else if((ent = getpwuid(uid))) {
+               return 0; /* uid is assigned to another user, fall back to root 
*/
+       } else {
+               return uid; /* uid is open, package may add user in 
post_install */
+       }
+}
+#include <grp.h>
+static int64_t lookup_gid(UNUSED void *ctx, const char *gname, int64_t gid)
+{
+       struct group *ent = getgrnam(gname);
+       if(ent) {
+               return ent->gr_gid; /* gname exists, return assigned gid */
+       } else if((ent = getgrgid(gid))) {
+               return 0; /* gid is assigned to another group, fall back to 
root */
+       } else {
+               return gid; /* gid is open, package may add group in 
post_install */
+       }
+}
+
 static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
                struct archive_entry *entry, const char *filename)
 {
@@ -115,10 +140,15 @@ static int perform_extraction(alpm_handle_t *handle, 
struct archive *archive,
                                  ARCHIVE_EXTRACT_TIME |
                                  ARCHIVE_EXTRACT_UNLINK |
                                  ARCHIVE_EXTRACT_SECURE_SYMLINKS;
+       struct archive *w = archive_write_disk_new();
+       archive_write_disk_set_group_lookup(w, NULL, lookup_gid, NULL);
+       archive_write_disk_set_user_lookup(w, NULL, lookup_uid, NULL);
+       archive_write_disk_set_options(w, archive_flags);
 
        archive_entry_set_pathname(entry, filename);
 
-       ret = archive_read_extract(archive, entry, archive_flags);
+       ret = archive_read_extract2(archive, entry, w);
+       archive_write_free(w);
        if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {
                /* operation succeeded but a "non-critical" error was 
encountered */
                _alpm_log(handle, ALPM_LOG_WARNING, _("warning given when 
extracting %s (%s)\n"),
-- 
2.7.2

Reply via email to