[pacman-dev] [PATCH] Remove .FILELIST generation from makepkg (and elsewhere)

Dan McGee dan at archlinux.org
Sat Dec 29 13:36:05 EST 2007


This is something pacman can do on its own straight from the archive, and we
will reduce the chance of problems occurring becuase of inproper FILELIST
generation as we have had in the past with special characters in filenames.

Once we remove it from makepkg. we can remove any usage of it from all of
our other tools, including pacman, pactest, and contrib/ utilities.

Note that removing it from pacman uncovered a few other bugs anyway, so this
was probably a good move.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 contrib/re-pacman     |    8 ++----
 lib/libalpm/package.c |   64 ++++++++++++++----------------------------------
 pactest/pmpkg.py      |   20 +-------------
 scripts/makepkg.sh.in |   11 +-------
 4 files changed, 25 insertions(+), 78 deletions(-)

diff --git a/contrib/re-pacman b/contrib/re-pacman
index 0d0328b..fff1c87 100755
--- a/contrib/re-pacman
+++ b/contrib/re-pacman
@@ -60,20 +60,18 @@ if [ "x${ver}" = "x" ]; then
 fi
 
 echo ":: Cleaning up old files"
-rm -f .PKGINFO .FILELIST "${1}-${ver}.pkg.tar.gz"
+rm -f .PKGINFO "${1}-${ver}.pkg.tar.gz"
 
 echo ":: Building PKGINFO"
 make_pkginfo ${1} > .PKGINFO
-echo ":: Building FILELIST"
-pacman -Ql ${1} | cut -d' ' -f2- > .FILELIST
 
-flist=".PKGINFO .FILELIST"
+flist=".PKGINFO"
 flist="${flist} $(pacman -Ql ${1} | sed 's|\w* \(.*\)|/\1|g' | grep -v '/$')"
 
 echo ":: Building final package tarball"
 echo ${flist} | tr ' ' '\n' | tar czf "${1}-${ver}.pkg.tar.gz" -T - 2>/dev/null
 
