summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--Makefile.in2
-rw-r--r--doc/makepkg.8.in10
-rw-r--r--doc/pacman.8.in15
-rw-r--r--etc/makepkg.conf4
-rwxr-xr-xscripts/gensync2
-rwxr-xr-xscripts/makepkg41
-rwxr-xr-xscripts/makeworld2
-rwxr-xr-xscripts/pacman-optimize8
-rwxr-xr-xscripts/updatesync2
-rw-r--r--src/db.c140
-rw-r--r--src/md5.h2
-rw-r--r--src/pacconf.h2
-rw-r--r--src/package.c10
-rw-r--r--src/package.h2
-rw-r--r--src/pacman.c40
-rw-r--r--src/util.c97
-rw-r--r--src/util.h1
18 files changed, 292 insertions, 100 deletions
diff --git a/ChangeLog b/ChangeLog
index 6f92d4ed..0904c43d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.9.7 - patch from Miklos Vanja fixed md5sums on x86_64
+ - patch from Miklos Vanja adds --sudosync to makepkg
+ - changed license field to operate as an array, not a string
+ - added more logic for file conflict checks - if one target
+ is a file and the other is a directory, then it's a conflict
+ - fixed the integrity check in pacman-optimize
+ - reverted NoUpgrade to old behaviour and instead, added the
+ NoExtract directive to pacman.conf, which prevents a file
+ from ever being extracted on to the system
+ eg, NoExtract = home/httpd/html/index.html
2.9.6 - added a pacman-optimize script to try and defragment the DB
- modified NoUpgrade behaviour to avoid extracting files
that are missing from the filesystem -- this helps in
@@ -9,7 +19,7 @@ VERSION DESCRIPTION
moved from one package to another
- add db_remove() which is responsible for clearing out stale
hash table entries when packages are removed
- - added cache support to makepkg
+ - added ccache support to makepkg
- patch from Aurelien Foret fixes a few memory leaks
2.9.5 - bugfix: missing files after re-ordering packages wrt
deps with --upgrade
diff --git a/Makefile.in b/Makefile.in
index 34c463f7..ed8d2190 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.9.6
+PACVER = 2.9.7
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in
index 569f3596..0de31bf1 100644
--- a/doc/makepkg.8.in
+++ b/doc/makepkg.8.in
@@ -342,6 +342,11 @@ Do not perform any dependency checks. This will let you override/ignore any
dependencies required. There's a good chance this option will break the build
process if all of the dependencies aren't installed.
.TP
+.B "\-e, \-\-noextract"
+Do not extract source files. Instead, use whatever already exists in the
+src/ directory. This is handy if you want to go into src and manually
+patch/tweak code, then make a package out of the result.
+.TP
.B "\-f, \-\-force"
\fBmakepkg\fP will not build a package if a \fIpkgname-pkgver-pkgrel.pkg.tar.gz\fP
file already exists in the build directory. You can override this behaviour with
@@ -384,6 +389,11 @@ or run-time dependencies, it will run pacman to try and resolve them. If succes
pacman will download the missing packages from a package repository and
install them for you.
.TP
+.B "\-S, \-\-sudosync"
+Install missing dependencies using pacman and sudo. This is the same as \fB-s\fP
+except that makepkg will call pacman with sudo. This means you don't have to
+build as root to use dependency auto-resolution.
+.TP
.B "\-w <destdir>"
Write the resulting package file to the directory \fI<destdir>\fP instead of the
current working directory.
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 09c47d50..32e04e3a 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -1,4 +1,4 @@
-.TH pacman 8 "September 17, 2004" "pacman #VERSION#" ""
+.TH pacman 8 "July 6, 2005" "pacman #VERSION#" ""
.SH NAME
pacman \- package manager utility
.SH SYNOPSIS
@@ -106,9 +106,9 @@ List all files in the specified repositories. Multiple repositories can
be specified on the command line.
.TP
.B "\-p, \-\-print-uris"
-Print out URIs for each specified package and its dependencies. These
-can be piped to a file and downloaded at a later time, using a program
-like wget.
+Print out URIs for each package that will be installed, including any
+dependencies that have yet to be installed. These can be piped to a
+file and downloaded at a later time, using a program like wget.
.TP
.B "\-s, \-\-search <string>"
This will search each package in the package list for names or descriptions
@@ -272,6 +272,13 @@ Disables passive ftp connections when downloading packages. (aka Active Mode)
All files listed with a \fBNoUpgrade\fP directive will never be touched during a package
install/upgrade. \fINote:\fP do not include the leading slash when specifying files.
.TP
+.B "NoExtract = <file> [file] ..."
+All files listed with a \fBNoExtract\fP directive will never be extracted from
+a package into the filesystem. This can be useful when you don't want part of
+a package to be installed. For example, if your httpd root uses an index.php,
+then you would not want the index.html file to be extracted from the apache
+package.
+.TP
.B "UseSyslog"
Log action messages through syslog(). This will insert pacman log entries into your
/var/log/messages or equivalent.
diff --git a/etc/makepkg.conf b/etc/makepkg.conf
index d43b0e67..5f787397 100644
--- a/etc/makepkg.conf
+++ b/etc/makepkg.conf
@@ -12,8 +12,8 @@ export CHOST="i686-pc-linux-gnu"
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries
# will use the P6 instruction set and only run on P6+ systems)
-export CFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
-export CXXFLAGS="-march=i686 -O2 -pipe -Wl,-O1"
+export CFLAGS="-march=i686 -O2 -pipe"
+export CXXFLAGS="-march=i686 -O2 -pipe"
# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries
# will run on any x86 system)
#export CFLAGS="-mcpu=i686 -O2 -pipe"
diff --git a/scripts/gensync b/scripts/gensync
index 0ebc1386..3cfcbcaa 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.9.6'
+myver='2.9.7'
usage() {
echo "gensync $myver"
diff --git a/scripts/makepkg b/scripts/makepkg
index 31e78f97..0361e8bd 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.9.6'
+myver='2.9.7'
startdir=`pwd`
PKGDEST=$startdir
USE_COLOR="n"
@@ -108,7 +108,7 @@ handledeps() {
local missingdeps=0
local deplist="$*"
local haveperm=0
- if [ "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
+ if [ \( "`id -u`" = "0" -a "$INFAKEROOT" != "1" \) -o "$DEP_SUDO" = 1 ]; then
haveperm=1
fi
@@ -122,6 +122,15 @@ handledeps() {
exit 1
fi
# TODO: check deps again to make sure they were resolved
+ elif [ "$DEP_SUDO" = "1" ]; then
+ # install missing deps from binary packages (using pacman -S and sudo)
+ msg "Installing missing dependencies..."
+ sudo pacman -D $deplist
+ if [ "$?" = "127" ]; then
+ error "Failed to install missing dependencies."
+ exit 1
+ fi
+ # TODO: check deps again to make sure they were resolved
elif [ "$DEP_SRC" = "1" ]; then
# install missing deps by building them from source.
# we look for each package name in $ABSROOT and build it.
@@ -163,8 +172,8 @@ handledeps() {
fi
elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then
if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then
- warning "Cannot auto-install missing dependencies as a normal user!"
- plain "Run makepkg as root to resolve dependencies automatically."
+ warning "Cannot auto-install missing dependencies as a normal user without sudo!"
+ plain "Run makepkg as root or with -S to resolve dependencies automatically."
fi
missingdeps=1
fi
@@ -191,6 +200,7 @@ usage() {
echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)"
echo " -r, --rmdeps Remove installed dependencies after a successful build"
echo " -s, --syncdeps Install missing dependencies with pacman"
+ echo " -S, --sudosync Install missing dependencies with pacman and sudo"
echo " -w <destdir> Write package to <destdir> instead of the working dir"
echo
echo " if -p is not specified, makepkg will look for a PKGBUILD"
@@ -205,6 +215,7 @@ CLEANCACHE=0
INSTALL=0
GENMD5=0
DEP_BIN=0
+DEP_SUDO=0
DEP_SRC=0
NODEPS=0
FORCE=0
@@ -221,6 +232,7 @@ while [ "$#" -ne "0" ]; do
--clean) CLEANUP=1 ;;
--cleancache) CLEANCACHE=1 ;;
--syncdeps) DEP_BIN=1 ;;
+ --sudosync) DEP_SUDO=1 ;;
--builddeps) DEP_SRC=1 ;;
--nodeps) NODEPS=1 ;;
--noextract) NOEXTRACT=1 ;;
@@ -240,7 +252,7 @@ while [ "$#" -ne "0" ]; do
exit 1
;;
-*)
- while getopts "cCsbdehifgj:mnorp:w:-" opt; do
+ while getopts "cCsSbdehifgj:mnorp:w:-" opt; do
case $opt in
c) CLEANUP=1 ;;
C) CLEANCACHE=1 ;;
@@ -261,6 +273,7 @@ while [ "$#" -ne "0" ]; do
p) BUILDSCRIPT=$OPTARG ;;
r) RMDEPS=1 ;;
s) DEP_BIN=1 ;;
+ S) DEP_SUDO=1 ;;
w) PKGDEST=$OPTARG ;;
-)
OPTIND=0
@@ -280,6 +293,12 @@ while [ "$#" -ne "0" ]; do
shift
done
+# check for sudo
+if [ "$DEP_SUDO" = "1" -a ! "`type -p sudo`" ]; then
+ error "Cannot find the sudo binary! Is sudo installed?"
+ exit 1
+fi
+
# convert a (possibly) relative path to absolute
cd $PKGDEST 2>/dev/null
if [ $? -ne 0 ]; then
@@ -320,6 +339,10 @@ if [ `echo $pkgrel | grep '-'` ]; then
error "pkgrel is not allowed to contain hyphens."
exit 1
fi
+if [ "$install" -a ! -f "$install" ]; then
+ error "install scriptlet ($install) does not exist."
+ exit 1
+fi
if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a "$GENMD5" = "0" ]; then
if [ "$INSTALL" = "1" ]; then
@@ -631,7 +654,6 @@ echo "pkgname = $pkgname" >>.PKGINFO
echo "pkgver = $pkgver-$pkgrel" >>.PKGINFO
echo "pkgdesc = $pkgdesc" >>.PKGINFO
echo "url = $url" >>.PKGINFO
-echo "license = $license" >>.PKGINFO
echo "builddate = $builddate" >>.PKGINFO
echo "packager = $packager" >>.PKGINFO
echo "size = $size" >>.PKGINFO
@@ -639,6 +661,9 @@ if [ "$CARCH" != "" ]; then
echo "arch = $CARCH" >>.PKGINFO
fi
+for it in "${license[@]}"; do
+ echo "license = $it" >>.PKGINFO
+done
for it in "${replaces[@]}"; do
echo "replaces = $it" >>.PKGINFO
done
@@ -688,6 +713,10 @@ fi
if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
msg "Removing installed dependencies..."
pacman -R $makedeplist $deplist
+
+elif [ "$RMDEPS" = "1" -a "$DEP_SUDO" = "1" ]; then
+ msg "Removing installed dependencies..."
+ sudo pacman -R $makedeplist $deplist
fi
msg "Finished making: $pkgname (`date`)"
diff --git a/scripts/makeworld b/scripts/makeworld
index 30418afd..7d4c762c 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -20,7 +20,7 @@
# USA.
#
-version="2.9.6"
+version="2.9.7"
toplevel=`pwd`
usage() {
diff --git a/scripts/pacman-optimize b/scripts/pacman-optimize
index b9573cbb..cb321f2c 100755
--- a/scripts/pacman-optimize
+++ b/scripts/pacman-optimize
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.9.6'
+myver='2.9.7'
usage() {
echo "pacman-optimize $myver"
@@ -77,7 +77,7 @@ touch /tmp/pacman.lck
# step 1: sum the old db
echo "==> md5sum'ing the old database..."
-tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.old
+tar --same-order -c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.old
# step 1: copy the entire db directory to a new one
echo "==> copying $dbroot..."
@@ -87,7 +87,7 @@ cp -a $dbroot $dbroot.new || die_r "error copying $dbroot"
echo "==> md5sum'ing the new database..."
mv $dbroot $dbroot.bak || die_r "error renaming $dbroot"
mv $dbroot.new $dbroot || die_r "error renaming $dbroot.new"
-tar c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.new
+tar --same-order -c $dbroot 2>/dev/null | md5sum >/tmp/pacsums.new
# step 3: compare sums
echo "==> checking integrity..."
@@ -96,7 +96,7 @@ if [ $? -ne 0 ]; then
# failed, move the old one back into place
rm -rf $dbroot
mv $dbroot.bak $dbroot
- die_r "integrity check FAILED, reverting to old databse"
+ die_r "integrity check FAILED, reverting to old database"
fi
# step 4: remove the backup
diff --git a/scripts/updatesync b/scripts/updatesync
index e36d25e7..5385ed66 100755
--- a/scripts/updatesync
+++ b/scripts/updatesync
@@ -21,7 +21,7 @@
# USA.
#
-myver='2.9.6'
+myver='2.9.7'
usage() {
echo "updatesync $myver"
diff --git a/src/db.c b/src/db.c
index 005498c4..82e76318 100644
--- a/src/db.c
+++ b/src/db.c
@@ -327,12 +327,6 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL);
}
trim(info->url);
- } else if(!strcmp(line, "%LICENSE%")) {
- if(fgets(info->license, sizeof(info->license), fp) == NULL) {
- FREEPKG(info);
- return(NULL);
- }
- trim(info->license);
} else if(!strcmp(line, "%ARCH%")) {
if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
FREEPKG(info);
@@ -386,6 +380,11 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
}
trim(tmp);
info->size = atol(tmp);
+ } else if(!strcmp(line, "%LICENSE%")) {
+ while(fgets(line, 512, fp) && strlen(trim(line))) {
+ char *s = strdup(line);
+ info->license = list_add(info->license, s);
+ }
} else if(!strcmp(line, "%REPLACES%")) {
/* the REPLACES tag is special -- it only appears in sync repositories,
* not the local one. */
@@ -529,7 +528,10 @@ int db_write(pacdb_t *db, pkginfo_t *info, unsigned int inforeq)
fputs("%URL%\n", fp);
fprintf(fp, "%s\n\n", info->url);
fputs("%LICENSE%\n", fp);
- fprintf(fp, "%s\n\n", info->license);
+ for(lp = info->license; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char*)lp->data);
+ }
+ fprintf(fp, "\n");
fputs("%ARCH%\n", fp);
fprintf(fp, "%s\n\n", info->arch);
fputs("%BUILDDATE%\n", fp);
@@ -762,68 +764,84 @@ PMList* db_find_conflicts(pacdb_t *db, PMList *targets, char *root, PMList **ski
pkginfo_t *p = (pkginfo_t*)i->data;
pkginfo_t *dbpkg = NULL;
for(j = p->files; j; j = j->next) {
+ int isdir = 0;
filestr = (char*)j->data;
snprintf(path, PATH_MAX, "%s%s", root, filestr);
- if(!stat(path, &buf) && !S_ISDIR(buf.st_mode)) {
+ /* is this target a file or directory? */
+ if(path[strlen(path)-1] == '/') {
+ isdir = 1;
+ path[strlen(path)-1] = '\0';
+ }
+ if(!lstat(path, &buf)) {
int ok = 0;
- if(dbpkg == NULL) {
- dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES);
-
- if(dbpkg)
- strhash_add_list(htables[target_num], dbpkg->files);
- }
- if(dbpkg && strhash_isin(htables[target_num], filestr)) {
+ if(!S_ISLNK(buf.st_mode) && ((isdir && !S_ISDIR(buf.st_mode)) || (!isdir && S_ISDIR(buf.st_mode)))) {
+ /* if the package target is a directory, and the filesystem target
+ * is not (or vice versa) then it's a conflict
+ */
+ ok = 0;
+ } else if(S_ISDIR(buf.st_mode)) {
+ /* if it's a directory, then we have no conflict */
ok = 1;
- }
- /* Make sure that the supposedly-conflicting file is not actually just
- * a symlink that points to a path that used to exist in the package.
- */
- /* Check if any part of the conflicting file's path is a symlink */
- if(dbpkg && !ok) {
- MALLOC(str, PATH_MAX);
- for(k = dbpkg->files; k; k = k->next) {
- snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
- stat(str, &buf2);
- if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) {
- printf("inodes match: %s and %s\n", path, str);
- ok = 1;
+ } else {
+ if(dbpkg == NULL) {
+ dbpkg = db_scan(db, p->name, INFRQ_DESC | INFRQ_FILES);
+
+ if(dbpkg)
+ strhash_add_list(htables[target_num], dbpkg->files);
+ }
+ if(dbpkg && strhash_isin(htables[target_num], filestr)) {
+ ok = 1;
+ }
+ /* Make sure that the supposedly-conflicting file is not actually just
+ * a symlink that points to a path that used to exist in the package.
+ */
+ /* Check if any part of the conflicting file's path is a symlink */
+ if(dbpkg && !ok) {
+ MALLOC(str, PATH_MAX);
+ for(k = dbpkg->files; k; k = k->next) {
+ snprintf(str, PATH_MAX, "%s%s", root, (char*)k->data);
+ stat(str, &buf2);
+ if(buf.st_ino == buf2.st_ino && buf.st_dev == buf2.st_dev) {
+ /*printf("inodes match: %s and %s\n", path, str);*/
+ ok = 1;
+ }
}
+ FREE(str);
}
- FREE(str);
- }
- /* Check if the conflicting file has been moved to another package/target */
- if(!ok) {
- /* Look at all the targets */
- for(k = targets; k && !ok; k = k->next) {
- pkginfo_t *p1 = (pkginfo_t*)k->data;
- /* As long as they're not the current package */
- if(strcmp(p1->name, p->name)) {
- pkginfo_t *dbpkg2 = NULL;
- dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES);
- /* If it used to exist in there, but doesn't anymore */
- if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) {
- /*printf("file %s moved from %s to %s\n", filestr, p1->name, p->name);*/
+ /* Check if the conflicting file has been moved to another package/target */
+ if(!ok) {
+ /* Look at all the targets */
+ for(k = targets; k && !ok; k = k->next) {
+ pkginfo_t *p1 = (pkginfo_t*)k->data;
+ /* As long as they're not the current package */
+ if(strcmp(p1->name, p->name)) {
+ pkginfo_t *dbpkg2 = NULL;
+ dbpkg2 = db_scan(db, p1->name, INFRQ_DESC | INFRQ_FILES);
+ /* If it used to exist in there, but doesn't anymore */
+ if(dbpkg2 && !is_in(filestr, p1->files) && is_in(filestr, dbpkg2->files)) {
+ /*printf("file %s moved from %s to %s\n", filestr, p1->name, p->name);*/
- ok = 1;
- /* Add to the "skip list" of files that we shouldn't remove during an upgrade.
- *
- * This is a workaround for the following scenario:
- *
- * - the old package A provides file X
- * - the new package A does not
- * - the new package B provides file X
- * - package A depends on B, so B is upgraded first
- *
- * Package B is upgraded, so file X is installed. Then package A
- * is upgraded, and it *removes* file X, since it no longer exists
- * in package A.
- *
- * Our workaround is to scan through all "old" packages and all "new"
- * ones, looking for files that jump to different packages.
- */
- *skip_list = list_add(*skip_list, filestr);
+ ok = 1;
+ /* Add to the "skip list" of files that we shouldn't remove during an upgrade.
+ *
+ * This is a workaround for the following scenario:
+ *
+ * - the old package A provides file X
+ * - the new package A does not
+ * - the new package B provides file X
+ * - package A depends on B, so B is upgraded first
+ *
+ * Package B is upgraded, so file X is installed. Then package A
+ * is upgraded, and it *removes* file X, since it no longer exists
+ * in package A.
+ *
+ * Our workaround is to scan through all "old" packages and all "new"
+ * ones, looking for files that jump to different packages.
+ */
+ *skip_list = list_add(*skip_list, filestr);
+ }
+ FREEPKG(dbpkg2);
}
- FREEPKG(dbpkg2);
}
}
}
diff --git a/src/md5.h b/src/md5.h
index e6e4ea64..20aae92b 100644
--- a/src/md5.h
+++ b/src/md5.h
@@ -31,7 +31,7 @@ typedef unsigned char *POINTER;
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
-typedef unsigned long int UINT4;
+typedef unsigned int UINT4;
/* MD5 context. */
diff --git a/src/pacconf.h b/src/pacconf.h
index 2274b9ec..8c2794ff 100644
--- a/src/pacconf.h
+++ b/src/pacconf.h
@@ -22,7 +22,7 @@
#define _PAC_PACCONF_H
#ifndef PACVER
-#define PACVER "2.9.6"
+#define PACVER "2.9.7"
#endif
#ifndef PACDBDIR
diff --git a/src/package.c b/src/package.c
index 5eba3a49..747a8dd5 100644
--- a/src/package.c
+++ b/src/package.c
@@ -197,8 +197,6 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
info->groups = list_add(info->groups, strdup(ptr));
} else if(!strcmp(key, "URL")) {
strncpy(info->url, ptr, sizeof(info->url));
- } else if(!strcmp(key, "LICENSE")) {
- strncpy(info->license, ptr, sizeof(info->license));
} else if(!strcmp(key, "BUILDDATE")) {
strncpy(info->builddate, ptr, sizeof(info->builddate));
} else if(!strcmp(key, "INSTALLDATE")) {
@@ -211,6 +209,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output)
char tmp[32];
strncpy(tmp, ptr, sizeof(tmp));
info->size = atol(tmp);
+ } else if(!strcmp(key, "LICENSE")) {
+ info->license = list_add(info->license, strdup(ptr));
} else if(!strcmp(key, "DEPEND")) {
info->depends = list_add(info->depends, strdup(ptr));
} else if(!strcmp(key, "CONFLICT")) {
@@ -244,7 +244,6 @@ pkginfo_t* newpkg()
pkg->version[0] = '\0';
pkg->desc[0] = '\0';
pkg->url[0] = '\0';
- pkg->license[0] = '\0';
pkg->builddate[0] = '\0';
pkg->installdate[0] = '\0';
pkg->packager[0] = '\0';
@@ -254,6 +253,7 @@ pkginfo_t* newpkg()
pkg->scriptlet = 0;
pkg->force = 0;
pkg->reason = REASON_EXPLICIT;
+ pkg->license = NULL;
pkg->requiredby = NULL;
pkg->conflicts = NULL;
pkg->files = NULL;
@@ -340,7 +340,9 @@ void dump_pkg_full(pkginfo_t *info)
FREELIST(pm);
printf("Packager : %s\n", info->packager);
printf("URL : %s\n", info->url);
- printf("License : %s\n", info->license);
+ pm = list_sort(info->license);
+ list_display("License :", pm);
+ FREELIST(pm);
printf("Architecture : %s\n", info->arch);
printf("Size : %ld\n", info->size);
printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : "");
diff --git a/src/package.h b/src/package.h
index ac300323..6b1b905b 100644
--- a/src/package.h
+++ b/src/package.h
@@ -50,7 +50,6 @@ typedef struct __pkginfo_t {
char version[64];
char desc[512];
char url[256];
- char license[128];
char builddate[32];
char installdate[32];
char packager[64];
@@ -60,6 +59,7 @@ typedef struct __pkginfo_t {
unsigned short scriptlet;
unsigned short force;
unsigned short reason;
+ PMList *license;
PMList *replaces;
PMList *groups;
PMList *files;
diff --git a/src/pacman.c b/src/pacman.c
index 3daa1fe4..b8d8eed5 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -92,6 +92,7 @@ char *pmo_proxyhost = NULL;
unsigned short pmo_proxyport = 0;
char *pmo_xfercommand = NULL;
PMList *pmo_noupgrade = NULL;
+PMList *pmo_noextract = NULL;
PMList *pmo_ignorepkg = NULL;
PMList *pmo_holdpkg = NULL;
unsigned short pmo_chomp = 0;
@@ -1801,15 +1802,14 @@ int pacman_add(pacdb_t *db, PMList *targets, PMList *dependonly)
snprintf(expath, PATH_MAX, "%s%s", pmo_root, pathname);
}
- /* if a file is in NoUpgrade and missing from the filesystem,
- * then we never extract it.
+ /* if a file is in NoExtract then we never extract it.
*
* eg, /home/httpd/html/index.html may be removed so index.php
* could be used
*/
- if(stat(expath, &buf) && is_in(pathname, pmo_noupgrade)) {
- vprint("%s is in NoUpgrade - skipping\n", pathname);
- logaction(stderr, "warning: %s is in NoUpgrade -- skipping extraction", pathname);
+ if(is_in(pathname, pmo_noextract)) {
+ vprint("%s is in NoExtract - skipping\n", pathname);
+ logaction(stderr, "warning: %s is in NoExtract -- skipping extraction", pathname);
tar_skip_regfile(tar);
continue;
}
@@ -2105,7 +2105,7 @@ int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist)
}
/* load package info from all targets */
- for(lp = targets; lp; lp = lp->next) {
+ for(lp = targets; lp && lp->data; lp = lp->next) {
info = db_scan(db, (char*)lp->data, INFRQ_ALL);
if(info == NULL) {
PMList *groups;
@@ -2150,6 +2150,10 @@ int pacman_remove(pacdb_t *db, PMList *targets, PMList *skiplist)
}
alltargs = list_add(alltargs, info);
}
+ if(!alltargs) {
+ /* no targets, nothing to do */
+ return(0);
+ }
if(!pmo_nodeps && !pmo_upgrade) {
vprint("checking dependencies...\n");
lp = checkdeps(db, PM_REMOVE, alltargs);
@@ -2447,14 +2451,14 @@ int pacman_query(pacdb_t *db, PMList *targets)
fprintf(stderr, "error: no file was specified for --owns\n");
return(1);
}
- if(realpath(package, rpath)) {
+ if(rel2abs(package, rpath, sizeof(rpath)-1)) {
int gotcha = 0;
rewinddir(db->dir);
while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL && !gotcha) {
for(lp = info->files; lp && !gotcha; lp = lp->next) {
sprintf(path, "%s%s", pmo_root, (char*)lp->data);
if(!strcmp(path, rpath)) {
- printf("%s is owned by %s %s\n", package, info->name, info->version);
+ printf("%s is owned by %s %s\n", rpath, info->name, info->version);
gotcha = 1;
}
}
@@ -2679,6 +2683,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
{
PMList *i, *j, *k;
PMList *newtargs = targs;
+ char realpkgname[255];
for(i = targs; i; i = i->next) {
pkginfo_t *pkg = (pkginfo_t*)i->data;
@@ -2708,6 +2713,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
FREEPKG(dep);
continue;
}
+ strncpy(realpkgname, dep->name, sizeof(realpkgname));
/* see if it was explicitly installed */
if(dep->reason == REASON_EXPLICIT) {
vprint("excluding %s -- explicitly installed\n", dep->name);
@@ -2725,7 +2731,7 @@ PMList* removedeps(pacdb_t *db, PMList *targs)
FREEPKG(dep);
if(!needed) {
/* add it to the target list */
- dep = db_scan(db, depend.name, INFRQ_ALL);
+ dep = db_scan(db, realpkgname, INFRQ_ALL);
newtargs = list_add(newtargs, dep);
newtargs = removedeps(db, newtargs);
}
@@ -3374,10 +3380,10 @@ int runscriptlet(char *installfn, char *script, char *ver, char *oldver)
vprint("Executing %s script...\n", script);
if(oldver) {
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | /usr/sbin/chroot %s /bin/sh",
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | /usr/sbin/chroot %s /bin/bash",
scriptpath, script, ver, oldver, pmo_root);
} else {
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/sh",
+ snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | /usr/sbin/chroot %s /bin/bash",
scriptpath, script, ver, pmo_root);
}
vprint("%s\n", cmdline);
@@ -3612,6 +3618,18 @@ int parseconfig(char *configfile)
}
pmo_noupgrade = list_add(pmo_noupgrade, strdup(p));
vprint("config: noupgrade: %s\n", p);
+ } else if(!strcmp(key, "NOEXTRACT")) {
+ char *p = ptr;
+ char *q;
+ while((q = strchr(p, ' '))) {
+ *q = '\0';
+ pmo_noextract = list_add(pmo_noextract, strdup(p));
+ vprint("config: noextract: %s\n", p);
+ p = q;
+ p++;
+ }
+ pmo_noextract = list_add(pmo_noextract, strdup(p));
+ vprint("config: noextract: %s\n", p);
} else if(!strcmp(key, "IGNOREPKG")) {
char *p = ptr;
char *q;
diff --git a/src/util.c b/src/util.c
index 08241691..b68b71f2 100644
--- a/src/util.c
+++ b/src/util.c
@@ -219,6 +219,103 @@ int rmrf(char *path)
return(0);
}
+/* Convert a relative path to an absolute path
+ *
+ * This function was taken from the pathconvert library and massaged
+ * to match our coding style. The pathconvert version is
+ * Copyright (c) 1997 Shigio Yamaguchi.
+ */
+char *rel2abs(const char *path, char *result, const size_t size)
+{
+ const char *pp, *bp;
+ /* endp points the last position which is safe in the result buffer. */
+ const char *endp = result + size - 1;
+ char *rp;
+ int length;
+ char base[PATH_MAX+1];
+
+ getcwd(base, PATH_MAX);
+
+ if(*path == '/') {
+ if(strlen(path) >= size) {
+ goto erange;
+ }
+ strcpy(result, path);
+ goto finish;
+ } else if(*base != '/' || !size) {
+ errno = EINVAL;
+ return (NULL);
+ } else if(size == 1) {
+ goto erange;
+ }
+
+ length = strlen(base);
+
+ if(!strcmp(path, ".") || !strcmp(path, "./")) {
+ if(length >= size) {
+ goto erange;
+ }
+ strcpy(result, base);
+ /* rp points the last char. */
+ rp = result + length - 1;
+ /* remove the last '/'. */
+ if(*rp == '/') {
+ if(length > 1) {
+ *rp = 0;
+ }
+ } else {
+ rp++;
+ }
+ /* rp point NULL char */
+ if(*++path == '/') {
+ /* Append '/' to the tail of path name. */
+ *rp++ = '/';
+ if(rp > endp) {
+ goto erange;
+ }
+ *rp = 0;
+ }
+ goto finish;
+ }
+ bp = base + length;
+ if(*(bp - 1) == '/') {
+ --bp;
+ }
+ /* up to root. */
+ for(pp = path; *pp && *pp == '.'; ) {
+ if(!strncmp(pp, "../", 3)) {
+ pp += 3;
+ while(bp > base && *--bp != '/');
+ } else if(!strncmp(pp, "./", 2)) {
+ pp += 2;
+ } else if(!strncmp(pp, "..\0", 3)) {
+ pp += 2;
+ while(bp > base && *--bp != '/');
+ } else {
+ break;
+ }
+ }
+ /* down to leaf. */
+ length = bp - base;
+ if(length >= size) {
+ goto erange;
+ }
+ strncpy(result, base, length);
+ rp = result + length;
+ if(*pp || *(pp - 1) == '/' || length == 0) {
+ *rp++ = '/';
+ }
+ if(rp + strlen(pp) > endp) {
+ goto erange;
+ }
+ strcpy(rp, pp);
+finish:
+ return result;
+erange:
+ errno = ERANGE;
+ return (NULL);
+}
+
/* output a string, but wrap words properly with a specified indentation
*/
void indentprint(char *str, int indent)
diff --git a/src/util.h b/src/util.h
index 2d711391..a536c2e1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -34,6 +34,7 @@ int unpack(char *archive, const char *prefix, const char *fn);
int copyfile(char *src, char *dest);
int makepath(char *path);
int rmrf(char *path);
+char *rel2abs(const char *path, char *result, const size_t size);
void indentprint(char *str, int indent);
char* trim(char *str);
char* strtoupper(char *str);