From 226ac092dca4754b7b5a421e226c5971e3b607b2 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 20 Jul 2012 00:01:55 +0000 Subject: Fri Jul 20 00:01:55 UTC 2012 --- ...flict-for-replacing-owned-empty-directory.patch | 152 +++++++++++++++++++++ .../0002-Check-empty-subdirectory-ownership.patch | 61 +++++++++ libre/pacman/PKGBUILD | 36 +++-- libre/pacman/pacman.conf | 25 ++-- libre/pacman/pacman.conf.mips64el | 31 ++--- libre/pacman/pacman.conf.x86_64 | 27 ++-- libre/pacman/pacman.install | 11 +- libre/pacman/rePKGBUILD | 37 +++++ 8 files changed, 311 insertions(+), 69 deletions(-) create mode 100644 libre/pacman/0001-Add-conflict-for-replacing-owned-empty-directory.patch create mode 100644 libre/pacman/0002-Check-empty-subdirectory-ownership.patch create mode 100644 libre/pacman/rePKGBUILD (limited to 'libre/pacman') diff --git a/libre/pacman/0001-Add-conflict-for-replacing-owned-empty-directory.patch b/libre/pacman/0001-Add-conflict-for-replacing-owned-empty-directory.patch new file mode 100644 index 000000000..85622aaac --- /dev/null +++ b/libre/pacman/0001-Add-conflict-for-replacing-owned-empty-directory.patch @@ -0,0 +1,152 @@ +From 717fdb8ee0fd23cf72fc7d2832317f513caefa2c Mon Sep 17 00:00:00 2001 +From: Allan McRae +Date: Sun, 8 Jul 2012 21:36:36 +1000 +Subject: [PATCH 1/4] Add conflict for replacing owned empty directory + +When two packages own an empty directory, pacman finds no conflict when +one of those packages wants to replace the directory with a file or a +symlink. When it comes to actually extracting the new file/symlink, +pacman sees the directory is still there (we do not remove empty +directories if they are owned by a package) and refuses to extract. + +Detect this potential conflict early and bail. Note that it is a +_potential_ conflict and not a guaranteed one as the other package owning +the directory could be updated or removed first which would remove +the conflict. However, pacman currently can not sort package installation +order to ensure this, so this conflict requires manual upgrade ordering. + +Signed-off-by: Allan McRae +Signed-off-by: Dan McGee +--- + lib/libalpm/conflict.c | 32 ++++++++++++++++++++++++++------ + test/pacman/tests/fileconflict009.py | 20 ++++++++++++++++++++ + test/pacman/tests/fileconflict010.py | 20 ++++++++++++++++++++ + 3 files changed, 66 insertions(+), 6 deletions(-) + create mode 100644 test/pacman/tests/fileconflict009.py + create mode 100644 test/pacman/tests/fileconflict010.py + +diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c +index 32f6f30..efa1a87 100644 +--- a/lib/libalpm/conflict.c ++++ b/lib/libalpm/conflict.c +@@ -328,15 +328,35 @@ const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist, + return NULL; + } + +-static int dir_belongsto_pkg(const char *root, const char *dirpath, ++static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, + alpm_pkg_t *pkg) + { ++ alpm_list_t *i; + struct stat sbuf; + char path[PATH_MAX]; + char abspath[PATH_MAX]; +- struct dirent *ent = NULL; + DIR *dir; ++ struct dirent *ent = NULL; ++ const char *root = handle->root; ++ ++ /* TODO: this is an overly strict check but currently pacman will not ++ * overwrite a directory with a file (case 10/11 in add.c). Adjusting that ++ * is not simple as even if the directory is being unowned by a conflicting ++ * package, pacman does not sort this to ensure all required directory ++ * "removals" happen before installation of file/symlink */ ++ ++ /* check that no other _installed_ package owns the directory */ ++ for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) { ++ if(pkg == i->data) { ++ continue; ++ } ++ ++ if(_alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) { ++ return 0; ++ } ++ } + ++ /* check all files in directory are owned by the package */ + snprintf(abspath, PATH_MAX, "%s%s", root, dirpath); + dir = opendir(abspath); + if(dir == NULL) { +@@ -349,13 +369,13 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath, + if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } +- snprintf(path, PATH_MAX, "%s/%s", dirpath, name); ++ snprintf(path, PATH_MAX, "%s%s", dirpath, name); + snprintf(abspath, PATH_MAX, "%s%s", root, path); + if(stat(abspath, &sbuf) != 0) { + continue; + } + if(S_ISDIR(sbuf.st_mode)) { +- if(dir_belongsto_pkg(root, path, pkg)) { ++ if(dir_belongsto_pkg(handle, path, pkg)) { + continue; + } else { + closedir(dir); +@@ -529,9 +549,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, + sprintf(dir, "%s/", filestr); + if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) { + _alpm_log(handle, ALPM_LOG_DEBUG, +- "check if all files in %s belongs to %s\n", ++ "check if all files in %s belong to %s\n", + dir, dbpkg->name); +- resolved_conflict = dir_belongsto_pkg(handle->root, filestr, dbpkg); ++ resolved_conflict = dir_belongsto_pkg(handle, dir, dbpkg); + } + free(dir); + } +diff --git a/test/pacman/tests/fileconflict009.py b/test/pacman/tests/fileconflict009.py +new file mode 100644 +index 0000000..904af4a +--- /dev/null ++++ b/test/pacman/tests/fileconflict009.py +@@ -0,0 +1,20 @@ ++self.description = "dir->symlink change during package upgrade (directory conflict)" ++ ++lp1 = pmpkg("pkg1") ++lp1.files = ["dir/"] ++self.addpkg2db("local", lp1) ++ ++lp2 = pmpkg("pkg2") ++lp2.files = ["dir/"] ++self.addpkg2db("local", lp2) ++ ++p = pmpkg("pkg1", "1.0-2") ++p.files = ["dir -> /usr/dir"] ++self.addpkg2db("sync", p) ++ ++self.args = "-S pkg1" ++ ++self.addrule("PACMAN_RETCODE=1") ++self.addrule("PKG_VERSION=pkg1|1.0-1") ++self.addrule("PKG_VERSION=pkg2|1.0-1") ++self.addrule("DIR_EXIST=dir/") +diff --git a/test/pacman/tests/fileconflict010.py b/test/pacman/tests/fileconflict010.py +new file mode 100644 +index 0000000..0a3ce83 +--- /dev/null ++++ b/test/pacman/tests/fileconflict010.py +@@ -0,0 +1,20 @@ ++self.description = "dir->file change during package upgrade (directory conflict)" ++ ++lp1 = pmpkg("pkg1") ++lp1.files = ["dir/"] ++self.addpkg2db("local", lp1) ++ ++lp2 = pmpkg("pkg2") ++lp2.files = ["dir/"] ++self.addpkg2db("local", lp2) ++ ++p = pmpkg("pkg1", "1.0-2") ++p.files = ["dir"] ++self.addpkg2db("sync", p) ++ ++self.args = "-S pkg1" ++ ++self.addrule("PACMAN_RETCODE=1") ++self.addrule("PKG_VERSION=pkg1|1.0-1") ++self.addrule("PKG_VERSION=pkg2|1.0-1") ++self.addrule("DIR_EXIST=dir/") +-- +1.7.11.1 + diff --git a/libre/pacman/0002-Check-empty-subdirectory-ownership.patch b/libre/pacman/0002-Check-empty-subdirectory-ownership.patch new file mode 100644 index 000000000..6cf496d16 --- /dev/null +++ b/libre/pacman/0002-Check-empty-subdirectory-ownership.patch @@ -0,0 +1,61 @@ +From 44e9fdd0e848382337edb97d41e7317638a67bac Mon Sep 17 00:00:00 2001 +From: Allan McRae +Date: Sun, 8 Jul 2012 23:58:37 +1000 +Subject: [PATCH 2/4] Check empty subdirectory ownership + +When checking if a package owns a directory, it is important to check +not only that all the files in the directory are part of the package, +but also if the directory is part of a package. This catches empty +subdirectories during conflict checking for directory to file/symlink +replacements. + +Signed-off-by: Allan McRae +Signed-off-by: Dan McGee +--- + lib/libalpm/conflict.c | 5 +++++ + test/pacman/tests/fileconflict012.py | 17 +++++++++++++++++ + 2 files changed, 22 insertions(+) + create mode 100644 test/pacman/tests/fileconflict012.py + +diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c +index efa1a87..d6e5d8c 100644 +--- a/lib/libalpm/conflict.c ++++ b/lib/libalpm/conflict.c +@@ -339,6 +339,11 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, + struct dirent *ent = NULL; + const char *root = handle->root; + ++ /* check directory is actually in package - used for subdirectory checks */ ++ if(!_alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) { ++ return 0; ++ } ++ + /* TODO: this is an overly strict check but currently pacman will not + * overwrite a directory with a file (case 10/11 in add.c). Adjusting that + * is not simple as even if the directory is being unowned by a conflicting +diff --git a/test/pacman/tests/fileconflict012.py b/test/pacman/tests/fileconflict012.py +new file mode 100644 +index 0000000..421b739 +--- /dev/null ++++ b/test/pacman/tests/fileconflict012.py +@@ -0,0 +1,17 @@ ++self.description = "dir->file change during package upgrade (filesystem file conflict)" ++ ++lp1 = pmpkg("pkg1") ++lp1.files = ["dir/"] ++self.addpkg2db("local", lp1) ++ ++self.filesystem = ["dir/file"] ++ ++p = pmpkg("pkg1", "1.0-2") ++p.files = ["dir"] ++self.addpkg2db("sync", p) ++ ++self.args = "-S pkg1" ++ ++self.addrule("PACMAN_RETCODE=1") ++self.addrule("PKG_VERSION=pkg1|1.0-1") ++self.addrule("DIR_EXIST=dir/") +-- +1.7.11.1 + diff --git a/libre/pacman/PKGBUILD b/libre/pacman/PKGBUILD index d8d3a6d26..4f05be586 100644 --- a/libre/pacman/PKGBUILD +++ b/libre/pacman/PKGBUILD @@ -4,38 +4,42 @@ # Maintainer: Dave Reisner pkgname=pacman -pkgver=4.0.2 -pkgrel=1 +pkgver=4.0.3 +pkgrel=3 pkgdesc="A library-based package manager with dependency support" arch=('i686' 'x86_64' 'mips64el') url="http://www.archlinux.org/pacman/" license=('GPL') groups=('base') depends=('bash' 'glibc>=2.15' 'libarchive>=3.0.2' 'curl>=7.19.4' - 'gpgme' 'pacman-mirrorlist') + 'gpgme' 'pacman-mirrorlist' 'archlinux-keyring' 'parabola-keyring') makedepends=('asciidoc') optdepends=('fakeroot: for makepkg usage as normal user') backup=(etc/pacman.conf etc/makepkg.conf) install=pacman.install options=(!libtool) source=(ftp://ftp.archlinux.org/other/pacman/$pkgname-$pkgver.tar.gz{,.sig} + 0001-Add-conflict-for-replacing-owned-empty-directory.patch + 0002-Check-empty-subdirectory-ownership.patch pacman.conf pacman.conf.x86_64 pacman.conf.mips64el makepkg.conf) -md5sums=('289ba4a19a16393096e065cec1cb9b0a' - '575140dce3ea597d91b6d081aa3f6a00' - '858d1ffb284afc6b15f72578ba3cac50' - '7dade0c0a4d597c480d779afa4f5097c' - 'd4ca1a1d8e6708c0302a225628a489eb' +md5sums=('387965c7125e60e5f0b9ff3b427fe0f9' + '1a70392526c8768470da678b31905a6e' + '1a9b79788640907a2b34e8671cacc94a' + 'a9ddd43891bed364e1e97d27b2887bf1' + '080d9f76f56e135cc62205874636aa0f' + 'ce9943fc8086d491890565e91ea1a0d8' + 'eb8dba9bd0b315230fbf0e5dc0a7335b' 'debc512689a1aa8c124fe0ccf27f5758') -# keep an upgrade path for older installations -PKGEXT='.pkg.tar.gz' - build() { cd $srcdir/$pkgname-$pkgver + patch -p1 -i $srcdir/0001-Add-conflict-for-replacing-owned-empty-directory.patch + patch -p1 -i $srcdir/0002-Check-empty-subdirectory-ownership.patch + ./configure --prefix=/usr --sysconfdir=/etc \ --localstatedir=/var --enable-doc make @@ -83,8 +87,10 @@ package() { -e "s|@CARCHFLAGS[@]|$myflags|g" # install completion files - mkdir -p $pkgdir/etc/bash_completion.d/ - install -m644 contrib/bash_completion $pkgdir/etc/bash_completion.d/pacman - mkdir -p $pkgdir/usr/share/zsh/site-functions/ - install -m644 contrib/zsh_completion $pkgdir/usr/share/zsh/site-functions/_pacman + install -Dm644 contrib/bash_completion "$pkgdir/usr/share/bash-completion/completions/pacman" + for f in makepkg pacman-key; do + ln -s pacman "$pkgdir/usr/share/bash-completion/completions/$f" + done + + install -Dm644 contrib/zsh_completion $pkgdir/usr/share/zsh/site-functions/_pacman } diff --git a/libre/pacman/pacman.conf b/libre/pacman/pacman.conf index 92befa5fa..115217b59 100644 --- a/libre/pacman/pacman.conf +++ b/libre/pacman/pacman.conf @@ -36,18 +36,13 @@ Architecture = auto CheckSpace #VerbosePkgLists -# PGP signature checking -# NOTE: None of this will work without running `pacman-key --init` first. -# The compiled in default is equivalent to the following line. This requires -# you to locally sign and trust packager keys using `pacman-key` for them to be -# considered valid. +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. #SigLevel = Optional TrustedOnly -# If you wish to check signatures but avoid local sign and trust issues, use -# the following line. This will treat any key imported into pacman's keyring as -# trusted. -#SigLevel = Optional TrustAll -# For now, off by default unless you read the above. -SigLevel = Never + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. # # REPOSITORIES @@ -77,7 +72,7 @@ SigLevel = Never #Include = /etc/pacman.d/mirrorlist [libre] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[testing] @@ -85,11 +80,11 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [core] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist [extra] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[community-testing] @@ -97,7 +92,7 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [community] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist # Parabola also supports community projects and personal repositories, to find diff --git a/libre/pacman/pacman.conf.mips64el b/libre/pacman/pacman.conf.mips64el index a74f2d3da..f286c3290 100644 --- a/libre/pacman/pacman.conf.mips64el +++ b/libre/pacman/pacman.conf.mips64el @@ -16,9 +16,7 @@ #GPGDir = /etc/pacman.d/gnupg/ HoldPkg = pacman glibc # If upgrades are available for these packages they will be asked for first -# Don't list pacman here unless you want it broken when there is a -# libarchive or glibc update. -#SyncFirst = +SyncFirst = pacman #XferCommand = /usr/bin/curl -C - -f %u > %o #XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u #CleanMethod = KeepInstalled @@ -35,21 +33,16 @@ Architecture = mips64el #UseSyslog #UseDelta #TotalDownload -#CheckSpace +CheckSpace #VerbosePkgLists -# PGP signature checking -# NOTE: None of this will work without running `pacman-key --init` first. -# The compiled in default is equivalent to the following line. This requires -# you to locally sign and trust packager keys using `pacman-key` for them to be -# considered valid. +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. #SigLevel = Optional TrustedOnly -# If you wish to check signatures but avoid local sign and trust issues, use -# the following line. This will treat any key imported into pacman's keyring as -# trusted. -#SigLevel = Optional TrustAll -# For now, off by default unless you read the above. -SigLevel = Never + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. # # REPOSITORIES @@ -79,7 +72,7 @@ SigLevel = Never #Include = /etc/pacman.d/mirrorlist [libre] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[testing] @@ -87,11 +80,11 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [core] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist [extra] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[community-testing] @@ -99,7 +92,7 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [community] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist # Parabola also supports community projects and personal repositories, to find diff --git a/libre/pacman/pacman.conf.x86_64 b/libre/pacman/pacman.conf.x86_64 index 0eddc159c..4c67b089f 100644 --- a/libre/pacman/pacman.conf.x86_64 +++ b/libre/pacman/pacman.conf.x86_64 @@ -36,18 +36,13 @@ Architecture = auto CheckSpace #VerbosePkgLists -# PGP signature checking -# NOTE: None of this will work without running `pacman-key --init` first. -# The compiled in default is equivalent to the following line. This requires -# you to locally sign and trust packager keys using `pacman-key` for them to be -# considered valid. +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. #SigLevel = Optional TrustedOnly -# If you wish to check signatures but avoid local sign and trust issues, use -# the following line. This will treat any key imported into pacman's keyring as -# trusted. -#SigLevel = Optional TrustAll -# For now, off by default unless you read the above. -SigLevel = Never + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. # # REPOSITORIES @@ -77,7 +72,7 @@ SigLevel = Never #Include = /etc/pacman.d/mirrorlist [libre] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[testing] @@ -85,11 +80,11 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [core] -#SigLevel = PackageRequired +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist [extra] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist #[community-testing] @@ -97,7 +92,7 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist [community] -#SigLevel = PackageOptional +SigLevel = PackageRequired Include = /etc/pacman.d/mirrorlist # If you want to run 32 bit applications on your x86_64 system, @@ -108,7 +103,7 @@ Include = /etc/pacman.d/mirrorlist #Include = /etc/pacman.d/mirrorlist #[multilib] -#SigLevel = PackageOptional +#SigLevel = PackageRequired #Include = /etc/pacman.d/mirrorlist # Parabola also supports community projects and personal repositories, to find diff --git a/libre/pacman/pacman.install b/libre/pacman/pacman.install index 4369edab1..5dc55c0c2 100644 --- a/libre/pacman/pacman.install +++ b/libre/pacman/pacman.install @@ -9,7 +9,9 @@ post_upgrade() { if [ "$(vercmp $2 3.5.0)" -lt 0 ]; then _warnupgrade fi - _check_pubring + if [ ! -f "etc/pacman.d/gnupg/pubring.gpg" ] || [ "$(vercmp $2 4.0.3-2)" -lt 0 ]; then + _check_pubring + fi } post_install() { @@ -17,9 +19,10 @@ post_install() { } _check_pubring() { - if [ ! -f "etc/pacman.d/gnupg/pubring.gpg" ]; then - echo " >>> Run \`pacman-key --init\` to set up your pacman keyring." - fi + echo " >>> Run \`pacman-key --init; pacman-key --populate archlinux\`" + echo " >>> And \`pacman-key --populate parabola\`" + echo " >>> to import the data required by pacman for package verification." + echo " >>> See: https://www.archlinux.org/news/having-pacman-verify-packages" } _warnupgrade() { diff --git a/libre/pacman/rePKGBUILD b/libre/pacman/rePKGBUILD new file mode 100644 index 000000000..810eff5b9 --- /dev/null +++ b/libre/pacman/rePKGBUILD @@ -0,0 +1,37 @@ +# Maintainer: Nicolas Reynolds +source PKGBUILD +unset build package md5sums source check +_repo=core +source=(PKGBUILD + ftp://ftp.archlinux.org/${_repo}/os/${CARCH}/${pkgname%-libre}-$pkgver-$pkgrel-$CARCH$PKGEXT + # files for pkg modifications + pacman.conf + pacman.conf.x86_64 + ) +options=(!strip) + +build() { + cd "${srcdir}/" + rm -vf .{INSTALL,PKGINFO} ${srcdir}/${pkgname%-libre}-$pkgver-$pkgrel-$CARCH$PKGEXT + # put actions for package modifications below this line + +} + +package() { + cp -a ${srcdir}/* ${pkgdir} + + rm ${pkgdir}/{PKGBUILD,pacman.conf{,.x86_64}} + +# No need to repackage for mips64el + case "$CARCH" in + i686) + install -m644 $srcdir/pacman.conf $pkgdir/etc/pacman.conf + ;; + x86_64) + install -m644 $srcdir/pacman.conf.x86_64 $pkgdir/etc/pacman.conf + ;; + esac +} + + +# vim:set ts=2 sw=2 et: -- cgit v1.2.3-54-g00ecf