summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2004-07-03 06:25:48 +0200
committerJudd Vinet <judd@archlinux.org>2004-07-03 06:25:48 +0200
commitf6661379c68b541115efe25285965bbd4eb32d25 (patch)
tree270ebd31a01ead27fd676ebac673a909cfc08534
parenta2ee533f84aa858df5710d799c52b7d06a77b1de (diff)
downloadpacman-f6661379c68b541115efe25285965bbd4eb32d25.tar.gz
pacman-f6661379c68b541115efe25285965bbd4eb32d25.tar.xz
Imported from pacman-2.8.tar.gz
-rw-r--r--ChangeLog19
-rw-r--r--Makefile.in2
-rw-r--r--TODO1
-rw-r--r--doc/makepkg.8.in40
-rw-r--r--doc/pacman.8.in2
-rw-r--r--etc/pacman.conf100
-rw-r--r--libftp/ftplib.c8
-rwxr-xr-xscripts/gensync2
-rwxr-xr-xscripts/makepkg14
-rwxr-xr-xscripts/makeworld2
-rw-r--r--src/db.c174
-rw-r--r--src/db.h2
-rw-r--r--src/package.c41
-rw-r--r--src/package.h3
-rw-r--r--src/pacman.c176
-rw-r--r--src/pacman.h2
-rw-r--r--src/pacsync.c12
-rw-r--r--src/rpmvercmp.c118
-rw-r--r--src/rpmvercmp.h4
-rw-r--r--src/util.c36
-rw-r--r--src/util.h4
21 files changed, 551 insertions, 211 deletions
diff --git a/ChangeLog b/ChangeLog
index defa4407..f4d5dc5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.8 - Bugfixes:
+ - #861: file:/// urls not handled properly with XferCommand
+ - #1003: set umask before scriptlet calls
+ - #1027: download problems with http urls using -U/-A
+ - #1044: segfaults when using -Rs
+ - #863: "missing post_remove" errors with some packages
+ - #875: detect low disk space properly
+ - #986: makepkg -e doesn't validate files
+ - #1010: add -j option to makepkg
+ - #1028: make pacman -Sp runnable as non-root
+ - added pre_install and pre_upgrade scriptlet support
+ - added an "Architecture" field in the package meta-data
+ - added patch from Aurelien Foret which improves performance
+ adding or removing packages
+ - added implementation of GNU's strverscmp function for better
+ portability
+ - added explicit unlink() calls when --force is used, which
+ prevents those nasty "Text file busy" errors when you
+ force-upgrade something like pacman or glibc.
2.7.9 - added the "force" option to packages, so --sysupgrade can
downgrade packages when it needs to
2.7.8 - added post_remove scriptlet support
diff --git a/Makefile.in b/Makefile.in
index c5238b6f..eee644cc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
-PACVER = 2.7.9
+PACVER = 2.8
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
diff --git a/TODO b/TODO
index ec0fea3c..8cec3c94 100644
--- a/TODO
+++ b/TODO
@@ -4,6 +4,5 @@
- when performing replaces, pacman should not remove old packages until
the conflict checks are passed
- handle version comparators in makepkg dep resolution (eg, glibc>=2.2.5)
-- add post_remove, pre_install, pre_upgrade functions to scriptlets
- check $PACCONF env var
- add a --pretend option
diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in
index 27461315..63d417e1 100644
--- a/doc/makepkg.8.in
+++ b/doc/makepkg.8.in
@@ -1,4 +1,4 @@
-.TH makepkg 8 "April 29, 2004" "makepkg #VERSION#" ""
+.TH makepkg 8 "July 2, 2004" "makepkg #VERSION#" ""
.SH NAME
makepkg \- package build utility
.SH SYNOPSIS
@@ -120,12 +120,20 @@ itself" after installation and do the opposite right before it is removed.
The exact time the script is run varies with each operation:
.TP
+.B pre_install
+script is run right before files are extracted.
+
+.TP
.B post_install
-script is run right after files are installed.
+script is run right after files are extracted.
+
+.TP
+.B pre_upgrade
+script is run right before files are extracted.
.TP
.B post_upgrade
-script is run after all files have been upgraded.
+script is run after files are extracted.
.TP
.B pre_remove
@@ -152,6 +160,14 @@ The install script does not need to be specified in the \fIsource\fP array.
.RS
.nf
# arg 1: the new package version
+pre_install() {
+ #
+ # do pre-install stuff here
+ #
+ /bin/true
+}
+
+# arg 1: the new package version
post_install() {
#
# do post-install stuff here
@@ -161,6 +177,15 @@ post_install() {
# arg 1: the new package version
# arg 2: the old package version
+pre_upgrade() {
+ #
+ # do pre-upgrade stuff here
+ #
+ /bin/true
+}
+
+# arg 1: the new package version
+# arg 2: the old package version
post_upgrade() {
#
# do post-upgrade stuff here
@@ -221,6 +246,11 @@ This field contains an optional URL that is associated with the piece of softwar
being packaged. This is typically the project's website.
.TP
+.B license
+Sets the license type (eg, "GPL", "BSD", "NON-FREE"). (\fBNote\fP: This
+option is still in development and may change in the future)
+
+.TP
.B install
Specifies a special install script that is to be included in the package.
This file should reside in the same directory as the PKGBUILD, and will be
@@ -328,6 +358,10 @@ Output syntax and commandline options.
.B "\-i, \-\-install"
Install/Upgrade the package after a successful build.
.TP
+.B "\-j <jobs>"
+Sets MAKEFLAGS="-j<jobs>" before building the package. This is useful for overriding
+the MAKEFLAGS setting in /etc/makepkg.conf.
+.TP
.B "\-m, \-\-nocolor"
Disable color in output messages
.TP
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 32cd42db..29ba0c0b 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "April 29, 2004" "pacman #VERSION#" ""
+.TH pacman 8 "July 2, 2004" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 6ecb832a..39162727 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -29,69 +29,69 @@ NoUpgrade = etc/lilo.conf boot/grub/menu.lst
# REPOSITORIES
#
[current]
-Server = ftp://ftp.archlinux.org/current
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current
-Server = ftp://ftp.archlinux.de/pub/archlinux/current
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/current
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/current
-Server = ftp://ftp.kegep.tuc.gr/archlinux/current
-Server = http://darkstar.ist.utl.pt/archlinux/current
-Server = ftp://archlinux.creativa.cl/current
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current
-Server = ftp://saule.mintis.lt/pub/linux/current
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current
+Server = ftp://ftp.archlinux.org/current/os/i686
+Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current/os/i686
+Server = ftp://ftp.archlinux.de/pub/archlinux/current/os/i686
+Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current/os/i686
+Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/current/os/i686
+Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/current/os/i686
+Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/current/os/i686
+Server = ftp://ftp.kegep.tuc.gr/archlinux/current/os/i686
+Server = http://darkstar.ist.utl.pt/archlinux/current/os/i686
+Server = ftp://archlinux.creativa.cl/current/os/i686
+Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current/os/i686
+Server = ftp://saule.mintis.lt/pub/linux/current/os/i686
+Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current/os/i686
# Uncomment this block to access the EXTRA package set
#
[extra]
-Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra
-Server = ftp://ftp.archlinux.de/pub/archlinux/extra
-Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/extra
-Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/extra
-Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/extra
-Server = ftp://ftp.archlinux.org/extra
-Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/extra
-Server = ftp://ftp.kegep.tuc.gr/archlinux/extra
-Server = http://darkstar.ist.utl.pt/archlinux/extra
-Server = ftp://archlinux.creativa.cl/extra
-Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/extra
-Server = ftp://saule.mintis.lt/pub/linux/extra
-Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra
+Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra/os/i686
+Server = ftp://ftp.archlinux.de/pub/archlinux/extra/os/i686
+Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/extra/os/i686
+Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/extra/os/i686
+Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/extra/os/i686
+Server = ftp://ftp.archlinux.org/extra/os/i686
+Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/extra/os/i686
+Server = ftp://ftp.kegep.tuc.gr/archlinux/extra/os/i686
+Server = http://darkstar.ist.utl.pt/archlinux/extra/os/i686
+Server = ftp://archlinux.creativa.cl/extra/os/i686
+Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/extra/os/i686
+Server = ftp://saule.mintis.lt/pub/linux/extra/os/i686
+Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra/os/i686
# If you use the RELEASE tree, you should disable the CURRENT
# tree to avoid conflicts
#
#[release]
-#Server = ftp://ftp.archlinux.org/release
-#Server = ftp://ftp.archlinux.de/pub/archlinux/release
-#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/release
-#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/release
-#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/release
-#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/release
-#Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/release
-#Server = ftp://ftp.kegep.tuc.gr/archlinux/release
-#Server = http://darkstar.ist.utl.pt/archlinux/release
-#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/release
-#Server = ftp://saule.mintis.lt/pub/linux/release
-#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/release
+#Server = ftp://ftp.archlinux.org/release/os/i686
+#Server = ftp://ftp.archlinux.de/pub/archlinux/release/os/i686
+#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/release/os/i686
+#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/release/os/i686
+#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/release/os/i686
+#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/release/os/i686
+#Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/release/os/i686
+#Server = ftp://ftp.kegep.tuc.gr/archlinux/release/os/i686
+#Server = http://darkstar.ist.utl.pt/archlinux/release/os/i686
+#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/release/os/i686
+#Server = ftp://saule.mintis.lt/pub/linux/release/os/i686
+#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/release/os/i686
# Uncomment this block to access the UNSTABLE package set
#
#[unstable]
-#Server = ftp://ftp.archlinux.org/unstable
-#Server = ftp://ftp.archlinux.de/pub/archlinux/unstable
-#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable
-#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unstable
-#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unstable
-#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unstable
-#Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/unstable
-#Server = http://darkstar.ist.utl.pt/archlinux/unstable
-#Server = ftp://archlinux.creativa.cl/unstable
-#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable
-#Server = ftp://saule.mintis.lt/pub/linux/unstable
-#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unstable
+#Server = ftp://ftp.archlinux.org/unstable/os/i686
+#Server = ftp://ftp.archlinux.de/pub/archlinux/unstable/os/i686
+#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable/os/i686
+#Server = ftp://ftp.mpi-sb.mpg.de/pub/linux/mirror/ftp.ibiblio.org/pub/Linux/distributions/archlinux/unstable/os/i686
+#Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/unstable/os/i686
+#Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/unstable/os/i686
+#Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/unstable/os/i686
+#Server = http://darkstar.ist.utl.pt/archlinux/unstable/os/i686
+#Server = ftp://archlinux.creativa.cl/unstable/os/i686
+#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable/os/i686
+#Server = ftp://saule.mintis.lt/pub/linux/unstable/os/i686
+#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unstable/os/i686
# An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories.
diff --git a/libftp/ftplib.c b/libftp/ftplib.c
index 1e299b5b..b69744eb 100644
--- a/libftp/ftplib.c
+++ b/libftp/ftplib.c
@@ -1139,9 +1139,9 @@ static int FtpXfer(const char *localfile, const char *path,
else
{
while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0)
- if (fwrite(dbuf, 1, l, local) <= 0)
+ if (fwrite(dbuf, 1, l, local) < l)
{
- perror("localfile write");
+ perror("\nlocalfile write");
rv = 0;
break;
}
@@ -1486,9 +1486,9 @@ static int HttpXfer(const char *localfile, const char *path, int *size,
{
nControl->dir = FTPLIB_READ;
while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nControl)) > 0) {
- if (fwrite(dbuf, 1, l, local) <= 0)
+ if (fwrite(dbuf, 1, l, local) < l)
{
- perror("localfile write");
+ perror("\nlocalfile write");
rv = 0;
break;
}
diff --git a/scripts/gensync b/scripts/gensync
index 665135f6..c15a67d1 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.7.9'
+myver='2.8'
usage() {
echo "gensync $myver"
diff --git a/scripts/makepkg b/scripts/makepkg
index d4ce6e32..971bbf79 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.7.9'
+myver='2.8'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"
@@ -184,6 +184,7 @@ usage() {
echo " -g, --genmd5 Generate MD5sums for source files"
echo " -h, --help This help"
echo " -i, --install Install package after successful build"
+ echo " -j <jobs> Set MAKEFLAGS to \"-j<jobs>\" before building"
echo " -m, --nocolor Disable colorized output messages"
echo " -n, --nostrip Do not strip binaries/libraries"
echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
@@ -236,7 +237,7 @@ while [ "$#" -ne "0" ]; do
exit 1
;;
-*)
- while getopts "cCsbdehifgmnrp:w:-" opt; do
+ while getopts "cCsbdehifgj:mnrp:w:-" opt; do
case $opt in
c) CLEANUP=1 ;;
C) CLEANCACHE=1 ;;
@@ -251,6 +252,7 @@ while [ "$#" -ne "0" ]; do
n) NOSTRIP=1 ;;
w) PKGDEST=$OPTARG ;;
p) BUILDSCRIPT=$OPTARG ;;
+ j) export MAKEFLAGS="-j$OPTARG" ;;
r) RMDEPS=1 ;;
h)
usage
@@ -401,7 +403,7 @@ for netfile in ${source[@]}; do
exit 1
fi
proto=`echo $netfile | sed 's|://.*||'`
- if [ "$proto" != "ftp" -a "$proto" != "http" ]; then
+ if [ "$proto" != "ftp" -a "$proto" != "http" -a "$proto" != "https" ]; then
error "$netfile was not found in the build directory and is not a proper URL."
msg "Aborting..."
exit 1
@@ -423,7 +425,8 @@ done
if [ "$GENMD5" = "0" ]; then
if [ "$NOEXTRACT" = "1" ]; then
- warning "Skipping source extraction -- using existing src/ tree"
+ warning "Skipping source extraction -- using existing src/ tree"
+ warning "Skipping source integrity checks -- using existing src/ tree"
else
# MD5 validation
if [ ${#md5sums[@]} -ne ${#source[@]} ]; then
@@ -615,6 +618,9 @@ echo "license = $license" >>.PKGINFO
echo "builddate = $builddate" >>.PKGINFO
echo "packager = $packager" >>.PKGINFO
echo "size = $size" >>.PKGINFO
+if [ "$CARCH" != "" ]; then
+ echo "arch = $CARCH" >>.PKGINFO
+fi
for it in "${replaces[@]}"; do
echo "replaces = $it" >>.PKGINFO
diff --git a/scripts/makeworld b/scripts/makeworld
index 16dd9f32..1657e696 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -21,7 +21,7 @@
#
toplevel=`pwd`
-version="2.7.9"
+version="2.8"
usage() {
echo "makeworld version $version"
diff --git a/src/db.c b/src/db.c
index 33b1ea56..467ee133 100644
--- a/src/db.c
+++ b/src/db.c
@@ -222,6 +222,12 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL);
}
trim(info->license);
+ } else if(!strcmp(line, "%ARCH%")) {
+ if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
+ FREEPKG(info);
+ return(NULL);
+ }
+ trim(info->arch);
} else if(!strcmp(line, "%BUILDDATE%")) {
if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) {
FREEPKG(info);
@@ -339,15 +345,17 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
}
/* INSTALL */
- snprintf(path, PATH_MAX, "%s/%s/install", db->path, ent->d_name);
- if(!stat(path, &buf)) {
- info->scriptlet = 1;
+ if(inforeq & INFRQ_ALL) {
+ snprintf(path, PATH_MAX, "%s/%s/install", db->path, ent->d_name);
+ if(!stat(path, &buf)) {
+ info->scriptlet = 1;
+ }
}
return(info);
}
-int db_write(pacdb_t *db, pkginfo_t *info)
+int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
{
char topdir[PATH_MAX];
FILE *fp = NULL;
@@ -367,87 +375,95 @@ int db_write(pacdb_t *db, pkginfo_t *info)
umask(0022);
/* DESC */
- snprintf(path, PATH_MAX, "%s/desc", topdir);
- fp = fopen(path, "w");
- if(fp == NULL) {
- perror("db_write");
- umask(oldmask);
- return(1);
- }
- fputs("%NAME%\n", fp);
- fprintf(fp, "%s\n\n", info->name);
- fputs("%VERSION%\n", fp);
- fprintf(fp, "%s\n\n", info->version);
- fputs("%DESC%\n", fp);
- fprintf(fp, "%s\n\n", info->desc);
- fputs("%GROUPS%\n", fp);
- for(lp = info->groups; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
+ if(inforeq & INFRQ_DESC) {
+ snprintf(path, PATH_MAX, "%s/desc", topdir);
+ fp = fopen(path, "w");
+ if(fp == NULL) {
+ perror("db_write");
+ umask(oldmask);
+ return(1);
+ }
+ fputs("%NAME%\n", fp);
+ fprintf(fp, "%s\n\n", info->name);
+ fputs("%VERSION%\n", fp);
+ fprintf(fp, "%s\n\n", info->version);
+ fputs("%DESC%\n", fp);
+ fprintf(fp, "%s\n\n", info->desc);
+ fputs("%GROUPS%\n", fp);
+ for(lp = info->groups; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fputs("%URL%\n", fp);
+ fprintf(fp, "%s\n\n", info->url);
+ fputs("%LICENSE%\n", fp);
+ fprintf(fp, "%s\n\n", info->license);
+ fputs("%ARCH%\n", fp);
+ fprintf(fp, "%s\n\n", info->arch);
+ fputs("%BUILDDATE%\n", fp);
+ fprintf(fp, "%s\n\n", info->builddate);
+ fputs("%INSTALLDATE%\n", fp);
+ fprintf(fp, "%s\n\n", info->installdate);
+ fputs("%PACKAGER%\n", fp);
+ fprintf(fp, "%s\n\n", info->packager);
+ fputs("%SIZE%\n", fp);
+ fprintf(fp, "%ld\n\n", info->size);
+ fclose(fp);
}
- fprintf(fp, "\n");
- fputs("%URL%\n", fp);
- fprintf(fp, "%s\n\n", info->url);
- fputs("%LICENSE%\n", fp);
- fprintf(fp, "%s\n\n", info->license);
- fputs("%BUILDDATE%\n", fp);
- fprintf(fp, "%s\n\n", info->builddate);
- fputs("%INSTALLDATE%\n", fp);
- fprintf(fp, "%s\n\n", info->installdate);
- fputs("%PACKAGER%\n", fp);
- fprintf(fp, "%s\n\n", info->packager);
- fputs("%SIZE%\n", fp);
- fprintf(fp, "%ld\n\n", info->size);
- fclose(fp);
/* FILES */
- snprintf(path, PATH_MAX, "%s/files", topdir);
- fp = fopen(path, "w");
- if(fp == NULL) {
- perror("db_write");
- umask(oldmask);
- return(1);
- }
- fputs("%FILES%\n", fp);
- for(lp = info->files; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
- }
- fprintf(fp, "\n");
- fputs("%BACKUP%\n", fp);
- for(lp = info->backup; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
+ if(inforeq & INFRQ_FILES) {
+ snprintf(path, PATH_MAX, "%s/files", topdir);
+ fp = fopen(path, "w");
+ if(fp == NULL) {
+ perror("db_write");
+ umask(oldmask);
+ return(1);
+ }
+ fputs("%FILES%\n", fp);
+ for(lp = info->files; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fputs("%BACKUP%\n", fp);
+ for(lp = info->backup; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fclose(fp);
}
- fprintf(fp, "\n");
- fclose(fp);
/* DEPENDS */
- snprintf(path, PATH_MAX, "%s/depends", topdir);
- fp = fopen(path, "w");
- if(fp == NULL) {
- perror("db_write");
- umask(oldmask);
- return(1);
- }
- fputs("%DEPENDS%\n", fp);
- for(lp = info->depends; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
- }
- fprintf(fp, "\n");
- fputs("%REQUIREDBY%\n", fp);
- for(lp = info->requiredby; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
- }
- fprintf(fp, "\n");
- fputs("%CONFLICTS%\n", fp);
- for(lp = info->conflicts; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
- }
- fprintf(fp, "\n");
- fputs("%PROVIDES%\n", fp);
- for(lp = info->provides; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char*)lp->data);
- }
- fprintf(fp, "\n");
- fclose(fp);
+ if(inforeq & INFRQ_DEPENDS) {
+ snprintf(path, PATH_MAX, "%s/depends", topdir);
+ fp = fopen(path, "w");
+ if(fp == NULL) {
+ perror("db_write");
+ umask(oldmask);
+ return(1);
+ }
+ fputs("%DEPENDS%\n", fp);
+ for(lp = info->depends; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fputs("%REQUIREDBY%\n", fp);
+ for(lp = info->requiredby; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fputs("%CONFLICTS%\n", fp);
+ for(lp = info->conflicts; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fputs("%PROVIDES%\n", fp);
+ for(lp = info->provides; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
/* INSTALL */
/* nothing needed here (script is automatically extracted) */
diff --git a/src/db.h b/src/db.h
index 6160a5f0..c070a323 100644
--- a/src/db.h
+++ b/src/db.h
@@ -40,7 +40,7 @@ void db_close(pacdb_t *db);
PMList* db_loadpkgs(pacdb_t *db);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq);
pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq);
-int db_write(pacdb_t *db, pkginfo_t *info);
+int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq);
void db_search(pacdb_t *db, PMList *cache, const char *treename, PMList *needles);
PMList* db_find_conflicts(pacdb_t *db, PMList* targets, char *root);
PMList *whatprovides(pacdb_t *db, char* package);
diff --git a/src/package.c b/src/package.c
index b9087d85..435d18d2 100644
--- a/src/package.c
+++ b/src/package.c
@@ -36,6 +36,7 @@ pkginfo_t* load_pkg(char *pkgfile)
int i;
int config = 0;
int filelist = 0;
+ int scriptcheck = 0;
TAR *tar;
pkginfo_t *info = NULL;
PMList *backup = NULL;
@@ -47,14 +48,15 @@ pkginfo_t* load_pkg(char *pkgfile)
(writefunc_t)gzwrite
};
- info = newpkg();
-
if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
perror("could not open package");
return(NULL);
}
+
+ info = newpkg();
+
for(i = 0; !th_read(tar); i++) {
- if(config && filelist) {
+ if(config && filelist && scriptcheck) {
/* we have everything we need */
break;
}
@@ -87,6 +89,7 @@ pkginfo_t* load_pkg(char *pkgfile)
continue;
} else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) {
info->scriptlet = 1;
+ scriptcheck = 1;
} else if(!strcmp(th_get_pathname(tar), ".FILELIST")) {
/* Build info->files from the filelist */
FILE *fp;
@@ -112,7 +115,9 @@ pkginfo_t* load_pkg(char *pkgfile)
}
FREE(fn);
filelist = 1;
+ continue;
} else {
+ scriptcheck = 1;
if(!filelist) {
/* no .FILELIST present in this package.. build the filelist the */
/* old-fashioned way, one at a time */
@@ -197,6 +202,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
strncpy(info->installdate, ptr, sizeof(info->installdate));
} else if(!strcmp(key, "PACKAGER")) {
strncpy(info->packager, ptr, sizeof(info->packager));
+ } else if(!strcmp(key, "ARCH")) {
+ strncpy(info->arch, ptr, sizeof(info->arch));
} else if(!strcmp(key, "SIZE")) {
char tmp[32];
strncpy(tmp, ptr, sizeof(tmp));
@@ -239,6 +246,7 @@ pkginfo_t* newpkg()
pkg->installdate[0] = '\0';
pkg->packager[0] = '\0';
pkg->md5sum[0] = '\0';
+ pkg->arch[0] = '\0';
pkg->size = 0;
pkg->scriptlet = 0;
pkg->force = 0;
@@ -327,6 +335,7 @@ void dump_pkg_full(pkginfo_t *info)
printf("Packager : %s\n", info->packager);
printf("URL : %s\n", info->url);
printf("License : %s\n", info->license);
+ printf("Architecture : %s\n", info->arch);
printf("Size : %ld\n", info->size);
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : "");
@@ -380,18 +389,24 @@ void dump_pkg_sync(pkginfo_t *info)
printf("\nMD5 Sum : %s\n", info->md5sum);
}
-int split_pkgname(char *pkg, char **name, char **version)
+int split_pkgname(char *pkgfile, char *name, char *version)
{
- char tmp[256];
+ char tmp[512];
char *p, *q;
- strncpy(tmp, pkg, 256);
-
- p = strstr(tmp, ".pkg.tar.gz");
- if(p == NULL) {
- return(-1);
+ /* trim path name (if any) */
+ if((p = strrchr(pkgfile, '/')) == NULL) {
+ p = pkgfile;
+ } else {
+ p++;
}
- *p = 0;
+ strncpy(tmp, p, 512);
+ /* trim file extension (if any) */
+ if((p = strstr(tmp, ".pkg.tar.gz"))) {
+ *p = 0;
+ }
+
+ p = tmp + strlen(tmp);
for(q = --p; *q && *q != '-'; q--);
if(*q != '-' || q == tmp) {
@@ -401,10 +416,10 @@ int split_pkgname(char *pkg, char **name, char **version)
if(*p != '-' || p == tmp) {
return(-1);
}
- *version = strdup(p+1);
+ strncpy(version, p+1, 64);
*p = 0;
- *name = strdup(tmp);
+ strncpy(name, tmp, 256);
return(0);
}
diff --git a/src/package.h b/src/package.h
index 91d2fdc9..58ef93da 100644
--- a/src/package.h
+++ b/src/package.h
@@ -51,6 +51,7 @@ typedef struct __pkginfo_t {
char installdate[32];
char packager[64];
char md5sum[33];
+ char arch[32];
unsigned long size;
unsigned short scriptlet;
unsigned short force;
@@ -84,7 +85,7 @@ int pkgcmp(const void *p1, const void *p2);
int is_pkgin(pkginfo_t *needle, PMList *haystack);
void dump_pkg_full(pkginfo_t *info);
void dump_pkg_sync(pkginfo_t *info);
-int split_pkgname(char *pkg, char **name, char **version);
+int split_pkgname(char *pkgfile, char *name, char *version);
#endif
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman.c b/src/pacman.c
index 2670ede5..96a9a7f4 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -1,7 +1,7 @@
/*
* pacman.c
*
- * Copyright (c) 2002 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2002-2004 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -143,7 +143,7 @@ int main(int argc, char *argv[])
pm_access = READ_ONLY;
if(pmo_op != PM_MAIN && pmo_op != PM_QUERY && pmo_op != PM_DEPTEST) {
if(pmo_op == PM_SYNC && !pmo_s_sync &&
- (pmo_s_search || pmo_group || pmo_q_list || pmo_q_info)) {
+ (pmo_s_search || pmo_s_printuris || pmo_group || pmo_q_list || pmo_q_info)) {
/* special case: PM_SYNC can be used w/ pmo_s_search by any user */
} else {
if(geteuid() != 0) {
@@ -349,23 +349,31 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = cache; i; i = i->next) {
char *str = (char *)i->data;
- char *name, *version;
+ char name[256], version[64];
- if(split_pkgname(str, &name, &version) != 0) {
+ if(strstr(str, ".pkg.tar.gz") == NULL) {
clean = list_add(clean, strdup(str));
continue;
}
/* we keep partially downloaded files */
if(strstr(str, ".pkg.tar.gz.part")) {
- FREE(name);
- FREE(version);
+ continue;
+ }
+ if(split_pkgname(str, name, version) != 0) {
+ clean = list_add(clean, strdup(str));
continue;
}
for(j = i->next; j; j = j->next) {
char *s = (char *)j->data;
- char *n, *v;
+ char n[256], v[64];
- if(split_pkgname(s, &n, &v) != 0) {
+ if(strstr(s, ".pkg.tar.gz") == NULL) {
+ continue;
+ }
+ if(strstr(s, ".pkg.tar.gz.part")) {
+ continue;
+ }
+ if(split_pkgname(s, n, v) != 0) {
continue;
}
if(!strcmp(name, n)) {
@@ -379,11 +387,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
clean = list_add(clean, strdup(ptr));
}
}
- FREE(n);
- FREE(v);
}
- FREE(name);
- FREE(version);
}
FREELIST(cache);
@@ -805,7 +809,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
continue;
}
local = db_scan(db, targ, INFRQ_DESC);
- if(local && !pmo_s_downloadonly) {
+ if(local && !pmo_s_downloadonly && !pmo_s_printuris) {
/* this is an upgrade, compare versions and determine if it is necessary */
cmp = rpmvercmp(local->version, sync->pkg->version);
if(cmp > 0) {
@@ -1282,7 +1286,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = final; i; i = i->next) {
syncpkg_t *sync = (syncpkg_t*)i->data;
if(sync->replaces) {
- pkginfo_t *new = db_scan(db, sync->pkg->name, INFRQ_ALL);
+ pkginfo_t *new = db_scan(db, sync->pkg->name, INFRQ_DEPENDS);
for(j = sync->replaces; j; j = j->next) {
pkginfo_t *old = (pkginfo_t*)j->data;
/* merge lists */
@@ -1290,21 +1294,21 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(!is_in(k->data, new->requiredby)) {
/* replace old's name with new's name in the requiredby's dependency list */
PMList *m;
- pkginfo_t *depender = db_scan(db, k->data, INFRQ_ALL);
+ pkginfo_t *depender = db_scan(db, k->data, INFRQ_DEPENDS);
for(m = depender->depends; m; m = m->next) {
if(!strcmp(m->data, old->name)) {
FREE(m->data);
m->data = strdup(new->name);
}
}
- db_write(db, depender);
+ db_write(db, depender, INFRQ_DEPENDS);
/* add the new requiredby */
new->requiredby = list_add(new->requiredby, strdup(k->data));
}
}
}
- db_write(db, new);
+ db_write(db, new, INFRQ_DEPENDS);
FREEPKG(new);
}
}
@@ -1376,8 +1380,9 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* this target looks like an URL. download it and then
* strip the URL portion from the target.
*/
+ char spath[PATH_MAX];
char url[PATH_MAX];
- server_t server;
+ server_t *server;
PMList *servers = NULL;
PMList *files = NULL;
char *host, *path, *fn;
@@ -1389,12 +1394,23 @@ int pacman_add(pacdb_t *db, PMList *targets)
*path = '\0';
path++;
fn = strrchr(path, '/');
- *fn = '\0';
- fn++;
- server.protocol = url;
- server.server = host;
- server.path = path;
- servers = list_add(servers, &server);
+ if(fn) {
+ *fn = '\0';
+ if(path[0] == '/') {
+ snprintf(spath, PATH_MAX, "%s/", path);
+ } else {
+ snprintf(spath, PATH_MAX, "/%s/", path);
+ }
+ fn++;
+ } else {
+ fn = path;
+ strcpy(spath, "/");
+ }
+ MALLOC(server, sizeof(server_t));
+ server->protocol = url;
+ server->server = host;
+ server->path = spath;
+ servers = list_add(servers, server);
files = list_add(files, fn);
if(downloadfiles(servers, ".", files)) {
fprintf(stderr, "error: failed to download %s\n", (char*)targ->data);
@@ -1600,9 +1616,37 @@ int pacman_add(pacdb_t *db, PMList *targets)
printf("upgrading %s... ", info->name);
neednl = 1;
+
/* we'll need the full record for backup checks later */
oldpkg = db_scan(db, info->name, INFRQ_ALL);
+ /* pre_upgrade scriptlet */
+ if(info->scriptlet) {
+ char tmpdir[PATH_MAX];
+ char *rtmpdir;
+ snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
+ if(mkdtemp(tmpdir) == NULL) {
+ perror("error creating temp directory");
+ return(1);
+ }
+ /* chop off the pmo_root so we can find the tmpdir in the chroot */
+ rtmpdir = tmpdir + strlen(pmo_root) - 1;
+ unpack(file->data, tmpdir, ".INSTALL");
+ /* run the post-install script if it exists */
+ snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
+ if(grep(pm_install, "pre_upgrade")) {
+ char cmdline[PATH_MAX+1];
+ snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
+ vprint("Executing pre-upgrade script...\n");
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_upgrade %s %s\" | chroot %s /bin/sh",
+ pm_install, info->version, (oldpkg ? oldpkg->version : ""), pmo_root);
+ system(cmdline);
+ }
+ if(rmrf(tmpdir)) {
+ fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
+ }
+ }
+
if(oldpkg) {
list_add(tmp, strdup(info->name));
vprint("removing old package first...\n");
@@ -1626,6 +1670,32 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) {
printf("installing %s... ", info->name);
neednl = 1;
+ /* pre_install scriptlet */
+ if(info->scriptlet) {
+ char tmpdir[PATH_MAX];
+ char *rtmpdir;
+ snprintf(tmpdir, PATH_MAX, "%stmp/pacman-XXXXXX", pmo_root);
+ if(mkdtemp(tmpdir) == NULL) {
+ perror("error creating temp directory");
+ return(1);
+ }
+ /* chop off the pmo_root so we can find the tmpdir in the chroot */
+ rtmpdir = tmpdir + strlen(pmo_root) - 1;
+ unpack(file->data, tmpdir, ".INSTALL");
+ /* run the post-install script if it exists */
+ snprintf(pm_install, PATH_MAX, "%s/.INSTALL", tmpdir);
+ if(grep(pm_install, "pre_install")) {
+ char cmdline[PATH_MAX+1];
+ snprintf(pm_install, PATH_MAX, "%s/.INSTALL", rtmpdir);
+ vprint("Executing pre-install script...\n");
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s pre_install %s\" | chroot %s /bin/sh",
+ pm_install, info->version, pmo_root);
+ system(cmdline);
+ }
+ if(rmrf(tmpdir)) {
+ fprintf(stderr, "warning: could not remove tmpdir %s\n", tmpdir);
+ }
+ }
}
fflush(stdout);
@@ -1781,6 +1851,14 @@ int pacman_add(pacdb_t *db, PMList *targets)
logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath);
/*tar_skip_regfile(tar);*/
}
+ if(pmo_force) {
+ /* if pmo_force was used, then unlink() each file (whether it's there
+ * or not) before extracting. this prevents the old "Text file busy"
+ * error that crops up if one tries to --force a glibc or pacman
+ * upgrade.
+ */
+ unlink(expath);
+ }
if(tar_extract_file(tar, expath)) {
logaction(stderr, "could not extract %s: %s", pathname, strerror(errno));
errors++;
@@ -1821,7 +1899,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
pkginfo_t *tmpp = NULL;
PMList *tmppm = NULL;
- tmpp = db_scan(db, ((pkginfo_t*)lp->data)->name, INFRQ_DEPENDS);
+ tmpp = db_scan(db, ((pkginfo_t*)lp->data)->name, INFRQ_DESC | INFRQ_DEPENDS);
if(tmpp == NULL) {
continue;
}
@@ -1840,7 +1918,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
vprint("Updating database...");
/* make an install date (in UTC) */
strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate));
- if(db_write(db, info)) {
+ if(db_write(db, info, INFRQ_ALL)) {
logaction(stderr, "error updating database for %s!", info->name);
return(1);
}
@@ -1860,13 +1938,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(splitdep(lp->data, &depend)) {
continue;
}
- depinfo = db_scan(db, depend.name, INFRQ_ALL);
+ depinfo = db_scan(db, depend.name, INFRQ_DEPENDS);
if(depinfo == NULL) {
/* look for a provides package */
PMList *provides = whatprovides(db, depend.name);
if(provides) {
/* use the first one */
- depinfo = db_scan(db, provides->data, INFRQ_ALL);
+ depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
if(depinfo == NULL) {
/* wtf */
continue;
@@ -1876,19 +1954,20 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
}
depinfo->requiredby = list_add(depinfo->requiredby, strdup(info->name));
- db_write(db, depinfo);
+ db_write(db, depinfo, INFRQ_DEPENDS);
freepkg(depinfo);
}
printf("done.\n"); fflush(stdout);
/* run the post-install script if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf)) {
+ if(!stat(pm_install, &buf) && (grep(pm_install, "post_install") || grep(pm_install, "post_upgrade"))) {
char cmdline[PATH_MAX+1];
snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
vprint("Executing post-install script...\n");
- snprintf(cmdline, PATH_MAX, "chroot %s /bin/sh %s post_%s %s %s", pmo_root, pm_install,
- (pmo_upgrade ? "upgrade" : "install"), info->version, ((pmo_upgrade && oldpkg) ? oldpkg->version : ""));
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s post_%s %s %s\" | chroot %s /bin/sh",
+ pm_install, (pmo_upgrade ? "upgrade" : "install"), info->version,
+ ((pmo_upgrade && oldpkg) ? oldpkg->version : ""), pmo_root);
system(cmdline);
}
}
@@ -2021,10 +2100,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
fflush(stdout);
/* run the pre-remove script if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf)) {
+ if(!stat(pm_install, &buf) && grep(pm_install, "pre_remove")) {
vprint("Executing pre-remove script...\n");
snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
- snprintf(line, PATH_MAX, "chroot %s /bin/sh %s pre_remove %s", pmo_root, pm_install, info->version);
+ snprintf(line, PATH_MAX, "echo \"umask 0022; source %s pre_remove %s\" | chroot %s /bin/sh",
+ pm_install, info->version, pmo_root);
system(line);
}
@@ -2084,10 +2164,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) {
/* run the post-remove script if it exists */
snprintf(pm_install, PATH_MAX, "%s%s/%s/%s-%s/install", pmo_root, pmo_dbpath, db->treename, info->name, info->version);
- if(!stat(pm_install, &buf)) {
+ if(!stat(pm_install, &buf) && grep(pm_install, "post_remove")) {
vprint("Executing post-remove script...\n");
snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
- snprintf(line, PATH_MAX, "chroot %s /bin/sh %s post_remove %s", pmo_root, pm_install, info->version);
+ snprintf(line, PATH_MAX, "echo \"umask 0022; source %s post_remove %s\" | chroot %s /bin/sh",
+ pm_install, info->version, pmo_root);
system(line);
}
@@ -2119,7 +2200,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(splitdep((char*)lp->data, &depend)) {
continue;
}
- depinfo = db_scan(db, depend.name, INFRQ_ALL);
+ depinfo = db_scan(db, depend.name, INFRQ_DEPENDS);
if(depinfo == NULL) {
/* look for a provides package */
PMList *provides = whatprovides(db, depend.name);
@@ -2128,7 +2209,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
* the first one.
*/
/* use the first one */
- depinfo = db_scan(db, provides->data, INFRQ_ALL);
+ depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
list_free(provides);
if(depinfo == NULL) {
/* wtf */
@@ -2154,7 +2235,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
break;
}
}
- db_write(db, depinfo);
+ db_write(db, depinfo, INFRQ_DEPENDS);
freepkg(depinfo);
}
if(!pmo_upgrade) {
@@ -2493,12 +2574,27 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
continue;
}
dep = db_scan(db, depend.name, INFRQ_DESC | INFRQ_DEPENDS);
+ if(dep == NULL) {
+ /* package not found... look for a provisio instead */
+ k = whatprovides(db, depend.name);
+ if(k == NULL) {
+ fprintf(stderr, "warning: cannot find package \"%s\" or anything that provides it!\n", depend.name);
+ continue;
+ }
+ dep = db_scan(db, k->data, INFRQ_DESC | INFRQ_DEPENDS);
+ if(dep == NULL) {
+ fprintf(stderr, "dep is NULL!\n");
+ fflush(stderr);
+ }
+ FREELIST(k);
+ }
if(is_pkgin(dep, targs)) {
continue;
}
/* see if other packages need it */
for(k = dep->requiredby; k && !needed; k = k->next) {
- pkginfo_t *dummy = db_scan(db, k->data, INFRQ_DESC);
+ pkginfo_t *dummy;
+ dummy = db_scan(db, k->data, INFRQ_DESC);
if(!is_pkgin(dummy, targs)) {
needed = 1;
}
diff --git a/src/pacman.h b/src/pacman.h
index a36d690c..9a8520bb 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.7.9"
+#define PACVER "2.8"
#endif
#ifndef PKGDIR
diff --git a/src/pacsync.c b/src/pacsync.c
index d1045a63..4ea0bc95 100644
--- a/src/pacsync.c
+++ b/src/pacsync.c
@@ -95,7 +95,7 @@ int sync_synctree()
/* uncompress the sync database */
vprint("Unpacking %s...\n", path);
- if(unpack(path, ldir)) {
+ if(unpack(path, ldir, NULL)) {
return(1);
}
}
@@ -122,7 +122,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
for(i = servers; i && !done; i = i->next) {
server_t *server = (server_t*)i->data;
- if(!pmo_xfercommand) {
+ if(!pmo_xfercommand && strcmp(server->protocol, "file")) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpInit();
vprint("Connecting to %s:21\n", server->server);
@@ -180,7 +180,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
continue;
}
- if(pmo_xfercommand) {
+ if(pmo_xfercommand && strcmp(server->protocol, "file")) {
int ret;
int usepart = 0;
char *ptr1, *ptr2;
@@ -291,7 +291,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
} else {
filedone = 1;
}
- } else if(!strcmp(server->protocol, "http") || pmo_proxyhost) {
+ } else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) {
char src[PATH_MAX];
char *host;
unsigned port;
@@ -329,7 +329,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
}
if(!HttpGet(server->server, output, src, &fsz, control, offset)) {
fprintf(stderr, "\nfailed downloading %s from %s: %s\n",
- fn, server->server, FtpLastResponse(control));
+ src, server->server, FtpLastResponse(control));
/* we leave the partially downloaded file in place so it can be resumed later */
} else {
filedone = 1;
@@ -372,7 +372,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
if(!pmo_xfercommand) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpQuit(control);
- } else if(!strcmp(server->protocol, "http") || pmo_proxyhost) {
+ } else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) {
HttpQuit(control);
}
}
diff --git a/src/rpmvercmp.c b/src/rpmvercmp.c
index 3de46fd7..5ea656e5 100644
--- a/src/rpmvercmp.c
+++ b/src/rpmvercmp.c
@@ -22,9 +22,10 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include "config.h"
+#include "rpmvercmp.h"
/* this function was taken from rpm 4.0.4 and rewritten */
-
int rpmvercmp(const char *a, const char *b)
{
char *str1, *str2;
@@ -117,4 +118,119 @@ int rpmvercmp(const char *a, const char *b)
return(*one ? 1 : -1);
}
+#ifndef HAVE_STRVERSCMP
+
+/* GNU's strverscmp() function, taken from glibc 2.3.2 sources
+ */
+
+/* Compare strings while treating digits characters numerically.
+ Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
+ fractionnal parts, S_Z: idem but with leading Zeroes only */
+#define S_N 0x0
+#define S_I 0x4
+#define S_F 0x8
+#define S_Z 0xC
+
+/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
+#define CMP 2
+#define LEN 3
+
+
+/* Compare S1 and S2 as strings holding indices/version numbers,
+ returning less than, equal to or greater than zero if S1 is less than,
+ equal to or greater than S2 (for more info, see the texinfo doc).
+*/
+
+int strverscmp (s1, s2)
+ const char *s1;
+ const char *s2;
+{
+ const unsigned char *p1 = (const unsigned char *) s1;
+ const unsigned char *p2 = (const unsigned char *) s2;
+ unsigned char c1, c2;
+ int state;
+ int diff;
+
+ /* Symbol(s) 0 [1-9] others (padding)
+ Transition (10) 0 (01) d (00) x (11) - */
+ static const unsigned int next_state[] =
+ {
+ /* state x d 0 - */
+ /* S_N */ S_N, S_I, S_Z, S_N,
+ /* S_I */ S_N, S_I, S_I, S_I,
+ /* S_F */ S_N, S_F, S_F, S_F,
+ /* S_Z */ S_N, S_F, S_Z, S_Z
+ };
+
+ static const int result_type[] =
+ {
+ /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
+ 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
+
+ /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
+ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+ /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP,
+ +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
+ /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
+ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+ /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP,
+ -1, CMP, CMP, CMP
+ };
+
+ if (p1 == p2)
+ return 0;
+
+ c1 = *p1++;
+ c2 = *p2++;
+ /* Hint: '0' is a digit too. */
+ state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
+
+ while ((diff = c1 - c2) == 0 && c1 != '\0')
+ {
+ state = next_state[state];
+ c1 = *p1++;
+ c2 = *p2++;
+ state |= (c1 == '0') + (isdigit (c1) != 0);
+ }
+
+ state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
+
+ switch (state)
+ {
+ case CMP:
+ return diff;
+
+ case LEN:
+ while (isdigit (*p1++))
+ if (!isdigit (*p2++))
+ return 1;
+
+ return isdigit (*p2) ? -1 : diff;
+
+ default:
+ return state;
+ }
+}
+
+#endif
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/rpmvercmp.h b/src/rpmvercmp.h
index be030c6c..14cf10f9 100644
--- a/src/rpmvercmp.h
+++ b/src/rpmvercmp.h
@@ -23,6 +23,10 @@
int rpmvercmp(const char *a, const char *b);
+#ifndef HAVE_STRVERSCMP
+int strverscmp(const char *s1, const char *s2);
+#endif
+
#endif
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/util.c b/src/util.c
index c5f4d28d..07d9f2e1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -66,7 +66,7 @@ int gzopen_frontend(char *pathname, int oflags, int mode)
return (int)gzf;
}
-int unpack(char *archive, char *prefix)
+int unpack(char *archive, const char *prefix, const char *fn)
{
TAR *tar = NULL;
char expath[PATH_MAX];
@@ -83,10 +83,20 @@ int unpack(char *archive, char *prefix)
return(1);
}
while(!th_read(tar)) {
+ if(fn && strcmp(fn, th_get_pathname(tar))) {
+ if(TH_ISREG(tar) && tar_skip_regfile(tar)) {
+ char errorstr[255];
+ snprintf(errorstr, 255, "bad tar archive: %s", archive);
+ perror(errorstr);
+ return(1);
+ }
+ continue;
+ }
snprintf(expath, PATH_MAX, "%s/%s", prefix, th_get_pathname(tar));
if(tar_extract_file(tar, expath)) {
fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), strerror(errno));
}
+ if(fn) break;
}
tar_close(tar);
@@ -289,4 +299,28 @@ char* trim(char *str)
return str;
}
+/* A cheap grep for text files, returns 1 if a substring
+ * was found in the text file fn, 0 if it wasn't
+ */
+int grep(const char *fn, const char *needle)
+{
+ FILE *fp;
+
+ if((fp = fopen(fn, "r")) == NULL) {
+ return(0);
+ }
+ while(!feof(fp)) {
+ char line[1024];
+ fgets(line, 1024, fp);
+ if(feof(fp)) continue;
+ if(strstr(line, needle)) {
+ fclose(fp);
+ return(1);
+ }
+ }
+ fclose(fp);
+ return(0);
+}
+
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/util.h b/src/util.h
index 94114d4e..cd6a17dd 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,7 +29,7 @@
#define FREE(p) { if (p) { free(p); (p)= NULL; }}
int gzopen_frontend(char *pathname, int oflags, int mode);
-int unpack(char *archive, char *prefix);
+int unpack(char *archive, const char *prefix, const char *fn);
int copyfile(char *src, char *dest);
int makepath(char *path);
int rmrf(char *path);
@@ -37,7 +37,7 @@ void indentprint(char *str, int indent);
int yesno(char* fmt, ...);
char* trim(char *str);
char* strtoupper(char *str);
-
+int grep(const char *fn, const char *needle);
#endif
/* vim: set ts=2 sw=2 noet: */