Imported from pacman-2.8.tar.gz

This commit is contained in:
Judd Vinet 2004-07-03 04:25:48 +00:00
parent a2ee533f84
commit f6661379c6
21 changed files with 551 additions and 211 deletions

View file

@ -1,5 +1,24 @@
VERSION DESCRIPTION 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 2.7.9 - added the "force" option to packages, so --sysupgrade can
downgrade packages when it needs to downgrade packages when it needs to
2.7.8 - added post_remove scriptlet support 2.7.8 - added post_remove scriptlet support

View file

@ -34,7 +34,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
PACVER = 2.7.9 PACVER = 2.8
TOPDIR = @srcdir@ TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/ SRCDIR = $(TOPDIR)/src/

1
TODO
View file

@ -4,6 +4,5 @@
- when performing replaces, pacman should not remove old packages until - when performing replaces, pacman should not remove old packages until
the conflict checks are passed the conflict checks are passed
- handle version comparators in makepkg dep resolution (eg, glibc>=2.2.5) - 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 - check $PACCONF env var
- add a --pretend option - add a --pretend option

View file

@ -1,4 +1,4 @@
.TH makepkg 8 "April 29, 2004" "makepkg #VERSION#" "" .TH makepkg 8 "July 2, 2004" "makepkg #VERSION#" ""
.SH NAME .SH NAME
makepkg \- package build utility makepkg \- package build utility
.SH SYNOPSIS .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. itself" after installation and do the opposite right before it is removed.
The exact time the script is run varies with each operation: The exact time the script is run varies with each operation:
.TP
.B pre_install
script is run right before files are extracted.
.TP .TP
.B post_install .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 .TP
.B post_upgrade .B post_upgrade
script is run after all files have been upgraded. script is run after files are extracted.
.TP .TP
.B pre_remove .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: .SH Install scripts must follow this format:
.RS .RS
.nf .nf
# arg 1: the new package version
pre_install() {
#
# do pre-install stuff here
#
/bin/true
}
# arg 1: the new package version # arg 1: the new package version
post_install() { post_install() {
# #
@ -159,6 +175,15 @@ post_install() {
/bin/true /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 1: the new package version
# arg 2: the old package version # arg 2: the old package version
post_upgrade() { 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 This field contains an optional URL that is associated with the piece of software
being packaged. This is typically the project's website. 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 .TP
.B install .B install
Specifies a special install script that is to be included in the package. 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" .B "\-i, \-\-install"
Install/Upgrade the package after a successful build. Install/Upgrade the package after a successful build.
.TP .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" .B "\-m, \-\-nocolor"
Disable color in output messages Disable color in output messages
.TP .TP

View file

@ -1,4 +1,4 @@
.TH pacman 8 "April 29, 2004" "pacman #VERSION#" "" .TH pacman 8 "July 2, 2004" "pacman #VERSION#" ""
.SH NAME .SH NAME
pacman \- package manager utility pacman \- package manager utility
.SH SYNOPSIS .SH SYNOPSIS

View file

@ -29,69 +29,69 @@ NoUpgrade = etc/lilo.conf boot/grub/menu.lst
# REPOSITORIES # REPOSITORIES
# #
[current] [current]
Server = ftp://ftp.archlinux.org/current Server = ftp://ftp.archlinux.org/current/os/i686
Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/current/os/i686
Server = ftp://ftp.archlinux.de/pub/archlinux/current Server = ftp://ftp.archlinux.de/pub/archlinux/current/os/i686
Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/current 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 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 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 Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/current/os/i686
Server = ftp://ftp.kegep.tuc.gr/archlinux/current Server = ftp://ftp.kegep.tuc.gr/archlinux/current/os/i686
Server = http://darkstar.ist.utl.pt/archlinux/current Server = http://darkstar.ist.utl.pt/archlinux/current/os/i686
Server = ftp://archlinux.creativa.cl/current Server = ftp://archlinux.creativa.cl/current/os/i686
Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/current/os/i686
Server = ftp://saule.mintis.lt/pub/linux/current Server = ftp://saule.mintis.lt/pub/linux/current/os/i686
Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/current/os/i686
# Uncomment this block to access the EXTRA package set # Uncomment this block to access the EXTRA package set
# #
[extra] [extra]
Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra Server = ftp://ftp.oit.unc.edu/pub/Linux/distributions/archlinux/extra/os/i686
Server = ftp://ftp.archlinux.de/pub/archlinux/extra Server = ftp://ftp.archlinux.de/pub/archlinux/extra/os/i686
Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/extra 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 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 Server = ftp://ftp.tu-chemnitz.de/pub/linux/sunsite.unc-mirror/distributions/archlinux/extra/os/i686
Server = ftp://ftp.archlinux.org/extra Server = ftp://ftp.archlinux.org/extra/os/i686
Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/extra Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/extra/os/i686
Server = ftp://ftp.kegep.tuc.gr/archlinux/extra Server = ftp://ftp.kegep.tuc.gr/archlinux/extra/os/i686
Server = http://darkstar.ist.utl.pt/archlinux/extra Server = http://darkstar.ist.utl.pt/archlinux/extra/os/i686
Server = ftp://archlinux.creativa.cl/extra Server = ftp://archlinux.creativa.cl/extra/os/i686
Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/extra Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/extra/os/i686
Server = ftp://saule.mintis.lt/pub/linux/extra Server = ftp://saule.mintis.lt/pub/linux/extra/os/i686
Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/extra 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 # If you use the RELEASE tree, you should disable the CURRENT
# tree to avoid conflicts # tree to avoid conflicts
# #
#[release] #[release]
#Server = ftp://ftp.archlinux.org/release #Server = ftp://ftp.archlinux.org/release/os/i686
#Server = ftp://ftp.archlinux.de/pub/archlinux/release #Server = ftp://ftp.archlinux.de/pub/archlinux/release/os/i686
#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/release #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 #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 #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 #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 #Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/release/os/i686
#Server = ftp://ftp.kegep.tuc.gr/archlinux/release #Server = ftp://ftp.kegep.tuc.gr/archlinux/release/os/i686
#Server = http://darkstar.ist.utl.pt/archlinux/release #Server = http://darkstar.ist.utl.pt/archlinux/release/os/i686
#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/release #Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/release/os/i686
#Server = ftp://saule.mintis.lt/pub/linux/release #Server = ftp://saule.mintis.lt/pub/linux/release/os/i686
#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/release #Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/release/os/i686
# Uncomment this block to access the UNSTABLE package set # Uncomment this block to access the UNSTABLE package set
# #
#[unstable] #[unstable]
#Server = ftp://ftp.archlinux.org/unstable #Server = ftp://ftp.archlinux.org/unstable/os/i686
#Server = ftp://ftp.archlinux.de/pub/archlinux/unstable #Server = ftp://ftp.archlinux.de/pub/archlinux/unstable/os/i686
#Server = ftp://ftp.ibiblio.org/pub/linux/distributions/archlinux/unstable #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 #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 #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 #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 #Server = ftp://ftp.parrswood.net/Mirrors/ftp.archlinux.org/unstable/os/i686
#Server = http://darkstar.ist.utl.pt/archlinux/unstable #Server = http://darkstar.ist.utl.pt/archlinux/unstable/os/i686
#Server = ftp://archlinux.creativa.cl/unstable #Server = ftp://archlinux.creativa.cl/unstable/os/i686
#Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable #Server = ftp://gd.tuwien.ac.at/opsys/linux/archlinux/unstable/os/i686
#Server = ftp://saule.mintis.lt/pub/linux/unstable #Server = ftp://saule.mintis.lt/pub/linux/unstable/os/i686
#Server = ftp://ftp.rez-gif.supelec.fr/pub/Linux/distrib/archlinux/unstable #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 # An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories. # tips on creating your own repositories.

View file

@ -1139,9 +1139,9 @@ static int FtpXfer(const char *localfile, const char *path,
else else
{ {
while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) 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; rv = 0;
break; break;
} }
@ -1486,9 +1486,9 @@ static int HttpXfer(const char *localfile, const char *path, int *size,
{ {
nControl->dir = FTPLIB_READ; nControl->dir = FTPLIB_READ;
while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nControl)) > 0) { 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; rv = 0;
break; break;
} }

View file

@ -20,7 +20,7 @@
# USA. # USA.
# #
myver='2.7.9' myver='2.8'
usage() { usage() {
echo "gensync $myver" echo "gensync $myver"

View file

@ -20,7 +20,7 @@
# USA. # USA.
# #
myver='2.7.9' myver='2.8'
startdir=`pwd` startdir=`pwd`
PKGDEST=$startdir PKGDEST=$startdir
USE_COLOR="n" USE_COLOR="n"
@ -184,6 +184,7 @@ usage() {
echo " -g, --genmd5 Generate MD5sums for source files" echo " -g, --genmd5 Generate MD5sums for source files"
echo " -h, --help This help" echo " -h, --help This help"
echo " -i, --install Install package after successful build" 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 " -m, --nocolor Disable colorized output messages"
echo " -n, --nostrip Do not strip binaries/libraries" echo " -n, --nostrip Do not strip binaries/libraries"
echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)" echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
@ -236,7 +237,7 @@ while [ "$#" -ne "0" ]; do
exit 1 exit 1
;; ;;
-*) -*)
while getopts "cCsbdehifgmnrp:w:-" opt; do while getopts "cCsbdehifgj:mnrp:w:-" opt; do
case $opt in case $opt in
c) CLEANUP=1 ;; c) CLEANUP=1 ;;
C) CLEANCACHE=1 ;; C) CLEANCACHE=1 ;;
@ -251,6 +252,7 @@ while [ "$#" -ne "0" ]; do
n) NOSTRIP=1 ;; n) NOSTRIP=1 ;;
w) PKGDEST=$OPTARG ;; w) PKGDEST=$OPTARG ;;
p) BUILDSCRIPT=$OPTARG ;; p) BUILDSCRIPT=$OPTARG ;;
j) export MAKEFLAGS="-j$OPTARG" ;;
r) RMDEPS=1 ;; r) RMDEPS=1 ;;
h) h)
usage usage
@ -401,7 +403,7 @@ for netfile in ${source[@]}; do
exit 1 exit 1
fi fi
proto=`echo $netfile | sed 's|://.*||'` 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." error "$netfile was not found in the build directory and is not a proper URL."
msg "Aborting..." msg "Aborting..."
exit 1 exit 1
@ -424,6 +426,7 @@ done
if [ "$GENMD5" = "0" ]; then if [ "$GENMD5" = "0" ]; then
if [ "$NOEXTRACT" = "1" ]; 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 else
# MD5 validation # MD5 validation
if [ ${#md5sums[@]} -ne ${#source[@]} ]; then if [ ${#md5sums[@]} -ne ${#source[@]} ]; then
@ -615,6 +618,9 @@ echo "license = $license" >>.PKGINFO
echo "builddate = $builddate" >>.PKGINFO echo "builddate = $builddate" >>.PKGINFO
echo "packager = $packager" >>.PKGINFO echo "packager = $packager" >>.PKGINFO
echo "size = $size" >>.PKGINFO echo "size = $size" >>.PKGINFO
if [ "$CARCH" != "" ]; then
echo "arch = $CARCH" >>.PKGINFO
fi
for it in "${replaces[@]}"; do for it in "${replaces[@]}"; do
echo "replaces = $it" >>.PKGINFO echo "replaces = $it" >>.PKGINFO

View file

@ -21,7 +21,7 @@
# #
toplevel=`pwd` toplevel=`pwd`
version="2.7.9" version="2.8"
usage() { usage() {
echo "makeworld version $version" echo "makeworld version $version"

View file

@ -222,6 +222,12 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL); return(NULL);
} }
trim(info->license); 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%")) { } else if(!strcmp(line, "%BUILDDATE%")) {
if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) { if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) {
FREEPKG(info); FREEPKG(info);
@ -339,15 +345,17 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
} }
/* INSTALL */ /* INSTALL */
if(inforeq & INFRQ_ALL) {
snprintf(path, PATH_MAX, "%s/%s/install", db->path, ent->d_name); snprintf(path, PATH_MAX, "%s/%s/install", db->path, ent->d_name);
if(!stat(path, &buf)) { if(!stat(path, &buf)) {
info->scriptlet = 1; info->scriptlet = 1;
} }
}
return(info); 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]; char topdir[PATH_MAX];
FILE *fp = NULL; FILE *fp = NULL;
@ -367,6 +375,7 @@ int db_write(pacdb_t *db, pkginfo_t *info)
umask(0022); umask(0022);
/* DESC */ /* DESC */
if(inforeq & INFRQ_DESC) {
snprintf(path, PATH_MAX, "%s/desc", topdir); snprintf(path, PATH_MAX, "%s/desc", topdir);
fp = fopen(path, "w"); fp = fopen(path, "w");
if(fp == NULL) { if(fp == NULL) {
@ -389,6 +398,8 @@ int db_write(pacdb_t *db, pkginfo_t *info)
fprintf(fp, "%s\n\n", info->url); fprintf(fp, "%s\n\n", info->url);
fputs("%LICENSE%\n", fp); fputs("%LICENSE%\n", fp);
fprintf(fp, "%s\n\n", info->license); fprintf(fp, "%s\n\n", info->license);
fputs("%ARCH%\n", fp);
fprintf(fp, "%s\n\n", info->arch);
fputs("%BUILDDATE%\n", fp); fputs("%BUILDDATE%\n", fp);
fprintf(fp, "%s\n\n", info->builddate); fprintf(fp, "%s\n\n", info->builddate);
fputs("%INSTALLDATE%\n", fp); fputs("%INSTALLDATE%\n", fp);
@ -398,8 +409,10 @@ int db_write(pacdb_t *db, pkginfo_t *info)
fputs("%SIZE%\n", fp); fputs("%SIZE%\n", fp);
fprintf(fp, "%ld\n\n", info->size); fprintf(fp, "%ld\n\n", info->size);
fclose(fp); fclose(fp);
}
/* FILES */ /* FILES */
if(inforeq & INFRQ_FILES) {
snprintf(path, PATH_MAX, "%s/files", topdir); snprintf(path, PATH_MAX, "%s/files", topdir);
fp = fopen(path, "w"); fp = fopen(path, "w");
if(fp == NULL) { if(fp == NULL) {
@ -418,8 +431,10 @@ int db_write(pacdb_t *db, pkginfo_t *info)
} }
fprintf(fp, "\n"); fprintf(fp, "\n");
fclose(fp); fclose(fp);
}
/* DEPENDS */ /* DEPENDS */
if(inforeq & INFRQ_DEPENDS) {
snprintf(path, PATH_MAX, "%s/depends", topdir); snprintf(path, PATH_MAX, "%s/depends", topdir);
fp = fopen(path, "w"); fp = fopen(path, "w");
if(fp == NULL) { if(fp == NULL) {
@ -448,6 +463,7 @@ int db_write(pacdb_t *db, pkginfo_t *info)
} }
fprintf(fp, "\n"); fprintf(fp, "\n");
fclose(fp); fclose(fp);
}
/* INSTALL */ /* INSTALL */
/* nothing needed here (script is automatically extracted) */ /* nothing needed here (script is automatically extracted) */

View file

@ -40,7 +40,7 @@ void db_close(pacdb_t *db);
PMList* db_loadpkgs(pacdb_t *db); PMList* db_loadpkgs(pacdb_t *db);
pkginfo_t* db_scan(pacdb_t *db, char *target, unsigned int inforeq); 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); 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); 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* db_find_conflicts(pacdb_t *db, PMList* targets, char *root);
PMList *whatprovides(pacdb_t *db, char* package); PMList *whatprovides(pacdb_t *db, char* package);