-rm -f .PKGINFO .FILELIST
+rm -f .PKGINFO
 echo ":: Package '${1}-${ver}.pkg.tar.gz' is now ready for installation"
 
 # vim: set ts=2 sw=2 noet:
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index f061bf1..49e562e 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -978,13 +978,11 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
 {
 	int ret = ARCHIVE_OK;
 	int config = 0;
-	int filelist = 0;
 	struct archive *archive;
 	struct archive_entry *entry;
 	pmpkg_t *info = NULL;
 	char *descfile = NULL;
 	int fd = -1;
-	alpm_list_t *all_files = NULL;
 	struct stat st;
 
 	ALPM_LOG_FUNC;
@@ -1024,10 +1022,12 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
 
 	/* If full is false, only read through the archive until we find our needed
 	 * metadata. If it is true, read through the entire archive, which serves
-	 * as a verfication of integrity. */
+	 * as a verfication of integrity and allows us to create the filelist. */
 	while((ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
 		const char *entry_name = archive_entry_pathname(entry);
 
+		/* NOTE: we used to look for .FILELIST, but it is easier (and safer) for
+		 * us to just generate this on our own. */
 		if(strcmp(entry_name, ".PKGINFO") == 0) {
 			/* extract this file into /tmp. it has info for us */
 			descfile = strdup("/tmp/alpm_XXXXXX");
@@ -1058,38 +1058,12 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
 			continue;
 		} else if(strcmp(entry_name,  ".INSTALL") == 0) {
 			info->scriptlet = 1;
-		} else if(strcmp(entry_name, ".FILELIST") == 0) {
-			/* Build info->files from the filelist */
-			FILE *fp;
-			char *fn;
-			char str[PATH_MAX+1];
-			int fd;
-
-			fn = strdup("/tmp/alpm_XXXXXX");
-			fd = mkstemp(fn);
-			archive_read_data_into_fd(archive,fd);
-			fp = fopen(fn, "r");
-			while(!feof(fp)) {
-				if(fgets(str, PATH_MAX, fp) == NULL) {
-					continue;
-				}
-				_alpm_strtrim(str);
-				info->files = alpm_list_add(info->files, strdup(str));
-			}
-			fclose(fp);
-			if(unlink(fn)) {
-				_alpm_log(PM_LOG_WARNING, _("could not remove tempfile %s\n"), fn);
-			}
-			FREE(fn);
-			close(fd);
-			filelist = 1;
-			continue;
 		} else if(*entry_name == '.') {
 			/* for now, ignore all files starting with '.' that haven't
 			 * already been handled (for future possibilities) */
 		} else {
-			/* Keep track of all files so we can generate a filelist later if missing */
-			all_files = alpm_list_add(all_files, strdup(entry_name));
+			/* Keep track of all files for filelist generation */
+			info->files = alpm_list_add(info->files, strdup(entry_name));
 		}
 
 		if(archive_read_data_skip(archive)) {
@@ -1100,7 +1074,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
 		}
 
 		/* if we are not doing a full read, see if we have all we need */
-		if(!full && config && filelist) {
+		if(!full && config) {
 			break;
 		}
 	}
@@ -1119,21 +1093,21 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
 
   archive_read_finish(archive);
 
-	if(!filelist) {
-		_alpm_log(PM_LOG_ERROR, _("missing package filelist in %s, generating one\n"), pkgfile);
-		info->files = all_files;
-	} else {
-		FREELIST(all_files);
-	}
-
-	/* this is IMPORTANT - "checking for conflicts" requires a sorted list, so we
-	 * ensure that here */
-	info->files = alpm_list_msort(info->files, alpm_list_count(info->files), _alpm_str_cmp);
-
-	/* internal */
+	/* internal fields for package struct */
 	info->origin = PKG_FROM_FILE;
 	info->origin_data.file = strdup(pkgfile);
-	info->infolevel = 0xFF;
+
+	if(full) {
+		/* "checking for conflicts" requires a sorted list, so we ensure that here */
+		_alpm_log(PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
+		info->files = alpm_list_msort(info->files, alpm_list_count(info->files),
+				_alpm_str_cmp);
+		info->infolevel = INFRQ_ALL;
+	} else {
+		/* get rid of any partial filelist we may have collected, as it is invalid */
+		FREELIST(info->files);
+		info->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_DEPENDS;
+	}
 
 	return(info);
 
diff --git a/pactest/pmpkg.py b/pactest/pmpkg.py
index 56cb26f..3ee5815 100755
--- a/pactest/pmpkg.py
+++ b/pactest/pmpkg.py
@@ -163,25 +163,9 @@ class pmpkg:
             mkinstallfile(".INSTALL", self.install)
             targets += " .INSTALL"
 
-        # .FILELIST
+        # package files
         if self.files:
-            # generate a filelist
-            filelist = []
-            current = ""
-            for path, dirs, files in os.walk("."):
-                # we have to strip the './' portion from the path
-                # and add a newline to each entry.
-                current = os.path.join(path, "")[2:]
-                if len(current) != 0:
-                    filelist.append(current + "\n")
-                for file in files:
-                    # skip .PKGINFO, etc.
-                    if(not file.startswith(".")):
-                        filelist.append(os.path.join(path, file)[2:] + "\n")
-            f = open('.FILELIST', 'w')
-            f.writelines(filelist)
-            f.close()
-            targets += " .FILELIST *"
+            targets += " *"
 
         #safely create the dir
         mkdir(os.path.dirname(self.path))
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index f37772a..3feb9cb 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -785,15 +785,6 @@ create_package() {
 	fi
 	local size=$(du -sb | awk '{print $1}')
 
-	msg2 "$(gettext "Generating .FILELIST file...")"
-	# The following command does the following:
-	# - find all directories and add a trailing /
-	# - find all other files/links
-	# - grep out dot files in root dir (e.g. .FILELIST .PKGINFO...)
-	# - sort the list
-	find . -mindepth 1 \( -type d -printf '%P/\n' \) ,  \( ! -type d -printf '%P\n' \) \
-		2>/dev/null | grep -v '^\.' | sort >.FILELIST
-
 	# write the .PKGINFO file
 	msg2 "$(gettext "Generating .PKGINFO file...")"
 	echo "# Generated by makepkg $myver" >.PKGINFO
@@ -845,7 +836,7 @@ create_package() {
 		plain "$(gettext "Example for GPL'ed software: license=('GPL').")"
 	fi
 
-	local comp_files=".PKGINFO .FILELIST"
+	local comp_files=".PKGINFO"
 
 	# check for an install script
 	# TODO: should we include ${pkgname}.install if it exists and $install is unset?
-- 
1.5.4.rc2





More information about the pacman-dev mailing list