summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJudd Vinet <judd@archlinux.org>2003-11-25 03:02:36 +0100
committerJudd Vinet <judd@archlinux.org>2003-11-25 03:02:36 +0100
commitf54a888a1facfd8f086d6414260be5f1b991a66b (patch)
treec18ecbc42067712300175c0d0ef635dc4ec0da1e
parent5aa3a24b17c5b1d2b43274e530259dab7711b9b0 (diff)
downloadpacman-f54a888a1facfd8f086d6414260be5f1b991a66b.tar.gz
pacman-f54a888a1facfd8f086d6414260be5f1b991a66b.tar.xz
Imported from pacman-2.7.tar.gz
-rw-r--r--ChangeLog9
-rw-r--r--Makefile.in2
-rw-r--r--README2
-rw-r--r--doc/makepkg.8.in41
-rw-r--r--doc/pacman.8.in3
-rw-r--r--etc/makepkg.conf5
-rw-r--r--etc/pacman.conf2
-rwxr-xr-xscripts/gensync43
-rwxr-xr-xscripts/makepkg174
-rwxr-xr-xscripts/makeworld12
-rw-r--r--src/db.c31
-rw-r--r--src/db.h2
-rw-r--r--src/list.c1
-rw-r--r--src/package.c5
-rw-r--r--src/package.h9
-rw-r--r--src/pacman.c357
-rw-r--r--src/pacman.h4
17 files changed, 500 insertions, 202 deletions
diff --git a/ChangeLog b/ChangeLog
index 02afc1dd..840691cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
VERSION DESCRIPTION
-----------------------------------------------------------------------------
+2.7 - Added build-time dependencies to makepkg (Jason Chu)
+ - Added md5sum integrity checking to packages in --sync
+ mode (Aurelien Foret)
+ - Memory leak fixes (Aurelien Foret)
+ - Added CARCH variable to makepkg.conf for use in PKGBUILDs
+ - Added LogFile option for direct-to-file logging
+ - Added -Qii handling to show modified config files
+ - Allow --sync targets to specify an explicit repository to
+ sync from (eg, pacman -S current/patch)
2.6.4 - Altered pacman_upgrade() to allow a package to replace itself
2.6.3 - A couple memory fixes in the new replaces code
2.6.2 - Fixed a memory cleanup bug
diff --git a/Makefile.in b/Makefile.in
index 7eda945f..987d4e1b 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.6.4
+PACVER = 2.7
TOPDIR = @srcdir@
SRCDIR = $(TOPDIR)/src/
diff --git a/README b/README
index d9b0b1c5..2aa5057a 100644
--- a/README
+++ b/README
@@ -51,7 +51,7 @@ it helps.
COPYRIGHT:
----------
-pacman is Copyright (c) 2002 Judd Vinet <jvinet@zeroflux.org> and is
+pacman is Copyright (c) 2002-2003 Judd Vinet <jvinet@zeroflux.org> and is
licensed through the GNU General Public License (see COPYING).
pacman uses "libtar", a library for reading/writing tar-files. This
diff --git a/doc/makepkg.8.in b/doc/makepkg.8.in
index 03c96a06..9ade54b0 100644
--- a/doc/makepkg.8.in
+++ b/doc/makepkg.8.in
@@ -1,4 +1,4 @@
-.TH makepkg 8 "September 01, 2003" "makepkg #VERSION#" ""
+.TH makepkg 8 "November 22, 2003" "makepkg #VERSION#" ""
.SH NAME
makepkg \- package build utility
.SH SYNOPSIS
@@ -36,7 +36,8 @@ pkgrel=1
pkgdesc="Utilities for inserting and removing modules from the linux kernel"
url="http://www.kernel.org"
backup=(etc/modules.conf)
-depends=('mawk' 'bash' 'glibc' 'zlib')
+makedepends=('bash' 'mawk')
+depends=('glibc' 'zlib')
source=(ftp://ftp.kernel.org/pub/linux/utils/kernel/$pkgname/v2.4/$pkgname-$pkgver.tar.bz2 \\
modules.conf)
md5sums=('2c0cca3ef6330a187c6ef4fe41ecaa4d' \\
@@ -64,9 +65,11 @@ The line with \fIbackup=\fP specifies files that should be treated specially
when removing or upgrading packages. See \fBHANDLING CONFIG FILES\fP in
the \fIpacman\fP manpage for more information on this.
-The seventh line lists the dependencies for this package. In order to build/run
-the package, all dependencies must be satisifed first. makepkg will check this
-before attempting to build the package.
+Lines 7 and 8 list the dependencies for this package. The \fIdepends\fP array
+specifies the run-time dependencies and \fImakedepends\fP specifies the build-time
+dependencies. In order to run the package, \fIdepends\fP must be satisfied. To
+build the package, \fBall\fP dependencies must be satisifed first. makepkg
+will check this before attempting to build the package.
The \fIsource\fP array tells makepkg which files to download/extract before compiling
begins. The \fImd5sums\fP array provides md5sums for each of these files. These
@@ -97,6 +100,8 @@ make prefix=$startdir/pkg/usr install
.fi
.RE
Notice that the "/usr" portion should be present with "prefix", but not "DESTDIR".
+"DESTDIR" is the favorable option to use, but not all Makefiles support it. Use
+"prefix" only when "DESTDIR" is unavailable.
Once the package is successfully installed into the package root, \fImakepkg\fP
will remove some directories (as per Arch Linux package guidelines; if you use
@@ -215,6 +220,15 @@ does not already exist in /var/cache/pacman/src, the file is downloaded
by wget.
.TP
+.B md5sums \fI(array)\fP
+If this field is present, it should contain an MD5 hash for every source file
+specified in the \fIsource\fP array (in the same order). makepkg will use
+this to verify source file integrity during subsequent builds. To easily
+generate md5sums, first build using the PKGBUILD then run
+\fBmakepkg -g >>PKGBILD\fP. Then you can edit the PKGBUILD and move the
+\fImd5sums\fP line from the bottom to an appropriate location.
+
+.TP
.B groups \fI(array)\fP
This is an array of symbolic names that represent groups of packages, allowing
you to install multiple packages by requesting a single target. For example,
@@ -238,6 +252,11 @@ package name. They can also include a version requirement of the form
See the PKGBUILD example above for an example of the \fIdepends\fP directive.
.TP
+.B makedepends \fI(array)\fP
+An array of packages that this package depends on to build (ie, not required
+to run). Packages in this list should follow the same format as \fIdepends\fP.
+
+.TP
.B conflicts \fI(array)\fP
An array of packages that will conflict with this package (ie, they cannot both
be installed at the same time). This directive follows the same format as
@@ -260,8 +279,8 @@ to the differing package names. \fIreplaces\fP handles this.
.SH MAKEPKG OPTIONS
.TP
.B "\-b, \-\-builddeps"
-Build missing dependencies from source. When makepkg finds missing
-dependencies, it will look for the dependencies' PKGBUILD files under
+Build missing dependencies from source. When makepkg finds missing build-time or
+run-time dependencies, it will look for the dependencies' PKGBUILD files under
$ABSROOT (set in your /etc/makepkg.conf). If it finds them it will
run another copy of makepkg to build and install the missing dependencies.
The child makepkg calls will be made with the \fB-b\fP and \fB-i\fP options.
@@ -299,9 +318,13 @@ Do not strip binaries and libraries.
.B "\-p <buildscript>"
Read the package script \fI<buildscript>\fP instead of the default (\fIPKGBUILD\fP).
.TP
+.B "\-r, \-\-rmdeps"
+Upon successful build, remove any dependencies installed by makepkg/pacman during
+dependency auto-resolution (using \fB-b\fP or \fB-s\fP).
+.TP
.B "\-s, \-\-syncdeps"
-Install missing dependencies using pacman. When makepkg finds missing
-dependencies, it will run pacman to try and resolve them. If successful,
+Install missing dependencies using pacman. When makepkg finds missing build-time
+or run-time dependencies, it will run pacman to try and resolve them. If successful,
pacman will download the missing packages from a package repository and
install them for you.
.TP
diff --git a/doc/pacman.8.in b/doc/pacman.8.in
index 778a5974..859f0b4b 100644
--- a/doc/pacman.8.in
+++ b/doc/pacman.8.in
@@ -211,6 +211,9 @@ install/upgrade. \fINote:\fP do not include the leading slash when specifying f
.B "UseSyslog"
Log action messages through syslog(). This will insert pacman log entries into your
/var/log/messages or equivalent.
+.TP
+.B "LogFile = /path/to/file"
+Log actions directly to a file, usually /var/log/pacman.log.
.SH CONFIG: REPOSITORIES
Each repository section defines a section name and at least one location where the packages
diff --git a/etc/makepkg.conf b/etc/makepkg.conf
index 0a2a7548..4c8f9969 100644
--- a/etc/makepkg.conf
+++ b/etc/makepkg.conf
@@ -7,14 +7,15 @@ export FTPAGENT="/usr/bin/wget --continue --passive-ftp --tries=3 --waitretry=3"
#export FTPAGENT="/usr/bin/snarf"
#export FTPAGENT="/usr/bin/lftpget -c"
+export CARCH="i686"
+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 CHOST="i686-pc-linux-gnu"
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 CHOST="i686-pc-linux-gnu"
#export CFLAGS="-mcpu=i686 -O2 -pipe"
#export CXXFLAGS="-mcpu=i686 -O2 -pipe"
diff --git a/etc/pacman.conf b/etc/pacman.conf
index 4e37d572..c2592b29 100644
--- a/etc/pacman.conf
+++ b/etc/pacman.conf
@@ -8,7 +8,7 @@
# GENERAL OPTIONS
#
[options]
-UseSyslog
+LogFile = /var/log/pacman.log
NoUpgrade = etc/passwd etc/group etc/shadow
NoUpgrade = etc/fstab etc/raidtab
NoUpgrade = etc/rc.conf etc/rc.local
diff --git a/scripts/gensync b/scripts/gensync
index 045c4f38..5a0b7eda 100755
--- a/scripts/gensync
+++ b/scripts/gensync
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.6.4'
+myver='2.7'
usage() {
echo "gensync $myver"
@@ -42,6 +42,22 @@ usage() {
exit 0
}
+get_md5checksum()
+{
+ source $1 || return 1
+ if [ "$pkgdir" != "" ]; then
+ pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
+ else
+ pkgfile="$destdir/$pkgname-$pkgver-$pkgrel.pkg.tar.gz"
+ fi
+ if [ -f $pkgfile ]; then
+ md5line=`md5sum $pkgfile`
+ [ ! -z "$md5line" ] && pkgmd5sum=${md5line% *}
+ echo $pkgmd5sum
+ fi
+ return 0
+}
+
db_write_entry()
{
unset pkgname pkgver pkgrel pkgdesc
@@ -61,6 +77,11 @@ db_write_entry()
echo "%DESC%" >>desc
echo "$pkgdesc" >>desc
echo "" >>desc
+ if [ ! -z $pkgmd5sum ]; then
+ echo "%MD5SUM%" >>desc
+ echo "$pkgmd5sum" >>desc
+ echo "" >>desc
+ fi
if [ ${#groups[*]} -gt 0 ]; then
echo "%GROUPS%" >>desc
for it in "${groups[@]}"; do
@@ -111,11 +132,14 @@ if [ "$1" = "-h" -o "$1" = "--help" ]; then
fi
d=`dirname $1`
-rootdir=`cd $d && pwd`
-rootdir="$rootdir/`basename $1`"
+rootdir=`cd $d && pwd`/`basename $1`
d=`dirname $2`
-destfile=`cd $d && pwd`
-destfile="$destfile/`basename $2`"
+destdir=`cd $d && pwd`
+destfile="$destdir/`basename $2`"
+pkgdir=
+if [ "$3" != "" ]; then
+ pkgdir=$3
+fi
rm -rf /tmp/.gensync || exit 1
mkdir -p /tmp/.gensync || exit 1
@@ -126,9 +150,16 @@ if [ ! -d $rootdir ]; then
exit 1
fi
-echo "gensync: building database entries..." >&2
+echo "gensync: building database entries, generating md5sums..." >&2
+cd `dirname $2`
#for category in `find $rootdir/* -type d -maxdepth 0`; do
for file in `find $rootdir/* -name PKGBUILD`; do
+ pkgmd5sum=`get_md5checksum $file $pkgdir`
+ if [ -z $pkgmd5sum ]; then
+ echo "gensync: error generating checksum for $file" >&2
+ rm -rf /tmp/.gensync
+ exit 1
+ fi
db_write_entry $file
if [ $? -gt 0 ]; then
echo "gensync: error writing entry for $file" >&2
diff --git a/scripts/makepkg b/scripts/makepkg
index 7cc8b992..10c1c2a0 100755
--- a/scripts/makepkg
+++ b/scripts/makepkg
@@ -20,7 +20,7 @@
# USA.
#
-myver='2.6.4'
+myver='2.7'
startdir=`pwd`
# source Arch's abs.conf if it's present
@@ -46,7 +46,7 @@ strip_url() {
}
checkdeps() {
- local missdep=`pacman -T $*`
+ local missdep=""
local deplist=""
missdep=`pacman -T $*`
@@ -77,6 +77,72 @@ checkdeps() {
echo $deplist
}
+handledeps() {
+ local missingdeps=0
+ local deplist="$*"
+ local haveperm=0
+ if [ "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
+ haveperm=1
+ fi
+
+ if [ "$deplist" != "" -a $haveperm -eq 1 ]; then
+ if [ "$DEP_BIN" = "1" ]; then
+ # install missing deps from binary packages (using pacman -S)
+ msg "==> Installing missing dependencies..."
+ pacman -D $deplist
+ if [ "$?" = "127" ]; then
+ msg "==> 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.
+ if [ "$ABSROOT" = "" ]; then
+ msg "==> ERROR: The ABSROOT environment variable is not defined."
+ exit 1
+ fi
+ # TODO: handle version comparators (eg, glibc>=2.2.5)
+ msg "==> Building missing dependencies..."
+ for dep in $deplist; do
+ candidates=`find $ABSROOT -type d -name "$dep"`
+ if [ "$candidates" = "" ]; then
+ msg "==> ERROR: Could not find \"$dep\" under $ABSROOT"
+ exit 1
+ fi
+ success=0
+ for pkgdir in $candidates; do
+ if [ -f $pkgdir/PKGBUILD ]; then
+ cd $pkgdir
+ if [ "$RMDEPS" = "1" ]; then
+ makepkg -i -c -b -r -w $PKGDEST
+ else
+ makepkg -i -c -b -w $PKGDEST
+ fi
+ if [ $? -eq 0 ]; then
+ success=1
+ break
+ fi
+ fi
+ done
+ if [ "$success" = "0" ]; then
+ msg "==> ERROR: Failed to build \"$dep\""
+ exit 1
+ fi
+ done
+ # TODO: check deps again to make sure they were resolved
+ else
+ missingdeps=1
+ fi
+ elif [ "$deplist" != "" -a $haveperm -eq 0 ]; then
+ if [ "$DEP_SRC" = "1" -o "$DEP_BIN" = "1" ]; then
+ msg "==> WARNING: Cannot auto-install missing dependencies as a normal user!"
+ msg "==> Run makepkg as root to resolve dependencies automatically."
+ fi
+ missingdeps=1
+ fi
+ return $missingdeps
+}
usage() {
echo "makepkg version $myver"
@@ -92,6 +158,7 @@ usage() {
echo " -i, --install Install package after successful build"
echo " -n, --nostrip Do not strip binaries/libraries"
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 " -w <destdir> Write package to <destdir> instead of the working dir"
echo
@@ -100,6 +167,7 @@ usage() {
echo
}
+
# Options
CLEANUP=0
CLEANCACHE=0
@@ -110,6 +178,7 @@ DEP_SRC=0
NODEPS=0
FORCE=0
NOSTRIP=0
+RMDEPS=0
PKGDEST=$startdir
BUILDSCRIPT="./PKGBUILD"
@@ -117,15 +186,16 @@ ARGLIST=$@
while [ "$#" -ne "0" ]; do
case $1 in
- --clean) CLEANUP=1 ;;
+ --clean) CLEANUP=1 ;;
--cleancache) CLEANCACHE=1 ;;
- --syncdeps) DEP_BIN=1 ;;
- --builddeps) DEP_SRC=1 ;;
- --nodeps) NODEPS=1 ;;
- --install) INSTALL=1 ;;
- --force) FORCE=1 ;;
- --nostrip) NOSTRIP=1 ;;
- --genmd5) GENMD5=1 ;;
+ --syncdeps) DEP_BIN=1 ;;
+ --builddeps) DEP_SRC=1 ;;
+ --nodeps) NODEPS=1 ;;
+ --install) INSTALL=1 ;;
+ --force) FORCE=1 ;;
+ --nostrip) NOSTRIP=1 ;;
+ --genmd5) GENMD5=1 ;;
+ --rmdeps) RMDEPS=1 ;;
--help)
usage
exit 0
@@ -135,7 +205,7 @@ while [ "$#" -ne "0" ]; do
exit 1
;;
-*)
- while getopts "cCsbdhifgnp:w:-" opt; do
+ while getopts "cCsbdhifgnrp:w:-" opt; do
case $opt in
c) CLEANUP=1 ;;
C) CLEANCACHE=1 ;;
@@ -148,6 +218,7 @@ while [ "$#" -ne "0" ]; do
n) NOSTRIP=1 ;;
w) PKGDEST=$OPTARG ;;
p) BUILDSCRIPT=$OPTARG ;;
+ r) RMDEPS=1 ;;
h)
usage
exit 0
@@ -170,6 +241,11 @@ while [ "$#" -ne "0" ]; do
shift
done
+# convert a (possibly) relative path to absolute
+cd $PKGDEST
+PKGDEST=`pwd`
+cd -
+
if [ "$CLEANCACHE" = "1" ]; then
if [ "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
msg "==> Cleaning up source files from the cache."
@@ -182,7 +258,7 @@ if [ "$CLEANCACHE" = "1" ]; then
fi
unset pkgname pkgver pkgrel pkgdesc url groups provides md5sums
-unset replaces depends conflicts backup source install build
+unset replaces depends conflicts backup source install build makedepends
umask 0022
if [ ! -f $BUILDSCRIPT ]; then
@@ -240,56 +316,19 @@ fi
msg "==> Making package: $pkgname (`date`)"
-unset deplist
+unset deplist makedeplist
if [ `type -p pacman` -a "$NODEPS" = "0" ]; then
- msg "==> Checking Dependencies..."
+ msg "==> Checking Runtime Dependencies..."
deplist=`checkdeps ${depends[@]}`
- if [ "$deplist" != "" ]; then
- if [ "$DEP_BIN" = "1" ]; then
- # install missing deps from binary packages (using pacman -S)
- msg "==> Installing missing dependencies..."
- pacman -D $deplist
- if [ "$?" = "127" ]; then
- msg "==> 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.
- if [ "$ABSROOT" = "" ]; then
- msg "==> ERROR: The ABSROOT environment variable is not defined."
- exit 1
- fi
- # TODO: handle version comparators (eg, glibc>=2.2.5)
- msg "==> Building missing dependencies..."
- for dep in $deplist; do
- candidates=`find $ABSROOT -type d -name "$dep"`
- if [ "$candidates" = "" ]; then
- msg "==> ERROR: Could not find \"$dep\" under $ABSROOT"
- exit 1
- fi
- success=0
- for pkgdir in $candidates; do
- if [ -f $pkgdir/PKGBUILD ]; then
- cd $pkgdir
- echo makepkg -i -c -b -w $PKGDEST
- makepkg -i -c -b -w $PKGDEST
- if [ $? -eq 0 ]; then
- success=1
- break
- fi
- fi
- done
- if [ "$success" = "0" ]; then
- msg "==> ERROR: Failed to build \"$dep\""
- exit 1
- fi
- done
- # TODO: check deps again to make sure they were resolved
- else
- exit 1
- fi
+ handledeps $deplist
+ if [ $? -gt 0 ]; then
+ exit 1
+ fi
+ msg "==> Checking Buildtime Dependencies..."
+ makedeplist=`checkdeps ${makedepends[@]}`
+ handledeps $makedeplist
+ if [ $? -gt 0 ]; then
+ exit 1
fi
elif [ "$NODEPS" = "1" ]; then
msg "==> WARNING: skipping dependency checks."
@@ -387,7 +426,7 @@ if [ "$GENMD5" = "0" ]; then
*.tar)
cmd="tar -xf $file" ;;
*.zip)
- cmd="unzip -qq $file" ;;
+ cmd="unzip -qqo $file" ;;
*.gz)
cmd="gunzip $file" ;;
*.bz2)
@@ -502,7 +541,7 @@ if [ "$NOSTRIP" = "0" ]; then
fi
# get some package meta info
-builddate=`LC_ALL= ; date -u "+%a %b %e %k:%M:%S %Y"`
+builddate=`LC_ALL= ; LANG= ; date -u "+%a %b %e %H:%M:%S %Y"`
if [ "$PACKAGER" != "" ]; then
packager="$PACKAGER"
else
@@ -566,14 +605,19 @@ $cmd | sort >../filelist
cd $startdir
if [ "$CLEANUP" = "1" ]; then
- msg "==> Cleaning up"
+ msg "==> Cleaning up..."
rm -rf src pkg filelist
fi
+if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
+ msg "==> Removing installed dependencies..."
+ pacman -R $makedeplist $deplist
+fi
+
msg "==> Finished making: $pkgname (`date`)"
-if [ "$INSTALL" = "1" ]; then
- msg "==> Running pacman --upgrade"
+if [ "$INSTALL" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then
+ msg "==> Running pacman --upgrade..."
pacman --upgrade $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz
exit $?
fi
diff --git a/scripts/makeworld b/scripts/makeworld
index 4ce1a772..a5d4c6e8 100755
--- a/scripts/makeworld
+++ b/scripts/makeworld
@@ -21,7 +21,7 @@
#
toplevel=`pwd`
-version="2.6.4"
+version="2.7"
usage() {
echo "makeworld version $version"
@@ -33,6 +33,7 @@ usage() {
echo " -f, --force Overwrite existing packages"
echo " -i, --install Install package after successful build"
echo " -h, --help This help"
+ echo " -r, --rmdeps Remove installed dependencies after a successful build"
echo " -s, --syncdeps Install missing dependencies with pacman"
echo
echo " where <category> is one or more directory names under the ABS root"
@@ -55,6 +56,7 @@ for arg in $*; do
--builddeps) MAKEPKG_OPTS="$MAKEPKG_OPTS -b" ;;
--nodeps) MAKEPKG_OPTS="$MAKEPKG_OPTS -d" ;;
--force) MAKEPKG_OPTS="$MAKEPKG_OPTS -f" ;;
+ --rmdeps) MAKEPKG_OPTS="$MAKEPKG_OPTS -r" ;;
--help)
usage
exit 0
@@ -64,7 +66,7 @@ for arg in $*; do
exit 1
;;
-*)
- while getopts "chisbdf-" opt; do
+ while getopts "chisbdfr-" opt; do
case $opt in
c) MAKEPKG_OPTS="$MAKEPKG_OPTS -c" ;;
i) MAKEPKG_OPTS="$MAKEPKG_OPTS -i" ;;
@@ -72,6 +74,7 @@ for arg in $*; do
b) MAKEPKG_OPTS="$MAKEPKG_OPTS -b" ;;
d) MAKEPKG_OPTS="$MAKEPKG_OPTS -d" ;;
f) MAKEPKG_OPTS="$MAKEPKG_OPTS -f" ;;
+ r) MAKEPKG_OPTS="$MAKEPKG_OPTS -r" ;;
h)
usage
exit 0
@@ -100,6 +103,11 @@ if [ "$dest" = "" ]; then
exit 1
fi
+# convert a (possibly) relative path to absolute
+cd $dest
+dest=`pwd`
+cd -
+
sd=`date +"[%b %d %H:%M]"`
for category in $*; do
diff --git a/src/db.c b/src/db.c
index a9e4270e..862d8020 100644
--- a/src/db.c
+++ b/src/db.c
@@ -62,21 +62,14 @@ void db_close(pacdb_t* db)
/* frees pkgcache if necessary and returns a new package
* cache from db
*/
-PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache)
+PMList* db_loadpkgs(pacdb_t *db)
{
pkginfo_t *info;
- PMList *lp;
pkginfo_t **arr = NULL;
unsigned int arrct = 0;
int i;
PMList *cache = NULL;
- /* if pm_packages already contains data, free it first */
- for(lp = pkgcache; lp; lp = lp->next) {
- FREEPKG(lp->data);
- }
- list_free(pkgcache);
-
rewinddir(db->dir);
while((info = db_scan(db, NULL, INFRQ_DESC)) != NULL) {
/* add to the collective */
@@ -168,7 +161,6 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
if(ent == NULL) {
return(NULL);
}
- info = newpkg();
/* we always load DESC */
inforeq |= INFRQ_DESC;
@@ -179,12 +171,15 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
return(NULL);
}
+ info = newpkg();
+
/* DESC */
if(inforeq & INFRQ_DESC) {
snprintf(path, PATH_MAX, "%s/%s/desc", db->path, ent->d_name);
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
+ FREEPKG(info);
return(NULL);
}
while(!feof(fp)) {
@@ -194,16 +189,19 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
trim(line);
if(!strcmp(line, "%NAME%")) {
if(fgets(info->name, sizeof(info->name), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->name);
} else if(!strcmp(line, "%VERSION%")) {
if(fgets(info->version, sizeof(info->version), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->version);
} else if(!strcmp(line, "%DESC%")) {
if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->desc);
@@ -214,27 +212,32 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
}
} else if(!strcmp(line, "%URL%")) {
if(fgets(info->url, sizeof(info->url), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->url);
} else if(!strcmp(line, "%BUILDDATE%")) {
if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->builddate);
} else if(!strcmp(line, "%INSTALLDATE%")) {
if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->installdate);
} else if(!strcmp(line, "%PACKAGER%")) {
if(fgets(info->packager, sizeof(info->packager), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(info->packager);
} else if(!strcmp(line, "%SIZE%")) {
char tmp[32];
if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ FREEPKG(info);
return(NULL);
}
trim(tmp);
@@ -247,6 +250,14 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
char *s = strdup(line);
info->replaces = list_add(info->replaces, s);
}
+ } else if(!strcmp(line, "%MD5SUM%")) {
+ /* MD5SUM tag only appears in sync repositories,
+ * not the local one.
+ */
+ if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) {
+ FREEPKG(info);
+ return(NULL);
+ }
}
}
fclose(fp);
@@ -258,6 +269,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "error: %s: %s\n", path, strerror(errno));
+ FREEPKG(info);
return(NULL);
}
while(fgets(line, 256, fp)) {
@@ -284,6 +296,7 @@ pkginfo_t* db_read(pacdb_t *db, struct dirent *ent, unsigned int inforeq)
fp = fopen(path, "r");
if(fp == NULL) {
fprintf(stderr, "db_read: error: %s: %s\n", path, strerror(errno));
+ FREEPKG(info);
return(NULL);
}
while(!feof(fp)) {
diff --git a/src/db.h b/src/db.h
index 8f1424ba..a26ad1c2 100644
--- a/src/db.h
+++ b/src/db.h
@@ -37,7 +37,7 @@ typedef struct __pacdb_t {
pacdb_t* db_open(char *root, char *dbpath, char *treename);
void db_close(pacdb_t *db);
-PMList* db_loadpkgs(pacdb_t *db, PMList *pkgcache);
+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);
diff --git a/src/list.c b/src/list.c
index d3ccfc89..8d1d2820 100644
--- a/src/list.c
+++ b/src/list.c
@@ -183,6 +183,7 @@ PMList *list_sort(PMList *list)
if(arr) {
free(arr);
+ arr = NULL;
}
return(lp);
diff --git a/src/package.c b/src/package.c
index cffc2f51..0f6b0c91 100644
--- a/src/package.c
+++ b/src/package.c
@@ -69,10 +69,12 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
parse_descfile(descfile, info, &backup, output);
if(!strlen(info->name)) {
fprintf(stderr, "load_pkg: missing package name in %s.\n", pkgfile);
+ FREEPKG(info);
return(NULL);
}
if(!strlen(info->version)) {
fprintf(stderr, "load_pkg: missing package version in %s.\n", pkgfile);
+ FREEPKG(info);
return(NULL);
}
for(lp = backup; lp; lp = lp->next) {
@@ -123,6 +125,7 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
char errorstr[255];
snprintf(errorstr, 255, "bad package file in %s", pkgfile);
perror(errorstr);
+ FREEPKG(info);
return(NULL);
}
expath = NULL;
@@ -131,6 +134,7 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output)
if(!config) {
fprintf(stderr, "load_pkg: missing package info file in %s\n", pkgfile);
+ FREEPKG(info);
return(NULL);
}
@@ -231,6 +235,7 @@ pkginfo_t* newpkg()
pkg->builddate[0] = '\0';
pkg->installdate[0] = '\0';
pkg->packager[0] = '\0';
+ pkg->md5sum[0] = '\0';
pkg->size = 0;
pkg->scriptlet = 0;
pkg->requiredby = NULL;
diff --git a/src/package.h b/src/package.h
index 11547057..b7d72f8f 100644
--- a/src/package.h
+++ b/src/package.h
@@ -25,6 +25,14 @@
#define FREEPKG(p) { freepkg(p); p = NULL; }
+#define FREELISTPKGS(p) {\
+ PMList *i;\
+ for(i = p; i; i = i->next) {\
+ FREEPKG(i->data);\
+ }\
+ FREELIST(p);\
+}
+
/* mods for depend_t.mod */
#define DEP_ANY 0
#define DEP_EQ 1
@@ -41,6 +49,7 @@ typedef struct __pkginfo_t {
char builddate[32];
char installdate[32];
char packager[64];
+ char md5sum[33];
unsigned long size;
unsigned short scriptlet;
PMList *replaces;
diff --git a/src/pacman.c b/src/pacman.c
index 03051f92..3c33ac7b 100644
--- a/src/pacman.c
+++ b/src/pacman.c
@@ -77,6 +77,7 @@ unsigned short pmo_s_clean = 0;
unsigned short pmo_group = 0;
/* configuration file options */
char *pmo_dbpath = NULL;
+char *pmo_logfile = NULL;
PMList *pmo_noupgrade = NULL;
PMList *pmo_ignorepkg = NULL;
unsigned short pmo_usesyslog = 0;
@@ -90,6 +91,7 @@ PMList *pm_packages = NULL;
/* list of targets specified on command line */
PMList *pm_targets = NULL;
+FILE *logfd = NULL;
char *lckfile = "/tmp/pacman.lck";
char *workfile = NULL;
enum {READ_ONLY, READ_WRITE} pm_access;
@@ -108,6 +110,11 @@ int main(int argc, char *argv[])
maxcols = atoi(cenv);
}
+ if(argc < 2) {
+ usage(PM_MAIN, (char*)basename(argv[0]));
+ return(0);
+ }
+
/* default root */
MALLOC(pmo_root, PATH_MAX);
strcpy(pmo_root, "/");
@@ -115,14 +122,11 @@ int main(int argc, char *argv[])
MALLOC(pmo_dbpath, PATH_MAX);
strcpy(pmo_dbpath, PKGDIR);
- if(argc < 2) {
- usage(PM_MAIN, (char*)basename(argv[0]));
- return(0);
- }
-
/* parse the command line */
ret = parseargs(PM_ADD, argc, argv);
if(ret) {
+ FREE(pmo_root);
+ FREE(pmo_dbpath);
return(ret);
}
@@ -160,6 +164,13 @@ int main(int argc, char *argv[])
if(pmo_usesyslog) {
openlog("pacman", 0, LOG_USER);
}
+ if(pmo_logfile && geteuid() == 0) {
+ /* open the log file */
+ logfd = fopen(pmo_logfile, "a");
+ if(logfd == NULL) {
+ perror("warning: cannot open logfile");
+ }
+ }
/* check for db existence */
/* add a trailing '/' if there isn't one */
@@ -198,7 +209,7 @@ int main(int argc, char *argv[])
}
/* load pm_packages cache */
- pm_packages = db_loadpkgs(db_local, pm_packages);
+ pm_packages = db_loadpkgs(db_local);
/* start the requested operation */
switch(pmo_op) {
@@ -213,9 +224,6 @@ int main(int argc, char *argv[])
ret = 1;
}
db_close(db_local);
- FREELIST(pm_packages);
- FREE(pmo_root);
- FREE(pmo_dbpath);
cleanup(ret);
/* not reached */
return(0);
@@ -316,7 +324,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
oldmask = umask(0000);
- if(makepath("/var/cache/pacman/pkg")) {
+ if(makepath("/var/cache/pacman/pkg")) {
fprintf(stderr, "error: could not create new cache directory: %s\n", strerror(errno));
return(1);
}
@@ -329,9 +337,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
if(pmo_s_sync) {
/* grab a fresh package list */
printf(":: Synchronizing package databases... \n");
- if(pmo_usesyslog) {
- syslog(LOG_INFO, "synchronizing package lists");
- }
+ logaction(NULL, "synchronizing package lists");
sync_synctree();
}
@@ -351,8 +357,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
dbs->sync = sync;
dbs->db = db_sync;
/* cache packages */
- dbs->pkgcache = NULL;
- dbs->pkgcache = db_loadpkgs(db_sync, dbs->pkgcache);
+ dbs->pkgcache = db_loadpkgs(db_sync);
databases = list_add(databases, dbs);
}
@@ -454,9 +459,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
} else if(pmo_s_upgrade) {
int newer = 0;
int ignore = 0;
- if(pmo_usesyslog) {
- syslog(LOG_INFO, "starting full system upgrade");
- }
+ logaction(NULL, "starting full system upgrade");
/* check for "recommended" package replacements */
for(i = databases; i && allgood; i = i->next) {
dbsync_t *dbs = (dbsync_t*)i->data;
@@ -571,58 +574,81 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = targets; i && allgood; i = i->next) {
if(i->data) {
int cmp, found = 0;
+ char *treename;
+ char *targ;
+ char *targline;
pkginfo_t *local;
syncpkg_t *sync = NULL;
MALLOC(sync, sizeof(syncpkg_t));
sync->replaces = NULL;
+ targline = strdup((char*)i->data);
+ targ = index(targline, '/');
+ if(targ) {
+ *targ = '\0';
+ targ++;
+ treename = targline;
+ } else {
+ targ = targline;
+ treename = NULL;
+ }
+
for(j = databases; !found && j; j = j->next) {
dbsync_t *dbs = (dbsync_t*)j->data;
for(k = dbs->pkgcache; !found && k; k = k->next) {
pkginfo_t *pkg = (pkginfo_t*)k->data;
- if(!strcmp((char*)i->data, pkg->name)) {
- found = 1;
- sync->dbs = dbs;
- /* re-fetch the package record with dependency info */
- sync->pkg = db_scan(sync->dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
- if(sync->pkg == NULL) {
- found = 0;
+ if(!strcmp(targ, pkg->name)) {
+ if(treename == NULL ||
+ (treename && !strcmp(treename, dbs->sync->treename))) {
+ found = 1;
+ sync->dbs = dbs;
+ /* re-fetch the package record with dependency info */
+ sync->pkg = db_scan(sync->dbs->db, pkg->name, INFRQ_DESC | INFRQ_DEPENDS);
+ if(sync->pkg == NULL) {
+ found = 0;
+ }
}
}
}
}
if(!found) {
- /* target not found: check if it's a group */
- k = NULL;
- for(j = databases; j; j = j->next) {
- dbsync_t *dbs = (dbsync_t*)j->data;
- PMList *l = pkg_ingroup(dbs->db, (char *)i->data);
- k = list_merge(k, l);
- FREELIST(l);
- }
- if(k != NULL) {
- printf(":: group %s:\n", (char*)i->data);
- list_display(" ", k);
- if(yesno(" Install whole content? [Y/n] ")) {
- targets = list_merge(targets, k);
- FREELIST(k);
- } else {
- PMList *l;
- for(l = k; l; l = l->next) {
- if(yesno(":: install %s from group %s? [Y/n] ", (char*)l->data, (char*)i->data)) {
- targets = list_add(targets, strdup((char*)l->data));
+ if(treename == NULL) {
+ /* target not found: check if it's a group */
+ k = NULL;
+ for(j = databases; j; j = j->next) {
+ dbsync_t *dbs = (dbsync_t*)j->data;
+ PMList *l = pkg_ingroup(dbs->db, targ);
+ k = list_merge(k, l);
+ FREELIST(l);
+ }
+ if(k != NULL) {
+ printf(":: group %s:\n", targ);
+ list_display(" ", k);
+ if(yesno(" Install whole content? [Y/n] ")) {
+ targets = list_merge(targets, k);
+ FREELIST(k);
+ } else {
+ PMList *l;
+ for(l = k; l; l = l->next) {
+ if(yesno(":: install %s from group %s? [Y/n] ", (char*)l->data, targ)) {
+ targets = list_add(targets, strdup((char*)l->data));
+ }
}
}
+ FREELIST(k);
+ } else {
+ fprintf(stderr, "%s: not found in sync db\n", targ);
+ allgood = 0;
}
- FREELIST(k);
} else {
- fprintf(stderr, "%s: not found in sync db\n", (char*)i->data);
+ fprintf(stderr, "%s: not present in \"%s\" repository\n", targ, treename);
allgood = 0;
}
FREE(sync);
+ FREE(targline);
continue;
}
- local = db_scan(db, (char*)i->data, INFRQ_DESC);
+ local = db_scan(db, targ, INFRQ_DESC);
if(local && !pmo_s_downloadonly) {
/* this is an upgrade, compare versions and determine if it is necessary */
cmp = rpmvercmp(local->version, sync->pkg->version);
@@ -632,6 +658,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
FREEPKG(local);
FREEPKG(sync->pkg);
FREE(sync);
+ FREE(targline);
continue;
}
} else if(cmp == 0) {
@@ -640,6 +667,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
FREEPKG(local);
FREEPKG(sync->pkg);
FREE(sync);
+ FREE(targline);
continue;
}
}
@@ -659,7 +687,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
- if(allgood) {
+ if(allgood && !pmo_s_search) {
/* check for inter-conflicts and whatnot */
if(!pmo_nodeps && !pmo_s_downloadonly) {
int errorout = 0;
@@ -757,7 +785,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* any packages in rmtargs need to be removed from final. */
/* rather than ripping out nodes from final, we just copy over */
- /* our "good" nodes to a new list and reassign. */
+ /* our "good" nodes to a new list and reassign. */
k = NULL;
for(i = final; i; i = i->next) {
syncpkg_t *s = (syncpkg_t*)i->data;
@@ -779,6 +807,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* list targets */
if(final && final->data && allgood) {
PMList *list = NULL;
+ char *str;
for(i = rmtargs; i; i = i->next) {
list = list_add(list, strdup(i->data));
}
@@ -791,9 +820,11 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
if(list) {
printf("\nRemove: ");
- indentprint(buildstring(list), 9);
+ str = buildstring(list);
+ indentprint(str, 9);
printf("\n");
FREELIST(list);
+ FREE(str);
}
for(i = final; i; i = i->next) {
syncpkg_t *s = (syncpkg_t*)i->data;
@@ -805,9 +836,11 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
printf("\nTargets: ");
- indentprint(buildstring(list), 9);
+ str = buildstring(list);
+ indentprint(str, 9);
printf("\n");
FREELIST(list);
+ FREE(str);
}
/* get confirmation */
@@ -835,6 +868,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
PMList *processed = NULL;
PMList *files = NULL;
+ snprintf(ldir, PATH_MAX, "%svar/cache/pacman/pkg", pmo_root);
+
/* group sync records by repository and download */
while(!done) {
if(current) {
@@ -853,8 +888,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
struct stat buf;
char path[PATH_MAX];
- snprintf(path, PATH_MAX, "%svar/cache/pacman/pkg/%s-%s.pkg.tar.gz",
- pmo_root, sync->pkg->name, sync->pkg->version);
+ snprintf(path, PATH_MAX, "%s/%s-%s.pkg.tar.gz",
+ ldir, sync->pkg->name, sync->pkg->version);
if(stat(path, &buf)) {
/* file is not in the cache dir, so add it to the list */
snprintf(path, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
@@ -865,7 +900,6 @@ int pacman_sync(pacdb_t *db, PMList *targets)
}
}
}
- snprintf(ldir, PATH_MAX, "%svar/cache/pacman/pkg", pmo_root);
if(files) {
struct stat buf;
@@ -878,14 +912,14 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* no cache directory.... try creating it */
snprintf(parent, PATH_MAX, "%svar/cache/pacman", pmo_root);
- logaction("warning: no %s cache exists. creating...\n", ldir);
+ logaction(stderr, "warning: no %s cache exists. creating...\n", ldir);
oldmask = umask(0000);
mkdir(parent, 0755);
if(mkdir(ldir, 0755)) {
/* couldn't mkdir the cache directory, so fall back to /tmp and unlink
* the package afterwards.
*/
- logaction("warning: couldn't create package cache, using /tmp instead\n");
+ logaction(stderr, "warning: couldn't create package cache, using /tmp instead\n");
snprintf(ldir, PATH_MAX, "/tmp");
varcache = 0;
}
@@ -907,6 +941,55 @@ int pacman_sync(pacdb_t *db, PMList *targets)
/* double-check */
FREELIST(files);
+ /* Check integrity of files */
+ printf("checking package integrity... ");
+ fflush(stdout);
+
+ for(i = final; i; i = i->next) {
+ syncpkg_t *sync;
+ char str[PATH_MAX], pkgname[PATH_MAX];
+ char *md5sum1, *md5sum2;
+
+ sync = (syncpkg_t*)i->data;
+ snprintf(pkgname, PATH_MAX, "%s-%s.pkg.tar.gz", sync->pkg->name, sync->pkg->version);
+
+ md5sum1 = sync->pkg->md5sum;
+ if(md5sum1 == NULL || md5sum1[0] == '\0') {
+ if(allgood) {
+ printf("\n");
+ }
+ fprintf(stderr, "error: can't get md5 checksum for package %s\n", pkgname);
+ allgood = 0;
+ continue;
+ }
+ snprintf(str, PATH_MAX, "%s/%s", ldir, pkgname);
+ md5sum2 = MDFile(str);
+ if(md5sum2 == NULL || md5sum2[0] == '\0') {
+ if(allgood) {
+ printf("\n");
+ }
+ fprintf(stderr, "error: can't get md5 checksum for archive %s\n", pkgname);
+ FREE(md5sum1);
+ allgood = 0;
+ continue;
+ }
+
+ if(strcmp(md5sum1, md5sum2) != 0) {
+ if(allgood) {
+ printf("\n");
+ }
+ fprintf(stderr, "error: archive %s is corrupted\n", pkgname);
+ allgood = 0;
+ }
+
+ FREE(md5sum2);
+ }
+ if(allgood) {
+ printf("done.\n");
+ } else {
+ fprintf(stderr, "\n");
+ }
+
if(!pmo_s_downloadonly) {
/* remove any conflicting packages (WITH dep checks) */
if(rmtargs) {
@@ -918,7 +1001,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
allgood = 0;
}
/* reload package cache */
- pm_packages = db_loadpkgs(db, pm_packages);
+ FREELISTPKGS(pm_packages);
+ pm_packages = db_loadpkgs(db);
}
FREELIST(rmtargs);
for(i = final; allgood && i; i = i->next) {
@@ -996,10 +1080,7 @@ int pacman_sync(pacdb_t *db, PMList *targets)
syncpkg_t *sync = (syncpkg_t*)i->data;
if(sync) {
FREEPKG(sync->pkg);
- for(j = sync->replaces; j; j = j->next) {
- FREEPKG(j->data);
- }
- FREELIST(sync->replaces);
+ FREELISTPKGS(sync->replaces);
}
FREE(sync);
i->data = NULL;
@@ -1011,13 +1092,8 @@ int pacman_sync(pacdb_t *db, PMList *targets)
for(i = databases; i; i = i->next) {
dbsync_t *dbs = (dbsync_t*)i->data;
db_close(dbs->db);
- for(j = dbs->pkgcache; j; j = j->next) {
- if(j->data) {
- freepkg(j->data);
- j->data = NULL;
- }
- }
- FREELIST(dbs->pkgcache);
+ dbs->db = NULL;
+ FREELISTPKGS(dbs->pkgcache);
FREE(dbs);
i->data = NULL;
}
@@ -1131,10 +1207,10 @@ int pacman_add(pacdb_t *db, PMList *targets)
}
if(rmtargs && !errorout) {
int retcode;
- int oldupg = pmo_upgrade;
+ int oldupg = pmo_upgrade;
/* any packages in rmtargs need to be removed from alltargs. */
/* rather than ripping out nodes from alltargs, we just copy over */
- /* our "good" nodes to a new list and reassign. */
+ /* our "good" nodes to a new list and reassign. */
k = NULL;
for(lp = alltargs; lp; lp = lp->next) {
pkginfo_t *p = (pkginfo_t*)lp->data;
@@ -1162,7 +1238,8 @@ int pacman_add(pacdb_t *db, PMList *targets)
return(1);
}
/* reload package cache */
- pm_packages = db_loadpkgs(db, pm_packages);
+ FREELISTPKGS(pm_packages);
+ pm_packages = db_loadpkgs(db);
pmo_upgrade = oldupg;
}
}
@@ -1236,7 +1313,8 @@ int pacman_add(pacdb_t *db, PMList *targets)
return(1);
}
/* reload package cache */
- pm_packages = db_loadpkgs(db, pm_packages);
+ FREELISTPKGS(pm_packages);
+ pm_packages = db_loadpkgs(db);
}
} else {
/* no previous package version is installed, so this is actually just an
@@ -1302,8 +1380,8 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* extract the package's version to a temporary file and md5 it */
temp = strdup("/tmp/pacman_XXXXXX");
mkstemp(temp);
- if(tar_extract_file(tar, temp)) {
- logaction("could not extract %s: %s\n", pathname, strerror(errno));
+ if(tar_extract_file(tar, temp)) {
+ logaction(stderr, "could not extract %s: %s\n", pathname, strerror(errno));
errors++;
continue;
}
@@ -1340,13 +1418,13 @@ int pacman_add(pacdb_t *db, PMList *targets)
char newpath[PATH_MAX];
snprintf(newpath, PATH_MAX, "%s.pacorig", expath);
if(rename(expath, newpath)) {
- logaction("error: could not rename %s: %s\n", expath, strerror(errno));
+ logaction(stderr, "error: could not rename %s: %s\n", expath, strerror(errno));
}
if(copyfile(temp, expath)) {
- logaction("error: could not copy %s to %s: %s\n", temp, expath, strerror(errno));
+ logaction(stderr, "error: could not copy %s to %s: %s\n", temp, expath, strerror(errno));
errors++;
} else {
- logaction("warning: %s saved as %s\n", expath, newpath);
+ logaction(stderr, "warning: %s saved as %s\n", expath, newpath);
}
}
} else if(md5_orig) {
@@ -1373,9 +1451,9 @@ int pacman_add(pacdb_t *db, PMList *targets)
installnew = 1;
snprintf(newpath, PATH_MAX, "%s.pacsave", expath);
if(rename(expath, newpath)) {
- logaction("error: could not rename %s: %s\n", expath, strerror(errno));
+ logaction(stderr, "error: could not rename %s: %s\n", expath, strerror(errno));
} else {
- logaction("warning: %s saved as %s\n", expath, newpath);
+ logaction(stderr, "warning: %s saved as %s\n", expath, newpath);
}
}
@@ -1399,11 +1477,11 @@ int pacman_add(pacdb_t *db, PMList *targets)
} else {
vprint("%s is in NoUpgrade - skipping\n", pathname);
strncat(expath, ".pacnew", PATH_MAX);
- logaction("warning: extracting %s%s as %s\n", pmo_root, pathname, expath);
+ logaction(stderr, "warning: extracting %s%s as %s\n", pmo_root, pathname, expath);
/*tar_skip_regfile(tar);*/
}
- if(tar_extract_file(tar, expath)) {
- logaction("could not extract %s: %s\n", pathname, strerror(errno));
+ if(tar_extract_file(tar, expath)) {
+ logaction(stderr, "could not extract %s: %s\n", pathname, strerror(errno));
errors++;
}
/* calculate an md5 hash if this is in info->backup */
@@ -1427,7 +1505,7 @@ int pacman_add(pacdb_t *db, PMList *targets)
tar_close(tar);
if(errors) {
ret = 1;
- logaction("errors occurred while %s %s\n",
+ logaction(stderr, "errors occurred while %s %s\n",
(pmo_upgrade ? "upgrading" : "installing"), info->name);
/* XXX: this "else" is disabled so the db_write() ALWAYS occurs. If it doesn't
@@ -1462,17 +1540,15 @@ int pacman_add(pacdb_t *db, PMList *targets)
/* make an install date (in UTC) */
strncpy(info->installdate, asctime(gmtime(&t)), sizeof(info->installdate));
if(db_write(db, info)) {
- logaction("error updating database for %s!\n", info->name);
+ logaction(stderr, "error updating database for %s!\n", info->name);
return(1);
}
vprint("done.\n");
- if(pmo_usesyslog) {
- if(pmo_upgrade && oldpkg) {
- syslog(LOG_INFO, "upgraded %s (%s -> %s)\n", info->name,
+ if(pmo_upgrade && oldpkg) {
+ logaction(NULL, "upgraded %s (%s -> %s)", info->name,
oldpkg->version, info->version);
- } else {
- syslog(LOG_INFO, "installed %s (%s)\n", info->name, info->version);
- }
+ } else {
+ logaction(NULL, "installed %s (%s)", info->name, info->version);
}
/* update dependency packages' REQUIREDBY fields */
@@ -1678,7 +1754,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
newpath = (char*)realloc(newpath, strlen(line)+strlen(".pacsave")+1);
sprintf(newpath, "%s.pacsave", line);
rename(line, newpath);
- logaction("warning: %s saved as %s\n", line, newpath);
+ logaction(stderr, "warning: %s saved as %s\n", line, newpath);
} else {
/*vprint(" unlinking %s\n", line);*/
if(unlink(line)) {
@@ -1761,9 +1837,7 @@ int pacman_remove(pacdb_t *db, PMList *targets)
}
if(!pmo_upgrade) {
printf("done.\n");
- if(pmo_usesyslog) {
- syslog(LOG_INFO, "removed %s (%s)\n", info->name, info->version);
- }
+ logaction(NULL, "removed %s (%s)\n", info->name, info->version);
}
}
@@ -1865,7 +1939,7 @@ int pacman_query(pacdb_t *db, PMList *targets)
int gotcha = 0;
rewinddir(db->dir);
while((info = db_scan(db, NULL, INFRQ_DESC | INFRQ_FILES)) != NULL && !gotcha) {
- for(lp = info->files; lp; lp = lp->next) {
+ 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);
@@ -1915,12 +1989,45 @@ int pacman_query(pacdb_t *db, PMList *targets)
} else {
/* find a target */
if(pmo_q_info) {
- info = db_scan(db, package, INFRQ_DESC | INFRQ_DEPENDS);
+ info = db_scan(db, package, INFRQ_ALL);
if(info == NULL) {
fprintf(stderr, "Package \"%s\" was not found.\n", package);
return(2);
}
dump_pkg(info);
+ if(pmo_q_info > 1 && info->backup) {
+ /* extra info */
+ printf("\n");
+ for(lp = info->backup; lp; lp = lp->next) {
+ struct stat buf;
+ char path[PATH_MAX];
+ char *md5sum;
+ char *str = strdup(lp->data);
+ char *ptr = index(str, '\t');
+ if(ptr == NULL) {
+ FREE(str);
+ continue;
+ }
+ *ptr = '\0';
+ ptr++;
+ snprintf(path, PATH_MAX-1, "%s%s", pmo_root, str);
+ if(!stat(path, &buf)) {
+ md5sum = MDFile(path);
+ if(md5sum == NULL) {
+ fprintf(stderr, "error calculating md5sum for %s\n", path);
+ continue;
+ }
+ if(strcmp(md5sum, ptr)) {
+ printf("MODIFIED\t%s\n", path);
+ } else {
+ printf("NOT MODIFIED\t%s\n", path);
+ }
+ } else {
+ printf("MISSING\t\t%s\n", path);
+ }
+ FREE(str);
+ }
+ }
printf("\n");
} else if(pmo_q_list) {
info = db_scan(db, package, INFRQ_DESC | INFRQ_FILES);
@@ -2319,7 +2426,7 @@ PMList* checkdeps(pacdb_t *db, unsigned short op, PMList *targets)
for(j = tp->depends; j; j = j->next) {
/* split into name/version pairs */
if(splitdep((char*)j->data, &depend)) {
- logaction("warning: invalid dependency in %s\n", (char*)tp->name);
+ logaction(stderr, "warning: invalid dependency in %s\n", (char*)tp->name);
continue;
}
found = 0;
@@ -2477,6 +2584,7 @@ int splitdep(char *depstr, depend_t *depend)
}
if(ptr == NULL) {
+ FREE(str);
return(0);
}
*ptr = '\0';
@@ -2589,7 +2697,7 @@ int parseargs(int op, int argc, char **argv)
case 'e': pmo_q_orphans = 1; break;
case 'f': pmo_force = 1; break;
case 'g': pmo_group = 1; break;
- case 'i': pmo_q_info = 1; break;
+ case 'i': pmo_q_info++; break;
case 'l': pmo_q_list = 1; break;
case 'n': pmo_nosave = 1; break;
case 'p': pmo_q_isfile = 1; break;
@@ -2735,6 +2843,9 @@ int parseconfig(char *configfile)
}
strncpy(pmo_dbpath, ptr, PATH_MAX);
vprint("config: dbpath: %s\n", pmo_dbpath);
+ } else if (!strcmp(key, "LOGFILE")) {
+ pmo_logfile = strndup(ptr, PATH_MAX);
+ vprint("config: log file: %s\n", pmo_logfile);
} else {
fprintf(stderr, "config: line %d: syntax error\n", linenum);
return(1);
@@ -2898,19 +3009,29 @@ void vprint(char *fmt, ...)
}
}
-/* Output a message to stderr, and (optionally) syslog */
-void logaction(char *fmt, ...)
+/* Output a message to stderr, and (optionally) syslog and/or a logfile */
+void logaction(FILE *fp, char *fmt, ...)
{
char msg[1024];
va_list args;
va_start(args, fmt);
vsnprintf(msg, 1024, fmt, args);
va_end(args);
-
- fprintf(stderr, "%s", msg);
+ if(fp) {
+ fprintf(fp, "%s", msg);
+ }
if(pmo_usesyslog) {
syslog(LOG_WARNING, "%s", msg);
}
+ if(logfd) {
+ time_t t;
+ struct tm *tm;
+ t = time(NULL);
+ tm = localtime(&t);
+
+ fprintf(logfd, "[%02d/%02d/%02d %02d:%02d] %s\n", tm->tm_mon, tm->tm_mday,
+ tm->tm_year-100, tm->tm_hour, tm->tm_min, msg);
+ }
}
/* Condense a list of strings into one long (space-delimited) string
@@ -2958,8 +3079,10 @@ int lckrm(char *file)
void cleanup(int signum)
{
+ PMList *lp;
+
if(pm_access == READ_WRITE && lckrm(lckfile)) {
- logaction("warning: could not remove lock file %s\n", lckfile);
+ logaction(stderr, "warning: could not remove lock file %s\n", lckfile);
}
if(workfile) {
/* remove the current file being downloaded (as it's not complete) */
@@ -2969,6 +3092,34 @@ void cleanup(int signum)
if(pmo_usesyslog) {
closelog();
}
+ if(logfd) {
+ fclose(logfd);
+ }
+
+ /* free memory */
+ for(lp = pmc_syncs; lp; lp = lp->next) {
+ sync_t *sync = (sync_t *)lp->data;
+ PMList *i;
+ for(i = sync->servers; i; i = i->next) {
+ server_t *server = (server_t *)i->data;
+ FREE(server->protocol);
+ FREE(server->server);
+ FREE(server->path);
+ }
+ FREELIST(sync->servers);
+ FREE(sync->treename);
+ }
+ FREELIST(pmc_syncs);
+ FREELIST(pmo_noupgrade);
+ FREELIST(pmo_ignorepkg);
+ FREE(pmo_root);
+ FREE(pmo_dbpath);
+
+ FREELIST(pm_targets);
+
+ /* this is segfaulting... quick fix for now
+ FREELISTPKGS(pm_packages);*/
+
exit(signum);
}
diff --git a/src/pacman.h b/src/pacman.h
index f5d8ca3d..5828f8cc 100644
--- a/src/pacman.h
+++ b/src/pacman.h
@@ -22,7 +22,7 @@
#define _PAC_PACMAN_H
#ifndef PACVER
-#define PACVER "2.6.4"
+#define PACVER "2.7"
#endif
#ifndef PKGDIR
@@ -64,7 +64,7 @@ void usage(int op, char *myname);
void version(void);
void vprint(char *fmt, ...);
-void logaction(char *fmt, ...);
+void logaction(FILE *fp, char *fmt, ...);
char* buildstring(PMList *strlist);
int lckmk(char *file, int retries, unsigned int sleep_secs);
int lckrm(char *lckfile);