View file

@ -36,6 +36,7 @@ pkginfo_t* load_pkg(char *pkgfile)
int i; int i;
int config = 0; int config = 0;
int filelist = 0; int filelist = 0;
int scriptcheck = 0;
TAR *tar; TAR *tar;
pkginfo_t *info = NULL; pkginfo_t *info = NULL;
PMList *backup = NULL; PMList *backup = NULL;
@ -47,14 +48,15 @@ pkginfo_t* load_pkg(char *pkgfile)
(writefunc_t)gzwrite (writefunc_t)gzwrite
}; };
info = newpkg();
if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) {
perror("could not open package"); perror("could not open package");
return(NULL); return(NULL);
} }
info = newpkg();
for(i = 0; !th_read(tar); i++) { for(i = 0; !th_read(tar); i++) {
if(config && filelist) { if(config && filelist && scriptcheck) {
/* we have everything we need */ /* we have everything we need */
break; break;
} }
@ -87,6 +89,7 @@ pkginfo_t* load_pkg(char *pkgfile)
continue; continue;
} else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) { } else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) {
info->scriptlet = 1; info->scriptlet = 1;
scriptcheck = 1;
} else if(!strcmp(th_get_pathname(tar), ".FILELIST")) { } else if(!strcmp(th_get_pathname(tar), ".FILELIST")) {
/* Build info->files from the filelist */ /* Build info->files from the filelist */
FILE *fp; FILE *fp;
@ -112,7 +115,9 @@ pkginfo_t* load_pkg(char *pkgfile)
} }
FREE(fn); FREE(fn);
filelist = 1; filelist = 1;
continue;
} else { } else {
scriptcheck = 1;
if(!filelist) { if(!filelist) {
/* no .FILELIST present in this package.. build the filelist the */ /* no .FILELIST present in this package.. build the filelist the */
/* old-fashioned way, one at a time */ /* 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)); strncpy(info->installdate, ptr, sizeof(info->installdate));
} else if(!strcmp(key, "PACKAGER")) { } else if(!strcmp(key, "PACKAGER")) {
strncpy(info->packager, ptr, sizeof(info->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")) { } else if(!strcmp(key, "SIZE")) {
char tmp[32]; char tmp[32];
strncpy(tmp, ptr, sizeof(tmp)); strncpy(tmp, ptr, sizeof(tmp));
@ -239,6 +246,7 @@ pkginfo_t* newpkg()
pkg->installdate[0] = '\0'; pkg->installdate[0] = '\0';
pkg->packager[0] = '\0'; pkg->packager[0] = '\0';
pkg->md5sum[0] = '\0'; pkg->md5sum[0] = '\0';
pkg->arch[0] = '\0';
pkg->size = 0; pkg->size = 0;
pkg->scriptlet = 0; pkg->scriptlet = 0;
pkg->force = 0; pkg->force = 0;
@ -327,6 +335,7 @@ void dump_pkg_full(pkginfo_t *info)
printf("Packager : %s\n", info->packager); printf("Packager : %s\n", info->packager);
printf("URL : %s\n", info->url); printf("URL : %s\n", info->url);
printf("License : %s\n", info->license); printf("License : %s\n", info->license);
printf("Architecture : %s\n", info->arch);
printf("Size : %ld\n", info->size); printf("Size : %ld\n", info->size);
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : ""); printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "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); 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; char *p, *q;
strncpy(tmp, pkg, 256); /* trim path name (if any) */
if((p = strrchr(pkgfile, '/')) == NULL) {
p = strstr(tmp, ".pkg.tar.gz"); p = pkgfile;
if(p == NULL) { } else {
return(-1); p++;
} }
strncpy(tmp, p, 512);
/* trim file extension (if any) */
if((p = strstr(tmp, ".pkg.tar.gz"))) {
*p = 0; *p = 0;
}
p = tmp + strlen(tmp);
for(q = --p; *q && *q != '-'; q--); for(q = --p; *q && *q != '-'; q--);
if(*q != '-' || q == tmp) { if(*q != '-' || q == tmp) {
@ -401,10 +416,10 @@ int split_pkgname(char *pkg, char **name, char **version)
if(*p != '-' || p == tmp) { if(*p != '-' || p == tmp) {
return(-1); return(-1);
} }
*version = strdup(p+1); strncpy(version, p+1, 64);
*p = 0; *p = 0;
*name = strdup(tmp); strncpy(name, tmp, 256);
return(0); return(0);
} }

View file

@ -51,6 +51,7 @@ typedef struct __pkginfo_t {
char installdate[32]; char installdate[32];
char packager[64]; char packager[64];
char md5sum[33]; char md5sum[33];
char arch[32];
unsigned long size; unsigned long size;
unsigned short scriptlet; unsigned short scriptlet;
unsigned short force; unsigned short force;
@ -84,7 +85,7 @@ int pkgcmp(const void *p1, const void *p2);
int is_pkgin(pkginfo_t *needle, PMList *haystack); int is_pkgin(pkginfo_t *needle, PMList *haystack);
void dump_pkg_full(pkginfo_t *info); void dump_pkg_full(pkginfo_t *info);
void dump_pkg_sync(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 #endif
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -1,7 +1,7 @@
/* /*
* pacman.c * 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 * 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 * 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; pm_access = READ_ONLY;
if(pmo_op != PM_MAIN && pmo_op != PM_QUERY && pmo_op != PM_DEPTEST) { if(pmo_op != PM_MAIN && pmo_op != PM_QUERY && pmo_op != PM_DEPTEST) {
if(pmo_op == PM_SYNC && !pmo_s_sync && 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 */ /* special case: PM_SYNC can be used w/ pmo_s_search by any user */
} else { } else {
if(geteuid() != 0) { if(geteuid() != 0) {
@ -349,23 +349,31 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = cache; i; i = i->next) { for(i = cache; i; i = i->next) {
char *str = (char *)i->data; 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)); clean = list_add(clean, strdup(str));
continue; continue;
} }
/* we keep partially downloaded files */ /* we keep partially downloaded files */
if(strstr(str, ".pkg.tar.gz.part")) { if(strstr(str, ".pkg.tar.gz.part")) {
FREE(name); continue;
FREE(version); }
if(split_pkgname(str, name, version) != 0) {
clean = list_add(clean, strdup(str));
continue; continue;
} }
for(j = i->next; j; j = j->next) { for(j = i->next; j; j = j->next) {
char *s = (char *)j->data; 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; continue;
} }
if(!strcmp(name, n)) { if(!strcmp(name, n)) {
@ -379,11 +387,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
clean = list_add(clean, strdup(ptr)); clean = list_add(clean, strdup(ptr));
} }
} }
FREE(n);
FREE(v);
} }
FREE(name);
FREE(version);
} }
FREELIST(cache); FREELIST(cache);
@ -805,7 +809,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
continue; continue;
} }
local = db_scan(db, targ, INFRQ_DESC); 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 */ /* this is an upgrade, compare versions and determine if it is necessary */
cmp = rpmvercmp(local->version, sync->pkg->version); cmp = rpmvercmp(local->version, sync->pkg->version);
if(cmp > 0) { if(cmp > 0) {
@ -1282,7 +1286,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = final; i; i = i->next) { for(i = final; i; i = i->next) {
syncpkg_t *sync = (syncpkg_t*)i->data; syncpkg_t *sync = (syncpkg_t*)i->data;
if(sync->replaces) { 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) { for(j = sync->replaces; j; j = j->next) {
pkginfo_t *old = (pkginfo_t*)j->data; pkginfo_t *old = (pkginfo_t*)j->data;
/* merge lists */ /* merge lists */
@ -1290,21 +1294,21 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(!is_in(k->data, new->requiredby)) { if(!is_in(k->data, new->requiredby)) {
/* replace old's name with new's name in the requiredby's dependency list */ /* replace old's name with new's name in the requiredby's dependency list */
PMList *m; 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) { for(m = depender->depends; m; m = m->next) {
if(!strcmp(m->data, old->name)) { if(!strcmp(m->data, old->name)) {
FREE(m->data); FREE(m->data);
m->data = strdup(new->name); m->data = strdup(new->name);
} }
} }
db_write(db, depender); db_write(db, depender, INFRQ_DEPENDS);
/* add the new requiredby */ /* add the new requiredby */
new->requiredby = list_add(new->requiredby, strdup(k->data)); new->requiredby = list_add(new->requiredby, strdup(k->data));
} }
} }
} }
db_write(db, new); db_write(db, new, INFRQ_DEPENDS);
FREEPKG(new); FREEPKG(new);
} }
} }
@ -1376,8 +1380,9 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* this target looks like an URL. download it and then /* this target looks like an URL. download it and then
* strip the URL portion from the target. * strip the URL portion from the target.
*/ */
char spath[PATH_MAX];
char url[PATH_MAX]; char url[PATH_MAX];
server_t server; server_t *server;
PMList *servers = NULL; PMList *servers = NULL;
PMList *files = NULL; PMList *files = NULL;
char *host, *path, *fn; char *host, *path, *fn;
@ -1389,12 +1394,23 @@ int pacman_add(pacdb_t *db, PMList *targets)
*path = '\0'; *path = '\0';
path++; path++;
fn = strrchr(path, '/'); fn = strrchr(path, '/');
if(fn) {
*fn = '\0'; *fn = '\0';
if(path[0] == '/') {
snprintf(spath, PATH_MAX, "%s/", path);
} else {
snprintf(spath, PATH_MAX, "/%s/", path);
}
fn++; fn++;
server.protocol = url; } else {
server.server = host; fn = path;
server.path = path; strcpy(spath, "/");
servers = list_add(servers, &server); }
MALLOC(server, sizeof(server_t));
server->protocol = url;
server->server = host;
server->path = spath;
servers = list_add(servers, server);
files = list_add(files, fn); files = list_add(files, fn);
if(downloadfiles(servers, ".", files)) { if(downloadfiles(servers, ".", files)) {
fprintf(stderr, "error: failed to download %s\n", (char*)targ->data); 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); printf("upgrading %s... ", info->name);
neednl = 1; neednl = 1;
/* we'll need the full record for backup checks later */ /* we'll need the full record for backup checks later */
oldpkg = db_scan(db, info->name, INFRQ_ALL); 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) { if(oldpkg) {
list_add(tmp, strdup(info->name)); list_add(tmp, strdup(info->name));
vprint("removing old package first...\n"); vprint("removing old package first...\n");
@ -1626,6 +1670,32 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) { if(!pmo_upgrade) {
printf("installing %s... ", info->name); printf("installing %s... ", info->name);
neednl = 1; 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); 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); logaction(stderr, "warning: extracting %s%s as %s", pmo_root, pathname, expath);
/*tar_skip_regfile(tar);*/ /*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)) { if(tar_extract_file(tar, expath)) {
logaction(stderr, "could not extract %s: %s", pathname, strerror(errno)); logaction(stderr, "could not extract %s: %s", pathname, strerror(errno));
errors++; errors++;
@ -1821,7 +1899,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
pkginfo_t *tmpp = NULL; pkginfo_t *tmpp = NULL;
PMList *tmppm = 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) { if(tmpp == NULL) {
continue; continue;
} }
@ -1840,7 +1918,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
vprint("Updating database..."); vprint("Updating database...");
/* make an install date (in UTC) */ /* make an install date (in UTC) */
strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate)); 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); logaction(stderr, "error updating database for %s!", info->name);
return(1); return(1);
} }
@ -1860,13 +1938,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
if(splitdep(lp->data, &depend)) { if(splitdep(lp->data, &depend)) {
continue; continue;
} }
depinfo = db_scan(db, depend.name, INFRQ_ALL); depinfo = db_scan(db, depend.name, INFRQ_DEPENDS);
if(depinfo == NULL) { if(depinfo == NULL) {
/* look for a provides package */ /* look for a provides package */
PMList *provides = whatprovides(db, depend.name); PMList *provides = whatprovides(db, depend.name);
if(provides) { if(provides) {
/* use the first one */ /* use the first one */
depinfo = db_scan(db, provides->data, INFRQ_ALL); depinfo = db_scan(db, provides->data, INFRQ_DEPENDS);
if(depinfo == NULL) { if(depinfo == NULL) {
/* wtf */ /* wtf */
continue; continue;
@ -1876,19 +1954,20 @@ int pacman_add(pacdb_t *db, PMList *targets)
} }
} }
depinfo->requiredby = list_add(depinfo->requiredby, strdup(info->name)); depinfo->requiredby = list_add(depinfo->requiredby, strdup(info->name));
db_write(db, depinfo); db_write(db, depinfo, INFRQ_DEPENDS);
freepkg(depinfo); freepkg(depinfo);
} }
printf("done.\n"); fflush(stdout); printf("done.\n"); fflush(stdout);
/* run the post-install script if it exists */ /* 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); 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]; char cmdline[PATH_MAX+1];
snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version); snprintf(pm_install, PATH_MAX, "%s/%s/%s-%s/install", pmo_dbpath, db->treename, info->name, info->version);
vprint("Executing post-install script...\n"); vprint("Executing post-install script...\n");
snprintf(cmdline, PATH_MAX, "chroot %s /bin/sh %s post_%s %s %s", pmo_root, pm_install, snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s post_%s %s %s\" | chroot %s /bin/sh",
(pmo_upgrade ? "upgrade" : "install"), info->version, ((pmo_upgrade && oldpkg) ? oldpkg->version : "")); pm_install, (pmo_upgrade ? "upgrade" : "install"), info->version,
((pmo_upgrade && oldpkg) ? oldpkg->version : ""), pmo_root);
system(cmdline); system(cmdline);
} }
} }
@ -2021,10 +2100,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
fflush(stdout); fflush(stdout);
/* run the pre-remove script if it exists */ /* 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); 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"); 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(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); system(line);
} }
@ -2084,10 +2164,11 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(!pmo_upgrade) { if(!pmo_upgrade) {
/* run the post-remove script if it exists */ /* 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); 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"); 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(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); system(line);
} }
@ -2119,7 +2200,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
if(splitdep((char*)lp->data, &depend)) { if(splitdep((char*)lp->data, &depend)) {
continue; continue;
} }
depinfo = db_scan(db, depend.name, INFRQ_ALL); depinfo = db_scan(db, depend.name, INFRQ_DEPENDS);
if(depinfo == NULL) { if(depinfo == NULL) {
/* look for a provides package */ /* look for a provides package */
PMList *provides = whatprovides(db, depend.name); PMList *provides = whatprovides(db, depend.name);
@ -2128,7 +2209,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
* the first one. * the first one.
*/ */
/* use 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); list_free(provides);
if(depinfo == NULL) { if(depinfo == NULL) {
/* wtf */ /* wtf */
@ -2154,7 +2235,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
break; break;
} }
} }
db_write(db, depinfo); db_write(db, depinfo, INFRQ_DEPENDS);
freepkg(depinfo); freepkg(depinfo);
} }
if(!pmo_upgrade) { if(!pmo_upgrade) {
@ -2493,12 +2574,27 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
continue; continue;
} }
dep = db_scan(db, depend.name, INFRQ_DESC | INFRQ_DEPENDS); 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)) { if(is_pkgin(dep, targs)) {
continue; continue;
} }
/* see if other packages need it */ /* see if other packages need it */
for(k = dep->requiredby; k && !needed; k = k->next) { 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)) { if(!is_pkgin(dummy, targs)) {
needed = 1; needed = 1;
} }

