From f6661379c68b541115efe25285965bbd4eb32d25 Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Sat, 3 Jul 2004 04:25:48 +0000 Subject: Imported from pacman-2.8.tar.gz --- ChangeLog | 19 ++++++ Makefile.in | 2 +- TODO | 1 - doc/makepkg.8.in | 40 ++++++++++++- doc/pacman.8.in | 2 +- etc/pacman.conf | 100 +++++++++++++++---------------- libftp/ftplib.c | 8 +-- scripts/gensync | 2 +- scripts/makepkg | 14 +++-- scripts/makeworld | 2 +- src/db.c | 174 +++++++++++++++++++++++++++++------------------------ src/db.h | 2 +- src/package.c | 41 +++++++++---- src/package.h | 3 +- src/pacman.c | 176 +++++++++++++++++++++++++++++++++++++++++------------- src/pacman.h | 2 +- src/pacsync.c | 12 ++-- src/rpmvercmp.c | 118 +++++++++++++++++++++++++++++++++++- src/rpmvercmp.h | 4 ++ src/util.c | 36 ++++++++++- src/util.h | 4 +- 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 @@ -119,13 +119,21 @@ installs, removes, or upgrades a package. This allows a package to "configure 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 @@ -151,6 +159,14 @@ The install script does not need to be specified in the \fIsource\fP array. .SH Install scripts must follow this format: .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() { # @@ -159,6 +175,15 @@ post_install() { /bin/true } +# 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() { @@ -220,6 +245,11 @@ if its an older version. This field contains an optional URL that is associated with the piece of software 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. @@ -328,6 +358,10 @@ Output syntax and commandline options. .B "\-i, \-\-install" Install/Upgrade the package after a successful build. .TP +.B "\-j " +Sets MAKEFLAGS="-j" 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 Set MAKEFLAGS to \"-j\" before building" echo " -m, --nocolor Disable colorized output messages" echo " -n, --nostrip Do not strip binaries/libraries" echo " -p 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 + * Copyright (c) 2002-2004 by Judd Vinet * * 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 #include #include +#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 , 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: */ -- cgit v1.2.3-24-g4f1b