[pacman-dev] [PATCH 1/3] alpm_unpack : change prefix handling to workaround FS#12148.

Xavier Chantry shiningxc at gmail.com
Mon Jan 19 17:05:39 EST 2009


Instead of appending the prefix to each entry name, we can chdir to the
prefix before extracting, and restoring when it is done.
This seems to work better with the strange and special case of FS#12148
where an archive contained the "./" entry.

Signed-off-by: Xavier Chantry <shiningxc at gmail.com>
---
 lib/libalpm/util.c |   31 +++++++++++++++++++++++--------
 1 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 1bec634..2af2f1f 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -291,16 +291,17 @@ int _alpm_lckrm()
  */
 int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
 {
-	int ret = 1;
+	int ret = 0;
 	mode_t oldmask;
 	struct archive *_archive;
 	struct archive_entry *entry;
-	char expath[PATH_MAX];
+	char cwd[PATH_MAX];
+	int restore_cwd = 0;
 
 	ALPM_LOG_FUNC;
 
 	if((_archive = archive_read_new()) == NULL)
-		RET_ERR(PM_ERR_LIBARCHIVE, -1);
+		RET_ERR(PM_ERR_LIBARCHIVE, 1);
 
 	archive_read_support_compression_all(_archive);
 	archive_read_support_format_all(_archive);
@@ -309,10 +310,25 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
 				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
 		_alpm_log(PM_LOG_ERROR, _("could not open %s: %s\n"), archive,
 				archive_error_string(_archive));
-		RET_ERR(PM_ERR_PKG_OPEN, -1);
+		RET_ERR(PM_ERR_PKG_OPEN, 1);
 	}
 
 	oldmask = umask(0022);
+
+	/* save the cwd so we can restore it later */
+	if(getcwd(cwd, PATH_MAX) == NULL) {
+		_alpm_log(PM_LOG_ERROR, _("could not get current working directory\n"));
+	} else {
+		restore_cwd = 1;
+	}
+
+	/* just in case our cwd was removed in the upgrade operation */
+	if(chdir(prefix) != 0) {
+		_alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), prefix, strerror(errno));
+		ret = 1;
+		goto cleanup;
+	}
+
 	while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) {
 		const struct stat *st;
 		const char *entryname; /* the name of the file in the archive */
@@ -337,10 +353,6 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
 		}
 
 		/* Extract the archive entry. */
-		ret = 0;
-		snprintf(expath, PATH_MAX, "%s/%s", prefix, entryname);
-		archive_entry_set_pathname(entry, expath);
-
 		int readret = archive_read_extract(_archive, entry, 0);
 		if(readret == ARCHIVE_WARN) {
 			/* operation succeeded but a non-critical error was encountered */
@@ -361,6 +373,9 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
 cleanup:
 	umask(oldmask);
 	archive_read_finish(_archive);
+	if(restore_cwd) {
+		chdir(cwd);
+	}
 	return(ret);
 }
 
-- 
1.6.1



More information about the pacman-dev mailing list