View file

@ -22,7 +22,7 @@
#define _PAC_PACMAN_H #define _PAC_PACMAN_H
#ifndef PACVER #ifndef PACVER
#define PACVER "2.7.9" #define PACVER "2.8"
#endif #endif
#ifndef PKGDIR #ifndef PKGDIR

View file

@ -95,7 +95,7 @@ int sync_synctree()
/* uncompress the sync database */ /* uncompress the sync database */
vprint("Unpacking %s...\n", path); vprint("Unpacking %s...\n", path);
if(unpack(path, ldir)) { if(unpack(path, ldir, NULL)) {
return(1); return(1);
} }
} }
@ -122,7 +122,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
for(i = servers; i && !done; i = i->next) { for(i = servers; i && !done; i = i->next) {
server_t *server = (server_t*)i->data; server_t *server = (server_t*)i->data;
if(!pmo_xfercommand) { if(!pmo_xfercommand && strcmp(server->protocol, "file")) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) { if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpInit(); FtpInit();
vprint("Connecting to %s:21\n", server->server); vprint("Connecting to %s:21\n", server->server);
@ -180,7 +180,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
continue; continue;
} }
if(pmo_xfercommand) { if(pmo_xfercommand && strcmp(server->protocol, "file")) {
int ret; int ret;
int usepart = 0; int usepart = 0;
char *ptr1, *ptr2; char *ptr1, *ptr2;
@ -291,7 +291,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
} else { } else {
filedone = 1; 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 src[PATH_MAX];
char *host; char *host;
unsigned port; unsigned port;
@ -329,7 +329,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
} }
if(!HttpGet(server->server, output, src, &fsz, control, offset)) { if(!HttpGet(server->server, output, src, &fsz, control, offset)) {
fprintf(stderr, "\nfailed downloading %s from %s: %s\n", 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 */ /* we leave the partially downloaded file in place so it can be resumed later */
} else { } else {
filedone = 1; filedone = 1;
@ -372,7 +372,7 @@ int downloadfiles(PMList *servers, const char *localpath, PMList *files)
if(!pmo_xfercommand) { if(!pmo_xfercommand) {
if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) { if(!strcmp(server->protocol, "ftp") && !pmo_proxyhost) {
FtpQuit(control); FtpQuit(control);
} else if(!strcmp(server->protocol, "http") || pmo_proxyhost) { } else if(!strcmp(server->protocol, "http") || (pmo_proxyhost && strcmp(server->protocol, "file"))) {
HttpQuit(control); HttpQuit(control);
} }
} }

View file

@ -22,9 +22,10 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include "config.h"
#include "rpmvercmp.h"
/* this function was taken from rpm 4.0.4 and rewritten */ /* this function was taken from rpm 4.0.4 and rewritten */
int rpmvercmp(const char *a, const char *b) int rpmvercmp(const char *a, const char *b)
{ {
char *str1, *str2; char *str1, *str2;
@ -117,4 +118,119 @@ int rpmvercmp(const char *a, const char *b)
return(*one ? 1 : -1); 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: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -23,6 +23,10 @@
int rpmvercmp(const char *a, const char *b); int rpmvercmp(const char *a, const char *b);
#ifndef HAVE_STRVERSCMP
int strverscmp(const char *s1, const char *s2);
#endif
#endif #endif
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -66,7 +66,7 @@ int gzopen_frontend(char *pathname, int oflags, int mode)
return (int)gzf; return (int)gzf;
} }
int unpack(char *archive, char *prefix) int unpack(char *archive, const char *prefix, const char *fn)
{ {
TAR *tar = NULL; TAR *tar = NULL;
char expath[PATH_MAX]; char expath[PATH_MAX];
@ -83,10 +83,20 @@ int unpack(char *archive, char *prefix)
return(1); return(1);
} }
while(!th_read(tar)) { 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)); snprintf(expath, PATH_MAX, "%s/%s", prefix, th_get_pathname(tar));
if(tar_extract_file(tar, expath)) { if(tar_extract_file(tar, expath)) {
fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), strerror(errno)); fprintf(stderr, "could not extract %s: %s\n", th_get_pathname(tar), strerror(errno));
} }
if(fn) break;
} }
tar_close(tar); tar_close(tar);
@ -289,4 +299,28 @@ char* trim(char *str)
return 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: */ /* vim: set ts=2 sw=2 noet: */

View file

@ -29,7 +29,7 @@
#define FREE(p) { if (p) { free(p); (p)= NULL; }} #define FREE(p) { if (p) { free(p); (p)= NULL; }}
int gzopen_frontend(char *pathname, int oflags, int mode); 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 copyfile(char *src, char *dest);
int makepath(char *path); int makepath(char *path);
int rmrf(char *path); int rmrf(char *path);
@ -37,7 +37,7 @@ void indentprint(char *str, int indent);
int yesno(char* fmt, ...); int yesno(char* fmt, ...);
char* trim(char *str); char* trim(char *str);
char* strtoupper(char *str); char* strtoupper(char *str);
int grep(const char *fn, const char *needle);
#endif #endif
/* vim: set ts=2 sw=2 noet: */ /* vim: set ts=2 sw=2 noet: */