summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfig.guess36
-rwxr-xr-xconfig.sub48
-rw-r--r--configure.ac55
-rw-r--r--contrib/.gitignore0
-rw-r--r--contrib/Makefile.am2
-rw-r--r--contrib/PKGBUILD.vim2
-rw-r--r--contrib/README4
-rw-r--r--contrib/bash_completion13
-rwxr-xr-x[-rw-r--r--]contrib/gensync (renamed from scripts/gensync.sh.in)77
-rwxr-xr-x[-rw-r--r--]contrib/updatesync (renamed from scripts/updatesync.sh.in)75
-rw-r--r--contrib/zsh_completion13
-rw-r--r--doc/Doxyfile18
-rw-r--r--doc/PKGBUILD.5.txt3
-rw-r--r--doc/makepkg.conf.5.txt10
-rw-r--r--doc/pacman.8.txt29
-rw-r--r--doc/pacman.conf.5.txt11
-rw-r--r--doc/repo-add.8.txt12
-rw-r--r--etc/makepkg.conf.in15
-rw-r--r--lib/libalpm/Makefile.am5
-rw-r--r--lib/libalpm/add.c99
-rw-r--r--lib/libalpm/alpm.c1
-rw-r--r--lib/libalpm/alpm.h52
-rw-r--r--lib/libalpm/alpm_list.c136
-rw-r--r--lib/libalpm/alpm_list.h3
-rw-r--r--lib/libalpm/be_files.c227
-rw-r--r--lib/libalpm/cache.c66
-rw-r--r--lib/libalpm/conflict.c63
-rw-r--r--lib/libalpm/conflict.h17
-rw-r--r--lib/libalpm/db.c78
-rw-r--r--lib/libalpm/db.h2
-rw-r--r--lib/libalpm/delta.c24
-rw-r--r--lib/libalpm/delta.h18
-rw-r--r--lib/libalpm/deps.c181
-rw-r--r--lib/libalpm/deps.h31
-rw-r--r--lib/libalpm/dload.c446
-rw-r--r--lib/libalpm/dload.h (renamed from lib/libalpm/error.h)26
-rw-r--r--lib/libalpm/error.c46
-rw-r--r--lib/libalpm/graph.h55
-rw-r--r--lib/libalpm/group.c10
-rw-r--r--lib/libalpm/group.h11
-rw-r--r--lib/libalpm/handle.c2
-rw-r--r--lib/libalpm/log.c1
-rw-r--r--lib/libalpm/package.c201
-rw-r--r--lib/libalpm/package.h30
-rw-r--r--lib/libalpm/po/POTFILES.in2
-rw-r--r--lib/libalpm/remove.c87
-rw-r--r--lib/libalpm/server.c469
-rw-r--r--lib/libalpm/server.h46
-rw-r--r--lib/libalpm/sync.c704
-rw-r--r--lib/libalpm/sync.h6
-rw-r--r--lib/libalpm/trans.c25
-rw-r--r--lib/libalpm/trans.h1
-rw-r--r--lib/libalpm/util.c70
-rw-r--r--lib/libalpm/util.h10
-rw-r--r--ltmain.sh58
-rw-r--r--pactest/Makefile.am3
-rwxr-xr-xpactest/pmtest.py7
-rw-r--r--pactest/tests/TESTS63
-rw-r--r--pactest/tests/add001.py13
-rw-r--r--pactest/tests/add002.py18
-rw-r--r--pactest/tests/add004.py18
-rw-r--r--pactest/tests/add010.py15
-rw-r--r--pactest/tests/add050.py17
-rw-r--r--pactest/tests/depconflict110.py2
-rw-r--r--pactest/tests/depconflict111.py2
-rw-r--r--pactest/tests/deptest001.py24
-rw-r--r--pactest/tests/fileconflict001.py2
-rw-r--r--pactest/tests/fileconflict002.py2
-rw-r--r--pactest/tests/ldconfig001.py2
-rw-r--r--pactest/tests/query003.py1
-rw-r--r--pactest/tests/reason001.py16
-rw-r--r--pactest/tests/remove001.py5
-rw-r--r--pactest/tests/remove030.py2
-rw-r--r--pactest/tests/remove049.py19
-rw-r--r--pactest/tests/remove050.py20
-rw-r--r--pactest/tests/remove051.py20
-rw-r--r--pactest/tests/smoke001.py2
-rw-r--r--pactest/tests/sync021.py2
-rw-r--r--pactest/tests/sync031.py19
-rw-r--r--pactest/tests/sync1001.py18
-rw-r--r--pactest/tests/sync1002.py19
-rw-r--r--pactest/tests/sync1006.py14
-rw-r--r--pactest/tests/sync1008.py (renamed from pactest/tests/sync1005.py)11
-rw-r--r--pactest/tests/sync1101.py1
-rw-r--r--pactest/tests/sync120.py2
-rw-r--r--pactest/tests/sync133.py2
-rw-r--r--pactest/tests/sync138.py2
-rw-r--r--pactest/tests/sync893.py4
-rw-r--r--pactest/tests/sync897.py6
-rw-r--r--pactest/tests/upgrade005.py (renamed from pactest/tests/add003.py)2
-rw-r--r--pactest/tests/upgrade010.py2
-rw-r--r--pactest/tests/upgrade012.py (renamed from pactest/tests/add011.py)2
-rw-r--r--pactest/tests/upgrade013.py (renamed from pactest/tests/add012.py)2
-rw-r--r--pactest/tests/upgrade014.py (renamed from pactest/tests/add013.py)2
-rw-r--r--pactest/tests/upgrade015.py (renamed from pactest/tests/add020.py)2
-rw-r--r--pactest/tests/upgrade016.py (renamed from pactest/tests/add021.py)2
-rw-r--r--pactest/tests/upgrade032.py19
-rw-r--r--pactest/tests/upgrade070.py (renamed from pactest/tests/add060.py)4
-rw-r--r--pactest/tests/upgrade071.py (renamed from pactest/tests/add040.py)2
-rw-r--r--pactest/tests/upgrade072.py (renamed from pactest/tests/add041.py)2
-rw-r--r--pactest/tests/upgrade073.py (renamed from pactest/tests/add042.py)2
-rw-r--r--pactest/tests/upgrade074.py (renamed from pactest/tests/add046.py)2
-rw-r--r--pactest/tests/upgrade075.py (renamed from pactest/tests/add047.py)2
-rw-r--r--pactest/tests/xfercommand001.py2
-rwxr-xr-xpactest/util.py2
-rw-r--r--po/POTFILES.in4
-rw-r--r--scripts/.gitignore2
-rw-r--r--scripts/Makefile.am10
-rw-r--r--scripts/makepkg.sh.in85
-rw-r--r--scripts/repo-add.sh.in12
-rw-r--r--src/pacman/Makefile.am2
-rw-r--r--src/pacman/callback.c124
-rw-r--r--src/pacman/callback.h3
-rw-r--r--src/pacman/conf.h16
-rw-r--r--src/pacman/deptest.c46
-rw-r--r--src/pacman/pacman.c101
-rw-r--r--src/pacman/pacman.h9
-rw-r--r--src/pacman/query.c47
-rw-r--r--src/pacman/remove.c6
-rw-r--r--src/pacman/sync.c218
-rw-r--r--src/pacman/upgrade.c (renamed from src/pacman/add.c)34
-rw-r--r--src/pacman/util.c63
-rw-r--r--src/pacman/util.h2
-rw-r--r--src/util/testdb.c8
-rw-r--r--src/util/testpkg.c2
125 files changed, 2385 insertions, 2565 deletions
diff --git a/config.guess b/config.guess
index 951383e3..f2a0acfb 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-05-17'
+timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -56,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -330,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
- i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*)
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
@@ -532,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -793,12 +793,15 @@ EOF
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
- x86)
+ x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
@@ -833,7 +836,14 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -954,8 +964,8 @@ EOF
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-gnu
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
@@ -1474,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.sub b/config.sub
index c060f448..6759825a 100755
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-04-29'
+timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -369,10 +369,14 @@ case $basic_machine in
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
@@ -443,6 +447,14 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
@@ -475,8 +487,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16c)
- basic_machine=cr16c-unknown
+ cr16)
+ basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -668,6 +680,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -813,6 +833,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -1021,6 +1049,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
diff --git a/configure.ac b/configure.ac
index eabb4a4e..aeec3f15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,16 +51,15 @@ m4_define([lib_revision], [1])
m4_define([lib_age], [3])
m4_define([pacman_version_major], [3])
-m4_define([pacman_version_minor], [1])
-m4_define([pacman_version_micro], [4])
-m4_define([pacman_version_suffix], [])
+m4_define([pacman_version_minor], [2])
+m4_define([pacman_version_micro], [0])
+m4_define([pacman_version_suffix], [devel])
m4_define([pacman_version],
[pacman_version_major.pacman_version_minor.pacman_version_micro])
m4_define([pacman_display_version],
pacman_version[]m4_ifdef([pacman_version_suffix],[pacman_version_suffix]))
# Autoconf initialization
-# AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_INIT([Pacman Package Manager], [pacman_display_version],
[pacman-dev@archlinux.org], [pacman])
AC_CONFIG_SRCDIR([config.h.in])
@@ -80,47 +79,52 @@ AC_DEFINE_UNQUOTED([LIB_VERSION], ["$LIB_VERSION"], [libalpm version number])
# Help line for root directory
AC_ARG_WITH(root-dir,
- AC_HELP_STRING([--with-root-dir=path], [set the location of pacman's root operating directory]),
+ AS_HELP_STRING([--with-root-dir=path], [set the location of pacman's root operating directory]),
[ROOTDIR=$withval], [ROOTDIR=/])
# Help line for package extension
AC_ARG_WITH(pkg-ext,
- AC_HELP_STRING([--with-pkg-ext=ext], [set the file extension used by packages]),
+ AS_HELP_STRING([--with-pkg-ext=ext], [set the file extension used by packages]),
[PKGEXT=$withval], [PKGEXT=.pkg.tar.gz])
# Help line for source package directory
AC_ARG_WITH(src-ext,
- AC_HELP_STRING([--with-src-ext=ext], [set the file extension used by source packages]),
+ AS_HELP_STRING([--with-src-ext=ext], [set the file extension used by source packages]),
[SRCEXT=$withval], [SRCEXT=.src.tar.gz])
# Help line for database extension
AC_ARG_WITH(db-ext,
- AC_HELP_STRING([--with-db-ext=ext], [set the file extension used by the database]),
+ AS_HELP_STRING([--with-db-ext=ext], [set the file extension used by the database]),
[DBEXT=$withval], [DBEXT=.db.tar.gz])
+# Help line for libdownload/libfetch
+AC_ARG_ENABLE(internal-download,
+ AS_HELP_STRING([--disable-internal-download], [do not build with libdownload/libfetch support]),
+ [internaldownload=$enableval], [internaldownload=yes])
+
# Help line for documentation
AC_ARG_ENABLE(doc,
- AC_HELP_STRING([--disable-doc], [prevent make from looking at doc/ dir]),
+ AS_HELP_STRING([--disable-doc], [prevent make from looking at doc/ dir]),
[wantdoc=$enableval], [wantdoc=yes])
# Help line for doxygen
AC_ARG_ENABLE(doxygen,
- AC_HELP_STRING([--enable-doxygen], [build your own API docs via Doxygen]),
+ AS_HELP_STRING([--enable-doxygen], [build your own API docs via Doxygen]),
[wantdoxygen=$enableval], [wantdoxygen=no])
# Help line for asciidoc
AC_ARG_ENABLE(asciidoc,
- AC_HELP_STRING([--enable-asciidoc], [build your own manpages with Asciidoc]),
+ AS_HELP_STRING([--enable-asciidoc], [build your own manpages with Asciidoc]),
[wantasciidoc=$enableval], [wantasciidoc=no])
# Help line for debug
AC_ARG_ENABLE(debug,
- AC_HELP_STRING([--enable-debug], [enable debugging support]),
+ AS_HELP_STRING([--enable-debug], [enable debugging support]),
[debug=$enableval], [debug=no])
# Help line for pacman.static
AC_ARG_ENABLE(pacman-static,
- AC_HELP_STRING([--disable-pacman-static], [do not build static version of pacman]),
+ AS_HELP_STRING([--disable-pacman-static], [do not build static version of pacman]),
[pacmanstatic=$enableval], [pacmanstatic=yes])
# Checks for programs.
@@ -129,7 +133,6 @@ AC_PROG_CC_C99
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
-AC_PROG_RANLIB
AC_PROG_LIBTOOL
AC_CHECK_PROGS([PYTHON], [python2.5 python2.4 python], [false])
@@ -138,10 +141,21 @@ AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION(0.13.1)
# Check for libarchive
-AC_CHECK_LIB([archive], [archive_read_data], , AC_MSG_ERROR([libarchive is needed to compile pacman!]))
+AC_CHECK_LIB([archive], [archive_read_data], ,
+ AC_MSG_ERROR([libarchive is needed to compile pacman!]))
-# Check for libdownload
-AC_CHECK_LIB([download], [downloadParseURL], , AC_MSG_ERROR([libdownload is needed to compile pacman!]))
+# Enable or disable usage of libdownload/libfetch
+AC_MSG_CHECKING(whether to link with download library)
+if test "x$internaldownload" = "xyes" ; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE([INTERNAL_DOWNLOAD], , [Use internal download library])
+ # Check for libdownload if it was actually requested
+ AC_CHECK_LIB([download], [downloadParseURL], ,
+ AC_MSG_ERROR([libdownload is needed to compile pacman!]))
+else
+ AC_MSG_RESULT(no)
+fi
+AM_CONDITIONAL(INTERNAL_DOWNLOAD, test "x$internaldownload" = "xyes")
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h libintl.h limits.h locale.h string.h strings.h sys/ioctl.h sys/statvfs.h sys/time.h syslog.h wchar.h])
@@ -156,13 +170,13 @@ AC_STRUCT_TM
AC_TYPE_UID_T
# Checks for library functions.
-AC_FUNC_CLOSEDIR_VOID
AC_FUNC_FORK
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_MKTIME
AC_TYPE_SIGNAL
-AC_CHECK_FUNCS([geteuid realpath regcomp strcasecmp strdup strerror \
- strndup strrchr strsep strstr strverscmp swprintf uname])
+AC_CHECK_FUNCS([geteuid realpath regcomp strcasecmp \
+ strndup strrchr strsep strverscmp swprintf \
+ wcwidth uname])
# Enable large file support if available
AC_SYS_LARGEFILE
@@ -360,6 +374,7 @@ pacman_display_version:
Compilation options:
Run make in doc/ dir : ${wantdoc}
+ Use download library : ${internaldownload}
Doxygen support : ${usedoxygen}
Asciidoc support : ${useasciidoc}
debug support : ${debug}
diff --git a/contrib/.gitignore b/contrib/.gitignore
deleted file mode 100644
index e69de29b..00000000
--- a/contrib/.gitignore
+++ /dev/null
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 7066f409..7eee91a1 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,9 +1,11 @@
EXTRA_DIST = \
PKGBUILD.vim \
bash_completion \
+ gensync \
pacdiff \
pacsearch \
re-pacman \
+ updatesync \
vimprojects \
wget-xdelta.sh \
zsh_completion \
diff --git a/contrib/PKGBUILD.vim b/contrib/PKGBUILD.vim
index 57e4cf0e..8f45ae44 100644
--- a/contrib/PKGBUILD.vim
+++ b/contrib/PKGBUILD.vim
@@ -151,7 +151,7 @@ hi def link pbValidSha1sums Number
" options
syn keyword pb_k_options options contained
-syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|ccache\|distcc\|makeflags\|force\)/ contained
+syn match pbOptions /\(no\)\?\(strip\|docs\|libtool\|emptydirs\|zipman\|ccache\|distcc\|makeflags\|force\)/ contained
syn match pbOptionsNeg /\!/ contained
syn match pbOptionsDeprec /no/ contained
syn region pbOptionsGroup start=/^options=(/ end=/)/ contains=pb_k_options,pbOptions,pbOptionsNeg,pbOptionsDeprec,pbIllegalOption,shDoubleQuote,shSingleQuote
diff --git a/contrib/README b/contrib/README
index 7eb36aae..1a1b6a9c 100644
--- a/contrib/README
+++ b/contrib/README
@@ -24,3 +24,7 @@ vimprojects - a project file for the vim project plugin.
wget-xdelta.sh - A download script for pacman which allows binary deltas
generated with makepkg to be used instead of downloading full binary packages.
This should cut download sizes for some package upgrades significantly.
+
+gensync, updatesync - The former repository management scripts that have since
+been superseded by repo-add and repo-remove. They are here for posterity's
+sake, and to show how repo-add and repo-remove can be wrapped in other scripts.
diff --git a/contrib/bash_completion b/contrib/bash_completion
index 77192858..11f021c8 100644
--- a/contrib/bash_completion
+++ b/contrib/bash_completion
@@ -146,14 +146,13 @@ _pacman ()
toparse="${a:2}"
case "${arg}" in
- -@(A|U|R|S|Q|h|V))
+ -@(U|R|S|Q|h|V))
op="${arg/-}"
mod="${mod}${a:2}"
;;
--)
arg="${a:2}"
case "${arg}" in
- add) op="A" ;;
remove) op="R" ;;
upgrade) op="U" ;;
query) op="Q" ;;
@@ -187,6 +186,7 @@ _pacman ()
dbonly) mod="${mod}k" ;;
nosave) mod="${mod}n" ;;
recursive) mod="${mod}s" ;;
+ unneeded) mod="${mod}u" ;;
esac ;;
*) toparse="${a}" ;;
esac
@@ -202,7 +202,6 @@ _pacman ()
if [ $COMP_CWORD -eq 1 ] && [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '\
- -A --add \
-h --help \
-Q --query \
-R --remove \
@@ -216,9 +215,10 @@ _pacman ()
if [[ "$cur" == -* ]]; then
case "${op}" in
- A|U)
+ U)
COMPREPLY=( $( compgen -W '\
--asdeps \
+ --asexplicit \
-d --nodeps \
-f --force \
-h --help \
@@ -242,6 +242,7 @@ _pacman ()
-k --dbonly \
-n --nosave \
-s --recursive \
+ -u --unneeded \
--config \
--logfile \
--noconfirm \
@@ -257,9 +258,9 @@ _pacman ()
S)
COMPREPLY=( $( compgen -W '\
--asdeps \
+ --asexplicit \
-c --clean \
-d --nodeps \
- -e --dependsonly \
-f --force \
-g --groups \
-h --help \
@@ -316,7 +317,7 @@ _pacman ()
rem_selected
else
case "${op}" in
- A|U)
+ U)
COMPREPLY=( $( compgen -d -- "$cur" ) \
$( compgen -f -X '!*.pkg.tar.gz' -- "$cur" ) )
return 0
diff --git a/scripts/gensync.sh.in b/contrib/gensync
index d5dec275..51d32ceb 100644..100755
--- a/scripts/gensync.sh.in
+++ b/contrib/gensync
@@ -1,7 +1,6 @@
#!/bin/bash
#
# gensync
-# @configure_input@
#
# Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
#
@@ -19,42 +18,35 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# gettext initialization
-export TEXTDOMAIN='pacman'
-export TEXTDOMAINDIR='@localedir@'
-
-myver='@PACKAGE_VERSION@'
+myver='3.1.1'
# functions
usage() {
printf "gensync (pacman) %s\n\n" "$myver"
- printf "$(gettext "Usage: %s <root> <destfile> [package_directory]")\n\n" "$0"
- printf "$(gettext "\
-NOTE: this script is DEPRECATED. It will be removed in the next major\n\
-release of pacman, so please use repo-add and repo-remove instead.\n\n")"
- printf "$(gettext "\
+ printf "Usage: %s <root> <destfile> [package_directory]\n\n" "$0"
+ printf "\
gensync will generate a sync database by reading all PKGBUILD files\n\
from <root>. gensync builds the database in a temporary directory\n\
-and then compresses it to <destfile>.\n\n")"
- printf "$(gettext "\
+and then compresses it to <destfile>.\n\n"
+ printf "\
gensync will calculate md5sums of packages in the same directory as\n\
-<destfile>, unless an alternate [package_directory] is specified.\n\n")"
- printf "$(gettext "\
+<destfile>, unless an alternate [package_directory] is specified.\n\n"
+ printf "\
note: The <destfile> name is important. It must be of the form\n\
{treename}.db.tar.gz where {treename} is the name of the custom\n\
package repository you configured in /etc/pacman.conf. The\n\
generated database must reside in the same directory as your\n\
- custom packages (also configured in /etc/pacman.conf)\n\n")"
- echo "$(gettext "Example: gensync /var/abs/local /home/mypkgs/custom.db.tar.gz")"
+ custom packages (also configured in /etc/pacman.conf)\n\n"
+ echo "Example: gensync /var/abs/local /home/mypkgs/custom.db.tar.gz"
}
version() {
printf "gensync (pacman) %s\n" "$myver"
- printf "$(gettext "\
+ printf "\
Copyright (C) 2002-2007 Judd Vinet <jvinet@zeroflux.org>.\n\n\
This is free software; see the source for copying conditions.\n\
-There is NO WARRANTY, to the extent permitted by law.\n")"
+There is NO WARRANTY, to the extent permitted by law.\n"
}
error () {
@@ -67,26 +59,8 @@ die () {
exit 1
}
-check_force () {
- local i
- for i in ${options[@]}; do
- local lc=$(echo $i | tr [:upper:] [:lower:])
- if [ "$lc" = "force" ]; then
- true
- fi
- done
- false
-}
-
# PROGRAM START
-# determine whether we have gettext; make it a no-op if we do not
-if [ ! $(type -t gettext) ]; then
- gettext() {
- echo "$@"
- }
-fi
-
if [ "$1" = "-h" -o "$1" = "--help" ]; then
usage
exit 0
@@ -103,10 +77,10 @@ if [ $# -lt 2 ]; then
fi
# source system and user makepkg.conf
-if [ -r @sysconfdir@/makepkg.conf ]; then
- source @sysconfdir@/makepkg.conf
+if [ -r /etc/makepkg.conf ]; then
+ source /etc/makepkg.conf
else
- die "$(gettext "%s not found. Can not continue.")" "@sysconfdir@/makepkg.conf"
+ die "/etc/makepkg.conf not found. Cannot continue."
fi
if [ -r ~/.makepkg.conf ]; then
@@ -124,22 +98,17 @@ if [ "$3" != "" ]; then
pkgdir="$3"
fi
-[ ! -d "$rootdir" ] && die "$(gettext "invalid root dir: %s")" $rootdir
-
-printf "$(gettext "\
-NOTE: this script is DEPRECATED. It will be removed in the next major\n\
-release of pacman, so please use repo-add and repo-remove instead.\n\n")"
+[ ! -d "$rootdir" ] && die "invalid root dir: $rootdir"
-echo "$(gettext "gensync: building database entries, generating md5sums...")" >&2
+echo "gensync: building database entries, generating md5sums..." >&2
cd "$destdir"
pkgs=""
-forcepkgs=""
for file in $(find "$rootdir"/* -name "$BUILDSCRIPT"); do
unset pkgname pkgver pkgrel options
- source $file || die "$(gettext "failed to parse %s")" $file
+ source $file || die "failed to parse $file"
if [ "$arch" = 'any' ]; then
CARCH='any'
fi
@@ -150,20 +119,16 @@ for file in $(find "$rootdir"/* -name "$BUILDSCRIPT"); do
fi
if [ ! -f "$pkgfile" ]; then
- error "$(gettext "could not find %s-%s-%s-%s%s - skipping")" $pkgname $pkgver $pkgrel $CARCH $PKGEXT
+ error "could not find %s-%s-%s-%s%s - skipping" $pkgname $pkgver $pkgrel $CARCH $PKGEXT
else
- if check_force; then
- forcepkgs="$forcepkgs $pkgfile"
- else
- pkgs="$pkgs $pkgfile"
- fi
+ pkgs="$pkgs $pkgfile"
fi
done
-echo "$(gettext "creating repo DB...")"
+echo "creating repo DB..."
# we'll trim the output just a tad, as gensync may be used on large repos
-repo-add $destfile $pkgs --force $force_pkgs \
+repo-add $destfile $pkgs \
| grep -e "package" -e "database"
# vim: set ts=2 sw=2 noet:
diff --git a/scripts/updatesync.sh.in b/contrib/updatesync
index 5f5cc6c9..f88e8237 100644..100755
--- a/scripts/updatesync.sh.in
+++ b/contrib/updatesync
@@ -1,7 +1,6 @@
#!/bin/bash
#
# updatesync
-# @configure_input@
#
# Copyright (c) 2004 by Jason Chu <jason@archlinux.org>
# Derived from gensync (c) 2002-2006 Judd Vinet <jvinet@zeroflux.org>
@@ -20,40 +19,33 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# gettext initialization
-export TEXTDOMAIN='pacman'
-export TEXTDOMAINDIR='@localedir@'
-
-myver='@PACKAGE_VERSION@'
+myver='3.1.1'
# functions
usage() {
printf "updatesync (pacman) %s\n\n" "$myver"
- printf "$(gettext "Usage: %s <action> <destfile> <option> [package_directory]")\n\n" "$0"
- printf "$(gettext "\
-NOTE: this script is DEPRECATED. It will be removed in the next major\n\
-release of pacman, so please use repo-add and repo-remove instead.\n\n")"
- printf "$(gettext "\
+ printf "Usage: %s <action> <destfile> <option> [package_directory]\n\n" "$0"
+ printf "\
updatesync will update a sync database by reading a PKGBUILD and\n\
modifying the destfile. updatesync updates the database in a temporary\n\
-directory and then compresses it to <destfile>.\n\n")"
- printf "$(gettext "There are two types of actions:\n\n")"
- printf "$(gettext "upd - Will update a package's entry or create it if it doesn't exist.\n It takes the package's PKGBUILD as an option.\n")"
- printf "$(gettext "del - Will remove a package's entry from the db. It takes the package's\n name as an option.\n")"
+directory and then compresses it to <destfile>.\n\n"
+ printf "There are two types of actions:\n\n"
+ printf "upd - Will update a package's entry or create it if it doesn't exist.\n It takes the package's PKGBUILD as an option.\n"
+ printf "del - Will remove a package's entry from the db. It takes the package's\n name as an option.\n"
echo
- printf "$(gettext "\
+ printf "\
updatesync will calculate md5sums of packages in the same directory as\n\
-<destfile>, unless an alternate [package_directory] is specified.\n\n")"
- echo "$(gettext "Example: updatesync upd /home/mypkgs/custom.db.tar.gz PKGBUILD")"
+<destfile>, unless an alternate [package_directory] is specified.\n\n"
+ echo "Example: updatesync upd /home/mypkgs/custom.db.tar.gz PKGBUILD"
}
version() {
printf "updatesync (pacman) %s\n" "$myver"
- printf "$(gettext "\
+ printf "\
Copyright (C) 2004 Jason Chu <jason@archlinux.org>.\n\n\
This is free software; see the source for copying conditions.\n\
-There is NO WARRANTY, to the extent permitted by law.\n")"
+There is NO WARRANTY, to the extent permitted by law.\n"
}
error () {
@@ -66,26 +58,8 @@ die () {
exit 1
}
-check_force () {
- local i
- for i in ${options[@]}; do
- local lc=$(echo $i | tr [:upper:] [:lower:])
- if [ "$lc" = "force" ]; then
- true
- fi
- done
- false
-}
-
# PROGRAM START
-# determine whether we have gettext; make it a no-op if we do not
-if [ ! $(type -t gettext) ]; then
- gettext() {
- echo "$@"
- }
-fi
-
if [ "$1" = "-h" -o "$1" = "--help" ]; then
usage
exit 0
@@ -102,10 +76,10 @@ if [ $# -lt 3 ]; then
fi
# source system and user makepkg.conf
-if [ -r @sysconfdir@/makepkg.conf ]; then
- source @sysconfdir@/makepkg.conf
+if [ -r /etc/makepkg.conf ]; then
+ source /etc/makepkg.conf
else
- die "$(gettext "%s not found. Can not continue.")" "@sysconfdir@/makepkg.conf"
+ die "/etc/makepkg.conf not found. Cannot continue."
fi
if [ -r ~/.makepkg.conf ]; then
@@ -124,39 +98,30 @@ pkgdir="$(pwd)"
if [ "$4" != "" ]; then
pkgdir="$4"
fi
-opt_force=""
-
-printf "$(gettext "\
-NOTE: this script is DEPRECATED. It will be removed in the next major\n\
-release of pacman, so please use repo-add and repo-remove instead.\n\n")"
if [ "$action" = "upd" ]; then # INSERT / UPDATE
if [ ! -f "$option" ]; then
- die "$(gettext "%s not found")" $option
+ die "$option not found"
fi
unset pkgname pkgver pkgrel options
- source $option || die "$(gettext "failed to parse %s")" $option
+ source $option || die "failed to parse $option"
if [ "$arch" = 'any' ]; then
CARCH='any'
fi
pkgfile="$pkgdir/$pkgname-$pkgver-$pkgrel-${CARCH}${PKGEXT}"
if [ ! -f "$pkgfile" ]; then
- die "$(gettext "could not find %s-%s-%s-%s%s - aborting")" $pkgname $pkgver $pkgrel $CARCH $PKGEXT
- fi
-
- if check_force; then
- opt_force="--force"
+ die "could not find %s-%s-%s-%s%s - aborting" $pkgname $pkgver $pkgrel $CARCH $PKGEXT
fi
- repo-add "$pkgdb" $opt_force "$pkgfile"
+ repo-add "$pkgdb" "$pkgfile"
else # DELETE
fname="$(basename $option)"
if [ "$fname" = "PKGBUILD" ]; then
if [ ! -f "$option" ]; then
- die "$(gettext "%s not found")" $option
+ die "%s not found" $option
fi
unset pkgname pkgver pkgrel options
diff --git a/contrib/zsh_completion b/contrib/zsh_completion
index 8dec06df..e1273184 100644
--- a/contrib/zsh_completion
+++ b/contrib/zsh_completion
@@ -6,7 +6,6 @@ typeset -A opt_args
# options for passing to _arguments: main pacman commands
_pacman_opts_commands=(
- '-A[Add a package to the system]'
'-Q[Query the package database]'
'-R[Remove a package from the system]'
'-S[Synchronize packages]'
@@ -29,7 +28,7 @@ _pacman_opts_common=(
'--noscriptlet[Do not execute the install scriptlet if one exists]'
)
-# options for passing to _arguments: options for --add and --update commands
+# options for passing to _arguments: options for --upgrade commands
_pacman_opts_pkgfile=(
'-d[Skip dependency checks]'
'-f[Overwrite conflicting files]'
@@ -78,7 +77,6 @@ _pacman_opts_sync_actions=(
# options for passing to _arguments: options for --sync command
_pacman_opts_sync_modifiers=(
'-d[Skip dependency checks]'
- '-e[Install dependencies only]'
'-f[Overwrite conflicting files]'
'-i[View package information]'
'-l[List all packages in a repository]'
@@ -91,15 +89,9 @@ _pacman_opts_sync_modifiers=(
'*--ignoregroup[Ignore a group upgrade]:package group:
_pacman_completions_all_groups'
'--asdeps[Install packages as non-explicitly installed]'
+ '--asexplicit[Install packages as explicitly installed]'
)
-# handles --action subcommand
-_pacman_action_add() {
- _arguments -s : \
- "$_pacman_opts_common[@]" \
- "$_pacman_opts_pkgfile[@]"
-}
-
# handles --help subcommand
_pacman_action_help() {
_arguments -s : \
@@ -290,7 +282,6 @@ _pacman_get_command() {
# main dispatcher
_pacman() {
case $words[2] in
- -A*) _pacman_action_add ;;
-Q*g*) # ipkg groups
_arguments -s : \
"$_pacman_opts_common[@]" \
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 5174c651..3aea8944 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -1,4 +1,4 @@
-# Doxyfile 1.5.2
+# Doxyfile 1.5.5
#---------------------------------------------------------------------------
# Project related configuration options
@@ -29,6 +29,7 @@ STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
+QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
@@ -37,10 +38,14 @@ TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
+TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -49,6 +54,7 @@ EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
@@ -60,6 +66,7 @@ SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
+SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
@@ -126,6 +133,10 @@ HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
@@ -194,7 +205,9 @@ EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH = ../..
INCLUDE_FILE_PATTERNS = *.h
-PREDEFINED = HAVE_CONFIG_H= SYMHIDDEN= SYMEXPORT=
+PREDEFINED = HAVE_CONFIG_H= \
+ SYMHIDDEN= \
+ SYMEXPORT=
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
@@ -227,6 +240,7 @@ DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 3
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
diff --git a/doc/PKGBUILD.5.txt b/doc/PKGBUILD.5.txt
index ac394729..aa870097 100644
--- a/doc/PKGBUILD.5.txt
+++ b/doc/PKGBUILD.5.txt
@@ -182,6 +182,9 @@ Options and Directives
*emptydirs*;;
Leave empty directories in packages.
+ *zipman*;;
+ Compress man pages with gzip.
+
*ccache*;;
Allow the use of ccache during build. More useful in its negative
form `!ccache` with select packages that have problems building
diff --git a/doc/makepkg.conf.5.txt b/doc/makepkg.conf.5.txt
index f6e4b382..113ad140 100644
--- a/doc/makepkg.conf.5.txt
+++ b/doc/makepkg.conf.5.txt
@@ -37,6 +37,9 @@ Options
well; the download URL is placed on the end of the command. This is more
flexible than the former `FTPAGENT` variable, as any protocol can have a
download agent. Several examples are provided in the default makepkg.conf.
+ All instances of `%u` will be replaced with the download URL. If present,
+ instances of `%o` will be replaced with the local filename, plus a ``.part''
+ extension, which allows to do file resumes properly.
**CARCH=**"carch"::
Specifies your computer architecture; possible values include such things
@@ -94,8 +97,8 @@ Options
running in the DistCC cluster. In addition, you will want to modify your
`MAKEFLAGS`.
-**OPTIONS=(**strip !docs libtool emptydirs**)**::
- This array contains options that affect the default packaging. All four are
+**OPTIONS=(**strip !docs libtool emptydirs zipman**)**::
+ This array contains options that affect the default packaging. They are
equivalent to options that can be placed in the PKGBUILD; the defaults are
shown here. All options should always be left in the array; to enable or
disable an option simply remove or place an ``!'' at the front of the
@@ -117,6 +120,9 @@ Options
*emptydirs*;;
Leave empty directories in packages.
+ *zipman*;;
+ Compress man pages with gzip.
+
**INTEGRITY_CHECK=(**check1 ...**)**::
File integrity checks to use. Multiple checks may be specified; this
affects both generation and checking. The current valid options are:
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index f6eb69c3..a6bc3d9a 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -28,13 +28,6 @@ ends to be written (for instance, a GUI front end).
Operations
----------
-*-A, \--add* (deprecated)::
- Add a package to the system. Either a URL or file path can be specified.
- The package will be uncompressed into the installation root and the
- database will be updated. The package will not be installed if another
- version is already installed. *NOTE*: please use '\--upgrade' in place of
- this option.
-
*-Q, \--query*::
Query the package database. This operation allows you to view installed
packages and their files, as well as meta-information about individual
@@ -86,11 +79,17 @@ You can also use `pacman -Su` to upgrade all packages that are out of date. See
Options
-------
*\--asdeps*::
- Install packages non-explicitly; in other works, fake their install reason
+ Install packages non-explicitly; in other words, fake their install reason
to be installed as a dependency. This is useful for makepkg and other
build from source tools that need to install dependencies before building
the package.
+*\--asexplicit*::
+ Install packages explicitly; in other words, fake their install reason to
+ be explicitly installed. This is useful if you want to mark a dependency
+ as explicitly installed so it will not be removed by the '\--recursive'
+ remove operation.
+
*-b, \--dbpath* <'path'>::
Specify an alternative database location (a typical default is
``/var/lib/pacman''). This should not be used unless you know what you are
@@ -226,7 +225,12 @@ Remove Options[[RO]]
that (A) they are not required by other packages; and (B) they were not
explicitly installed by the user. This operation is recursive and analogous
to a backwards '\--sync' operation, and helps keep a clean system without
- orphans.
+ orphans. If you want to omit condition (B), pass this option twice.
+
+*-u, \--unneeded*::
+ Removes the targets that are not required by any other packages.
+ This is mostly useful when removing a group without using the '-c' option,
+ to avoid breaking any dependencies.
Sync Options[[SO]]
@@ -241,10 +245,9 @@ Sync Options[[SO]]
packages that are no longer installed; use two to remove all packages
from the cache. In both cases, you will have a yes or no option to
remove packages and/or unused downloaded databases.
-
-*-e, \--dependsonly*::
- Install all dependencies of a package, but not the specified package
- itself. This is pretty useless and we're not sure why it even exists.
++
+If you use a network shared cache, see the 'CleanMethod' option in
+linkman:pacman.conf[5].
*-g, \--groups*::
Display all the members for each package group specified. If no group
diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index cb9d2c55..5514e2c0 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -40,6 +40,8 @@ Include = /etc/pacman.d/core
Server = file:///home/pkgs
--------
+*NOTE*: Each directive must be in CamelCase. If the case isn't respected, the directive
+won't be recognized. For example. noupgrade or NOUPGRADE will not work.
Options
-------
@@ -117,6 +119,15 @@ Options
These files refer to files in the package archive, so do not include the
leading slash (the RootDir) when specifying them.
+*CleanMethod =* KeepInstalled | KeepCurrent::
+ If set to `KeepInstalled` (the default), the '-Sc' operation will clean
+ packages that are no longer installed (not present in the local database).
+ If set to `KeepCurrent`, '-Sc' will clean outdated packages (not present in
+ any sync database).
+ The second behavior is useful when the package cache is shared among
+ multiple machines, where the local databases are usually different, but the
+ sync databases in use could be the same.
+
*UseSyslog*::
Log action messages through syslog(). This will insert log entries into
``/var/log/messages'' or equivalent.
diff --git a/doc/repo-add.8.txt b/doc/repo-add.8.txt
index 5664949f..80faef46 100644
--- a/doc/repo-add.8.txt
+++ b/doc/repo-add.8.txt
@@ -16,7 +16,7 @@ repo-add - package database maintenance utility
Synopsis
--------
-repo-add <path-to-db> [--force] <package> ...
+repo-add <path-to-db> <package> ...
repo-remove <path-to-db> <packagename> ...
@@ -34,16 +34,6 @@ specified on the command line. Multiple packages to remove can be specified
on the command line.
-Options
--------
-*--force* (repo-add only)::
- Add a force entry to the sync database, which tells pacman to skip version
- number comparison and update the package regardless. This flag can be
- specified in the middle of the command line, with any packages listed
- before the flag being added as normal entries, and any specified after
- being marked as force upgrades.
-
-
See Also
--------
linkman:makepkg[8], linkman:pacman[8]
diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in
index 4da4a63d..345194d3 100644
--- a/etc/makepkg.conf.in
+++ b/etc/makepkg.conf.in
@@ -8,11 +8,11 @@
#
#-- The download utilities that makepkg should use to acquire sources
# Format: 'protocol::agent'
-DLAGENTS=('ftp::/usr/bin/wget -c --passive-ftp -t 3 --waitretry=3'
- 'http::/usr/bin/wget -c -t 3 --waitretry=3'
- 'https::/usr/bin/wget -c -t 3 --waitretry=3 --no-check-certificate'
- 'rsync::/usr/bin/rsync -z'
- 'scp::/usr/bin/scp -C')
+DLAGENTS=('ftp::/usr/bin/wget -c --passive-ftp -t 3 --waitretry=3 -O %o %u'
+ 'http::/usr/bin/wget -c -t 3 --waitretry=3 -O %o %u'
+ 'https::/usr/bin/wget -c -t 3 --waitretry=3 --no-check-certificate -O %o %u'
+ 'rsync::/usr/bin/rsync -z %u %o'
+ 'scp::/usr/bin/scp -C %u %o')
# Other common tools:
# /usr/bin/snarf
@@ -58,15 +58,16 @@ BUILDENV=(fakeroot !distcc color !ccache !xdelta)
# These are default values for the options=() settings
#########################################################################
#
-# Default: OPTIONS=(strip !docs libtool emptydirs)
+# Default: OPTIONS=(strip !docs libtool emptydirs zipman)
# A negated option will do the opposite of the comments below.
#
#-- strip: Strip symbols from binaries/libraries
#-- docs: Save doc and info directories
#-- libtool: Leave libtool (.la) files in packages
#-- emptydirs: Leave empty directories in packages
+#-- zipman: Compress manpages with gzip
#
-OPTIONS=(strip !docs libtool emptydirs)
+OPTIONS=(strip !docs libtool emptydirs zipman)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5)
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am
index 14d42a0c..7b737363 100644
--- a/lib/libalpm/Makefile.am
+++ b/lib/libalpm/Makefile.am
@@ -31,14 +31,15 @@ libalpm_la_SOURCES = \
db.h db.c \
delta.h delta.c \
deps.h deps.c \
- error.h error.c \
+ dload.h dload.c \
+ error.c \
+ graph.h \
group.h group.c \
handle.h handle.c \
log.h log.c \
md5.h md5.c \
package.h package.c \
remove.h remove.c \
- server.h server.c \
sync.h sync.c \
trans.h trans.c \
util.h util.c
diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index 0a1a1924..ca4cfa9a 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -37,7 +37,6 @@
#include "alpm_list.h"
#include "trans.h"
#include "util.h"
-#include "error.h"
#include "cache.h"
#include "log.h"
#include "backup.h"
@@ -68,41 +67,25 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
pkgname = alpm_pkg_get_name(pkg);
pkgver = alpm_pkg_get_version(pkg);
- if(trans->type != PM_TRANS_TYPE_UPGRADE) {
- /* only install this package if it is not already installed */
- if(_alpm_db_get_pkgfromcache(db, pkgname)) {
- pm_errno = PM_ERR_PKG_INSTALLED;
- goto error;
- }
- }
-
/* check if an older version of said package is already in transaction
* packages. if so, replace it in the list */
for(i = trans->packages; i; i = i->next) {
- pmpkg_t *pkg = i->data;
- if(strcmp(pkg->name, pkgname) == 0) {
- if(_alpm_versioncmp(pkg->version, pkgver) < 0) {
- pmpkg_t *newpkg;
+ pmpkg_t *transpkg = i->data;
+ if(strcmp(transpkg->name, pkgname) == 0) {
+ if(_alpm_versioncmp(transpkg->version, pkgver) < 0) {
_alpm_log(PM_LOG_WARNING, _("replacing older version %s-%s by %s in target list\n"),
- pkg->name, pkg->version, pkgver);
- if((newpkg = _alpm_pkg_load(name, 1)) == NULL) {
- /* pm_errno is already set by pkg_load() */
- goto error;
- }
+ transpkg->name, transpkg->version, pkgver);
_alpm_pkg_free(i->data);
- i->data = newpkg;
+ i->data = pkg;
} else {
- _alpm_log(PM_LOG_WARNING, _("newer version %s-%s is in the target list -- skipping\n"),
- pkg->name, pkg->version);
+ _alpm_log(PM_LOG_WARNING, _("skipping %s-%s because newer version %s is in the target list\n"),
+ pkgname, pkgver, transpkg->version);
+ _alpm_pkg_free(pkg);
}
return(0);
}
}
- if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
- pkg->reason = PM_PKG_REASON_DEPEND;
- }
-
/* add the package to the transaction */
trans->packages = alpm_list_add(trans->packages, pkg);
@@ -138,12 +121,13 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
/* look for unsatisfied dependencies */
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
- lp = alpm_checkdeps(db, trans->type == PM_TRANS_TYPE_UPGRADE, NULL, trans->packages);
+ lp = alpm_checkdeps(db, 1, NULL, trans->packages);
if(lp != NULL) {
if(data) {
*data = lp;
} else {
- FREELIST(lp);
+ alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(lp);
}
RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1);
}
@@ -167,7 +151,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
_alpm_log(PM_LOG_ERROR, _("you cannot install two conflicting packages at the same time\n"));
}
if(outer) {
- _alpm_log(PM_LOG_ERROR, _("replacing packages with -A and -U is not supported yet\n"));
+ _alpm_log(PM_LOG_ERROR, _("replacing packages with -U is not supported yet\n"));
_alpm_log(PM_LOG_ERROR, _("you can replace packages manually using -Rd and -U\n"));
}
RET_ERR(PM_ERR_CONFLICTING_DEPS, -1);
@@ -175,7 +159,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
/* re-order w.r.t. dependencies */
_alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n");
- lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_ADD);
+ lp = _alpm_sortbydeps(trans->packages, 0);
/* free the old alltargs */
alpm_list_free(trans->packages);
trans->packages = lp;
@@ -193,7 +177,8 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
if(data) {
*data = lp;
} else {
- FREELIST(lp);
+ alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_fileconflict_free);
+ alpm_list_free(lp);
}
RET_ERR(PM_ERR_FILE_CONFLICTS, -1);
}
@@ -210,6 +195,9 @@ static int upgrade_remove(pmpkg_t *oldpkg, pmpkg_t *newpkg, pmtrans_t *trans, pm
* with the type PM_TRANS_TYPE_REMOVEUPGRADE. TODO: kill this weird
* behavior. */
pmtrans_t *tr = _alpm_trans_new();
+
+ ALPM_LOG_FUNC;
+
_alpm_log(PM_LOG_DEBUG, "removing old package first (%s-%s)\n",
oldpkg->name, oldpkg->version);
@@ -437,7 +425,7 @@ static int extract_single_file(struct archive *archive,
/* if we force hash_orig to be non-NULL retroactive backup works */
if(needbackup && !hash_orig) {
- hash_orig = strdup("");
+ STRDUP(hash_orig, "", RET_ERR(PM_ERR_MEMORY, -1));
}
}
}
@@ -449,12 +437,16 @@ static int extract_single_file(struct archive *archive,
char *tempfile;
char *hash_local = NULL, *hash_pkg = NULL;
int fd;
+ int ret;
/* extract the package's version to a temporary file and checksum it */
- tempfile = strdup("/tmp/alpm_XXXXXX");
+ STRDUP(tempfile, "/tmp/alpm_XXXXXX", RET_ERR(PM_ERR_MEMORY, -1));
fd = mkstemp(tempfile);
+ if(fd == -1) {
+ RET_ERR(PM_ERR_SYSTEM, -1);
+ }
- int ret = archive_read_data_into_fd(archive, fd);
+ ret = archive_read_data_into_fd(archive, fd);
close(fd);
if(ret == ARCHIVE_WARN) {
/* operation succeeded but a non-critical error was encountered */
@@ -485,11 +477,8 @@ static int extract_single_file(struct archive *archive,
}
char *backup = NULL;
/* length is tab char, null byte and MD5 (32 char) */
- int backup_len = strlen(oldbackup) + 34;
- backup = malloc(backup_len);
- if(!backup) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
+ size_t backup_len = strlen(oldbackup) + 34;
+ MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(backup, "%s\t%s", oldbackup, hash_pkg);
backup[backup_len-1] = '\0';
@@ -617,7 +606,7 @@ static int extract_single_file(struct archive *archive,
char *backup = NULL, *hash = NULL;
char *oldbackup = alpm_list_getdata(b);
/* length is tab char, null byte and MD5 (32 char) */
- int backup_len = strlen(oldbackup) + 34;
+ size_t backup_len = strlen(oldbackup) + 34;
if(!oldbackup || strcmp(oldbackup, entryname) != 0) {
continue;
@@ -625,10 +614,7 @@ static int extract_single_file(struct archive *archive,
_alpm_log(PM_LOG_DEBUG, "appending backup entry for %s\n", filename);
hash = alpm_get_md5sum(filename);
- backup = malloc(backup_len);
- if(!backup) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
+ MALLOC(backup, backup_len, RET_ERR(PM_ERR_MEMORY, -1));
sprintf(backup, "%s\t%s", oldbackup, hash);
backup[backup_len-1] = '\0';
@@ -644,14 +630,13 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
pmtrans_t *trans, pmdb_t *db)
{
int i, ret = 0, errors = 0;
- struct archive *archive;
- struct archive_entry *entry;
- char cwd[PATH_MAX] = "";
char scriptlet[PATH_MAX+1];
int is_upgrade = 0;
double percent = 0.0;
pmpkg_t *oldpkg = NULL;
+ ALPM_LOG_FUNC;
+
snprintf(scriptlet, PATH_MAX, "%s%s-%s/install", db->path,
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
@@ -666,12 +651,8 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
/* we'll need to save some record for backup checks later */
oldpkg = _alpm_pkg_dup(local);
- /* copy over the install reason (unless alldeps is set) */
- if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
- newpkg->reason = PM_PKG_REASON_DEPEND;
- } else {
+ /* copy over the install reason */
newpkg->reason = alpm_pkg_get_reason(local);
- }
/* pre_upgrade scriptlet */
if(alpm_pkg_has_scriptlet(newpkg) && !(trans->flags & PM_TRANS_FLAG_NOSCRIPTLET)) {
@@ -692,6 +673,13 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
}
}
+ /* we override any pre-set reason if we have alldeps or allexplicit set */
+ if(trans->flags & PM_TRANS_FLAG_ALLDEPS) {
+ newpkg->reason = PM_PKG_REASON_DEPEND;
+ } else if(trans->flags & PM_TRANS_FLAG_ALLEXPLICIT) {
+ newpkg->reason = PM_PKG_REASON_EXPLICIT;
+ }
+
if(oldpkg) {
/* set up fake remove transaction */
int ret = upgrade_remove(oldpkg, newpkg, trans, db);
@@ -701,15 +689,20 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
}
if(!(trans->flags & PM_TRANS_FLAG_DBONLY)) {
+ struct archive *archive;
+ struct archive_entry *entry;
+ char cwd[PATH_MAX] = "";
+
_alpm_log(PM_LOG_DEBUG, "extracting files\n");
if ((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
+ RET_ERR(PM_ERR_LIBARCHIVE, -1);
}
archive_read_support_compression_all(archive);
archive_read_support_format_all(archive);
+ _alpm_log(PM_LOG_DEBUG, "archive: %s\n", newpkg->origin_data.file);
if(archive_read_open_filename(archive, newpkg->origin_data.file,
ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
RET_ERR(PM_ERR_PKG_OPEN, -1);
@@ -850,7 +843,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
return(0);
}
- pkg_count = alpm_list_count(trans->targets);
+ pkg_count = alpm_list_count(trans->packages);
pkg_current = 1;
/* loop through our package list adding/upgrading one at a time */
diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c
index fb19d076..ee29d534 100644
--- a/lib/libalpm/alpm.c
+++ b/lib/libalpm/alpm.c
@@ -25,7 +25,6 @@
/* libalpm */
#include "alpm.h"
#include "alpm_list.h"
-#include "error.h"
#include "handle.h"
#include "util.h"
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 96b63ca6..a7ea0630 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -45,14 +45,12 @@ typedef struct __pmdb_t pmdb_t;
typedef struct __pmpkg_t pmpkg_t;
typedef struct __pmdelta_t pmdelta_t;
typedef struct __pmgrp_t pmgrp_t;
-typedef struct __pmserver_t pmserver_t;
typedef struct __pmtrans_t pmtrans_t;
typedef struct __pmsyncpkg_t pmsyncpkg_t;
typedef struct __pmdepend_t pmdepend_t;
typedef struct __pmdepmissing_t pmdepmissing_t;
typedef struct __pmconflict_t pmconflict_t;
typedef struct __pmfileconflict_t pmfileconflict_t;
-typedef struct __pmgraph_t pmgraph_t;
/*
* Library
@@ -81,8 +79,7 @@ int alpm_logaction(char *fmt, ...);
* Downloading
*/
-typedef void (*alpm_cb_download)(const char *filename, int file_xfered,
- int file_total, int list_xfered, int list_total);
+typedef void (*alpm_cb_download)(const char *filename, int xfered, int total);
/*
* Options
@@ -241,22 +238,15 @@ const char *alpm_delta_get_md5sum(pmdelta_t *delta);
* Groups
*/
const char *alpm_grp_get_name(const pmgrp_t *grp);
-const alpm_list_t *alpm_grp_get_pkgs(const pmgrp_t *grp);
+alpm_list_t *alpm_grp_get_pkgs(const pmgrp_t *grp);
/*
* Sync
*/
-/* Types */
-typedef enum _pmsynctype_t {
- PM_SYNC_TYPE_REPLACE = 1,
- PM_SYNC_TYPE_UPGRADE,
- PM_SYNC_TYPE_DEPEND
-} pmsynctype_t;
-
-pmsynctype_t alpm_sync_get_type(const pmsyncpkg_t *sync);
pmpkg_t *alpm_sync_get_pkg(const pmsyncpkg_t *sync);
-void *alpm_sync_get_data(const pmsyncpkg_t *sync);
+alpm_list_t *alpm_sync_get_removes(const pmsyncpkg_t *sync);
+pmpkg_t *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync);
int alpm_sync_sysupgrade(pmdb_t *db_local,
alpm_list_t *dbs_sync, alpm_list_t **syncpkgs);
@@ -266,10 +256,9 @@ int alpm_sync_sysupgrade(pmdb_t *db_local,
/* Types */
typedef enum _pmtranstype_t {
- PM_TRANS_TYPE_ADD = 1,
+ PM_TRANS_TYPE_UPGRADE = 1,
PM_TRANS_TYPE_REMOVE,
PM_TRANS_TYPE_REMOVEUPGRADE,
- PM_TRANS_TYPE_UPGRADE,
PM_TRANS_TYPE_SYNC
} pmtranstype_t;
@@ -282,13 +271,16 @@ typedef enum _pmtransflag_t {
PM_TRANS_FLAG_CASCADE = 0x10,
PM_TRANS_FLAG_RECURSE = 0x20,
PM_TRANS_FLAG_DBONLY = 0x40,
- PM_TRANS_FLAG_DEPENDSONLY = 0x80,
+ /* 0x80 flag can go here */
PM_TRANS_FLAG_ALLDEPS = 0x100,
PM_TRANS_FLAG_DOWNLOADONLY = 0x200,
PM_TRANS_FLAG_NOSCRIPTLET = 0x400,
PM_TRANS_FLAG_NOCONFLICTS = 0x800,
PM_TRANS_FLAG_PRINTURIS = 0x1000,
- PM_TRANS_FLAG_NEEDED = 0x2000
+ PM_TRANS_FLAG_NEEDED = 0x2000,
+ PM_TRANS_FLAG_ALLEXPLICIT = 0x4000,
+ PM_TRANS_FLAG_UNNEEDED = 0x8000,
+ PM_TRANS_FLAG_RECURSEALL = 0x10000
} pmtransflag_t;
/* Transaction Events */
@@ -353,7 +345,6 @@ typedef void (*alpm_trans_cb_progress)(pmtransprog_t, const char *, int, int, in
pmtranstype_t alpm_trans_get_type();
unsigned int alpm_trans_get_flags();
-alpm_list_t * alpm_trans_get_targets();
alpm_list_t * alpm_trans_get_pkgs();
int alpm_trans_init(pmtranstype_t type, pmtransflag_t flags,
alpm_trans_cb_event cb_event, alpm_trans_cb_conv conv,
@@ -378,13 +369,16 @@ typedef enum _pmdepmod_t {
PM_DEP_MOD_LT
} pmdepmod_t;
-pmdepend_t *alpm_splitdep(const char *depstring);
int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
alpm_list_t *alpm_checkdeps(pmdb_t *db, int reversedeps,
alpm_list_t *remove, alpm_list_t *upgrade);
+alpm_list_t *alpm_deptest(pmdb_t *db, alpm_list_t *targets);
const char *alpm_miss_get_target(const pmdepmissing_t *miss);
pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);
+const char *alpm_miss_get_causingpkg(const pmdepmissing_t *miss);
+
+alpm_list_t *alpm_checkdbconflicts(pmdb_t *db_local);
const char *alpm_conflict_get_package1(pmconflict_t *conflict);
const char *alpm_conflict_get_package2(pmconflict_t *conflict);
@@ -439,12 +433,6 @@ enum _pmerrno_t {
PM_ERR_DB_REMOVE,
/* Servers */
PM_ERR_SERVER_BAD_URL,
- /* Configuration */
- PM_ERR_OPT_LOGFILE,
- PM_ERR_OPT_DBPATH,
- PM_ERR_OPT_LOCALDB,
- PM_ERR_OPT_SYNCDB,
- PM_ERR_OPT_USESYSLOG,
/* Transactions */
PM_ERR_TRANS_NOT_NULL,
PM_ERR_TRANS_NULL,
@@ -460,14 +448,12 @@ enum _pmerrno_t {
PM_ERR_PKG_INVALID,
PM_ERR_PKG_OPEN,
PM_ERR_PKG_LOAD,
- PM_ERR_PKG_INSTALLED,
PM_ERR_PKG_CANT_FRESH,
PM_ERR_PKG_CANT_REMOVE,
PM_ERR_PKG_INVALID_NAME,
- PM_ERR_PKG_CORRUPTED,
PM_ERR_PKG_REPO_NOT_FOUND,
/* Deltas */
- PM_ERR_DLT_CORRUPTED,
+ PM_ERR_DLT_INVALID,
PM_ERR_DLT_PATCHFAILED,
/* Groups */
PM_ERR_GRP_NOT_FOUND,
@@ -478,14 +464,14 @@ enum _pmerrno_t {
/* Misc */
PM_ERR_USER_ABORT,
PM_ERR_INTERNAL_ERROR,
- PM_ERR_LIBARCHIVE_ERROR,
PM_ERR_DB_SYNC,
PM_ERR_RETRIEVE,
PM_ERR_PKG_HOLD,
PM_ERR_INVALID_REGEX,
- /* Downloading */
- PM_ERR_CONNECT_FAILED,
- PM_ERR_FORK_FAILED
+ /* External library errors */
+ PM_ERR_LIBARCHIVE,
+ PM_ERR_LIBDOWNLOAD,
+ PM_ERR_EXTERNAL_DOWNLOAD
};
extern enum _pmerrno_t pm_errno;
diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c
index 57c8376a..ae54e190 100644
--- a/lib/libalpm/alpm_list.c
+++ b/lib/libalpm/alpm_list.c
@@ -1,7 +1,7 @@
/*
* alpm_list.c
*
- * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,15 +17,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* libalpm */
#include "alpm_list.h"
-#include "util.h"
+
+/* check exported library symbols with: nm -C -D <lib> */
+#define SYMEXPORT __attribute__((visibility("default")))
+#define SYMHIDDEN __attribute__((visibility("internal")))
/**
* @addtogroup alpm_list List Functions
@@ -40,25 +41,6 @@
/* Allocation */
/**
- * @brief Allocate a new alpm_list_t.
- *
- * @return a new alpm_list_t item, or NULL on failure
- */
-alpm_list_t SYMEXPORT *alpm_list_new()
-{
- alpm_list_t *list = NULL;
-
- list = malloc(sizeof(alpm_list_t));
- if(list) {
- list->data = NULL;
- list->prev = list; /* maintain a back reference to the tail pointer */
- list->next = NULL;
- }
-
- return(list);
-}
-
-/**
* @brief Free a list, but not the contained data.
*
* @param list the list to free
@@ -107,30 +89,26 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
{
alpm_list_t *ptr, *lp;
- ptr = list;
+ ptr = calloc(1, sizeof(alpm_list_t));
if(ptr == NULL) {
- ptr = alpm_list_new();
- if(ptr == NULL) {
- return(NULL);
- }
+ return(list);
}
- lp = alpm_list_last(ptr);
- if(lp == ptr && lp->data == NULL) {
- /* nada */
- } else {
- lp->next = alpm_list_new();
- if(lp->next == NULL) {
- return(NULL);
- }
- lp->next->prev = lp;
- lp = lp->next;
- list->prev = lp;
+ ptr->data = data;
+ ptr->next = NULL;
+
+ /* Special case: the input list is empty */
+ if(list == NULL) {
+ ptr->prev = ptr;
+ return(ptr);
}
- lp->data = data;
+ lp = alpm_list_last(list);
+ lp->next = ptr;
+ ptr->prev = lp;
+ list->prev = ptr;
- return(ptr);
+ return(list);
}
/**
@@ -144,12 +122,15 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
*/
alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)
{
- if(!fn) {
- return alpm_list_add(list, data);
+ if(!fn || !list) {
+ return(alpm_list_add(list, data));
} else {
alpm_list_t *add = NULL, *prev = NULL, *next = list;
- add = alpm_list_new();
+ add = calloc(1, sizeof(alpm_list_t));
+ if(add == NULL) {
+ return(list);
+ }
add->data = data;
/* Find insertion point. */
@@ -159,26 +140,25 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_
next = next->next;
}
- /* Insert node before insertion point. */
- add->prev = prev;
- add->next = next;
-
- if(next != NULL) {
- next->prev = add; /* Not at end. */
- }
-
- if(prev != NULL) {
- prev->next = add; /* In middle. */
- } else {
- list = add; /* At beginning, or new list */
- }
-
- if(next == NULL) {
- /* At end, adjust tail pointer on head node */
+ /* Insert the add node to the list */
+ if(prev == NULL) { /* special case: we insert add as the first element */
+ add->prev = list->prev; /* list != NULL */
+ add->next = list;
+ list->prev = add;
+ return(add);
+ } else if(next == NULL) { /* another special case: add last element */
+ add->prev = prev;
+ add->next = NULL;
+ prev->next = add;
list->prev = add;
+ return(list);
+ } else {
+ add->prev = prev;
+ add->next = next;
+ next->prev = add;
+ prev->next = add;
+ return(list);
}
-
- return(list);
}
}
@@ -198,10 +178,10 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
alpm_list_t *tmp;
if (first == NULL) {
- return second;
+ return(second);
}
if (second == NULL) {
- return first;
+ return(first);
}
/* tmp is the last element of the first list */
tmp = first->prev;
@@ -464,18 +444,22 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
{
const alpm_list_t *lp;
- alpm_list_t *newlist = NULL;
+ alpm_list_t *newlist = NULL, *backup;
- lp = alpm_list_last(list);
- if(list) {
- /* break our reverse circular list */
- list->prev = NULL;
+ if(list == NULL) {
+ return(NULL);
}
+ lp = alpm_list_last(list);
+ /* break our reverse circular list */
+ backup = list->prev;
+ list->prev = NULL;
+
while(lp) {
newlist = alpm_list_add(newlist, lp->data);
lp = lp->prev;
}
+ list->prev = backup; /* restore tail pointer */
return(newlist);
}
@@ -490,14 +474,18 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
*/
inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list)
{
- return((alpm_list_t*)list);
+ if(list) {
+ return((alpm_list_t*)list);
+ } else {
+ return(NULL);
+ }
}
/**
* @brief Return nth element from list (starting from 0).
*
* @param list the list
- * @param n the index of the item to find
+ * @param n the index of the item to find (n < alpm_list_count(list) IS needed)
*
* @return an alpm_list_t node for index `n`
*/
@@ -519,7 +507,11 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, int n)
*/
inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
{
- return(node->next);
+ if(node) {
+ return(node->next);
+ } else {
+ return(NULL);
+ }
}
/**
diff --git a/lib/libalpm/alpm_list.h b/lib/libalpm/alpm_list.h
index ae373910..b3846ba0 100644
--- a/lib/libalpm/alpm_list.h
+++ b/lib/libalpm/alpm_list.h
@@ -19,6 +19,8 @@
#ifndef _ALPM_LIST_H
#define _ALPM_LIST_H
+#include <stdlib.h> /* size_t */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -45,7 +47,6 @@ typedef void (*alpm_list_fn_free)(void *); /* item deallocation callback */
typedef int (*alpm_list_fn_cmp)(const void *, const void *); /* item comparison callback */
/* allocation */
-alpm_list_t *alpm_list_new(void);
void alpm_list_free(alpm_list_t *list);
void alpm_list_free_inner(alpm_list_t *list, alpm_list_fn_free fn);
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 4cd0985e..7cc01c26 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -39,7 +39,6 @@
#include "log.h"
#include "util.h"
#include "alpm.h"
-#include "error.h"
#include "handle.h"
#include "package.h"
#include "delta.h"
@@ -106,7 +105,7 @@ void _alpm_db_rewind(pmdb_t *db)
rewinddir(db->handle);
}
-static int _alpm_db_splitname(const char *target, char *name, char *version)
+static int splitname(const char *target, pmpkg_t *pkg)
{
/* the format of a db entry is as follows:
* package-version-rel/
@@ -115,10 +114,10 @@ static int _alpm_db_splitname(const char *target, char *name, char *version)
*/
char *tmp, *p, *q;
- if(target == NULL) {
+ if(target == NULL || pkg == NULL) {
return(-1);
}
- tmp = strdup(target);
+ STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
p = tmp + strlen(tmp);
/* do the magic parsing- find the beginning of the version string
@@ -130,14 +129,16 @@ static int _alpm_db_splitname(const char *target, char *name, char *version)
}
/* copy into fields and return */
- if(version) {
- strncpy(version, p+1, PKG_VERSION_LEN);
+ if(pkg->version) {
+ FREE(pkg->version);
}
+ STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
/* insert a terminator at the end of the name (on hyphen)- then copy it */
*p = '\0';
- if(name) {
- strncpy(name, tmp, PKG_NAME_LEN);
+ if(pkg->name) {
+ FREE(pkg->name);
}
+ STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
free(tmp);
return(0);
@@ -148,7 +149,6 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
struct dirent *ent = NULL;
struct stat sbuf;
char path[PATH_MAX];
- char name[PKG_FULLNAME_LEN];
char *ptr = NULL;
int found = 0;
pmpkg_t *pkg = NULL;
@@ -168,7 +168,9 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
/* search for a specific package (by name only) */
rewinddir(db->handle);
while(!found && (ent = readdir(db->handle)) != NULL) {
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ char *name;
+
+ if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
continue;
}
/* stat the entry, make sure it's a directory */
@@ -176,7 +178,9 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
continue;
}
- strncpy(name, ent->d_name, PKG_FULLNAME_LEN);
+
+ STRDUP(name, ent->d_name, return(NULL));
+
/* truncate the string at the second-to-last hyphen, */
/* which will give us the package name */
if((ptr = rindex(name, '-'))) {
@@ -185,10 +189,12 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
if((ptr = rindex(name, '-'))) {
*ptr = '\0';
}
- if(!strcmp(name, target)) {
+ if(strcmp(name, target) == 0) {
found = 1;
}
+ FREE(name);
}
+
if(!found) {
return(NULL);
}
@@ -199,7 +205,7 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
if(ent == NULL) {
return(NULL);
}
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+ if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
isdir = 0;
continue;
}
@@ -217,7 +223,7 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
return(NULL);
}
/* split the db entry name */
- if(_alpm_db_splitname(ent->d_name, pkg->name, pkg->version) != 0) {
+ if(splitname(ent->d_name, pkg) != 0) {
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
ent->d_name);
alpm_pkg_free(pkg);
@@ -251,7 +257,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
RET_ERR(PM_ERR_DB_NULL, -1);
}
- if(info == NULL || info->name[0] == 0 || info->version[0] == 0) {
+ if(info == NULL || info->name == NULL || info->version == NULL) {
_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n");
return(-1);
}
@@ -296,120 +302,115 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
break;
}
_alpm_strtrim(line);
- if(!strcmp(line, "%FILENAME%")) {
- if(fgets(info->filename, sizeof(info->filename), fp) == NULL) {
+ if(strcmp(line, "%FILENAME%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->filename);
- } else if(!strcmp(line, "%DESC%")) {
- if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
+ STRDUP(info->filename, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%DESC%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->desc);
- } else if(!strcmp(line, "%GROUPS%")) {
+ STRDUP(info->desc, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%GROUPS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->groups = alpm_list_add(info->groups, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->groups = alpm_list_add(info->groups, linedup);
}
- } else if(!strcmp(line, "%URL%")) {
- if(fgets(info->url, sizeof(info->url), fp) == NULL) {
+ } else if(strcmp(line, "%URL%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->url);
- } else if(!strcmp(line, "%LICENSE%")) {
+ STRDUP(info->url, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%LICENSE%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->licenses = alpm_list_add(info->licenses, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->licenses = alpm_list_add(info->licenses, linedup);
}
- } else if(!strcmp(line, "%ARCH%")) {
- if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
+ } else if(strcmp(line, "%ARCH%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->arch);
- } else if(!strcmp(line, "%BUILDDATE%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ STRDUP(info->arch, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%BUILDDATE%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
+ _alpm_strtrim(line);
- char first = tolower(tmp[0]);
+ char first = tolower(line[0]);
if(first > 'a' && first < 'z') {
struct tm tmp_tm = {0}; //initialize to null incase of failure
setlocale(LC_TIME, "C");
- strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm);
+ strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->builddate = mktime(&tmp_tm);
setlocale(LC_TIME, "");
} else {
- info->builddate = atol(tmp);
+ info->builddate = atol(line);
}
- } else if(!strcmp(line, "%INSTALLDATE%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ } else if(strcmp(line, "%INSTALLDATE%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
+ _alpm_strtrim(line);
- char first = tolower(tmp[0]);
+ char first = tolower(line[0]);
if(first > 'a' && first < 'z') {
struct tm tmp_tm = {0}; //initialize to null incase of failure
setlocale(LC_TIME, "C");
- strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm);
+ strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->installdate = mktime(&tmp_tm);
setlocale(LC_TIME, "");
} else {
- info->installdate = atol(tmp);
+ info->installdate = atol(line);
}
- } else if(!strcmp(line, "%PACKAGER%")) {
- if(fgets(info->packager, sizeof(info->packager), fp) == NULL) {
+ } else if(strcmp(line, "%PACKAGER%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->packager);
- } else if(!strcmp(line, "%REASON%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ STRDUP(info->packager, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%REASON%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->reason = atol(tmp);
- } else if(!strcmp(line, "%SIZE%") || !strcmp(line, "%CSIZE%")) {
+ info->reason = atol(_alpm_strtrim(line));
+ } else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) {
/* NOTE: the CSIZE and SIZE fields both share the "size" field
* in the pkginfo_t struct. This can be done b/c CSIZE
* is currently only used in sync databases, and SIZE is
* only used in local databases.
*/
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->size = atol(tmp);
+ info->size = atol(_alpm_strtrim(line));
/* also store this value to isize if isize is unset */
if(info->isize == 0) {
- info->isize = atol(tmp);
+ info->isize = info->size;
}
- } else if(!strcmp(line, "%ISIZE%")) {
+ } else if(strcmp(line, "%ISIZE%") == 0) {
/* ISIZE (installed size) tag only appears in sync repositories,
* not the local one. */
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->isize = atol(tmp);
- } else if(!strcmp(line, "%MD5SUM%")) {
+ info->isize = atol(_alpm_strtrim(line));
+ } else if(strcmp(line, "%MD5SUM%") == 0) {
/* MD5SUM tag only appears in sync repositories,
* not the local one. */
- if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- } else if(!strcmp(line, "%REPLACES%")) {
- /* the REPLACES tag is special -- it only appears in sync repositories,
- * not the local one. */
+ STRDUP(info->md5sum, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%REPLACES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->replaces = alpm_list_add(info->replaces, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->replaces = alpm_list_add(info->replaces, linedup);
}
- } else if(!strcmp(line, "%FORCE%")) {
- /* FORCE tag only appears in sync repositories,
- * not the local one. */
+ } else if(strcmp(line, "%FORCE%") == 0) {
info->force = 1;
}
}
@@ -426,13 +427,17 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
while(fgets(line, 256, fp)) {
_alpm_strtrim(line);
- if(!strcmp(line, "%FILES%")) {
+ if(strcmp(line, "%FILES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->files = alpm_list_add(info->files, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->files = alpm_list_add(info->files, linedup);
}
- } else if(!strcmp(line, "%BACKUP%")) {
+ } else if(strcmp(line, "%BACKUP%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->backup = alpm_list_add(info->backup, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->backup = alpm_list_add(info->backup, linedup);
}
}
}
@@ -450,37 +455,30 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
while(!feof(fp)) {
fgets(line, 255, fp);
_alpm_strtrim(line);
- if(!strcmp(line, "%DEPENDS%")) {
+ if(strcmp(line, "%DEPENDS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- pmdepend_t *dep = alpm_splitdep(line);
+ pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line));
info->depends = alpm_list_add(info->depends, dep);
}
- } else if(!strcmp(line, "%OPTDEPENDS%")) {
+ } else if(strcmp(line, "%OPTDEPENDS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->optdepends = alpm_list_add(info->optdepends, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->optdepends = alpm_list_add(info->optdepends, linedup);
}
- } else if(!strcmp(line, "%CONFLICTS%")) {
+ } else if(strcmp(line, "%CONFLICTS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->conflicts = alpm_list_add(info->conflicts, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->conflicts = alpm_list_add(info->conflicts, linedup);
}
- } else if(!strcmp(line, "%PROVIDES%")) {
+ } else if(strcmp(line, "%PROVIDES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->provides = alpm_list_add(info->provides, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->provides = alpm_list_add(info->provides, linedup);
}
}
- /* TODO: we were going to move these things here, but it should wait.
- * A better change would be to figure out how to restructure the DB. */
- /* else if(!strcmp(line, "%REPLACES%")) {
- * the REPLACES tag is special -- it only appears in sync repositories,
- * not the local one. *
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->replaces = alpm_list_add(info->replaces, strdup(line));
- }
- } else if(!strcmp(line, "%FORCE%")) {
- * FORCE tag only appears in sync repositories,
- * not the local one. *
- info->force = 1;
- } */
}
fclose(fp);
fp = NULL;
@@ -488,12 +486,13 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* DELTAS */
if(inforeq & INFRQ_DELTAS) {
- snprintf(path, PATH_MAX, "%s/%s-%s/deltas", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%s/%s-%s/deltas", db->path,
+ info->name, info->version);
if((fp = fopen(path, "r"))) {
while(!feof(fp)) {
fgets(line, 255, fp);
_alpm_strtrim(line);
- if(!strcmp(line, "%DELTAS%")) {
+ if(strcmp(line, "%DELTAS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
info->deltas = alpm_list_add(info->deltas, _alpm_delta_parse(line));
}
@@ -561,7 +560,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "%%NAME%%\n%s\n\n"
"%%VERSION%%\n%s\n\n", info->name, info->version);
- if(info->desc[0]) {
+ if(info->desc) {
fprintf(fp, "%%DESC%%\n"
"%s\n\n", info->desc);
}
@@ -573,7 +572,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
fprintf(fp, "\n");
}
if(local) {
- if(info->url[0]) {
+ if(info->url) {
fprintf(fp, "%%URL%%\n"
"%s\n\n", info->url);
}
@@ -584,7 +583,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "\n");
}
- if(info->arch[0]) {
+ if(info->arch) {
fprintf(fp, "%%ARCH%%\n"
"%s\n\n", info->arch);
}
@@ -596,7 +595,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
fprintf(fp, "%%INSTALLDATE%%\n"
"%ju\n\n", (uintmax_t)info->installdate);
}
- if(info->packager[0]) {
+ if(info->packager) {
fprintf(fp, "%%PACKAGER%%\n"
"%s\n\n", info->packager);
}
@@ -695,18 +694,16 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "\n");
}
- if(!local) {
- if(info->replaces) {
- fputs("%REPLACES%\n", fp);
- for(lp = info->replaces; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->force) {
- fprintf(fp, "%%FORCE%%\n"
- "\n");
+ if(info->replaces) {
+ fputs("%REPLACES%\n", fp);
+ for(lp = info->replaces; lp; lp = lp->next) {
+ fprintf(fp, "%s\n", (char *)lp->data);
}
+ fprintf(fp, "\n");
+ }
+ if(info->force) {
+ /* note the extra newline character, which is necessary! */
+ fprintf(fp, "%%FORCE%%\n\n");
}
fclose(fp);
fp = NULL;
diff --git a/lib/libalpm/cache.c b/lib/libalpm/cache.c
index 0ad923a5..bfc4fd9e 100644
--- a/lib/libalpm/cache.c
+++ b/lib/libalpm/cache.c
@@ -31,7 +31,6 @@
#include "log.h"
#include "alpm.h"
#include "util.h"
-#include "error.h"
#include "package.h"
#include "group.h"
#include "db.h"
@@ -81,10 +80,7 @@ void _alpm_db_free_pkgcache(pmdb_t *db)
_alpm_log(PM_LOG_DEBUG, "freeing package cache for repository '%s'\n",
db->treename);
- alpm_list_t *tmp;
- for(tmp = db->pkgcache; tmp; tmp = alpm_list_next(tmp)) {
- _alpm_pkg_free(tmp->data);
- }
+ alpm_list_free_inner(db->pkgcache, (alpm_list_fn_free)_alpm_pkg_free);
alpm_list_free(db->pkgcache);
db->pkgcache = NULL;
@@ -115,21 +111,15 @@ alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db)
int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg)
{
- pmpkg_t *newpkg;
-
ALPM_LOG_FUNC;
if(db == NULL || pkg == NULL) {
return(-1);
}
- newpkg = _alpm_pkg_dup(pkg);
- if(newpkg == NULL) {
- return(-1);
- }
_alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n",
- alpm_pkg_get_name(newpkg), db->treename);
- db->pkgcache = alpm_list_add_sorted(db->pkgcache, newpkg, _alpm_pkg_cmp);
+ alpm_pkg_get_name(pkg), db->treename);
+ db->pkgcache = alpm_list_add_sorted(db->pkgcache, pkg, _alpm_pkg_cmp);
_alpm_db_free_grpcache(db);
@@ -208,33 +198,29 @@ int _alpm_db_load_grpcache(pmdb_t *db)
pmpkg_t *pkg = lp->data;
for(i = alpm_pkg_get_groups(pkg); i; i = i->next) {
- if(!alpm_list_find_str(db->grpcache, i->data)) {
- pmgrp_t *grp = _alpm_grp_new();
-
- strncpy(grp->name, i->data, GRP_NAME_LEN);
- grp->name[GRP_NAME_LEN-1] = '\0';
- grp->packages = alpm_list_add_sorted(grp->packages,
- /* gross signature forces us to
- * discard const */
- (void*)alpm_pkg_get_name(pkg),
- _alpm_str_cmp);
- db->grpcache = alpm_list_add_sorted(db->grpcache, grp, _alpm_grp_cmp);
- } else {
- alpm_list_t *j;
-
- for(j = db->grpcache; j; j = j->next) {
- pmgrp_t *grp = j->data;
-
- if(strcmp(grp->name, i->data) == 0) {
- const char *pkgname = alpm_pkg_get_name(pkg);
- if(!alpm_list_find_str(grp->packages, pkgname)) {
- grp->packages = alpm_list_add_sorted(grp->packages,
- (void*)pkgname,
- _alpm_str_cmp);
- }
- }
+ const char *grpname = i->data;
+ alpm_list_t *j;
+ pmgrp_t *grp = NULL;
+ int found = 0;
+
+ /* first look through the group cache for a group with this name */
+ for(j = db->grpcache; j; j = j->next) {
+ grp = j->data;
+
+ if(strcmp(grp->name, grpname) == 0
+ && !alpm_list_find_ptr(grp->packages, pkg)) {
+ grp->packages = alpm_list_add(grp->packages, pkg);
+ found = 1;
+ break;
}
}
+ if(found) {
+ continue;
+ }
+ /* we didn't find the group, so create a new one with this name */
+ grp = _alpm_grp_new(grpname);
+ grp->packages = alpm_list_add(grp->packages, pkg);
+ db->grpcache = alpm_list_add(db->grpcache, grp);
}
}
@@ -252,10 +238,6 @@ void _alpm_db_free_grpcache(pmdb_t *db)
}
for(lg = db->grpcache; lg; lg = lg->next) {
- pmgrp_t *grp = lg->data;
-
- alpm_list_free(grp->packages);
- grp->packages = NULL;
_alpm_grp_free(lg->data);
lg->data = NULL;
}
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 3442902c..68665e78 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -36,7 +36,6 @@
#include "handle.h"
#include "trans.h"
#include "util.h"
-#include "error.h"
#include "log.h"
#include "cache.h"
#include "deps.h"
@@ -49,12 +48,30 @@ pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2)
MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
- strncpy(conflict->package1, package1, PKG_NAME_LEN);
- strncpy(conflict->package2, package2, PKG_NAME_LEN);
+ STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL));
return(conflict);
}
+void _alpm_conflict_free(pmconflict_t *conflict)
+{
+ FREE(conflict->package2);
+ FREE(conflict->package1);
+ FREE(conflict);
+}
+
+pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict)
+{
+ pmconflict_t *newconflict;
+ CALLOC(newconflict, 1, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
+
+ STRDUP(newconflict->package1, conflict->package1, RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL));
+
+ return(newconflict);
+}
+
int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack)
{
alpm_list_t *i;
@@ -86,7 +103,7 @@ static int does_conflict(pmpkg_t *pkg1, const char *conflict, pmpkg_t *pkg2)
{
const char *pkg1name = alpm_pkg_get_name(pkg1);
const char *pkg2name = alpm_pkg_get_name(pkg2);
- pmdepend_t *conf = alpm_splitdep(conflict);
+ pmdepend_t *conf = _alpm_splitdep(conflict);
int match = 0;
match = alpm_depcmp(pkg2, conf);
@@ -94,7 +111,7 @@ static int does_conflict(pmpkg_t *pkg1, const char *conflict, pmpkg_t *pkg2)
_alpm_log(PM_LOG_DEBUG, "package %s conflicts with %s (by %s)\n",
pkg1name, pkg2name, conflict);
}
- FREE(conf);
+ _alpm_dep_free(conf);
return(match);
}
@@ -110,7 +127,7 @@ static void add_conflict(alpm_list_t **baddeps, const char *pkg1,
if(conflict && !_alpm_conflict_isin(conflict, *baddeps)) {
*baddeps = alpm_list_add(*baddeps, conflict);
} else {
- FREE(conflict);
+ _alpm_conflict_free(conflict);
}
}
@@ -200,9 +217,13 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages)
return(baddeps);
}
-/* Check for transaction conflicts */
-alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages) {
- return(alpm_list_join(_alpm_innerconflicts(packages), _alpm_outerconflicts(db, packages)));
+/** Check the package conflicts in a database
+ *
+ * @param db_local the database to check
+ * @return an alpm_list_t of pmconflict_t
+ */
+alpm_list_t SYMEXPORT *alpm_checkdbconflicts(pmdb_t *db_local) {
+ return(_alpm_innerconflicts(_alpm_db_get_pkgcache(db_local)));
}
/* Returns a alpm_list_t* of file conflicts.
@@ -299,15 +320,15 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts,
const char* name1, const char* name2)
{
pmfileconflict_t *conflict;
- MALLOC(conflict, sizeof(pmfileconflict_t), return(conflicts));
+ MALLOC(conflict, sizeof(pmfileconflict_t), RET_ERR(PM_ERR_MEMORY, NULL));
conflict->type = type;
- strncpy(conflict->target, name1, PKG_NAME_LEN);
- strncpy(conflict->file, filestr, CONFLICT_FILE_LEN);
+ STRDUP(conflict->target, name1, RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(conflict->file, filestr, RET_ERR(PM_ERR_MEMORY, NULL));
if(name2) {
- strncpy(conflict->ctarget, name2, PKG_NAME_LEN);
+ STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL));
} else {
- conflict->ctarget[0] = '\0';
+ conflict->ctarget = "";
}
conflicts = alpm_list_add(conflicts, conflict);
@@ -317,6 +338,16 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts,
return(conflicts);
}
+void _alpm_fileconflict_free(pmfileconflict_t *conflict)
+{
+ if(strlen(conflict->ctarget) > 0) {
+ FREE(conflict->ctarget);
+ }
+ FREE(conflict->file);;
+ FREE(conflict->target);
+ FREE(conflict);
+}
+
/* Find file conflicts that may occur during the transaction with two checks:
* 1: check every target against every target
* 2: check every target against the filesystem */
@@ -351,13 +382,13 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *roo
PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", (percent * 100),
numtargs, current);
/* CHECK 1: check every target against every target */
+ _alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s\n",
+ alpm_pkg_get_name(p1));
for(j = i->next; j; j = j->next) {
p2 = j->data;
if(!p2) {
continue;
}
- _alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s and %s\n",
- alpm_pkg_get_name(p1), alpm_pkg_get_name(p2));
tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2));
if(tmpfiles) {
diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h
index a846aace..71ed579d 100644
--- a/lib/libalpm/conflict.h
+++ b/lib/libalpm/conflict.h
@@ -23,27 +23,28 @@
#include "db.h"
#include "package.h"
-#define CONFLICT_FILE_LEN 512
-
struct __pmconflict_t {
- char package1[PKG_NAME_LEN];
- char package2[PKG_NAME_LEN];
+ char *package1;
+ char *package2;
};
struct __pmfileconflict_t {
- char target[PKG_NAME_LEN];
+ char *target;
pmfileconflicttype_t type;
- char file[CONFLICT_FILE_LEN];
- char ctarget[PKG_NAME_LEN];
+ char *file;
+ char *ctarget;
};
pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2);
+pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict);
+void _alpm_conflict_free(pmconflict_t *conflict);
int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack);
alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages);
alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages);
-alpm_list_t *_alpm_checkconflicts(pmdb_t *db, alpm_list_t *packages);
alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *root);
+void _alpm_fileconflict_free(pmfileconflict_t *conflict);
+
#endif /* _ALPM_CONFLICT_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 1485c34a..e8ae11a3 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -39,8 +39,7 @@
#include "alpm_list.h"
#include "log.h"
#include "util.h"
-#include "error.h"
-#include "server.h"
+#include "dload.h"
#include "handle.h"
#include "cache.h"
#include "alpm.h"
@@ -190,14 +189,9 @@ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url)
}
if(url && strlen(url)) {
- pmserver_t *server;
- if((server = _alpm_server_new(url)) == NULL) {
- /* pm_errno is set by _alpm_server_new */
- return(-1);
- }
- db->servers = alpm_list_add(db->servers, server);
- _alpm_log(PM_LOG_DEBUG, "adding new server to database '%s': protocol '%s', server '%s', path '%s'\n",
- db->treename, server->s_url->scheme, server->s_url->host, server->s_url->doc);
+ db->servers = alpm_list_add(db->servers, strdup(url));
+ _alpm_log(PM_LOG_DEBUG, "adding new server URL to database '%s': %s\n",
+ db->treename, url);
} else {
FREELIST(db->servers);
_alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename);
@@ -217,7 +211,6 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
{
alpm_list_t *lp;
char path[PATH_MAX];
- alpm_list_t *files = NULL;
time_t newmtime = 0, lastupdate = 0;
const char *dbpath;
int ret;
@@ -250,29 +243,21 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
/* build a one-element list */
snprintf(path, PATH_MAX, "%s" DBEXT, db->treename);
- files = alpm_list_add(files, strdup(path));
-
dbpath = alpm_option_get_dbpath();
- ret = _alpm_downloadfiles_forreal(db->servers, dbpath, files, lastupdate,
- &newmtime, NULL, 0);
- FREELIST(files);
+ ret = _alpm_download_single_file(path, db->servers, dbpath,
+ lastupdate, &newmtime);
+
if(ret == 1) {
/* mtimes match, do nothing */
pm_errno = 0;
return(1);
} else if(ret == -1) {
- /* we use downloadLastErrString and downloadLastErrCode here, error returns from
- * libdownload */
- _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s [%d]\n",
- downloadLastErrString, downloadLastErrCode);
- RET_ERR(PM_ERR_DB_SYNC, -1);
+ /* pm_errno was set by the download code */
+ _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
+ return(-1);
} else {
- if(newmtime != 0) {
- _alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %ju\n",
- db->treename, (uintmax_t)newmtime);
- _alpm_db_setlastupdate(db, newmtime);
- }
+ /* form the path to the db location */
snprintf(path, PATH_MAX, "%s%s" DBEXT, dbpath, db->treename);
/* remove the old dir */
@@ -293,6 +278,12 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
if(_alpm_db_install(db, path) == -1) {
return -1;
}
+ /* if we have a new mtime, set the DB last update value */
+ if(newmtime) {
+ _alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %ju\n",
+ db->treename, (uintmax_t)newmtime);
+ _alpm_db_setlastupdate(db, newmtime);
+ }
}
return(0);
@@ -319,8 +310,7 @@ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db)
*/
const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db)
{
- char path[PATH_MAX];
- pmserver_t *s;
+ char *url;
ALPM_LOG_FUNC;
@@ -328,10 +318,9 @@ const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db)
ASSERT(handle != NULL, return(NULL));
ASSERT(db != NULL, return(NULL));
- s = (pmserver_t*)db->servers->data;
+ url = (char*)db->servers->data;
- snprintf(path, PATH_MAX, "%s://%s%s", s->s_url->scheme, s->s_url->host, s->s_url->doc);
- return strdup(path);
+ return(url);
}
@@ -445,26 +434,21 @@ pmdb_t *_alpm_db_new(const char *dbpath, const char *treename)
CALLOC(db->path, 1, pathsize, RET_ERR(PM_ERR_MEMORY, NULL));
sprintf(db->path, "%s%s/", dbpath, treename);
-
- strncpy(db->treename, treename, PATH_MAX);
+ STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL));
return(db);
}
void _alpm_db_free(pmdb_t *db)
{
- alpm_list_t *tmp;
-
ALPM_LOG_FUNC;
/* cleanup pkgcache */
_alpm_db_free_pkgcache(db);
/* cleanup server list */
- for(tmp = db->servers; tmp; tmp = alpm_list_next(tmp)) {
- _alpm_server_free(tmp->data);
- }
- alpm_list_free(db->servers);
+ FREELIST(db->servers);
FREE(db->path);
+ FREE(db->treename);
FREE(db);
return;
@@ -500,18 +484,16 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles)
for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
pmpkg_t *pkg = j->data;
const char *matched = NULL;
+ const char *name = alpm_pkg_get_name(pkg);
+ const char *desc = alpm_pkg_get_desc(pkg);
- /* check name */
- if (regexec(&reg, alpm_pkg_get_name(pkg), 0, 0, 0) == 0) {
- matched = alpm_pkg_get_name(pkg);
- }
- /* check plain text name */
- else if (strstr(alpm_pkg_get_name(pkg), targ)) {
- matched = alpm_pkg_get_name(pkg);
+ /* check name as regex AND as plain text */
+ if(name && (regexec(&reg, name, 0, 0, 0) == 0 || strstr(name, targ))) {
+ matched = name;
}
/* check desc */
- else if (regexec(&reg, alpm_pkg_get_desc(pkg), 0, 0, 0) == 0) {
- matched = alpm_pkg_get_desc(pkg);
+ else if (desc && regexec(&reg, desc, 0, 0, 0) == 0) {
+ matched = desc;
}
/* check provides */
/* TODO: should we be doing this, and should we print something
diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h
index 8c8c9bd7..743fa788 100644
--- a/lib/libalpm/db.h
+++ b/lib/libalpm/db.h
@@ -40,7 +40,7 @@ typedef enum _pmdbinfrq_t {
/* Database */
struct __pmdb_t {
char *path;
- char treename[PATH_MAX];
+ char *treename;
void *handle;
alpm_list_t *pkgcache;
alpm_list_t *grpcache;
diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c
index 3d33c595..e9870c8c 100644
--- a/lib/libalpm/delta.c
+++ b/lib/libalpm/delta.c
@@ -1,7 +1,7 @@
/*
* delta.c
*
- * Copyright (c) 2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2007-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@
/* libalpm */
#include "delta.h"
-#include "error.h"
#include "util.h"
#include "log.h"
#include "alpm_list.h"
@@ -99,7 +98,7 @@ unsigned long _alpm_delta_path_size(alpm_list_t *deltas)
alpm_list_t *dlts = deltas;
while(dlts) {
- pmdelta_t *d = (pmdelta_t *)alpm_list_getdata(dlts);
+ pmdelta_t *d = alpm_list_getdata(dlts);
sum += d->size;
dlts = alpm_list_next(dlts);
@@ -121,7 +120,7 @@ unsigned long _alpm_delta_path_size_uncached(alpm_list_t *deltas)
alpm_list_t *dlts = deltas;
while(dlts) {
- pmdelta_t *d = (pmdelta_t *)alpm_list_getdata(dlts);
+ pmdelta_t *d = alpm_list_getdata(dlts);
char *fname = _alpm_filecache_find(d->filename);
if(!fname) {
@@ -241,12 +240,12 @@ pmdelta_t *_alpm_delta_parse(char *line)
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
- strncpy(delta->from, tmp2, DLT_VERSION_LEN);
+ STRDUP(delta->from, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
- strncpy(delta->to, tmp2, DLT_VERSION_LEN);
+ STRDUP(delta->to, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
tmp2 = tmp;
tmp = strchr(tmp, ' ');
@@ -256,11 +255,20 @@ pmdelta_t *_alpm_delta_parse(char *line)
tmp2 = tmp;
tmp = strchr(tmp, ' ');
*(tmp++) = '\0';
- strncpy(delta->filename, tmp2, DLT_FILENAME_LEN);
+ STRDUP(delta->filename, tmp2, RET_ERR(PM_ERR_MEMORY, NULL));
- strncpy(delta->md5sum, tmp, DLT_MD5SUM_LEN);
+ STRDUP(delta->md5sum, tmp, RET_ERR(PM_ERR_MEMORY, NULL));
return(delta);
}
+void _alpm_delta_free(pmdelta_t *delta)
+{
+ FREE(delta->from);
+ FREE(delta->to);
+ FREE(delta->filename);
+ FREE(delta->md5sum);
+ FREE(delta);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h
index 3065d4d1..007e5d45 100644
--- a/lib/libalpm/delta.h
+++ b/lib/libalpm/delta.h
@@ -1,7 +1,7 @@
/*
* delta.h
*
- * Copyright (c) 2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2007-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,22 +21,20 @@
#include "alpm.h"
-#define DLT_FILENAME_LEN 512
-#define DLT_VERSION_LEN 64
-#define DLT_MD5SUM_LEN 33
-
struct __pmdelta_t {
- char from[DLT_VERSION_LEN];
- char to[DLT_VERSION_LEN];
+ char *from;
+ char *to;
unsigned long size;
- char filename[DLT_FILENAME_LEN];
- char md5sum[DLT_MD5SUM_LEN];
+ char *filename;
+ char *md5sum;
};
unsigned long _alpm_delta_path_size(alpm_list_t *deltas);
unsigned long _alpm_delta_path_size_uncached(alpm_list_t *deltas);
pmdelta_t *_alpm_delta_parse(char *line);
-alpm_list_t *_alpm_shortest_delta_path(alpm_list_t *deltas, const char *from, const char *to);
+void _alpm_delta_free(pmdelta_t *delta);
+alpm_list_t *_alpm_shortest_delta_path(alpm_list_t *deltas,
+ const char *from, const char *to);
#endif /* _ALPM_DELTA_H */
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index b967243d..24b17933 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -30,37 +30,21 @@
#include "alpm_list.h"
#include "util.h"
#include "log.h"
-#include "error.h"
+#include "graph.h"
#include "package.h"
#include "db.h"
#include "cache.h"
#include "handle.h"
-static pmgraph_t *_alpm_graph_new(void)
+void _alpm_dep_free(pmdepend_t *dep)
{
- pmgraph_t *graph = NULL;
-
- MALLOC(graph, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL));
-
- if(graph) {
- graph->state = 0;
- graph->data = NULL;
- graph->parent = NULL;
- graph->children = NULL;
- graph->childptr = NULL;
- }
- return(graph);
-}
-
-static void _alpm_graph_free(void *data)
-{
- pmgraph_t *graph = data;
- alpm_list_free(graph->children);
- free(graph);
+ FREE(dep->name);
+ FREE(dep->version);
+ FREE(dep);
}
-pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod,
- const char *depname, const char *depversion)
+pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep,
+ const char *causingpkg)
{
pmdepmissing_t *miss;
@@ -68,24 +52,27 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod,
MALLOC(miss, sizeof(pmdepmissing_t), RET_ERR(PM_ERR_MEMORY, NULL));
- strncpy(miss->target, target, PKG_NAME_LEN);
- miss->depend.mod = depmod;
- strncpy(miss->depend.name, depname, PKG_NAME_LEN);
- if(depversion) {
- strncpy(miss->depend.version, depversion, PKG_VERSION_LEN);
- } else {
- miss->depend.version[0] = 0;
- }
+ STRDUP(miss->target, target, RET_ERR(PM_ERR_MEMORY, NULL));
+ miss->depend = _alpm_dep_dup(dep);
+ STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL));
return(miss);
}
+void _alpm_depmiss_free(pmdepmissing_t *miss)
+{
+ _alpm_dep_free(miss->depend);
+ FREE(miss->target);
+ FREE(miss->causingpkg);
+ FREE(miss);
+}
+
/* Convert a list of pmpkg_t * to a graph structure,
* with a edge for each dependency.
* Returns a list of vertices (one vertex = one package)
* (used by alpm_sortbydeps)
*/
-static alpm_list_t *_alpm_graph_init(alpm_list_t *targets)
+static alpm_list_t *dep_graph_init(alpm_list_t *targets)
{
alpm_list_t *i, *j, *k;
alpm_list_t *vertices = NULL;
@@ -121,20 +108,19 @@ static alpm_list_t *_alpm_graph_init(alpm_list_t *targets)
/* Re-order a list of target packages with respect to their dependencies.
*
- * Example (PM_TRANS_TYPE_ADD):
+ * Example (reverse == 0):
* A depends on C
* B depends on A
* Target order is A,B,C,D
*
* Should be re-ordered to C,A,B,D
*
- * mode should be either PM_TRANS_TYPE_ADD or PM_TRANS_TYPE_REMOVE. This
- * affects the dependency order sortbydeps() will use.
+ * if reverse is > 0, the dependency order will be reversed.
*
* This function returns the new alpm_list_t* target list.
*
*/
-alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
+alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse)
{
alpm_list_t *newtargs = NULL;
alpm_list_t *vertices = NULL;
@@ -149,7 +135,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
_alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n");
- vertices = _alpm_graph_init(targets);
+ vertices = dep_graph_init(targets);
vptr = vertices;
vertex = vertices->data;
@@ -169,7 +155,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
pmpkg_t *vertexpkg = vertex->data;
pmpkg_t *childpkg = nextchild->data;
_alpm_log(PM_LOG_WARNING, _("dependency cycle detected:\n"));
- if(mode == PM_TRANS_TYPE_REMOVE) {
+ if(reverse) {
_alpm_log(PM_LOG_WARNING, _("%s will be removed after its %s dependency\n"), vertexpkg->name, childpkg->name);
} else {
_alpm_log(PM_LOG_WARNING, _("%s will be installed before its %s dependency\n"), vertexpkg->name, childpkg->name);
@@ -194,8 +180,8 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode)
_alpm_log(PM_LOG_DEBUG, "sorting dependencies finished\n");
- if(mode == PM_TRANS_TYPE_REMOVE) {
- /* we're removing packages, so reverse the order */
+ if(reverse) {
+ /* reverse the order */
alpm_list_t *tmptargs = alpm_list_reverse(newtargs);
/* free the old one */
alpm_list_free(newtargs);
@@ -217,6 +203,31 @@ static int satisfycmp(const void *pkg, const void *depend)
/** Checks dependencies and returns missing ones in a list.
* Dependencies can include versions with depmod operators.
* @param db pointer to the local package database
+ * @param targets an alpm_list_t* of dependencies strings to satisfy
+ * @return an alpm_list_t* of missing dependencies strings
+ */
+alpm_list_t SYMEXPORT *alpm_deptest(pmdb_t *db, alpm_list_t *targets)
+{
+ alpm_list_t *i, *ret = NULL;
+
+ for(i = targets; i; i = alpm_list_next(i)) {
+ pmdepend_t *dep;
+ char *target;
+
+ target = alpm_list_getdata(i);
+ dep = _alpm_splitdep(target);
+
+ if(!alpm_list_find(_alpm_db_get_pkgcache(db), dep, satisfycmp)) {
+ ret = alpm_list_add(ret, target);
+ }
+ _alpm_dep_free(dep);
+ }
+ return(ret);
+}
+
+/** Checks dependencies and returns missing ones in a list.
+ * Dependencies can include versions with depmod operators.
+ * @param db pointer to the local package database
* @param reversedeps handles the backward dependencies
* @param remove an alpm_list_t* of packages to be removed
* @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade)
@@ -264,8 +275,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
_alpm_log(PM_LOG_DEBUG, "checkdeps: missing dependency '%s' for package '%s'\n",
missdepstring, alpm_pkg_get_name(tp));
free(missdepstring);
- miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod,
- depend->name, depend->version);
+ miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend, "");
baddeps = alpm_list_add(baddeps, miss);
}
}
@@ -278,18 +288,18 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
pmpkg_t *lp = i->data;
for(j = alpm_pkg_get_depends(lp); j; j = j->next) {
pmdepend_t *depend = j->data;
+ pmpkg_t *causingpkg = alpm_list_find(modified, depend, satisfycmp);
/* we won't break this depend, if it is already broken, we ignore it */
/* 1. check upgrade list for satisfiers */
/* 2. check dblist for satisfiers */
- if(alpm_list_find(modified, depend, satisfycmp) &&
+ if(causingpkg &&
!alpm_list_find(upgrade, depend, satisfycmp) &&
!alpm_list_find(dblist, depend, satisfycmp)) {
char *missdepstring = alpm_dep_get_string(depend);
_alpm_log(PM_LOG_DEBUG, "checkdeps: transaction would break '%s' dependency of '%s'\n",
missdepstring, alpm_pkg_get_name(lp));
free(missdepstring);
- miss = _alpm_depmiss_new(lp->name, depend->mod,
- depend->name, depend->version);
+ miss = _alpm_depmiss_new(lp->name, depend, alpm_pkg_get_name(causingpkg));
baddeps = alpm_list_add(baddeps, miss);
}
}
@@ -356,7 +366,7 @@ int SYMEXPORT alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep)
return(satisfy);
}
-pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
+pmdepend_t *_alpm_splitdep(const char *depstring)
{
pmdepend_t *depend;
char *ptr = NULL;
@@ -365,9 +375,9 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
if(depstring == NULL) {
return(NULL);
}
- newstr = strdup(depstring);
+ STRDUP(newstr, depstring, RET_ERR(PM_ERR_MEMORY, NULL));
- MALLOC(depend, sizeof(pmdepend_t), return(NULL));
+ CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
/* Find a version comparator if one exists. If it does, set the type and
* increment the ptr accordingly so we can copy the right strings. */
@@ -391,25 +401,36 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
depend->mod = PM_DEP_MOD_GT;
*ptr = '\0';
ptr += 1;
-
} else {
- /* no version specified - copy in the name and return it */
+ /* no version specified - copy the name and return it */
depend->mod = PM_DEP_MOD_ANY;
- strncpy(depend->name, newstr, PKG_NAME_LEN);
- depend->version[0] = '\0';
+ STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL));
+ depend->version = NULL;
free(newstr);
return(depend);
}
/* if we get here, we have a version comparator, copy the right parts
* to the right places */
- strncpy(depend->name, newstr, PKG_NAME_LEN);
- strncpy(depend->version, ptr, PKG_VERSION_LEN);
+ STRDUP(depend->name, newstr, RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(depend->version, ptr, RET_ERR(PM_ERR_MEMORY, NULL));
free(newstr);
return(depend);
}
+pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep)
+{
+ pmdepend_t *newdep;
+ CALLOC(newdep, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL));
+
+ STRDUP(newdep->name, dep->name, RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL));
+ newdep->mod = dep->mod;
+
+ return(newdep);
+}
+
/* These parameters are messy. We check if this package, given a list of
* targets and a db is safe to remove. We do NOT remove it if it is in the
* target list, or if if the package was explictly installed and
@@ -523,7 +544,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
for(i = deps; i; i = i->next) {
int found = 0;
pmdepmissing_t *miss = i->data;
- pmdepend_t *missdep = &(miss->depend);
+ pmdepend_t *missdep = alpm_miss_get_dep(miss);
pmpkg_t *sync = NULL;
/* check if one of the packages in *list already satisfies this dependency */
@@ -548,7 +569,8 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
if(!sync) {
continue;
}
- found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove);
+ found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove)
+ && !_alpm_pkg_find(alpm_pkg_get_name(sync), *list);
if(!found) {
continue;
}
@@ -570,7 +592,8 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
continue;
}
found = alpm_depcmp(sync, missdep) && strcmp(sync->name, missdep->name)
- && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove);
+ && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove)
+ && !_alpm_pkg_find(alpm_pkg_get_name(sync), *list);
if(!found) {
continue;
}
@@ -611,7 +634,8 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
- FREELIST(deps);
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(deps);
return(0);
@@ -627,7 +651,17 @@ const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss)
/* Sanity checks */
ASSERT(miss != NULL, return(NULL));
- return miss->target;
+ return(miss->target);
+}
+
+const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss)
+{
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(miss != NULL, return(NULL));
+
+ return miss->causingpkg;
}
pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss)
@@ -637,7 +671,7 @@ pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss)
/* Sanity checks */
ASSERT(miss != NULL, return(NULL));
- return &(miss->depend);
+ return(miss->depend);
}
pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep)
@@ -647,7 +681,7 @@ pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep)
/* Sanity checks */
ASSERT(dep != NULL, return(-1));
- return dep->mod;
+ return(dep->mod);
}
const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep)
@@ -657,7 +691,7 @@ const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep)
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
- return dep->name;
+ return(dep->name);
}
const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
@@ -667,7 +701,7 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
- return dep->version;
+ return(dep->version);
}
/** Reverse of splitdep; make a dep string from a pmdepend_t struct.
@@ -677,7 +711,7 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep)
*/
char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep)
{
- char *opr, *str = NULL;
+ char *name, *opr, *ver, *str = NULL;
size_t len;
ALPM_LOG_FUNC;
@@ -685,6 +719,12 @@ char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep)
/* Sanity checks */
ASSERT(dep != NULL, return(NULL));
+ if(dep->name) {
+ name = dep->name;
+ } else {
+ name = "";
+ }
+
switch(dep->mod) {
case PM_DEP_MOD_ANY:
opr = "";
@@ -709,11 +749,18 @@ char SYMEXPORT *alpm_dep_get_string(const pmdepend_t *dep)
break;
}
+ if(dep->version) {
+ ver = dep->version;
+ } else {
+ ver = "";
+ }
+
/* we can always compute len and print the string like this because opr
- * and ver will be empty when PM_DEP_MOD_ANY is the depend type */
- len = strlen(dep->name) + strlen(opr) + strlen(dep->version) + 1;
+ * and ver will be empty when PM_DEP_MOD_ANY is the depend type. the
+ * reassignments above also ensure we do not do a strlen(NULL). */
+ len = strlen(name) + strlen(opr) + strlen(ver) + 1;
MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL));
- snprintf(str, len, "%s%s%s", dep->name, opr, dep->version);
+ snprintf(str, len, "%s%s%s", name, opr, ver);
return(str);
}
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 75cbb5bc..fe851288 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -29,31 +29,28 @@
/* Dependency */
struct __pmdepend_t {
pmdepmod_t mod;
- char name[PKG_NAME_LEN];
- char version[PKG_VERSION_LEN];
+ char *name;
+ char *version;
};
/* Missing dependency */
struct __pmdepmissing_t {
- char target[PKG_NAME_LEN];
- pmdepend_t depend;
+ char *target;
+ pmdepend_t *depend;
+ char *causingpkg; /* this is used in case of remove dependency error only */
};
-/* Graphs */
-struct __pmgraph_t {
- int state; /* 0: untouched, -1: entered, other: leaving time */
- void *data;
- struct __pmgraph_t *parent; /* where did we come from? */
- alpm_list_t *children;
- alpm_list_t *childptr; /* points to a child in children list */
-};
-
-pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod,
- const char *depname, const char *depversion);
-alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode);
+void _alpm_dep_free(pmdepend_t *dep);
+pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep);
+pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep,
+ const char *causinpkg);
+void _alpm_depmiss_free(pmdepmissing_t *miss);
+alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse);
void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit);
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
- alpm_list_t **list, alpm_list_t *remove, pmtrans_t *trans, alpm_list_t **data);
+ alpm_list_t **list, alpm_list_t *remove, pmtrans_t *trans, alpm_list_t
+ **data);
+pmdepend_t *_alpm_splitdep(const char *depstring);
#endif /* _ALPM_DEPS_H */
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
new file mode 100644
index 00000000..0977eea0
--- /dev/null
+++ b/lib/libalpm/dload.c
@@ -0,0 +1,446 @@
+/*
+ * download.c
+ *
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#if defined(INTERNAL_DOWNLOAD)
+#include <download.h> /* libdownload */
+#endif
+
+/* libalpm */
+#include "dload.h"
+#include "alpm_list.h"
+#include "alpm.h"
+#include "log.h"
+#include "util.h"
+#include "handle.h"
+
+static char *get_filename(const char *url) {
+ char *filename = strrchr(url, '/');
+ if(filename != NULL) {
+ filename++;
+ }
+ return(filename);
+}
+
+static char *get_destfile(const char *path, const char *filename) {
+ char *destfile;
+ /* len = localpath len + filename len + null */
+ int len = strlen(path) + strlen(filename) + 1;
+ CALLOC(destfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
+ snprintf(destfile, len, "%s%s", path, filename);
+
+ return(destfile);
+}
+
+static char *get_tempfile(const char *path, const char *filename) {
+ char *tempfile;
+ /* len = localpath len + filename len + '.part' len + null */
+ int len = strlen(path) + strlen(filename) + 6;
+ CALLOC(tempfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
+ snprintf(tempfile, len, "%s%s.part", path, filename);
+
+ return(tempfile);
+}
+
+#if defined(INTERNAL_DOWNLOAD)
+/* Build a 'struct url' from an url. */
+static struct url *url_for_string(const char *url)
+{
+ struct url *ret = NULL;
+ ret = downloadParseURL(url);
+ if(!ret) {
+ _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url);
+ RET_ERR(PM_ERR_SERVER_BAD_URL, NULL);
+ }
+
+ /* if no URL scheme specified, assume HTTP */
+ if(strlen(ret->scheme) == 0) {
+ _alpm_log(PM_LOG_WARNING, _("url scheme not specified, assuming HTTP\n"));
+ strcpy(ret->scheme, SCHEME_HTTP);
+ }
+ /* add a user & password for anonymous FTP */
+ if(strcmp(ret->scheme,SCHEME_FTP) == 0 && strlen(ret->user) == 0) {
+ strcpy(ret->user, "anonymous");
+ strcpy(ret->pwd, "libalpm@guest");
+ }
+
+ return(ret);
+}
+
+static int download_internal(const char *url, const char *localpath,
+ time_t mtimeold, time_t *mtimenew) {
+ FILE *dlf, *localf = NULL;
+ struct url_stat ust;
+ struct stat st;
+ int chk_resume = 0;
+ int dl_thisfile = 0;
+ char *tempfile, *destfile, *filename;
+ int ret = 0;
+ struct url *fileurl = url_for_string(url);
+
+ if(!fileurl) {
+ return(-1);
+ }
+
+ filename = get_filename(url);
+ if(!filename) {
+ return(-1);
+ }
+ destfile = get_destfile(localpath, filename);
+ tempfile = get_tempfile(localpath, filename);
+
+ /* pass the raw filename for passing to the callback function */
+ _alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", filename);
+
+ if(stat(tempfile, &st) == 0 && st.st_size > 0) {
+ _alpm_log(PM_LOG_DEBUG, "existing file found, using it\n");
+ fileurl->offset = (off_t)st.st_size;
+ dl_thisfile = st.st_size;
+ localf = fopen(tempfile, "ab");
+ chk_resume = 1;
+ } else {
+ fileurl->offset = (off_t)0;
+ dl_thisfile = 0;
+ }
+
+ /* libdownload does not reset the error code, reset it in
+ * the case of previous errors */
+ downloadLastErrCode = 0;
+
+ /* 10s timeout - TODO make a config option */
+ downloadTimeout = 10000;
+
+ dlf = downloadXGet(fileurl, &ust, (handle->nopassiveftp ? "" : "p"));
+
+ if(downloadLastErrCode != 0 || dlf == NULL) {
+ const char *host = _("disk");
+ if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
+ host = fileurl->host;
+ }
+ pm_errno = PM_ERR_LIBDOWNLOAD;
+ _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
+ filename, host, downloadLastErrString);
+ ret = -1;
+ goto cleanup;
+ } else {
+ _alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host);
+ }
+
+ if(ust.mtime && mtimeold && ust.mtime == mtimeold) {
+ _alpm_log(PM_LOG_DEBUG, "mtimes are identical, skipping %s\n", filename);
+ ret = 1;
+ goto cleanup;
+ }
+
+ if(ust.mtime && mtimenew) {
+ *mtimenew = ust.mtime;
+ }
+
+ if(chk_resume && fileurl->offset == 0) {
+ _alpm_log(PM_LOG_WARNING, _("cannot resume download, starting over\n"));
+ if(localf != NULL) {
+ fclose(localf);
+ localf = NULL;
+ }
+ }
+
+ if(localf == NULL) {
+ _alpm_rmrf(tempfile);
+ fileurl->offset = (off_t)0;
+ dl_thisfile = 0;
+ localf = fopen(tempfile, "wb");
+ if(localf == NULL) { /* still null? */
+ _alpm_log(PM_LOG_ERROR, _("cannot write to file '%s'\n"), tempfile);
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ /* Progress 0 - initialize */
+ if(handle->dlcb) {
+ handle->dlcb(filename, 0, ust.size);
+ }
+
+ int nread = 0;
+ char buffer[PM_DLBUF_LEN];
+ while((nread = fread(buffer, 1, PM_DLBUF_LEN, dlf)) > 0) {
+ if(ferror(dlf)) {
+ pm_errno = PM_ERR_LIBDOWNLOAD;
+ _alpm_log(PM_LOG_ERROR, _("error downloading '%s': %s\n"),
+ filename, downloadLastErrString);
+ ret = -1;
+ goto cleanup;
+ }
+
+ int nwritten = 0;
+ while(nwritten < nread) {
+ nwritten += fwrite(buffer, 1, (nread - nwritten), localf);
+ if(ferror(localf)) {
+ _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"),
+ destfile, strerror(errno));
+ ret = -1;
+ goto cleanup;
+ }
+ }
+ dl_thisfile += nread;
+
+ if(handle->dlcb) {
+ handle->dlcb(filename, dl_thisfile, ust.size);
+ }
+ }
+ /* probably safer to close the file descriptors now before renaming the file,
+ * for example to make sure the buffers are flushed.
+ */
+ fclose(localf);
+ localf = NULL;
+ fclose(dlf);
+ dlf = NULL;
+
+ rename(tempfile, destfile);
+ ret = 0;
+
+cleanup:
+ FREE(tempfile);
+ FREE(destfile);
+ if(localf != NULL) {
+ fclose(localf);
+ }
+ if(dlf != NULL) {
+ fclose(dlf);
+ }
+ downloadFreeURL(fileurl);
+ return(ret);
+}
+#endif
+
+static int download_external(const char *url, const char *localpath,
+ time_t mtimeold, time_t *mtimenew) {
+ int ret = 0;
+ int retval;
+ int usepart = 0;
+ char *ptr1, *ptr2;
+ char origCmd[PATH_MAX];
+ char parsedCmd[PATH_MAX] = "";
+ char cwd[PATH_MAX];
+ char *destfile, *tempfile, *filename;
+
+ if(!handle->xfercommand) {
+ RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
+ }
+
+ filename = get_filename(url);
+ if(!filename) {
+ RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
+ }
+ destfile = get_destfile(localpath, filename);
+ tempfile = get_tempfile(localpath, filename);
+
+ /* replace all occurrences of %o with fn.part */
+ strncpy(origCmd, handle->xfercommand, sizeof(origCmd));
+ ptr1 = origCmd;
+ while((ptr2 = strstr(ptr1, "%o"))) {
+ usepart = 1;
+ ptr2[0] = '\0';
+ strcat(parsedCmd, ptr1);
+ strcat(parsedCmd, tempfile);
+ ptr1 = ptr2 + 2;
+ }
+ strcat(parsedCmd, ptr1);
+ /* replace all occurrences of %u with the download URL */
+ strncpy(origCmd, parsedCmd, sizeof(origCmd));
+ parsedCmd[0] = '\0';
+ ptr1 = origCmd;
+ while((ptr2 = strstr(ptr1, "%u"))) {
+ ptr2[0] = '\0';
+ strcat(parsedCmd, ptr1);
+ strcat(parsedCmd, url);
+ ptr1 = ptr2 + 2;
+ }
+ strcat(parsedCmd, ptr1);
+ /* cwd to the download directory */
+ getcwd(cwd, PATH_MAX);
+ if(chdir(localpath)) {
+ _alpm_log(PM_LOG_WARNING, _("could not chdir to %s\n"), localpath);
+ pm_errno = PM_ERR_EXTERNAL_DOWNLOAD;
+ ret = -1;
+ goto cleanup;
+ }
+ /* execute the parsed command via /bin/sh -c */
+ _alpm_log(PM_LOG_DEBUG, "running command: %s\n", parsedCmd);
+ retval = system(parsedCmd);
+
+ if(retval == -1) {
+ _alpm_log(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
+ pm_errno = PM_ERR_EXTERNAL_DOWNLOAD;
+ ret = -1;
+ } else if(retval != 0) {
+ /* download failed */
+ _alpm_log(PM_LOG_DEBUG, "XferCommand command returned non-zero status "
+ "code (%d)\n", retval);
+ ret = -1;
+ } else {
+ /* download was successful */
+ if(usepart) {
+ rename(tempfile, destfile);
+ }
+ ret = 0;
+ }
+
+cleanup:
+ chdir(cwd);
+ if(ret == -1) {
+ /* hack to let an user the time to cancel a download */
+ sleep(2);
+ }
+ FREE(destfile);
+ FREE(tempfile);
+
+ return(ret);
+}
+
+static int download(const char *url, const char *localpath,
+ time_t mtimeold, time_t *mtimenew) {
+ int ret;
+ const char *proto = "file://";
+ int len = strlen(proto);
+ if(strncmp(url, proto, len) == 0) {
+ /* we can simply grab an absolute path from the file:// url by starting
+ * our path at the char following the proto (the root '/')
+ */
+ const char *sourcefile = url + len;
+ const char *filename = get_filename(url);
+ char *destfile = get_destfile(localpath, filename);
+
+ ret = _alpm_copyfile(sourcefile, destfile);
+ FREE(destfile);
+ /* copyfile returns 1 on failure, we want to return -1 on failure */
+ return(ret ? -1 : 0);
+ }
+
+ /* We have a few things to take into account here.
+ * 1. If we have both internal/external available, choose based on
+ * whether xfercommand is populated.
+ * 2. If we only have external available, we should first check
+ * if a command was provided before we drop into download_external.
+ */
+ if(handle->xfercommand == NULL) {
+#if defined(INTERNAL_DOWNLOAD)
+ ret = download_internal(url, localpath, mtimeold, mtimenew);
+#else
+ RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1);
+#endif
+ } else {
+ ret = download_external(url, localpath, mtimeold, mtimenew);
+ }
+ return(ret);
+}
+
+/*
+ * Download a single file
+ * - if mtimeold is non-NULL, then only download the file if it's different
+ * than mtimeold.
+ * - if *mtimenew is non-NULL, it will be filled with the mtime of the remote
+ * file.
+ *
+ * RETURN: 0 for successful download
+ * 1 if the mtimes are identical
+ * -1 on error
+ */
+int _alpm_download_single_file(const char *filename,
+ alpm_list_t *servers, const char *localpath,
+ time_t mtimeold, time_t *mtimenew)
+{
+ alpm_list_t *i;
+ int ret = -1;
+
+ for(i = servers; i; i = i->next) {
+ const char *server = i->data;
+ char *fileurl = NULL;
+ int len;
+
+ /* print server + filename into a buffer */
+ len = strlen(server) + strlen(filename) + 2;
+ CALLOC(fileurl, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, -1));
+ snprintf(fileurl, len, "%s/%s", server, filename);
+
+ ret = download(fileurl, localpath, mtimeold, mtimenew);
+ FREE(fileurl);
+ if(ret != -1) {
+ break;
+ }
+ }
+
+ return(ret);
+}
+
+int _alpm_download_files(alpm_list_t *files,
+ alpm_list_t *servers, const char *localpath)
+{
+ int ret = 0;
+ alpm_list_t *lp;
+
+ for(lp = files; lp; lp = lp->next) {
+ char *filename = lp->data;
+ if(_alpm_download_single_file(filename, servers,
+ localpath, 0, NULL) == -1) {
+ ret++;
+ }
+ }
+
+ return(ret);
+}
+
+/** Fetch a remote pkg.
+ * @param url URL of the package to download
+ * @return the downloaded filepath on success, NULL on error
+ * @addtogroup alpm_misc
+ */
+char SYMEXPORT *alpm_fetch_pkgurl(const char *url)
+{
+ char *filename, *filepath;
+ const char *cachedir;
+ int ret;
+
+ ALPM_LOG_FUNC;
+
+ filename = get_filename(url);
+
+ /* find a valid cache dir to download to */
+ cachedir = _alpm_filecache_setup();
+
+ /* download the file */
+ ret = download(url, cachedir, 0, NULL);
+ if(ret == -1) {
+ _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url);
+ return(NULL);
+ }
+ _alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", url);
+
+ /* we should be able to find the file the second time around */
+ filepath = _alpm_filecache_find(filename);
+ return(filepath);
+}
+
+/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/error.h b/lib/libalpm/dload.h
index e417195f..eb642522 100644
--- a/lib/libalpm/error.h
+++ b/lib/libalpm/dload.h
@@ -1,7 +1,7 @@
/*
- * error.h
+ * dload.h
*
- * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,13 +16,23 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _ALPM_ERROR_H
-#define _ALPM_ERROR_H
+#ifndef _ALPM_DLOAD_H
+#define _ALPM_DLOAD_H
-#define RET_ERR(err, ret) do { pm_errno = (err); \
- _alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \
- return(ret); } while(0)
+#include "alpm_list.h"
+#include "alpm.h"
-#endif /* _ALPM_ERROR_H */
+#include <time.h>
+
+#define PM_DLBUF_LEN (1024 * 10)
+
+int _alpm_download_single_file(const char *filename,
+ alpm_list_t *servers, const char *localpath,
+ time_t mtimeold, time_t *mtimenew);
+
+int _alpm_download_files(alpm_list_t *files,
+ alpm_list_t *servers, const char *localpath);
+
+#endif /* _ALPM_DLOAD_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c
index a68340ad..30e9cf86 100644
--- a/lib/libalpm/error.c
+++ b/lib/libalpm/error.c
@@ -1,10 +1,7 @@
/*
* error.c
*
- * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
- * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
- * Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
- * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,12 +19,14 @@
#include "config.h"
+#if defined(INTERNAL_DOWNLOAD)
+#include <download.h> /* downloadLastErrString */
+#endif
+
/* libalpm */
-#include "error.h"
#include "util.h"
#include "alpm.h"
-/* TODO does this really need a file all on its own? */
const char SYMEXPORT *alpm_strerrorlast(void)
{
return alpm_strerror(pm_errno);
@@ -74,13 +73,6 @@ const char SYMEXPORT *alpm_strerror(int err)
/* Servers */
case PM_ERR_SERVER_BAD_URL:
return _("invalid url for server");
- /* Configuration */
- case PM_ERR_OPT_LOGFILE:
- case PM_ERR_OPT_DBPATH:
- case PM_ERR_OPT_LOCALDB:
- case PM_ERR_OPT_SYNCDB:
- case PM_ERR_OPT_USESYSLOG:
- return _("could not set parameter");
/* Transactions */
case PM_ERR_TRANS_NOT_NULL:
return _("transaction already initialized");
@@ -109,21 +101,17 @@ const char SYMEXPORT *alpm_strerror(int err)
return _("cannot open package file");
case PM_ERR_PKG_LOAD:
return _("cannot load package data");
- case PM_ERR_PKG_INSTALLED:
- return _("package already installed");
case PM_ERR_PKG_CANT_FRESH:
return _("package not installed or lesser version");
case PM_ERR_PKG_CANT_REMOVE:
return _("cannot remove all files for package");
case PM_ERR_PKG_INVALID_NAME:
return _("package name is not valid");
- case PM_ERR_PKG_CORRUPTED:
- return _("corrupted package");
case PM_ERR_PKG_REPO_NOT_FOUND:
return _("no such repository");
/* Deltas */
- case PM_ERR_DLT_CORRUPTED:
- return _("corrupted delta");
+ case PM_ERR_DLT_INVALID:
+ return _("invalid or corrupted delta");
case PM_ERR_DLT_PATCHFAILED:
return _("delta patch failed");
/* Groups */
@@ -141,16 +129,26 @@ const char SYMEXPORT *alpm_strerror(int err)
return _("user aborted the operation");
case PM_ERR_INTERNAL_ERROR:
return _("internal error");
- case PM_ERR_LIBARCHIVE_ERROR:
- return _("libarchive error");
case PM_ERR_PKG_HOLD:
/* TODO wow this is not descriptive at all... what does this mean? */
return _("not confirmed");
case PM_ERR_INVALID_REGEX:
return _("invalid regular expression");
- /* Downloading */
- case PM_ERR_CONNECT_FAILED:
- return _("connection to remote host failed");
+ /* Errors from external libraries- our own wrapper error */
+ case PM_ERR_LIBARCHIVE:
+ /* it would be nice to use archive_error_string() here, but that
+ * requires the archive struct, so we can't. Just use a generic
+ * error string instead. */
+ return _("libarchive error");
+ case PM_ERR_LIBDOWNLOAD:
+#if defined(INTERNAL_DOWNLOAD)
+ return downloadLastErrString;
+#else
+ /* obviously shouldn't get here... */
+ return _("libdownload error");
+#endif
+ case PM_ERR_EXTERNAL_DOWNLOAD:
+ return _("error invoking external downloader");
/* Unknown error! */
default:
return _("unexpected error");
diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h
new file mode 100644
index 00000000..e3e40023
--- /dev/null
+++ b/lib/libalpm/graph.h
@@ -0,0 +1,55 @@
+/*
+ * graph.h - helpful graph structure and setup/teardown methods
+ *
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "alpm_list.h"
+#include "util.h" /* MALLOC() */
+#include "alpm.h"
+
+struct __pmgraph_t {
+ char state; /* 0: untouched, -1: entered, other: leaving time */
+ void *data;
+ struct __pmgraph_t *parent; /* where did we come from? */
+ alpm_list_t *children;
+ alpm_list_t *childptr; /* points to a child in children list */
+};
+typedef struct __pmgraph_t pmgraph_t;
+
+static pmgraph_t *_alpm_graph_new(void)
+{
+ pmgraph_t *graph = NULL;
+
+ MALLOC(graph, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL));
+
+ if(graph) {
+ graph->state = 0;
+ graph->data = NULL;
+ graph->parent = NULL;
+ graph->children = NULL;
+ graph->childptr = NULL;
+ }
+ return(graph);
+}
+
+static void _alpm_graph_free(void *data)
+{
+ pmgraph_t *graph = data;
+ alpm_list_free(graph->children);
+ free(graph);
+}
+
diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c
index 050bcbd5..1cc379c6 100644
--- a/lib/libalpm/group.c
+++ b/lib/libalpm/group.c
@@ -27,17 +27,17 @@
#include "group.h"
#include "alpm_list.h"
#include "util.h"
-#include "error.h"
#include "log.h"
#include "alpm.h"
-pmgrp_t *_alpm_grp_new()
+pmgrp_t *_alpm_grp_new(const char *name)
{
pmgrp_t* grp;
ALPM_LOG_FUNC;
CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL));
+ STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL));
return(grp);
}
@@ -50,7 +50,9 @@ void _alpm_grp_free(pmgrp_t *grp)
return;
}
- FREELIST(grp->packages);
+ FREE(grp->name);
+ /* do NOT free the contents of the list, just the nodes */
+ alpm_list_free(grp->packages);
FREE(grp);
}
@@ -74,7 +76,7 @@ const char SYMEXPORT *alpm_grp_get_name(const pmgrp_t *grp)
return grp->name;
}
-const alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp)
+alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp)
{
ALPM_LOG_FUNC;
diff --git a/lib/libalpm/group.h b/lib/libalpm/group.h
index 88fc8b32..5f8fdec4 100644
--- a/lib/libalpm/group.h
+++ b/lib/libalpm/group.h
@@ -19,17 +19,16 @@
#ifndef _ALPM_GROUP_H
#define _ALPM_GROUP_H
-/* Groups */
-#define GRP_NAME_LEN 256
-
#include "alpm.h"
struct __pmgrp_t {
- char name[GRP_NAME_LEN];
- alpm_list_t *packages; /* List of strings */
+ /** group name */
+ char *name;
+ /** list of pmpkg_t packages */
+ alpm_list_t *packages;
};
-pmgrp_t *_alpm_grp_new(void);
+pmgrp_t *_alpm_grp_new(const char *name);
void _alpm_grp_free(pmgrp_t *grp);
int _alpm_grp_cmp(const void *g1, const void *g2);
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 36822285..247ef71d 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -36,10 +36,8 @@
#include "alpm_list.h"
#include "util.h"
#include "log.h"
-#include "error.h"
#include "trans.h"
#include "alpm.h"
-#include "server.h"
/* global var for handle (private to libalpm) */
pmhandle_t *handle = NULL;
diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c
index 4445f935..3ba5042c 100644
--- a/lib/libalpm/log.c
+++ b/lib/libalpm/log.c
@@ -30,7 +30,6 @@
#include "log.h"
#include "handle.h"
#include "util.h"
-#include "error.h"
#include "alpm.h"
/** \addtogroup alpm_log Logging Functions
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 287c2ce4..3277dd09 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -42,7 +42,6 @@
#include "alpm_list.h"
#include "log.h"
#include "util.h"
-#include "error.h"
#include "db.h"
#include "cache.h"
#include "delta.h"
@@ -105,8 +104,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{
char *fpath;
- char *md5sum = NULL;
- int retval = 0;
+ int retval;
ALPM_LOG_FUNC;
@@ -116,28 +114,16 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
ASSERT(pkg->origin_data.db != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
- md5sum = alpm_get_md5sum(fpath);
- if(md5sum == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not get md5sum for package %s-%s\n"),
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- pm_errno = PM_ERR_NOT_A_FILE;
+ retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg));
+
+ if(retval == 0) {
+ return(0);
+ } else if (retval == 1) {
+ pm_errno = PM_ERR_PKG_INVALID;
retval = -1;
- } else {
- if(strcmp(md5sum, alpm_pkg_get_md5sum(pkg)) == 0) {
- _alpm_log(PM_LOG_DEBUG, "md5sums for package %s-%s match\n",
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- } else {
- _alpm_log(PM_LOG_ERROR, _("md5sums do not match for package %s-%s\n"),
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- pm_errno = PM_ERR_PKG_INVALID;
- retval = -1;
- }
}
- FREE(fpath);
- FREE(md5sum);
-
return(retval);
}
@@ -166,15 +152,17 @@ const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
}
- if(!strlen(pkg->filename)) {
+ if(pkg->filename == NULL || strlen(pkg->filename) == 0) {
/* construct the file name, it's not in the desc file */
+ char buffer[PATH_MAX];
if(pkg->arch && strlen(pkg->arch) > 0) {
- snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s-%s" PKGEXT,
+ snprintf(buffer, PATH_MAX, "%s-%s-%s" PKGEXT,
pkg->name, pkg->version, pkg->arch);
} else {
- snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s" PKGEXT,
+ snprintf(buffer, PATH_MAX, "%s-%s" PKGEXT,
pkg->name, pkg->version);
}
+ STRDUP(pkg->filename, buffer, RET_ERR(PM_ERR_MEMORY, NULL));
}
return pkg->filename;
@@ -520,7 +508,7 @@ void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
int ret = ARCHIVE_OK;
if((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+ RET_ERR(PM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
@@ -756,15 +744,12 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
- if(name && name[0] != 0) {
- strncpy(pkg->name, name, PKG_NAME_LEN);
- } else {
- pkg->name[0] = '\0';
+ if(name) {
+ STRDUP(pkg->name, name, RET_ERR(PM_ERR_MEMORY, pkg));
}
- if(version && version[0] != 0) {
- strncpy(pkg->version, version, PKG_VERSION_LEN);
- } else {
- pkg->version[0] = '\0';
+
+ if(version) {
+ STRDUP(pkg->version, version, RET_ERR(PM_ERR_MEMORY, pkg));
}
return(pkg);
@@ -772,31 +757,51 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
{
- pmpkg_t* newpkg;
+ pmpkg_t *newpkg;
+ alpm_list_t *i;
ALPM_LOG_FUNC;
CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
- memcpy(newpkg, pkg, sizeof(pmpkg_t));
+ STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->desc, pkg->desc, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->url, pkg->url, RET_ERR(PM_ERR_MEMORY, newpkg));
+ newpkg->builddate = pkg->builddate;
+ newpkg->installdate = pkg->installdate;
+ STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg));
+ newpkg->size = pkg->size;
+ newpkg->isize = pkg->isize;
+ newpkg->scriptlet = pkg->scriptlet;
+ newpkg->force = pkg->force;
+ newpkg->reason = pkg->reason;
+
newpkg->licenses = alpm_list_strdup(alpm_pkg_get_licenses(pkg));
- newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
+ newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
+ newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
newpkg->files = alpm_list_strdup(alpm_pkg_get_files(pkg));
newpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(pkg));
- newpkg->depends = alpm_list_copy_data(alpm_pkg_get_depends(pkg),
- sizeof(pmdepend_t));
+ for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
+ newpkg->depends = alpm_list_add(newpkg->depends, _alpm_dep_dup(i->data));
+ }
newpkg->optdepends = alpm_list_strdup(alpm_pkg_get_optdepends(pkg));
- newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
+ newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
newpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(pkg));
- newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
newpkg->deltas = alpm_list_copy_data(alpm_pkg_get_deltas(pkg),
- sizeof(pmdelta_t));
+ sizeof(pmdelta_t));
+
/* internal */
+ newpkg->origin = pkg->origin;
if(newpkg->origin == PKG_FROM_FILE) {
newpkg->origin_data.file = strdup(pkg->origin_data.file);
} else {
newpkg->origin_data.db = pkg->origin_data.db;
}
+ newpkg->infolevel = pkg->infolevel;
return(newpkg);
}
@@ -809,16 +814,27 @@ void _alpm_pkg_free(pmpkg_t *pkg)
return;
}
+ FREE(pkg->filename);
+ FREE(pkg->name);
+ FREE(pkg->version);
+ FREE(pkg->desc);
+ FREE(pkg->url);
+ FREE(pkg->packager);
+ FREE(pkg->md5sum);
+ FREE(pkg->arch);
FREELIST(pkg->licenses);
+ FREELIST(pkg->replaces);
+ FREELIST(pkg->groups);
FREELIST(pkg->files);
FREELIST(pkg->backup);
- FREELIST(pkg->depends);
+ alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
+ alpm_list_free(pkg->depends);
FREELIST(pkg->optdepends);
FREELIST(pkg->conflicts);
- FREELIST(pkg->groups);
FREELIST(pkg->provides);
- FREELIST(pkg->replaces);
- FREELIST(pkg->deltas);
+ alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
+ alpm_list_free(pkg->deltas);
+
if(pkg->origin == PKG_FROM_FILE) {
FREE(pkg->origin_data.file);
}
@@ -866,15 +882,18 @@ int _alpm_pkg_cmp(const void *p1, const void *p2)
return(strcmp(alpm_pkg_get_name(pk1), alpm_pkg_get_name(pk2)));
}
-/* Parses the package description file for the current package
- * TODO: this should ALL be in a backend interface (be_files), we should
- * be dealing with the abstracted concepts only in this file
+int _alpm_pkgname_pkg_cmp(const void *pkgname, const void *package)
+{
+ return(strcmp(alpm_pkg_get_name((pmpkg_t *) package), (char *) pkgname));
+}
+
+
+/* Parses the package description file for the current package. This
+ * is handed the struct archive when the .PKGINFO file is open.
* Returns: 0 on success, 1 on error
- *
*/
-static int parse_descfile(const char *descfile, pmpkg_t *info)
+static int parse_descfile(struct archive *a, pmpkg_t *info)
{
- FILE* fp = NULL;
char line[PATH_MAX];
char *ptr = NULL;
char *key = NULL;
@@ -882,13 +901,8 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
ALPM_LOG_FUNC;
- if((fp = fopen(descfile, "r")) == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), descfile, strerror(errno));
- return(-1);
- }
-
- while(!feof(fp)) {
- fgets(line, PATH_MAX, fp);
+ /* loop until we reach EOF (where archive_fgets will return NULL) */
+ while(_alpm_archive_fgets(line, PATH_MAX, a) != NULL) {
linenum++;
_alpm_strtrim(line);
if(strlen(line) == 0 || line[0] == '#') {
@@ -898,26 +912,26 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
key = strsep(&ptr, "=");
if(key == NULL || ptr == NULL) {
_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
- info->name[0] != '\0' ? info->name : "error", linenum);
+ info->name ? info->name : "error", linenum);
} else {
- _alpm_strtrim(key);
- _alpm_strtrim(ptr);
+ key = _alpm_strtrim(key);
+ ptr = _alpm_strtrim(ptr);
if(!strcmp(key, "pkgname")) {
- strncpy(info->name, ptr, sizeof(info->name));
+ STRDUP(info->name, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "pkgver")) {
- strncpy(info->version, ptr, sizeof(info->version));
+ STRDUP(info->version, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "pkgdesc")) {
- strncpy(info->desc, ptr, sizeof(info->desc));
+ STRDUP(info->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "group")) {
info->groups = alpm_list_add(info->groups, strdup(ptr));
} else if(!strcmp(key, "url")) {
- strncpy(info->url, ptr, sizeof(info->url));
+ STRDUP(info->url, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "license")) {
info->licenses = alpm_list_add(info->licenses, strdup(ptr));
} else if(!strcmp(key, "builddate")) {
char first = tolower(ptr[0]);
if(first > 'a' && first < 'z') {
- struct tm tmp_tm = {0}; //initialize to null incase of failure
+ struct tm tmp_tm = {0}; //initialize to null in case of failure
setlocale(LC_TIME, "C");
strptime(ptr, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->builddate = mktime(&tmp_tm);
@@ -926,14 +940,14 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
info->builddate = atol(ptr);
}
} else if(!strcmp(key, "packager")) {
- strncpy(info->packager, ptr, sizeof(info->packager));
+ STRDUP(info->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "arch")) {
- strncpy(info->arch, ptr, sizeof(info->arch));
+ STRDUP(info->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "size")) {
/* size in the raw package is uncompressed (installed) size */
info->isize = atol(ptr);
} else if(!strcmp(key, "depend")) {
- pmdepend_t *dep = alpm_splitdep(ptr);
+ pmdepend_t *dep = _alpm_splitdep(ptr);
info->depends = alpm_list_add(info->depends, dep);
} else if(!strcmp(key, "optdepend")) {
info->optdepends = alpm_list_add(info->optdepends, strdup(ptr));
@@ -947,13 +961,11 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
info->backup = alpm_list_add(info->backup, strdup(ptr));
} else {
_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
- info->name[0] != '\0' ? info->name : "error", linenum);
+ info->name ? info->name : "error", linenum);
}
}
line[0] = '\0';
}
- fclose(fp);
- unlink(descfile);
return(0);
}
@@ -973,8 +985,6 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
struct archive *archive;
struct archive_entry *entry;
pmpkg_t *info = NULL;
- char *descfile = NULL;
- int fd = -1;
struct stat st;
ALPM_LOG_FUNC;
@@ -984,7 +994,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
}
if((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+ RET_ERR(PM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
@@ -1005,48 +1015,28 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
info->size = st.st_size;
}
- /* TODO there is no reason to make temp files to read
- * from a libarchive archive, it can be done by reading
- * directly from the archive
- * See: archive_read_data_into_buffer
- * requires changes 'parse_descfile' as well
- * */
-
/* If full is false, only read through the archive until we find our needed
* metadata. If it is true, read through the entire archive, which serves
* as a verfication of integrity and allows us to create the filelist. */
while((ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
const char *entry_name = archive_entry_pathname(entry);
- /* NOTE: we used to look for .FILELIST, but it is easier (and safer) for
- * us to just generate this on our own. */
if(strcmp(entry_name, ".PKGINFO") == 0) {
- /* extract this file into /tmp. it has info for us */
- descfile = strdup("/tmp/alpm_XXXXXX");
- fd = mkstemp(descfile);
- if(archive_read_data_into_fd(archive, fd) != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("error extracting package description file to %s\n"),
- descfile);
- goto pkg_invalid;
- }
/* parse the info file */
- if(parse_descfile(descfile, info) == -1) {
+ if(parse_descfile(archive, info) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not parse package description file in %s\n"),
pkgfile);
goto pkg_invalid;
}
- if(!strlen(info->name)) {
+ if(info->name == NULL || strlen(info->name) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package name in %s\n"), pkgfile);
goto pkg_invalid;
}
- if(!strlen(info->version)) {
+ if(info->version == NULL || strlen(info->version) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);
goto pkg_invalid;
}
config = 1;
- unlink(descfile);
- FREE(descfile);
- close(fd);
continue;
} else if(strcmp(entry_name, ".INSTALL") == 0) {
info->scriptlet = 1;
@@ -1061,7 +1051,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
if(archive_read_data_skip(archive)) {
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
+ pm_errno = PM_ERR_LIBARCHIVE;
goto error;
}
@@ -1074,7 +1064,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
+ pm_errno = PM_ERR_LIBARCHIVE;
goto error;
}
@@ -1090,13 +1080,13 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
info->origin_data.file = strdup(pkgfile);
if(full) {
- /* "checking for conflicts" requires a sorted list, so we ensure that here */
+ /* "checking for conflicts" requires a sorted list, ensure that here */
_alpm_log(PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
info->files = alpm_list_msort(info->files, alpm_list_count(info->files),
_alpm_str_cmp);
info->infolevel = INFRQ_ALL;
} else {
- /* get rid of any partial filelist we may have collected, as it is invalid */
+ /* get rid of any partial filelist we may have collected, it is invalid */
FREELIST(info->files);
info->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_DEPENDS;
}
@@ -1105,13 +1095,6 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
pkg_invalid:
pm_errno = PM_ERR_PKG_INVALID;
- if(descfile) {
- unlink(descfile);
- FREE(descfile);
- }
- if(fd != -1) {
- close(fd);
- }
error:
_alpm_pkg_free(info);
archive_read_finish(archive);
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index d6c3eff9..f3de05d6 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -33,30 +33,17 @@ typedef enum _pmpkgfrom_t {
PKG_FROM_FILE
} pmpkgfrom_t;
-/* Packages */
-#define PKG_FILENAME_LEN 512
-#define PKG_NAME_LEN 256
-#define PKG_VERSION_LEN 64
-#define PKG_FULLNAME_LEN (PKG_NAME_LEN + PKG_VERSION_LEN)
-#define PKG_DESC_LEN 512
-#define PKG_URL_LEN 256
-#define PKG_DATE_LEN 32
-#define PKG_TYPE_LEN 32
-#define PKG_PACKAGER_LEN 64
-#define PKG_MD5SUM_LEN 33
-#define PKG_ARCH_LEN 32
-
struct __pmpkg_t {
- char filename[PKG_FILENAME_LEN];
- char name[PKG_NAME_LEN];
- char version[PKG_VERSION_LEN];
- char desc[PKG_DESC_LEN];
- char url[PKG_URL_LEN];
+ char *filename;
+ char *name;
+ char *version;
+ char *desc;
+ char *url;
time_t builddate;
time_t installdate;
- char packager[PKG_PACKAGER_LEN];
- char md5sum[PKG_MD5SUM_LEN];
- char arch[PKG_ARCH_LEN];
+ char *packager;
+ char *md5sum;
+ char *arch;
unsigned long size;
unsigned long isize;
unsigned short scriptlet;
@@ -90,6 +77,7 @@ pmpkg_t* _alpm_pkg_new(const char *name, const char *version);
pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg);
void _alpm_pkg_free(pmpkg_t *pkg);
int _alpm_pkg_cmp(const void *p1, const void *p2);
+int _alpm_pkgname_pkg_cmp(const void *pkgname, const void *package);
int _alpm_pkg_compare_versions(pmpkg_t *local_pkg, pmpkg_t *pkg);
pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full);
pmpkg_t *_alpm_pkg_find(const char *needle, alpm_list_t *haystack);
diff --git a/lib/libalpm/po/POTFILES.in b/lib/libalpm/po/POTFILES.in
index 80130f24..35bd864b 100644
--- a/lib/libalpm/po/POTFILES.in
+++ b/lib/libalpm/po/POTFILES.in
@@ -10,6 +10,7 @@ lib/libalpm/conflict.c
lib/libalpm/db.c
lib/libalpm/delta.c
lib/libalpm/deps.c
+lib/libalpm/dload.c
lib/libalpm/error.c
lib/libalpm/group.c
lib/libalpm/handle.c
@@ -17,7 +18,6 @@ lib/libalpm/log.c
lib/libalpm/md5.c
lib/libalpm/package.c
lib/libalpm/remove.c
-lib/libalpm/server.c
lib/libalpm/sync.c
lib/libalpm/trans.c
lib/libalpm/util.c
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index a0f9963a..f2e84ef5 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -37,7 +37,6 @@
#include "alpm_list.h"
#include "trans.h"
#include "util.h"
-#include "error.h"
#include "log.h"
#include "backup.h"
#include "package.h"
@@ -82,6 +81,60 @@ int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name)
return(0);
}
+static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db,
+ alpm_list_t *lp)
+{
+ ALPM_LOG_FUNC;
+
+ while(lp) {
+ alpm_list_t *i;
+ for(i = lp; i; i = i->next) {
+ pmdepmissing_t *miss = (pmdepmissing_t *)i->data;
+ pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target);
+ if(info) {
+ if(!_alpm_pkg_find(alpm_pkg_get_name(info), trans->packages)) {
+ _alpm_log(PM_LOG_DEBUG, "pulling %s in the targets list\n",
+ alpm_pkg_get_name(info));
+ trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info));
+ }
+ } else {
+ _alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"),
+ miss->target);
+ }
+ }
+ alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(lp);
+ lp = alpm_checkdeps(db, 1, trans->packages, NULL);
+ }
+}
+
+static void remove_prepare_keep_needed(pmtrans_t *trans, pmdb_t *db,
+ alpm_list_t *lp)
+{
+ ALPM_LOG_FUNC;
+
+ /* Remove needed packages (which break dependencies) from the target list */
+ while(lp != NULL) {
+ alpm_list_t *i;
+ for(i = lp; i; i = i->next) {
+ pmdepmissing_t *miss = (pmdepmissing_t *)i->data;
+ void *vpkg;
+ pmpkg_t *pkg;
+ trans->packages = alpm_list_remove(trans->packages, miss->causingpkg,
+ _alpm_pkgname_pkg_cmp, &vpkg);
+ pkg = vpkg;
+ if(pkg) {
+ _alpm_log(PM_LOG_WARNING, "removing %s from the target-list\n",
+ alpm_pkg_get_name(pkg));
+ _alpm_pkg_free(pkg);
+ }
+ }
+ alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(lp);
+ lp = alpm_checkdeps(db, 1, trans->packages, NULL);
+ }
+}
+
int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
{
alpm_list_t *lp;
@@ -102,31 +155,19 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
lp = alpm_checkdeps(db, 1, trans->packages, NULL);
if(lp != NULL) {
+
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
- while(lp) {
- alpm_list_t *i;
- for(i = lp; i; i = i->next) {
- pmdepmissing_t *miss = (pmdepmissing_t *)i->data;
- pmpkg_t *info = _alpm_db_get_pkgfromcache(db, miss->target);
- if(info) {
- if(!_alpm_pkg_find(alpm_pkg_get_name(info), trans->packages)) {
- _alpm_log(PM_LOG_DEBUG, "pulling %s in the targets list\n",
- alpm_pkg_get_name(info));
- trans->packages = alpm_list_add(trans->packages, _alpm_pkg_dup(info));
- }
- } else {
- _alpm_log(PM_LOG_ERROR, _("could not find %s in database -- skipping\n"),
- miss->target);
- }
- }
- FREELIST(lp);
- lp = alpm_checkdeps(db, 1, trans->packages, NULL);
- }
+ remove_prepare_cascade(trans, db, lp);
+ } else if (trans->flags & PM_TRANS_FLAG_UNNEEDED) {
+ /* Remove needed packages (which would break dependencies)
+ * from the target list */
+ remove_prepare_keep_needed(trans, db, lp);
} else {
if(data) {
*data = lp;
} else {
- FREELIST(lp);
+ alpm_list_free_inner(lp, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(lp);
}
RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1);
}
@@ -135,14 +176,14 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
/* re-order w.r.t. dependencies */
_alpm_log(PM_LOG_DEBUG, "sorting by dependencies\n");
- lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_REMOVE);
+ lp = _alpm_sortbydeps(trans->packages, 1);
/* free the old alltargs */
alpm_list_free(trans->packages);
trans->packages = lp;
if(trans->flags & PM_TRANS_FLAG_RECURSE) {
_alpm_log(PM_LOG_DEBUG, "finding removable dependencies\n");
- _alpm_recursedeps(db, trans->packages, 0);
+ _alpm_recursedeps(db, trans->packages, trans->flags & PM_TRANS_FLAG_RECURSEALL);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
diff --git a/lib/libalpm/server.c b/lib/libalpm/server.c
deleted file mode 100644
index 4bccf3ca..00000000
--- a/lib/libalpm/server.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * server.c
- *
- * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <string.h>
-#include <limits.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <download.h>
-
-/* libalpm */
-#include "server.h"
-#include "alpm_list.h"
-#include "error.h"
-#include "log.h"
-#include "alpm.h"
-#include "util.h"
-#include "handle.h"
-#include "package.h"
-
-pmserver_t *_alpm_server_new(const char *url)
-{
- struct url *u;
- pmserver_t *server;
-
- ALPM_LOG_FUNC;
-
- CALLOC(server, 1, sizeof(pmserver_t), RET_ERR(PM_ERR_MEMORY, NULL));
-
- u = downloadParseURL(url);
- if(!u) {
- _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid, ignoring\n"), url);
- RET_ERR(PM_ERR_SERVER_BAD_URL, NULL);
- }
- if(strlen(u->scheme) == 0) {
- _alpm_log(PM_LOG_WARNING, _("url scheme not specified, assuming http\n"));
- strcpy(u->scheme, "http");
- }
-
- if(strcmp(u->scheme,"ftp") == 0 && strlen(u->user) == 0) {
- strcpy(u->user, "anonymous");
- strcpy(u->pwd, "libalpm@guest");
- }
-
- /* remove trailing slashes, just to clean up the rest of the code */
- for(int i = strlen(u->doc) - 1; u->doc[i] == '/'; --i)
- u->doc[i] = '\0';
-
- server->s_url = u;
-
- return server;
-}
-
-void _alpm_server_free(pmserver_t *server)
-{
- ALPM_LOG_FUNC;
-
- if(server == NULL) {
- return;
- }
-
- /* free memory */
- downloadFreeURL(server->s_url);
- FREE(server);
-}
-
-/* remove filename info from "s_url->doc" and return it */
-static char *strip_filename(pmserver_t *server)
-{
- char *p = NULL, *fname = NULL;
- if(!server) {
- return(NULL);
- }
-
- p = strrchr(server->s_url->doc, '/');
- if(p && *(++p)) {
- fname = strdup(p);
- _alpm_log(PM_LOG_DEBUG, "stripping '%s' from '%s'\n",
- fname, server->s_url->doc);
- *p = 0;
- }
-
- /* s_url->doc now contains ONLY path information. return value
- * if the file information from the original URL */
- return(fname);
-}
-
-/* Return a 'struct url' for this server, for downloading 'filename'. */
-static struct url *url_for_file(pmserver_t *server, const char *filename)
-{
- struct url *ret = NULL;
- char *doc = NULL;
- int doclen = 0;
-
- doclen = strlen(server->s_url->doc) + strlen(filename) + 2;
- CALLOC(doc, doclen, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL));
-
- snprintf(doc, doclen, "%s/%s", server->s_url->doc, filename);
- ret = downloadMakeURL(server->s_url->scheme,
- server->s_url->host,
- server->s_url->port,
- doc,
- server->s_url->user,
- server->s_url->pwd);
- FREE(doc);
- return(ret);
-}
-
-/*
- * Download a list of files from a list of servers
- * - if one server fails, we try the next one in the list
- * - if *dl_total is non-NULL, then it will be used as the starting
- * download amount when TotalDownload is set. It will also be
- * set to the final download amount for the calling function to use.
- * - totalsize is the total download size for use when TotalDownload
- * is set. Use 0 if the total download size is not known.
- *
- * RETURN: 0 for successful download, 1 on error
- */
-int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath,
- alpm_list_t *files, int *dl_total, unsigned long totalsize)
-{
- return(_alpm_downloadfiles_forreal(servers, localpath, files, 0, NULL,
- dl_total, totalsize));
-}
-
-/*
- * This is the real downloadfiles, used directly by sync_synctree() to check
- * modtimes on remote files.
- * - if mtime1 is non-NULL, then only download files if they are different
- * than mtime1.
- * - if *mtime2 is non-NULL, it will be filled with the mtime of the remote
- * file.
- * - if *dl_total is non-NULL, then it will be used as the starting
- * download amount when TotalDownload is set. It will also be
- * set to the final download amount for the calling function to use.
- * - totalsize is the total download size for use when TotalDownload
- * is set. Use 0 if the total download size is not known.
- *
- * RETURN: 0 for successful download
- * 1 if the mtimes are identical
- * -1 on error
- */
-int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath,
- alpm_list_t *files, time_t mtime1, time_t *mtime2, int *dl_total,
- unsigned long totalsize)
-{
- int dl_thisfile = 0;
- alpm_list_t *lp;
- int done = 0;
- alpm_list_t *complete = NULL;
- alpm_list_t *i;
-
- ALPM_LOG_FUNC;
-
- if(files == NULL) {
- return(0);
- }
-
- for(i = servers; i && !done; i = i->next) {
- pmserver_t *server = i->data;
-
- /* get each file in the list */
- for(lp = files; lp; lp = lp->next) {
- struct url *fileurl = NULL;
- char realfile[PATH_MAX];
- char output[PATH_MAX];
- char *fn = (char *)lp->data;
- char pkgname[PKG_NAME_LEN];
-
- fileurl = url_for_file(server, fn);
- if(!fileurl) {
- return(-1);
- }
-
- /* pass the raw filename for passing to the callback function */
- strncpy(pkgname, fn, PKG_NAME_LEN);
- _alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", pkgname);
-
- snprintf(realfile, PATH_MAX, "%s%s", localpath, fn);
- snprintf(output, PATH_MAX, "%s%s.part", localpath, fn);
-
- if(alpm_list_find_str(complete, fn)) {
- continue;
- }
-
- if(!handle->xfercommand || !strcmp(fileurl->scheme, "file")) {
- FILE *dlf, *localf = NULL;
- struct url_stat ust;
- struct stat st;
- int chk_resume = 0;
-
- if(stat(output, &st) == 0 && st.st_size > 0) {
- _alpm_log(PM_LOG_DEBUG, "existing file found, using it\n");
- fileurl->offset = (off_t)st.st_size;
- dl_thisfile = st.st_size;
- if (dl_total != NULL) {
- *dl_total += st.st_size;
- }
- localf = fopen(output, "a");
- chk_resume = 1;
- } else {
- fileurl->offset = (off_t)0;
- dl_thisfile = 0;
- }
-
- /* libdownload does not reset the error code, reset it in
- * the case of previous errors */
- downloadLastErrCode = 0;
-
- /* 10s timeout - TODO make a config option */
- downloadTimeout = 10000;
-
- dlf = downloadXGet(fileurl, &ust, (handle->nopassiveftp ? "" : "p"));
-
- if(downloadLastErrCode != 0 || dlf == NULL) {
- const char *host = _("disk");
- if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) {
- host = fileurl->host;
- }
- _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"),
- fn, host, downloadLastErrString);
- if(localf != NULL) {
- fclose(localf);
- }
- /* try the next server */
- downloadFreeURL(fileurl);
- continue;
- } else {
- _alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host);
- }
-
- if(ust.mtime && mtime1 && ust.mtime == mtime1) {
- _alpm_log(PM_LOG_DEBUG, "mtimes are identical, skipping %s\n", fn);
- complete = alpm_list_add(complete, fn);
- if(localf != NULL) {
- fclose(localf);
- }
- if(dlf != NULL) {
- fclose(dlf);
- }
- downloadFreeURL(fileurl);
- return(1);
- }
-
- if(ust.mtime && mtime2) {
- *mtime2 = ust.mtime;
- }
-
- if(chk_resume && fileurl->offset == 0) {
- _alpm_log(PM_LOG_WARNING, _("cannot resume download, starting over\n"));
- if(localf != NULL) {
- fclose(localf);
- localf = NULL;
- }
- }
-
- if(localf == NULL) {
- _alpm_rmrf(output);
- fileurl->offset = (off_t)0;
- dl_thisfile = 0;
- localf = fopen(output, "w");
- if(localf == NULL) { /* still null? */
- _alpm_log(PM_LOG_ERROR, _("cannot write to file '%s'\n"), output);
- if(dlf != NULL) {
- fclose(dlf);
- }
- downloadFreeURL(fileurl);
- return(-1);
- }
- }
-
- /* Progress 0 - initialize */
- if(handle->dlcb) {
- handle->dlcb(pkgname, 0, ust.size, dl_total ? *dl_total : 0,
- totalsize);
- }
-
- int nread = 0;
- char buffer[PM_DLBUF_LEN];
- while((nread = fread(buffer, 1, PM_DLBUF_LEN, dlf)) > 0) {
- if(ferror(dlf)) {
- _alpm_log(PM_LOG_ERROR, _("error downloading '%s': %s\n"),
- fn, downloadLastErrString);
- fclose(localf);
- fclose(dlf);
- downloadFreeURL(fileurl);
- return(-1);
- }
-
- int nwritten = 0;
- while(nwritten < nread) {
- nwritten += fwrite(buffer, 1, (nread - nwritten), localf);
- if(ferror(localf)) {
- _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"),
- realfile, strerror(errno));
- fclose(localf);
- fclose(dlf);
- downloadFreeURL(fileurl);
- return(-1);
- }
- }
-
- if(nwritten != nread) {
-
- }
- dl_thisfile += nread;
- if (dl_total != NULL) {
- *dl_total += nread;
- }
-
- if(handle->dlcb) {
- handle->dlcb(pkgname, dl_thisfile, ust.size,
- dl_total ? *dl_total : 0, totalsize);
- }
- }
-
- downloadFreeURL(fileurl);
- fclose(localf);
- fclose(dlf);
- rename(output, realfile);
- complete = alpm_list_add(complete, fn);
- } else {
- int ret;
- int usepart = 0;
- char *ptr1, *ptr2;
- char origCmd[PATH_MAX];
- char parsedCmd[PATH_MAX] = "";
- char url[PATH_MAX];
- char cwd[PATH_MAX];
-
- /* build the full download url */
- snprintf(url, PATH_MAX, "%s://%s%s", fileurl->scheme,
- fileurl->host, fileurl->doc);
- /* we don't need this anymore */
- downloadFreeURL(fileurl);
-
- /* replace all occurrences of %o with fn.part */
- strncpy(origCmd, handle->xfercommand, sizeof(origCmd));
- ptr1 = origCmd;
- while((ptr2 = strstr(ptr1, "%o"))) {
- usepart = 1;
- ptr2[0] = '\0';
- strcat(parsedCmd, ptr1);
- strcat(parsedCmd, output);
- ptr1 = ptr2 + 2;
- }
- strcat(parsedCmd, ptr1);
- /* replace all occurrences of %u with the download URL */
- strncpy(origCmd, parsedCmd, sizeof(origCmd));
- parsedCmd[0] = '\0';
- ptr1 = origCmd;
- while((ptr2 = strstr(ptr1, "%u"))) {
- ptr2[0] = '\0';
- strcat(parsedCmd, ptr1);
- strcat(parsedCmd, url);
- ptr1 = ptr2 + 2;
- }
- strcat(parsedCmd, ptr1);
- /* cwd to the download directory */
- getcwd(cwd, PATH_MAX);
- if(chdir(localpath)) {
- _alpm_log(PM_LOG_WARNING, _("could not chdir to %s\n"), localpath);
- return(PM_ERR_CONNECT_FAILED);
- }
- /* execute the parsed command via /bin/sh -c */
- _alpm_log(PM_LOG_DEBUG, "running command: %s\n", parsedCmd);
- ret = system(parsedCmd);
- if(ret == -1) {
- _alpm_log(PM_LOG_WARNING, _("running XferCommand: fork failed!\n"));
- return(PM_ERR_FORK_FAILED);
- } else if(ret != 0) {
- /* download failed */
- _alpm_log(PM_LOG_DEBUG, "XferCommand command returned non-zero status code (%d)\n", ret);
- } else {
- /* download was successful */
- complete = alpm_list_add(complete, fn);
- if(usepart) {
- rename(output, realfile);
- }
- }
- chdir(cwd);
- }
- }
-
- if(alpm_list_count(complete) == alpm_list_count(files)) {
- done = 1;
- }
- }
- alpm_list_free(complete);
-
- return(done ? 0 : -1);
-}
-
-/** Fetch a remote pkg.
- * @param url URL of the package to download
- * @return the downloaded filepath on success, NULL on error
- * @addtogroup alpm_misc
- */
-char SYMEXPORT *alpm_fetch_pkgurl(const char *url)
-{
- pmserver_t *server;
- char *filename, *filepath;
- const char *cachedir;
-
- ALPM_LOG_FUNC;
-
- if(strstr(url, "://") == NULL) {
- _alpm_log(PM_LOG_DEBUG, "Invalid URL passed to alpm_fetch_pkgurl\n");
- return(NULL);
- }
-
- server = _alpm_server_new(url);
- if(!server) {
- return(NULL);
- }
-
- /* strip path information from the filename */
- filename = strip_filename(server);
- if(!filename) {
- _alpm_log(PM_LOG_ERROR, _("URL does not contain a file for download\n"));
- return(NULL);
- }
-
- /* find a valid cache dir to download to */
- cachedir = _alpm_filecache_setup();
-
- /* TODO this seems like needless complexity just to download one file */
- alpm_list_t *servers = alpm_list_add(NULL, server);
- alpm_list_t *files = alpm_list_add(NULL, filename);
-
- /* download the file */
- if(_alpm_downloadfiles(servers, cachedir, files, NULL, 0)) {
- _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url);
- return(NULL);
- }
- _alpm_log(PM_LOG_DEBUG, "successfully downloaded %s\n", filename);
- alpm_list_free(files);
- alpm_list_free(servers);
- _alpm_server_free(server);
-
- /* we should be able to find the file the second time around */
- filepath = _alpm_filecache_find(filename);
- return(filepath);
-}
-
-/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/server.h b/lib/libalpm/server.h
deleted file mode 100644
index b82fcb09..00000000
--- a/lib/libalpm/server.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * server.h
- *
- * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _ALPM_SERVER_H
-#define _ALPM_SERVER_H
-
-#include "alpm_list.h"
-#include "alpm.h"
-
-#include <time.h>
-#include <download.h>
-
-/* Servers */
-struct __pmserver_t {
- /* useless abstraction now? */
- struct url *s_url;
-};
-
-#define PM_DLBUF_LEN (1024 * 10)
-
-pmserver_t *_alpm_server_new(const char *url);
-void _alpm_server_free(pmserver_t *server);
-int _alpm_downloadfiles(alpm_list_t *servers, const char *localpath,
- alpm_list_t *files, int *dl_total, unsigned long totalsize);
-int _alpm_downloadfiles_forreal(alpm_list_t *servers, const char *localpath,
- alpm_list_t *files, time_t mtime1, time_t *mtime2, int *dl_total,
- unsigned long totalsize);
-
-#endif /* _ALPM_SERVER_H */
-
-/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
index a927f61b..decd52b5 100644
--- a/lib/libalpm/sync.c
+++ b/lib/libalpm/sync.c
@@ -34,7 +34,6 @@
#include "sync.h"
#include "alpm_list.h"
#include "log.h"
-#include "error.h"
#include "package.h"
#include "db.h"
#include "cache.h"
@@ -44,10 +43,10 @@
#include "util.h"
#include "handle.h"
#include "alpm.h"
-#include "server.h"
+#include "dload.h"
#include "delta.h"
-pmsyncpkg_t *_alpm_sync_new(int type, pmpkg_t *spkg, void *data)
+pmsyncpkg_t *_alpm_sync_new(pmpkgreason_t newreason, pmpkg_t *spkg, alpm_list_t *removes)
{
pmsyncpkg_t *sync;
@@ -55,9 +54,9 @@ pmsyncpkg_t *_alpm_sync_new(int type, pmpkg_t *spkg, void *data)
CALLOC(sync, 1, sizeof(pmsyncpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
- sync->type = type;
+ sync->newreason = newreason;
sync->pkg = spkg;
- sync->data = data;
+ sync->removes = removes;
return(sync);
}
@@ -70,32 +69,11 @@ void _alpm_sync_free(pmsyncpkg_t *sync)
return;
}
- /* TODO wow this is ugly */
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- alpm_list_free_inner(sync->data, (alpm_list_fn_free)_alpm_pkg_free);
- alpm_list_free(sync->data);
- sync->data = NULL;
- } else {
- _alpm_pkg_free(sync->data);
- sync->data = NULL;
- }
+ alpm_list_free(sync->removes);
+ sync->removes = NULL;
FREE(sync);
}
-static void synclist_free(alpm_list_t *syncpkgs)
-{
- if(syncpkgs) {
- alpm_list_t *tmp;
- for(tmp = syncpkgs; tmp; tmp = alpm_list_next(tmp)) {
- if(tmp->data) {
- _alpm_sync_free(tmp->data);
- }
- }
- alpm_list_free(syncpkgs);
- }
-
-}
-
/* Find recommended replacements for packages during a sync.
*/
static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
@@ -147,27 +125,29 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
* the package to replace.
*/
pmsyncpkg_t *sync;
- pmpkg_t *dummy = _alpm_pkg_dup(lpkg);
- if(dummy == NULL) {
- pm_errno = PM_ERR_MEMORY;
- synclist_free(*syncpkgs);
- return(-1);
- }
+
/* check if spkg->name is already in the packages list. */
+ /* TODO: same package name doesn't mean same package */
sync = _alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg));
if(sync) {
- /* found it -- just append to the replaces list */
- sync->data = alpm_list_add(sync->data, dummy);
+ /* found it -- just append to the removes list */
+ sync->removes = alpm_list_add(sync->removes, lpkg);
+ /* check the to-be-replaced package's reason field */
+ if(lpkg->reason == PM_PKG_REASON_EXPLICIT) {
+ sync->newreason = PM_PKG_REASON_EXPLICIT;
+ }
} else {
/* none found -- enter pkg into the final sync list */
- sync = _alpm_sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL);
+ /* copy over reason */
+ sync = _alpm_sync_new(alpm_pkg_get_reason(lpkg), spkg, NULL);
if(sync == NULL) {
- _alpm_pkg_free(dummy);
pm_errno = PM_ERR_MEMORY;
- synclist_free(*syncpkgs);
+ alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
+ alpm_list_free(*syncpkgs);
+ *syncpkgs = NULL;
return(-1);
}
- sync->data = alpm_list_add(NULL, dummy);
+ sync->removes = alpm_list_add(NULL, lpkg);
*syncpkgs = alpm_list_add(*syncpkgs, sync);
}
_alpm_log(PM_LOG_DEBUG, "%s-%s elected for removal (to be replaced by %s-%s)\n",
@@ -180,6 +160,35 @@ static int find_replacements(pmtrans_t *trans, pmdb_t *db_local,
return(0);
}
+/** Check for new version of pkg in sync repos
+ * (only the first occurrence is considered in sync)
+ */
+pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync)
+{
+ alpm_list_t *i;
+ pmpkg_t *spkg = NULL;
+
+ for(i = dbs_sync; !spkg && i; i = i->next) {
+ spkg = _alpm_db_get_pkgfromcache(i->data, alpm_pkg_get_name(pkg));
+ }
+
+ if(spkg == NULL) {
+ _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db => no upgrade\n",
+ alpm_pkg_get_name(pkg));
+ return(NULL);
+ }
+
+ /* compare versions and see if spkg is an upgrade */
+ if(_alpm_pkg_compare_versions(pkg, spkg)) {
+ _alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n",
+ alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg),
+ alpm_pkg_get_version(spkg));
+ return(spkg);
+ } else {
+ return(NULL);
+ }
+}
+
/** Get a list of upgradable packages on the current system
* Adds out of date packages to *list.
* @arg list pointer to a list of pmsyncpkg_t.
@@ -193,7 +202,7 @@ int SYMEXPORT alpm_sync_sysupgrade(pmdb_t *db_local,
int _alpm_sync_sysupgrade(pmtrans_t *trans,
pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **syncpkgs)
{
- alpm_list_t *i, *j;
+ alpm_list_t *i, *j, *replaced = NULL;
ALPM_LOG_FUNC;
@@ -205,76 +214,61 @@ int _alpm_sync_sysupgrade(pmtrans_t *trans,
return(-1);
}
- /* match installed packages with the sync dbs and compare versions */
+ /* compute the to-be-replaced packages for efficiency */
+ for(i = *syncpkgs; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ for(j = sync->removes; j; j = j->next) {
+ replaced = alpm_list_add(replaced, j->data);
+ }
+ }
+
+ /* for all not-replaced local package we check for upgrade */
_alpm_log(PM_LOG_DEBUG, "checking for package upgrades\n");
for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
- int replace = 0;
pmpkg_t *local = i->data;
- pmpkg_t *spkg = NULL;
- pmsyncpkg_t *sync;
- for(j = dbs_sync; !spkg && j; j = j->next) {
- spkg = _alpm_db_get_pkgfromcache(j->data, alpm_pkg_get_name(local));
- }
- if(spkg == NULL) {
- _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db -- skipping\n",
- alpm_pkg_get_name(local));
- continue;
- }
-
- /* we don't care about a to-be-replaced package's newer version */
- for(j = *syncpkgs; j && !replace; j=j->next) {
- sync = j->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- if(_alpm_pkg_find(alpm_pkg_get_name(spkg), sync->data)) {
- replace = 1;
- }
- }
- }
- if(replace) {
+ if(_alpm_pkg_find(alpm_pkg_get_name(local), replaced)) {
_alpm_log(PM_LOG_DEBUG, "'%s' is already elected for removal -- skipping\n",
alpm_pkg_get_name(local));
continue;
}
- /* compare versions and see if we need to upgrade */
- if(_alpm_pkg_compare_versions(local, spkg)) {
- _alpm_log(PM_LOG_DEBUG, "%s elected for upgrade (%s => %s)\n",
- alpm_pkg_get_name(local), alpm_pkg_get_version(local),
- alpm_pkg_get_version(spkg));
- if(!_alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg))) {
- /* If package is in the ignorepkg list, skip it */
- if(_alpm_pkg_should_ignore(spkg)) {
- _alpm_log(PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"),
- alpm_pkg_get_name(local), alpm_pkg_get_version(local),
- alpm_pkg_get_version(spkg));
- continue;
- }
+ pmpkg_t *spkg = alpm_sync_newversion(local, dbs_sync);
+ if(spkg) {
+ /* we found a new version */
+ /* skip packages in IgnorePkg or in IgnoreGroup */
+ if(_alpm_pkg_should_ignore(spkg)) {
+ _alpm_log(PM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"),
+ alpm_pkg_get_name(local), alpm_pkg_get_version(local),
+ alpm_pkg_get_version(spkg));
+ continue;
+ }
- pmpkg_t *tmp = _alpm_pkg_dup(local);
- if(tmp == NULL) {
- pm_errno = PM_ERR_MEMORY;
- synclist_free(*syncpkgs);
- return(-1);
- }
- sync = _alpm_sync_new(PM_SYNC_TYPE_UPGRADE, spkg, tmp);
- if(sync == NULL) {
- _alpm_pkg_free(tmp);
- pm_errno = PM_ERR_MEMORY;
- synclist_free(*syncpkgs);
- return(-1);
- }
- *syncpkgs = alpm_list_add(*syncpkgs, sync);
+ /* add the upgrade package to our pmsyncpkg_t list */
+ if(_alpm_sync_find(*syncpkgs, alpm_pkg_get_name(spkg))) {
+ /* avoid duplicated targets */
+ continue;
}
+ /* we can set any reason here, it will be overridden by add_commit */
+ pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
+ if(sync == NULL) {
+ alpm_list_free_inner(*syncpkgs, (alpm_list_fn_free)_alpm_sync_free);
+ alpm_list_free(*syncpkgs);
+ *syncpkgs = NULL;
+ alpm_list_free(replaced);
+ return(-1);
+ }
+ *syncpkgs = alpm_list_add(*syncpkgs, sync);
}
}
+ alpm_list_free(replaced);
return(0);
}
int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, char *name)
{
- char targline[PKG_FULLNAME_LEN];
+ char *targline;
char *targ;
alpm_list_t *j;
pmpkg_t *local;
@@ -287,8 +281,8 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(name != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+ STRDUP(targline, name, RET_ERR(PM_ERR_MEMORY, -1));
- strncpy(targline, name, PKG_FULLNAME_LEN);
targ = strchr(targline, '/');
if(targ) {
/* we are looking for a package in a specific database */
@@ -301,13 +295,15 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
repo_found = 1;
spkg = _alpm_db_get_pkgfromcache(db, targ);
if(spkg == NULL) {
- RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
+ pm_errno = PM_ERR_PKG_NOT_FOUND;
+ goto error;
}
}
}
if(!repo_found) {
_alpm_log(PM_LOG_ERROR, _("repository '%s' not found\n"), targline);
- RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1);
+ pm_errno = PM_ERR_PKG_REPO_NOT_FOUND;
+ goto error;
}
} else {
targ = targline;
@@ -316,10 +312,16 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
spkg = _alpm_db_get_pkgfromcache(db, targ);
}
if(spkg == NULL) {
- RET_ERR(PM_ERR_PKG_NOT_FOUND, -1);
+ pm_errno = PM_ERR_PKG_NOT_FOUND;
+ goto error;
}
}
+ if(_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
+ FREE(targline);
+ RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
+ }
+
if(_alpm_pkg_should_ignore(spkg)) {
int resp;
QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, spkg, NULL, NULL, &resp);
@@ -346,37 +348,34 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy
}
/* add the package to the transaction */
- if(!_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
- pmpkg_t *dummy = NULL;
- if(local) {
- dummy = _alpm_pkg_dup(local);
- if(dummy == NULL) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
- }
- sync = _alpm_sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy);
- if(sync == NULL) {
- _alpm_pkg_free(dummy);
- RET_ERR(PM_ERR_MEMORY, -1);
- }
- _alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
- alpm_pkg_get_name(spkg));
- trans->packages = alpm_list_add(trans->packages, sync);
+ sync = _alpm_sync_new(PM_PKG_REASON_EXPLICIT, spkg, NULL);
+ if(sync == NULL) {
+ goto error;
}
+ _alpm_log(PM_LOG_DEBUG, "adding target '%s' to the transaction set\n",
+ alpm_pkg_get_name(spkg));
+ trans->packages = alpm_list_add(trans->packages, sync);
+ FREE(targline);
return(0);
+
+error:
+ if(targline) {
+ FREE(targline);
+ }
+ return(-1);
}
/* Helper functions for alpm_list_remove
- */
+*/
static int syncpkg_cmp(const void *s1, const void *s2)
{
const pmsyncpkg_t *sp1 = s1;
const pmsyncpkg_t *sp2 = s2;
pmpkg_t *p1, *p2;
- p1 = alpm_sync_get_pkg(sp1);
- p2 = alpm_sync_get_pkg(sp2);
+ p1 = alpm_sync_get_pkg(sp1);
+ p2 = alpm_sync_get_pkg(sp2);
return(strcmp(alpm_pkg_get_name(p1), alpm_pkg_get_name(p2)));
}
@@ -397,14 +396,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
*data = NULL;
}
- if(!(trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
- for(i = trans->packages; i; i = i->next) {
- pmsyncpkg_t *sync = i->data;
- list = alpm_list_add(list, sync->pkg);
- }
+ for(i = trans->packages; i; i = i->next) {
+ pmsyncpkg_t *sync = i->data;
+ list = alpm_list_add(list, sync->pkg);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
+ /* store a pointer to the last original target so we can tell what was
+ * pulled by resolvedeps */
+ alpm_list_t *pulled = alpm_list_last(list);
/* Resolve targets dependencies */
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
@@ -412,10 +412,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
/* build remove list for resolvedeps */
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- for(j = sync->data; j; j = j->next) {
- remove = alpm_list_add(remove, j->data);
- }
+ for(j = sync->removes; j; j = j->next) {
+ remove = alpm_list_add(remove, j->data);
}
}
@@ -429,33 +427,27 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
}
}
- if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
- FREELIST(trans->packages);
- }
-
- for(i = list; i; i = i->next) {
- /* add the dependencies found by resolvedeps to the transaction set */
+ for(i = pulled->next; i; i = i->next) {
pmpkg_t *spkg = i->data;
- if(!_alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg))) {
- pmsyncpkg_t *sync = _alpm_sync_new(PM_SYNC_TYPE_DEPEND, spkg, NULL);
- if(sync == NULL) {
- ret = -1;
- goto cleanup;
- }
- trans->packages = alpm_list_add(trans->packages, sync);
- _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
- alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
+ pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_DEPEND, spkg, NULL);
+ if(sync == NULL) {
+ ret = -1;
+ goto cleanup;
}
+ trans->packages = alpm_list_add(trans->packages, sync);
+ _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
+ alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
}
/* re-order w.r.t. dependencies */
- alpm_list_t *sortlist = _alpm_sortbydeps(list, PM_TRANS_TYPE_ADD);
+ alpm_list_t *sortlist = _alpm_sortbydeps(list, 0);
alpm_list_t *newpkgs = NULL;
for(i = sortlist; i; i = i->next) {
for(j = trans->packages; j; j = j->next) {
pmsyncpkg_t *s = j->data;
if(s->pkg == i->data) {
newpkgs = alpm_list_add(newpkgs, s);
+ break;
}
}
}
@@ -472,180 +464,126 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "looking for conflicts\n");
- deps = _alpm_checkconflicts(db_local, list);
- if(deps) {
- int errorout = 0;
- alpm_list_t *asked = NULL;
- pmconflict_t *conflict = NULL;
-
- for(i = deps; i && !errorout; i = i->next) {
- pmsyncpkg_t *sync;
- pmpkg_t *found = NULL;
-
- conflict = i->data;
- _alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",
- conflict->package1, conflict->package2);
- /* check if the conflicting package is about to be removed/replaced.
- * if so, then just ignore it. */
- for(j = trans->packages; j && !found; j = j->next) {
- sync = j->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- found = _alpm_pkg_find(conflict->package2, sync->data);
- }
- }
- if(found) {
- _alpm_log(PM_LOG_DEBUG, "'%s' is already elected for removal -- skipping\n",
- alpm_pkg_get_name(found));
- continue;
- }
- sync = _alpm_sync_find(trans->packages, conflict->package1);
- if(sync == NULL) {
- _alpm_log(PM_LOG_DEBUG, "'%s' not found in transaction set -- skipping\n",
- conflict->package1);
- continue;
- }
- pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
- /* check if this package provides the package it's conflicting with */
- if(alpm_list_find(alpm_pkg_get_provides(sync->pkg),
- conflict->package2, _alpm_prov_cmp)) {
- /* treat like a replaces item so requiredby fields are
- * inherited properly. */
- _alpm_log(PM_LOG_DEBUG, "package '%s' provides its own conflict\n",
- conflict->package1);
- if(!local) {
- char *rmpkg = NULL;
- void *target, *depend;
- /* hmmm, package2 isn't installed, so it must be conflicting
- * with another package in our final list. For example:
- *
- * pacman -S blackbox xfree86
- *
- * If no x-servers are installed and blackbox pulls in xorg, then
- * xorg and xfree86 will conflict with each other. In this case,
- * we should follow the user's preference and rip xorg out of final,
- * opting for xfree86 instead.
- */
-
- /* figure out which one was requested in targets. If they both
- * were, then it's still an unresolvable conflict. */
- target = alpm_list_find_str(trans->targets, conflict->package1);
- depend = alpm_list_find_str(trans->targets, conflict->package2);
- if(depend && !target) {
- _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n",
- conflict->package2);
- /* remove conflict->package1 */
- rmpkg = conflict->package1;
- } else if(target && !depend) {
- _alpm_log(PM_LOG_DEBUG, "'%s' is in the target list -- keeping it\n",
- conflict->package1);
- /* remove conflict->package2 */
- rmpkg = conflict->package2;
- } else {
- /* miss->target2 is not needed, miss->target already provides
- * it, let's resolve the conflict */
- rmpkg = conflict->package2;
- }
- if(rmpkg) {
- pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, rmpkg);
- if(rsync) {
- void *vpkg;
- _alpm_log(PM_LOG_DEBUG, "removing '%s' from target list\n",
- rsync->pkg->name);
- trans->packages = alpm_list_remove(trans->packages, rsync,
- syncpkg_cmp, &vpkg);
- _alpm_sync_free(vpkg);
- }
- continue;
- }
+ /* 1. check for conflicts in the target list */
+ _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n");
+ deps = _alpm_innerconflicts(list);
+
+ for(i = deps; i; i = i->next) {
+ pmconflict_t *conflict = i->data;
+ pmsyncpkg_t *rsync, *sync, *sync1, *sync2;
+
+ /* have we already removed one of the conflicting targets? */
+ sync1 = _alpm_sync_find(trans->packages, conflict->package1);
+ sync2 = _alpm_sync_find(trans->packages, conflict->package2);
+ if(!sync1 || !sync2) {
+ continue;
+ }
+
+ _alpm_log(PM_LOG_DEBUG, "conflicting packages in the sync list: '%s' <-> '%s'\n",
+ conflict->package1, conflict->package2);
+
+ /* if sync1 provides sync2, we remove sync2 from the targets, and vice versa */
+ if(alpm_list_find(alpm_pkg_get_provides(sync1->pkg),
+ conflict->package2, _alpm_prov_cmp)) {
+ rsync = sync2;
+ sync = sync1;
+ } else if(alpm_list_find(alpm_pkg_get_provides(sync2->pkg),
+ conflict->package1, _alpm_prov_cmp)) {
+ rsync = sync1;
+ sync = sync2;
+ } else {
+ _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
+ pm_errno = PM_ERR_CONFLICTING_DEPS;
+ ret = -1;
+ if(data) {
+ pmconflict_t *newconflict = _alpm_conflict_dup(conflict);
+ if(newconflict) {
+ *data = alpm_list_add(*data, newconflict);
}
}
- /* It's a conflict -- see if they want to remove it */
- _alpm_log(PM_LOG_DEBUG, "resolving package '%s' conflict\n",
- conflict->package1);
- if(local) {
- int doremove = 0;
- if(!alpm_list_find_str(asked, conflict->package2)) {
- QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,
- conflict->package2, NULL, &doremove);
- asked = alpm_list_add(asked, strdup(conflict->package2));
- if(doremove) {
- pmpkg_t *q = _alpm_pkg_dup(local);
- if(sync->type != PM_SYNC_TYPE_REPLACE) {
- /* switch this sync type to REPLACE */
- sync->type = PM_SYNC_TYPE_REPLACE;
- _alpm_pkg_free(sync->data);
- sync->data = NULL;
- }
- /* append to the replaces list */
- _alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n",
- conflict->package2);
- sync->data = alpm_list_add(sync->data, q);
- /* see if the package is in the current target list */
- pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages,
- conflict->package2);
- if(rsync) {
- /* remove it from the target list */
- void *vpkg;
- _alpm_log(PM_LOG_DEBUG, "removing '%s' from target list\n",
- conflict->package2);
- trans->packages = alpm_list_remove(trans->packages, rsync,
- syncpkg_cmp, &vpkg);
- _alpm_sync_free(vpkg);
- }
- } else {
- /* abort */
- _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
- errorout = 1;
- }
- }
- } else {
- _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
- errorout = 1;
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_conflict_free);
+ alpm_list_free(deps);
+ goto cleanup;
+ }
+
+ /* Prints warning */
+ _alpm_log(PM_LOG_WARNING,
+ _("removing '%s' from target list because it conflicts with '%s'\n"),
+ rsync->pkg->name, sync->pkg->name);
+ void *vpkg;
+ trans->packages = alpm_list_remove(trans->packages, rsync,
+ syncpkg_cmp, &vpkg);
+ pmsyncpkg_t *syncpkg = vpkg;
+ list = alpm_list_remove(list, syncpkg->pkg, _alpm_pkg_cmp, NULL);
+ _alpm_sync_free(syncpkg);
+ continue;
+ }
+
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_conflict_free);
+ alpm_list_free(deps);
+ deps = NULL;
+
+ /* 2. we check for target vs db conflicts (and resolve)*/
+ _alpm_log(PM_LOG_DEBUG, "check targets vs db and db vs targets\n");
+ deps = _alpm_outerconflicts(db_local, list);
+
+ for(i = deps; i; i = i->next) {
+ pmconflict_t *conflict = i->data;
+
+ /* if conflict->package2 (the local package) is not elected for removal,
+ we ask the user */
+ int found = 0;
+ for(j = trans->packages; j && !found; j = j->next) {
+ pmsyncpkg_t *sync = j->data;
+ if(_alpm_pkg_find(conflict->package2, sync->removes)) {
+ found = 1;
}
}
- if(errorout) {
- /* The last conflict was unresolvable, so we duplicate it and add it to *data */
+ if(found) {
+ continue;
+ }
+
+ _alpm_log(PM_LOG_DEBUG, "package '%s' conflicts with '%s'\n",
+ conflict->package1, conflict->package2);
+
+ pmsyncpkg_t *sync = _alpm_sync_find(trans->packages, conflict->package1);
+ pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, conflict->package2);
+ int doremove = 0;
+ QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, conflict->package1,
+ conflict->package2, NULL, &doremove);
+ if(doremove) {
+ /* append to the removes list */
+ _alpm_log(PM_LOG_DEBUG, "electing '%s' for removal\n", conflict->package2);
+ sync->removes = alpm_list_add(sync->removes, local);
+ } else { /* abort */
+ _alpm_log(PM_LOG_ERROR, _("unresolvable package conflicts detected\n"));
pm_errno = PM_ERR_CONFLICTING_DEPS;
+ ret = -1;
if(data) {
- pmconflict_t *lastconflict = conflict;
- if((conflict = malloc(sizeof(pmconflict_t))) == NULL) {
- _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"),
- sizeof(pmconflict_t));
- FREELIST(*data);
- pm_errno = PM_ERR_MEMORY;
- } else {
- *conflict = *lastconflict;
- *data = alpm_list_add(*data, conflict);
+ pmconflict_t *newconflict = _alpm_conflict_dup(conflict);
+ if(newconflict) {
+ *data = alpm_list_add(*data, newconflict);
}
}
- FREELIST(asked);
- FREELIST(deps);
- ret = -1;
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_conflict_free);
+ alpm_list_free(deps);
goto cleanup;
}
- FREELIST(asked);
- FREELIST(deps);
}
EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL);
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_conflict_free);
+ alpm_list_free(deps);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
- /* rebuild remove and list */
- alpm_list_free(list);
- list = NULL;
- for(i = trans->packages; i; i = i->next) {
- pmsyncpkg_t *sync = i->data;
- list = alpm_list_add(list, sync->pkg);
- }
+ /* rebuild remove list */
alpm_list_free(remove);
remove = NULL;
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- for(j = sync->data; j; j = j->next) {
- remove = alpm_list_add(remove, j->data);
- }
+ for(j = sync->removes; j; j = j->next) {
+ remove = alpm_list_add(remove, j->data);
}
}
@@ -657,7 +595,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
if(data) {
*data = deps;
} else {
- FREELIST(deps);
+ alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
+ alpm_list_free(deps);
}
goto cleanup;
}
@@ -778,7 +717,7 @@ static int apply_deltas(pmtrans_t *trans, alpm_list_t *patches)
pmpkg_t *pkg;
pmdelta_t *d;
char command[PATH_MAX], fname[PATH_MAX];
- char pkgfilename[PKG_FILENAME_LEN];
+ char pkgfilename[PATH_MAX];
pkg = alpm_list_getdata(p);
p = alpm_list_next(p);
@@ -813,7 +752,7 @@ static int apply_deltas(pmtrans_t *trans, alpm_list_t *patches)
_alpm_log(PM_LOG_DEBUG, _("command: %s\n"), command);
- snprintf(pkgfilename, PKG_FILENAME_LEN, "%s-%s-%s" PKGEXT,
+ snprintf(pkgfilename, PATH_MAX, "%s-%s-%s" PKGEXT,
pkg->name, d->to, pkg->arch);
EVENT(trans, PM_TRANS_EVT_DELTA_PATCH_START, pkgfilename, d->filename);
@@ -854,107 +793,29 @@ static int apply_deltas(pmtrans_t *trans, alpm_list_t *patches)
* @param trans the transaction
* @param filename the filename of the file to test
* @param md5sum the expected md5sum of the file
- * @param data data to write the error messages to
*
- * @return 0 if the md5sum matched, 1 otherwise
+ * @return 0 if the md5sum matched, 1 if not, -1 in case of errors
*/
static int test_md5sum(pmtrans_t *trans, const char *filename,
- const char *md5sum, alpm_list_t **data)
+ const char *md5sum)
{
char *filepath;
- char *md5sum2;
- char *errormsg = NULL;
- int ret = 0;
+ int ret;
filepath = _alpm_filecache_find(filename);
- md5sum2 = alpm_get_md5sum(filepath);
- if(md5sum == NULL) {
- if(data) {
- /* TODO wtf is this? malloc'd strings for error messages? */
- if((errormsg = calloc(512, sizeof(char))) == NULL) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
- snprintf(errormsg, 512, _("can't get md5 checksum for file %s\n"),
- filename);
- *data = alpm_list_add(*data, errormsg);
- }
- ret = 1;
- } else if(md5sum2 == NULL) {
- if(data) {
- if((errormsg = calloc(512, sizeof(char))) == NULL) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
- snprintf(errormsg, 512, _("can't get md5 checksum for file %s\n"),
- filename);
- *data = alpm_list_add(*data, errormsg);
- }
- ret = 1;
- } else if(strcmp(md5sum, md5sum2) != 0) {
+ ret = _alpm_test_md5sum(filepath, md5sum);
+
+ if(ret == 1) {
int doremove = 0;
QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename,
NULL, NULL, &doremove);
if(doremove) {
unlink(filepath);
}
- if(data) {
- if((errormsg = calloc(512, sizeof(char))) == NULL) {
- RET_ERR(PM_ERR_MEMORY, -1);
- }
- snprintf(errormsg, 512, _("file %s was corrupted (bad MD5 checksum)\n"),
- filename);
- *data = alpm_list_add(*data, errormsg);
- }
- ret = 1;
}
FREE(filepath);
- FREE(md5sum2);
-
- return(ret);
-}
-
-/** Compares the md5sum of a delta to the expected value.
- *
- * @param trans the transaction
- * @param delta the delta to test
- * @param data data to write the error messages to
- *
- * @return 0 if the md5sum matched, 1 otherwise
- */
-static int test_delta_md5sum(pmtrans_t *trans, pmdelta_t *delta,
- alpm_list_t **data)
-{
- const char *filename;
- const char *md5sum;
- int ret = 0;
-
- filename = alpm_delta_get_filename(delta);
- md5sum = alpm_delta_get_md5sum(delta);
-
- ret = test_md5sum(trans, filename, md5sum, data);
-
- return(ret);
-}
-
-/** Compares the md5sum of a package to the expected value.
- *
- * @param trans the transaction
- * @param pkg the package to test
- * @param data data to write the error messages to
- *
- * @return 0 if the md5sum matched, 1 otherwise
- */
-static int test_pkg_md5sum(pmtrans_t *trans, pmpkg_t *pkg, alpm_list_t **data)
-{
- const char *filename;
- const char *md5sum;
- int ret = 0;
-
- filename = alpm_pkg_get_filename(pkg);
- md5sum = alpm_pkg_get_md5sum(pkg);
-
- ret = test_md5sum(trans, filename, md5sum, data);
return(ret);
}
@@ -964,9 +825,9 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
alpm_list_t *i, *j, *files = NULL;
alpm_list_t *patches = NULL, *deltas = NULL;
pmtrans_t *tr = NULL;
- int replaces = 0, retval = 0;
+ int replaces = 0;
+ int errors = 0;
const char *cachedir = NULL;
- int dltotal = 0, dl = 0;
ALPM_LOG_FUNC;
@@ -976,14 +837,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
cachedir = _alpm_filecache_setup();
trans->state = STATE_DOWNLOADING;
- /* Sum up the download sizes. This has to be in its own loop because
- * the download loop is grouped by db. */
- for(j = trans->packages; j; j = j->next) {
- pmsyncpkg_t *sync = j->data;
- pmpkg_t *spkg = sync->pkg;
- dltotal += alpm_pkg_download_size(spkg, db_local);
- }
-
/* group sync records by repository and download */
for(i = handle->dbs_sync; i; i = i->next) {
pmdb_t *current = i->data;
@@ -1047,7 +900,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
if(files) {
EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL);
- if(_alpm_downloadfiles(current->servers, cachedir, files, &dl, dltotal)) {
+ if(_alpm_download_files(files, current->servers, cachedir)) {
_alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"),
current->treename);
RET_ERR(PM_ERR_RETRIEVE, -1);
@@ -1064,22 +917,22 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
/* only output if there are deltas to work with */
if(deltas) {
+ errors = 0;
/* Check integrity of deltas */
EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL);
for(i = deltas; i; i = i->next) {
pmdelta_t *d = alpm_list_getdata(i);
+ const char *filename = alpm_delta_get_filename(d);
+ const char *md5sum = alpm_delta_get_md5sum(d);
- ret = test_delta_md5sum(trans, d, data);
-
- if(ret == 1) {
- retval = 1;
- } else if(ret == -1) { /* -1 is for serious errors */
- RET_ERR(pm_errno, -1);
+ if(test_md5sum(trans, filename, md5sum) != 0) {
+ errors++;
+ *data = alpm_list_add(*data, strdup(filename));
}
}
- if(retval) {
- pm_errno = PM_ERR_DLT_CORRUPTED;
+ if(errors) {
+ pm_errno = PM_ERR_DLT_INVALID;
goto error;
}
EVENT(trans, PM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL);
@@ -1103,21 +956,20 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
/* Check integrity of packages */
EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL);
+ errors = 0;
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
pmpkg_t *spkg = sync->pkg;
- int ret = 0;
-
- ret = test_pkg_md5sum(trans, spkg, data);
+ const char *filename = alpm_pkg_get_filename(spkg);
+ const char *md5sum = alpm_pkg_get_md5sum(spkg);
- if(ret == 1) {
- retval = 1;
- } else if(ret == -1) { /* -1 is for serious errors */
- RET_ERR(pm_errno, -1);
+ if(test_md5sum(trans, filename, md5sum) != 0) {
+ errors++;
+ *data = alpm_list_add(*data, strdup(filename));
}
}
- if(retval) {
- pm_errno = PM_ERR_PKG_CORRUPTED;
+ if(errors) {
+ pm_errno = PM_ERR_PKG_INVALID;
goto error;
}
EVENT(trans, PM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL);
@@ -1130,7 +982,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
tr = _alpm_trans_new();
if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not create removal transaction\n"));
- pm_errno = PM_ERR_MEMORY;
goto error;
}
@@ -1141,16 +992,14 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;
- if(sync->type == PM_SYNC_TYPE_REPLACE) {
- alpm_list_t *j;
- for(j = sync->data; j; j = j->next) {
- pmpkg_t *pkg = j->data;
- if(!_alpm_pkg_find(pkg->name, tr->packages)) {
- if(_alpm_trans_addtarget(tr, pkg->name) == -1) {
- goto error;
- }
- replaces++;
+ alpm_list_t *j;
+ for(j = sync->removes; j; j = j->next) {
+ pmpkg_t *pkg = j->data;
+ if(!_alpm_pkg_find(pkg->name, tr->packages)) {
+ if(_alpm_trans_addtarget(tr, pkg->name) == -1) {
+ goto error;
}
+ replaces++;
}
}
}
@@ -1175,7 +1024,6 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
tr = _alpm_trans_new();
if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not create transaction\n"));
- pm_errno = PM_ERR_MEMORY;
goto error;
}
if(_alpm_trans_init(tr, PM_TRANS_TYPE_UPGRADE, trans->flags | PM_TRANS_FLAG_NODEPS, trans->cb_event, trans->cb_conv, trans->cb_progress) == -1) {
@@ -1201,9 +1049,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data)
/* using alpm_list_last() is ok because addtarget() adds the new target at the
* end of the tr->packages list */
spkg = alpm_list_last(tr->packages)->data;
- if(sync->type == PM_SYNC_TYPE_DEPEND) {
- spkg->reason = PM_PKG_REASON_DEPEND;
- }
+ spkg->reason = sync->newreason;
}
if(_alpm_trans_prepare(tr, data) == -1) {
_alpm_log(PM_LOG_ERROR, _("could not prepare transaction\n"));
@@ -1246,14 +1092,6 @@ pmsyncpkg_t *_alpm_sync_find(alpm_list_t *syncpkgs, const char* pkgname)
return(NULL); /* not found */
}
-pmsynctype_t SYMEXPORT alpm_sync_get_type(const pmsyncpkg_t *sync)
-{
- /* Sanity checks */
- ASSERT(sync != NULL, return(-1));
-
- return sync->type;
-}
-
pmpkg_t SYMEXPORT *alpm_sync_get_pkg(const pmsyncpkg_t *sync)
{
/* Sanity checks */
@@ -1262,12 +1100,12 @@ pmpkg_t SYMEXPORT *alpm_sync_get_pkg(const pmsyncpkg_t *sync)
return sync->pkg;
}
-void SYMEXPORT *alpm_sync_get_data(const pmsyncpkg_t *sync)
+alpm_list_t SYMEXPORT *alpm_sync_get_removes(const pmsyncpkg_t *sync)
{
/* Sanity checks */
ASSERT(sync != NULL, return(NULL));
- return sync->data;
+ return sync->removes;
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/sync.h b/lib/libalpm/sync.h
index a6a3e74f..b71f0ef2 100644
--- a/lib/libalpm/sync.h
+++ b/lib/libalpm/sync.h
@@ -25,12 +25,12 @@
/* Sync package */
struct __pmsyncpkg_t {
- pmsynctype_t type;
+ pmpkgreason_t newreason;
pmpkg_t *pkg;
- void *data;
+ alpm_list_t *removes;
};
-pmsyncpkg_t *_alpm_sync_new(int type, pmpkg_t *spkg, void *data);
+pmsyncpkg_t *_alpm_sync_new(pmpkgreason_t newreason, pmpkg_t *spkg, alpm_list_t *removes);
void _alpm_sync_free(pmsyncpkg_t *data);
int _alpm_sync_sysupgrade(pmtrans_t *trans,
diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c
index ecc40a0f..eb53e952 100644
--- a/lib/libalpm/trans.c
+++ b/lib/libalpm/trans.c
@@ -35,7 +35,6 @@
/* libalpm */
#include "trans.h"
#include "alpm_list.h"
-#include "error.h"
#include "package.h"
#include "util.h"
#include "log.h"
@@ -228,7 +227,6 @@ pmtrans_t *_alpm_trans_new()
CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL));
- trans->targets = NULL;
trans->packages = NULL;
trans->skip_add = NULL;
trans->skip_remove = NULL;
@@ -250,10 +248,10 @@ void _alpm_trans_free(pmtrans_t *trans)
return;
}
- FREELIST(trans->targets);
if(trans->type == PM_TRANS_TYPE_SYNC) {
alpm_list_free_inner(trans->packages, (alpm_list_fn_free)_alpm_sync_free);
- } else {
+ } else if (trans->type == PM_TRANS_TYPE_REMOVE ||
+ trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
alpm_list_free_inner(trans->packages, (alpm_list_fn_free)_alpm_pkg_free);
}
alpm_list_free(trans->packages);
@@ -307,13 +305,7 @@ int _alpm_trans_addtarget(pmtrans_t *trans, char *target)
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
ASSERT(target != NULL, RET_ERR(PM_ERR_WRONG_ARGS, -1));
- if(alpm_list_find_str(trans->targets, target)) {
- return(0);
- //RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1);
- }
-
switch(trans->type) {
- case PM_TRANS_TYPE_ADD:
case PM_TRANS_TYPE_UPGRADE:
if(_alpm_add_loadtarget(trans, handle->db_local, target) == -1) {
/* pm_errno is set by _alpm_add_loadtarget() */
@@ -335,8 +327,6 @@ int _alpm_trans_addtarget(pmtrans_t *trans, char *target)
break;
}
- trans->targets = alpm_list_add(trans->targets, strdup(target));
-
return(0);
}
@@ -357,7 +347,6 @@ int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data)
}
switch(trans->type) {
- case PM_TRANS_TYPE_ADD:
case PM_TRANS_TYPE_UPGRADE:
if(_alpm_add_prepare(trans, handle->db_local, data) == -1) {
/* pm_errno is set by _alpm_add_prepare() */
@@ -402,7 +391,6 @@ int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data)
trans->state = STATE_COMMITING;
switch(trans->type) {
- case PM_TRANS_TYPE_ADD:
case PM_TRANS_TYPE_UPGRADE:
if(_alpm_add_commit(trans, handle->db_local) == -1) {
/* pm_errno is set by _alpm_add_commit() */
@@ -636,15 +624,6 @@ unsigned int SYMEXPORT alpm_trans_get_flags()
return handle->trans->flags;
}
-alpm_list_t SYMEXPORT * alpm_trans_get_targets()
-{
- /* Sanity checks */
- ASSERT(handle != NULL, return(NULL));
- ASSERT(handle->trans != NULL, return(NULL));
-
- return handle->trans->targets;
-}
-
alpm_list_t SYMEXPORT * alpm_trans_get_pkgs()
{
/* Sanity checks */
diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h
index 75608ce4..d74c3e90 100644
--- a/lib/libalpm/trans.h
+++ b/lib/libalpm/trans.h
@@ -39,7 +39,6 @@ struct __pmtrans_t {
pmtranstype_t type;
pmtransflag_t flags;
pmtransstate_t state;
- alpm_list_t *targets; /* list of (char *) */
alpm_list_t *packages; /* list of (pmpkg_t *) or (pmsyncpkg_t *) */
alpm_list_t *skip_add; /* list of (char *) */
alpm_list_t *skip_remove; /* list of (char *) */
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index e1413a25..9f431ed7 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -43,7 +43,6 @@
/* libalpm */
#include "util.h"
#include "log.h"
-#include "error.h"
#include "package.h"
#include "alpm.h"
#include "alpm_list.h"
@@ -371,6 +370,13 @@ int _alpm_lckrm()
/* Compression functions */
+/**
+ * @brief Unpack a specific file or all files in an archive.
+ *
+ * @param archive the archive to unpack
+ * @param prefix where to extract the files
+ * @param fn a file within the archive to unpack or NULL for all
+ */
int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
{
int ret = 1;
@@ -382,7 +388,7 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
ALPM_LOG_FUNC;
if((_archive = archive_read_new()) == NULL)
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1);
+ RET_ERR(PM_ERR_LIBARCHIVE, -1);
archive_read_support_compression_all(_archive);
archive_read_support_format_all(_archive);
@@ -408,13 +414,17 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn)
archive_entry_set_mode(entry, 0755);
}
+ /* If a specific file was requested skip entries that don't match. */
if (fn && strcmp(fn, entryname)) {
+ _alpm_log(PM_LOG_DEBUG, "skipping: %s\n", entryname);
if (archive_read_data_skip(_archive) != ARCHIVE_OK) {
ret = 1;
goto cleanup;
}
continue;
}
+
+ /* Extract the archive entry. */
ret = 0;
snprintf(expath, PATH_MAX, "%s/%s", prefix, entryname);
archive_entry_set_pathname(entry, expath);
@@ -640,13 +650,7 @@ char SYMEXPORT *alpm_get_md5sum(const char *filename)
ret = md5_file(filename, output);
if (ret > 0) {
- if (ret == 1) {
- _alpm_log(PM_LOG_ERROR, _("md5: %s can't be opened\n"), filename);
- } else if (ret == 2) {
- _alpm_log(PM_LOG_ERROR, _("md5: %s can't be read\n"), filename);
- }
-
- return(NULL);
+ RET_ERR(PM_ERR_NOT_A_FILE, NULL);
}
/* Convert the result to something readable */
@@ -660,4 +664,52 @@ char SYMEXPORT *alpm_get_md5sum(const char *filename)
return(md5sum);
}
+int _alpm_test_md5sum(const char *filepath, const char *md5sum)
+{
+ char *md5sum2;
+ int ret;
+
+ md5sum2 = alpm_get_md5sum(filepath);
+
+ if(md5sum == NULL || md5sum2 == NULL) {
+ ret = -1;
+ } else if(strcmp(md5sum, md5sum2) != 0) {
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+
+ FREE(md5sum2);
+ return(ret);
+}
+
+char *_alpm_archive_fgets(char *line, size_t size, struct archive *a)
+{
+ /* for now, just read one char at a time until we get to a
+ * '\n' char. we can optimize this later with an internal
+ * buffer. */
+ /* leave room for zero terminator */
+ char *last = line + size - 1;
+ char *i;
+
+ for(i = line; i < last; i++) {
+ int ret = archive_read_data(a, i, 1);
+ /* special check for first read- if null, return null,
+ * this indicates EOF */
+ if(i == line && (ret <= 0 || *i == '\0')) {
+ return(NULL);
+ }
+ /* check if read value was null or newline */
+ if(ret <= 0 || *i == '\0' || *i == '\n') {
+ last = i + 1;
+ break;
+ }
+ }
+
+ /* always null terminate the buffer */
+ *last = '\0';
+
+ return(line);
+}
+
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index e9e0af1f..74b4f981 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <time.h>
#include <sys/stat.h> /* struct stat */
+#include <archive.h> /* struct archive */
#ifdef ENABLE_NLS
#include <libintl.h> /* here so it doesn't need to be included elsewhere */
@@ -43,12 +44,17 @@
#define MALLOC(p, s, action) do { p = calloc(1, s); if(p == NULL) { ALLOC_FAIL(s); action; } } while(0)
#define CALLOC(p, l, s, action) do { p = calloc(l, s); if(p == NULL) { ALLOC_FAIL(s); action; } } while(0)
-#define STRDUP(r, s, action) do { r = strdup(s); if(r == NULL) { ALLOC_FAIL(strlen(s)); action; } } while(0)
+/* This strdup macro is NULL safe- copying NULL will yield NULL */
+#define STRDUP(r, s, action) do { if(s != NULL) { r = strdup(s); if(r == NULL) { ALLOC_FAIL(strlen(s)); action; } } else { r = NULL; } } while(0)
#define FREE(p) do { if(p) { free(p); p = NULL; } } while(0)
#define ASSERT(cond, action) do { if(!(cond)) { action; } } while(0)
+#define RET_ERR(err, ret) do { pm_errno = (err); \
+ _alpm_log(PM_LOG_DEBUG, "returning error %d from %s : %s\n", err, __func__, alpm_strerrorlast()); \
+ return(ret); } while(0)
+
int _alpm_makepath(const char *path);
int _alpm_makepath_mode(const char *path, mode_t mode);
int _alpm_copyfile(const char *src, const char *dest);
@@ -64,6 +70,8 @@ int _alpm_str_cmp(const void *s1, const void *s2);
char *_alpm_filecache_find(const char *filename);
const char *_alpm_filecache_setup(void);
int _alpm_lstat(const char *path, struct stat *buf);
+int _alpm_test_md5sum(const char *filepath, const char *md5sum);
+char *_alpm_archive_fgets(char *line, size_t size, struct archive *a);
#ifndef HAVE_STRVERSCMP
int strverscmp(const char *, const char *);
diff --git a/ltmain.sh b/ltmain.sh
index 4598ec61..c4a714df 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -2,7 +2,7 @@
# NOTE: Changing this file will not affect anything until you rerun configure.
#
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
-# 2007 Free Software Foundation, Inc.
+# 2007, 2008 Free Software Foundation, Inc.
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This program is free software; you can redistribute it and/or modify
@@ -43,8 +43,8 @@ EXIT_FAILURE=1
PROGRAM=ltmain.sh
PACKAGE=libtool
-VERSION=1.5.24
-TIMESTAMP=" (1.1220.2.455 2007/06/24 02:13:29)"
+VERSION=1.5.26
+TIMESTAMP=" (1.1220.2.492 2008/01/30 06:40:56)"
# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -113,15 +113,21 @@ esac
# These must not be set unconditionally because not all systems understand
# e.g. LANG=C (notably SCO).
# We save the old values to restore during execute mode.
-for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+lt_env=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
do
eval "if test \"\${$lt_var+set}\" = set; then
save_$lt_var=\$$lt_var
+ lt_env=\"$lt_var=\$$lt_var \$lt_env\"
$lt_var=C
export $lt_var
fi"
done
+if test -n "$lt_env"; then
+ lt_env="env $lt_env"
+fi
+
# Make sure IFS has a sensible default
lt_nl='
'
@@ -485,7 +491,7 @@ do
echo "\
$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
-Copyright (C) 2007 Free Software Foundation, Inc.
+Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
exit $?
@@ -788,6 +794,7 @@ if test -z "$show_help"; then
*.for) xform=for ;;
*.java) xform=java ;;
*.obj) xform=obj ;;
+ *.sx) xform=sx ;;
esac
libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
@@ -956,7 +963,7 @@ EOF
$run $rm "$lobj" "$output_obj"
$show "$command"
- if $run eval "$command"; then :
+ if $run eval $lt_env "$command"; then :
else
test -n "$output_obj" && $run $rm $removelist
exit $EXIT_FAILURE
@@ -1028,7 +1035,7 @@ EOF
command="$command$suppress_output"
$run $rm "$obj" "$output_obj"
$show "$command"
- if $run eval "$command"; then :
+ if $run eval $lt_env "$command"; then :
else
$run $rm $removelist
exit $EXIT_FAILURE
@@ -1161,6 +1168,7 @@ EOF
thread_safe=no
vinfo=
vinfo_number=no
+ single_module="${wl}-single_module"
func_infer_tag $base_compile
@@ -1646,6 +1654,11 @@ EOF
continue
;;
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
-module)
module=yes
continue
@@ -2149,7 +2162,12 @@ EOF
continue
fi
name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
- for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
for search_ext in .la $std_shrext .so .a; do
# Search the libtool library
lib="$searchdir/lib${name}${search_ext}"
@@ -2945,12 +2963,18 @@ EOF
# we do not want to link against static libs,
# but need to link against shared
eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -n "$deplibrary_names" ; then
for tmp in $deplibrary_names ; do
depdepl=$tmp
done
- if test -f "$path/$depdepl" ; then
+ if test -f "$deplibdir/$depdepl" ; then
+ depdepl="$deplibdir/$depdepl"
+ elif test -f "$path/$depdepl" ; then
depdepl="$path/$depdepl"
+ else
+ # Can't find it, oh well...
+ depdepl=
fi
# do not add paths which are already there
case " $newlib_search_path " in
@@ -3098,9 +3122,10 @@ EOF
case $linkmode in
oldlib)
- if test -n "$deplibs"; then
- $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
- fi
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
+ esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
@@ -4237,9 +4262,10 @@ EOF
;;
obj)
- if test -n "$deplibs"; then
- $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
- fi
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
+ esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
@@ -6478,7 +6504,7 @@ relink_command=\"$relink_command\""
fi
# Restore saved environment variables
- for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
do
eval "if test \"\${save_$lt_var+set}\" = set; then
$lt_var=\$save_$lt_var; export $lt_var
diff --git a/pactest/Makefile.am b/pactest/Makefile.am
index 879f23d0..85bb8017 100644
--- a/pactest/Makefile.am
+++ b/pactest/Makefile.am
@@ -7,8 +7,7 @@ check_SCRIPTS = \
pmrule.py \
pmtest.py \
util.py \
- $(wildcard tests/*.py) \
- tests/TESTS
+ $(wildcard tests/*.py)
noinst_SCRIPTS = $(check_SCRIPTS)
diff --git a/pactest/pmtest.py b/pactest/pmtest.py
index be36914b..d843ea6a 100755
--- a/pactest/pmtest.py
+++ b/pactest/pmtest.py
@@ -199,7 +199,7 @@ class pmtest:
if pacman["gdb"]:
cmd.append("libtool gdb --args")
if pacman["valgrind"]:
- cmd.append("valgrind --tool=memcheck --leak-check=full --show-reachable=yes")
+ cmd.append("valgrind -q --tool=memcheck --leak-check=full --show-reachable=yes")
cmd.append("%s --config=%s --root=%s --dbpath=%s --cachedir=%s" \
% (pacman["bin"],
os.path.join(self.root, PACCONF),
@@ -233,11 +233,6 @@ class pmtest:
vprint("\tretcode = %s" % self.retcode)
os.chdir(curdir)
- # Check if pacman failed because of bad permissions
- if self.retcode and not pacman["nolog"] \
- and grep(os.path.join(self.root, LOGFILE),
- "you cannot perform this operation unless you are root"):
- print "\tERROR: pacman support for fakeroot is not disabled"
# Check if the lock is still there
if os.path.isfile(PM_LOCK):
print "\tERROR: %s not removed" % PM_LOCK
diff --git a/pactest/tests/TESTS b/pactest/tests/TESTS
deleted file mode 100644
index e09a78b9..00000000
--- a/pactest/tests/TESTS
+++ /dev/null
@@ -1,63 +0,0 @@
-TODO: this is really outdated, needs regeneration (after we rename tests)
-
-add001: Install a package
-add002: Install a package (already installed)
-add003: Install a set of packages
-add004: Install a set of the same package at different versions
-add010: Install a package with a filesystem conflict
-add011: Install a package with a filesystem conflict (--force)
-add012: Install two packages with a conflicting file
-add013: Install two packages with a conflicting file (--force)
-add020: Install a package with an existing file
-add021: Install a package with an existing file (new modified)
-add030: Freshen a package
-add031: Freshen a package (installed is newer)
-add032: Freshen a package (installed is newer)
-add040: Install a package with a missing dependency
-add041: Install a package with a missing dependency (nodeps)
-add042: Install a package with cascaded dependencies
-add050: Install a package with a file in NoUpgrade
-add060: Install a package with a file in NoExtract
-query001: Query a package
-remove010: Remove a package, with a file marked for backup
-remove011: Remove a package, with a modified file marked for backup
-remove020: Remove a package, with a file marked for backup (--nosave)
-remove021: Remove a package, with a modified file marked for backup (--nosave)
-smoke001: Install a thousand packages in a single transaction
-sync001: Install a package from a sync db
-sync002: Upgrade a package from a sync db
-sync003: Install a package from a sync db, with a filesystem conflict
-sync010: Install a package from a sync db, with its dependencies
-sync040: Install two targets with a conflict
-sync041: Install two conflicting targets
-sync042: Install a sync package conflicting with a local one
-sync043: Install a sync package conflicting with a local one
-sync050: Install a virtual target (provided by a sync package)
-sync100: Sysupgrade with a newer sync package
-sync101: Sysupgrade with same version for local and sync packages
-sync102: Sysupgrade with a newer local package
-sync103: Sysupgrade with a local package not existing in sync db
-sync110: Sysupgrade of a package pulling new dependencies
-sync120: Sysupgrade of packages in 'IgnorePkg'
-sync130: Sysupgrade with a sync package replacing a local one
-sync131: Sysupgrade with a sync package replacing a set of local ones
-sync132: Sysupgrade with a replacement for a local package out of date
-sync133: Sysupgrade with a sync package replacing a local one in 'IgnorePkg'
-sync134: Sysupgrade with a set of sync packages replacing a set local one
-sync135: Sysupgrade with a set of sync packages replacing a set of local ones
-sync897: System upgrade
-sync898: System upgrade
-sync899: System upgrade
-sync990: Sync a package pulling a dependency conflicting with a target
-sync992: Sync a package pulling a conflicting dependency
-sync999: System upgrade
-upgrade001: Upgrade a package (newer version)
-upgrade002: Upgrade a package (same version)
-upgrade003: Upgrade a package (lesser version)
-upgrade004: Upgrade a package (not installed)
-upgrade010: Upgrade a package, with a file in NoUpgrade
-upgrade020: Upgrade a package, with a file in 'backup' (new modified)
-upgrade021: Upgrade a package, with a file in 'backup' (local modified, new unchanged)
-upgrade022: Upgrade a package, with a file in 'backup' (local and new modified)
-upgrade030: Upgrade packages with various reasons
-upgrade040: file relocation 1
diff --git a/pactest/tests/add001.py b/pactest/tests/add001.py
deleted file mode 100644
index 3dde4061..00000000
--- a/pactest/tests/add001.py
+++ /dev/null
@@ -1,13 +0,0 @@
-self.description = "Install a simple package with two files"
-
-p = pmpkg("dummy")
-p.files = ["bin/dummy",
- "usr/man/man1/dummy.1"]
-self.addpkg(p)
-
-self.args = "-A %s" % p.filename()
-
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("PKG_EXIST=dummy")
-for f in p.files:
- self.addrule("FILE_EXIST=%s" % f)
diff --git a/pactest/tests/add002.py b/pactest/tests/add002.py
deleted file mode 100644
index f6bc91a2..00000000
--- a/pactest/tests/add002.py
+++ /dev/null
@@ -1,18 +0,0 @@
-self.description = "Install an already-installed package"
-
-lp = pmpkg("dummy")
-lp.files = ["bin/dummy",
- "usr/man/man1/dummy.1"]
-self.addpkg2db("local", lp)
-
-p = pmpkg("dummy")
-p.files = ["bin/dummy",
- "usr/man/man1/dummy.1"]
-self.addpkg(p)
-
-self.args = "-A %s" % p.filename()
-
-self.addrule("PACMAN_RETCODE=1")
-self.addrule("!PKG_MODIFIED=dummy")
-for f in lp.files:
- self.addrule("!FILE_MODIFIED=%s" % f)
diff --git a/pactest/tests/add004.py b/pactest/tests/add004.py
deleted file mode 100644
index d0188563..00000000
--- a/pactest/tests/add004.py
+++ /dev/null
@@ -1,18 +0,0 @@
-self.description = "Install three of the same package at different versions"
-
-p1 = pmpkg("dummy", "1.0-2")
-p1.files = ["bin/dummy"]
-p2 = pmpkg("dummy", "2.0-1")
-p2.files = ["bin/dummy"]
-p3 = pmpkg("dummy")
-p3.files = ["bin/dummy"]
-
-for p in p1, p2, p3:
- self.addpkg(p)
-
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2, p3])
-
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("PKG_VERSION=dummy|2.0-1")
-for f in p2.files:
- self.addrule("FILE_EXIST=%s" % f)
diff --git a/pactest/tests/add010.py b/pactest/tests/add010.py
deleted file mode 100644
index a7874746..00000000
--- a/pactest/tests/add010.py
+++ /dev/null
@@ -1,15 +0,0 @@
-self.description = "Install a package with a filesystem conflict"
-
-p = pmpkg("dummy")
-p.files = ["bin/dummy",
- "usr/man/man1/dummy.1"]
-self.addpkg(p)
-
-self.filesystem = ["bin/dummy"]
-
-self.args = "-A %s" % p.filename()
-
-self.addrule("PACMAN_RETCODE=1")
-self.addrule("!PKG_EXIST=dummy")
-self.addrule("!FILE_MODIFIED=bin/dummy")
-self.addrule("!FILE_EXIST=usr/man/man1/dummy.1")
diff --git a/pactest/tests/add050.py b/pactest/tests/add050.py
deleted file mode 100644
index b48459ab..00000000
--- a/pactest/tests/add050.py
+++ /dev/null
@@ -1,17 +0,0 @@
-self.description = "Install a package with a file in NoUpgrade"
-
-p = pmpkg("dummy")
-p.files = ["etc/dummy.conf"]
-p.backup = ["etc/dummy.conf"]
-self.addpkg(p)
-
-self.filesystem = ["etc/dummy.conf"]
-
-self.option["noupgrade"] = ["etc/dummy.conf"]
-
-self.args = "-Af %s" % p.filename()
-
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("PKG_EXIST=dummy")
-self.addrule("!FILE_MODIFIED=etc/dummy.conf")
-self.addrule("FILE_PACNEW=etc/dummy.conf")
diff --git a/pactest/tests/depconflict110.py b/pactest/tests/depconflict110.py
index 2e326f52..fd56fa89 100644
--- a/pactest/tests/depconflict110.py
+++ b/pactest/tests/depconflict110.py
@@ -7,7 +7,7 @@ self.addpkg(p);
lp = pmpkg("pkg2", "1.0-1")
self.addpkg2db("local", lp)
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
self.addrule("PKG_EXIST=pkg2")
diff --git a/pactest/tests/depconflict111.py b/pactest/tests/depconflict111.py
index 6f95733b..0d11dd92 100644
--- a/pactest/tests/depconflict111.py
+++ b/pactest/tests/depconflict111.py
@@ -7,7 +7,7 @@ self.addpkg(p);
lp = pmpkg("pkg2", "1.0-1")
self.addpkg2db("local", lp)
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
self.addrule("PKG_EXIST=pkg2")
diff --git a/pactest/tests/deptest001.py b/pactest/tests/deptest001.py
index db0b7684..18569bea 100644
--- a/pactest/tests/deptest001.py
+++ b/pactest/tests/deptest001.py
@@ -1,20 +1,16 @@
self.description = "test deptest (-T) functionality"
-sp1 = pmpkg("pkg1")
-sp1.depends = ["dep"]
-self.addpkg2db("sync", sp1)
+lp1 = pmpkg("pkg1")
+self.addpkg2db("local", lp1)
-sp1dep = pmpkg("dep")
-self.addpkg2db("sync", sp1dep)
+lp3 = pmpkg("pkg3", "2.0-1")
+lp3.provides = ("prov=3.0")
+self.addpkg2db("local", lp3)
-sp2 = pmpkg("pkg2")
-self.addpkg2db("sync", sp2)
-
-lp2 = pmpkg("pkg2")
-self.addpkg2db("local", lp2)
-
-self.args = "-T pkg1 pkg2"
+self.args = "-T pkg1 pkg2 pkg3\>2.1 prov\>\=3.0"
self.addrule("PACMAN_RETCODE=127")
-self.addrule("PACMAN_OUTPUT=pkg1")
-self.addrule("!PACMAN_OUTPUT=pkg2")
+self.addrule("!PACMAN_OUTPUT=pkg1")
+self.addrule("PACMAN_OUTPUT=pkg2")
+self.addrule("PACMAN_OUTPUT=pkg3")
+self.addrule("!PACMAN_OUTPUT=prov")
diff --git a/pactest/tests/fileconflict001.py b/pactest/tests/fileconflict001.py
index 8aca9a0a..4c2069ee 100644
--- a/pactest/tests/fileconflict001.py
+++ b/pactest/tests/fileconflict001.py
@@ -13,7 +13,7 @@ p2 = pmpkg("pkg2")
p2.files = ["dir/symdir/file"]
self.addpkg(p2)
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2])
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
diff --git a/pactest/tests/fileconflict002.py b/pactest/tests/fileconflict002.py
index da04e332..c54f6daf 100644
--- a/pactest/tests/fileconflict002.py
+++ b/pactest/tests/fileconflict002.py
@@ -9,7 +9,7 @@ p2 = pmpkg("pkg2")
p2.files = ["dir/symdir/file"]
self.addpkg(p2)
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2])
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
diff --git a/pactest/tests/ldconfig001.py b/pactest/tests/ldconfig001.py
index aced413b..9ac2ff35 100644
--- a/pactest/tests/ldconfig001.py
+++ b/pactest/tests/ldconfig001.py
@@ -6,7 +6,7 @@ p = pmpkg("dummy")
self.addpkg(p)
# --debug is necessary to check PACMAN_OUTPUT
-self.args = "--debug -A %s" % p.filename()
+self.args = "--debug -U %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PACMAN_OUTPUT=ldconfig")
diff --git a/pactest/tests/query003.py b/pactest/tests/query003.py
index ea113081..41b8a45b 100644
--- a/pactest/tests/query003.py
+++ b/pactest/tests/query003.py
@@ -2,6 +2,7 @@ self.description = "Query search for a package"
p = pmpkg("foobar")
p.files = ["bin/foobar"]
+p.groups = ["group1", "group2"]
self.addpkg2db("local", p)
self.args = "-Qs %s" % p.name
diff --git a/pactest/tests/reason001.py b/pactest/tests/reason001.py
new file mode 100644
index 00000000..40433f5e
--- /dev/null
+++ b/pactest/tests/reason001.py
@@ -0,0 +1,16 @@
+self.description = "Copy reason (to-be-replaced -> replacement)"
+
+sp = pmpkg("libfoo-ng")
+sp.replaces = [ "libfoo" ]
+self.addpkg2db("sync", sp)
+
+lp = pmpkg("libfoo")
+lp.reason = 1
+self.addpkg2db("local", lp)
+
+self.args = "-Su"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=libfoo")
+self.addrule("PKG_EXIST=libfoo-ng")
+self.addrule("PKG_REASON=libfoo-ng|1")
diff --git a/pactest/tests/remove001.py b/pactest/tests/remove001.py
index 809bfdb7..d20dd079 100644
--- a/pactest/tests/remove001.py
+++ b/pactest/tests/remove001.py
@@ -1,4 +1,3 @@
-# If someone else can come up with a better name, please do so
self.description = "Remove a package listed 5 times"
p = pmpkg("foo")
@@ -6,5 +5,5 @@ self.addpkg2db("local", p)
self.args = "-R " + "foo "*5
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("!PKG_EXISTS=foo")
+self.addrule("PACMAN_RETCODE=1")
+self.addrule("PKG_EXISTS=foo")
diff --git a/pactest/tests/remove030.py b/pactest/tests/remove030.py
index cc23f144..9e2b9da5 100644
--- a/pactest/tests/remove030.py
+++ b/pactest/tests/remove030.py
@@ -3,7 +3,7 @@ self.description = "Remove a package in HoldPkg"
p1 = pmpkg("dummy")
self.addpkg2db("local", p1)
-self.option["holdpkg"] = ["dummy"]
+self.option["HoldPkg"] = ["dummy"]
self.args = "-R %s" % p1.name
diff --git a/pactest/tests/remove049.py b/pactest/tests/remove049.py
new file mode 100644
index 00000000..724f8da2
--- /dev/null
+++ b/pactest/tests/remove049.py
@@ -0,0 +1,19 @@
+self.description = "-Ru test"
+
+lp1 = pmpkg("pkg1")
+lp1.requiredby = [ "pkg3" ]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.depends = [ "pkg1" ]
+self.addpkg2db("local", lp3)
+
+self.args = "-Ru pkg1 pkg2"
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3") \ No newline at end of file
diff --git a/pactest/tests/remove050.py b/pactest/tests/remove050.py
new file mode 100644
index 00000000..44b0d18c
--- /dev/null
+++ b/pactest/tests/remove050.py
@@ -0,0 +1,20 @@
+self.description = "-Rs test (exclude explicit)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2" , "pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 0
+self.addpkg2db("local", lp3)
+
+self.args = "-Rs %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/pactest/tests/remove051.py b/pactest/tests/remove051.py
new file mode 100644
index 00000000..bba87bba
--- /dev/null
+++ b/pactest/tests/remove051.py
@@ -0,0 +1,20 @@
+self.description = "-Rss test (include explicit)"
+
+lp1 = pmpkg("pkg1")
+lp1.depends = ["pkg2" , "pkg3"]
+self.addpkg2db("local", lp1)
+
+lp2 = pmpkg("pkg2")
+lp2.reason = 1
+self.addpkg2db("local", lp2)
+
+lp3 = pmpkg("pkg3")
+lp3.reason = 0
+self.addpkg2db("local", lp3)
+
+self.args = "-Rss %s" % lp1.name
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("!PKG_EXIST=pkg1")
+self.addrule("!PKG_EXIST=pkg2")
+self.addrule("!PKG_EXIST=pkg3")
diff --git a/pactest/tests/smoke001.py b/pactest/tests/smoke001.py
index 71a08d3f..c6636391 100644
--- a/pactest/tests/smoke001.py
+++ b/pactest/tests/smoke001.py
@@ -12,7 +12,7 @@ for i in range(1000):
_list = []
[_list.append(p.filename()) for p in self.localpkgs]
-self.args = "-A %s" % " ".join(_list)
+self.args = "-U %s" % " ".join(_list)
self.addrule("PACMAN_RETCODE=0")
#for i in range(1000):
diff --git a/pactest/tests/sync021.py b/pactest/tests/sync021.py
index a4073eed..4c664d8e 100644
--- a/pactest/tests/sync021.py
+++ b/pactest/tests/sync021.py
@@ -12,7 +12,7 @@ sp3.groups = ["grp"]
for p in sp1, sp2, sp3:
self.addpkg2db("sync", p);
-self.option["ignorepkg"] = ["pkg2"]
+self.option["IgnorePkg"] = ["pkg2"]
self.args = "-S grp"
diff --git a/pactest/tests/sync031.py b/pactest/tests/sync031.py
new file mode 100644
index 00000000..4aa2ee39
--- /dev/null
+++ b/pactest/tests/sync031.py
@@ -0,0 +1,19 @@
+self.description = "Sync packages explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 1
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg2db("sync", p)
+
+self.args = "-S --asexplicit %s" % " ".join([p.name for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|0")
+self.addrule("PKG_REASON=pkg2|0")
diff --git a/pactest/tests/sync1001.py b/pactest/tests/sync1001.py
deleted file mode 100644
index 6c4aabcf..00000000
--- a/pactest/tests/sync1001.py
+++ /dev/null
@@ -1,18 +0,0 @@
-self.description = "Test -Se (ensure specified package is not installed)"
-
-sp1 = pmpkg("dummy")
-sp1.depends = [ "dep1", "dep2" ]
-self.addpkg2db("sync", sp1)
-
-sp2 = pmpkg("dep1")
-self.addpkg2db("sync", sp2)
-
-sp3 = pmpkg("dep2")
-self.addpkg2db("sync", sp3)
-
-self.args = "-Se dummy"
-
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("PKG_EXIST=dep1")
-self.addrule("PKG_EXIST=dep2")
-self.addrule("!PKG_EXIST=dummy")
diff --git a/pactest/tests/sync1002.py b/pactest/tests/sync1002.py
deleted file mode 100644
index c158838b..00000000
--- a/pactest/tests/sync1002.py
+++ /dev/null
@@ -1,19 +0,0 @@
-self.description = "Test -Se (resolve the dependencies' dependencies )"
-
-sp1 = pmpkg("pkg1")
-sp1.depends = [ "pkg2" ]
-self.addpkg2db("sync", sp1)
-
-sp2 = pmpkg("pkg2")
-sp2.depends = [ "pkg3" ]
-self.addpkg2db("sync", sp2)
-
-sp3 = pmpkg("pkg3")
-self.addpkg2db("sync", sp3)
-
-self.args = "-Se pkg1 pkg3"
-
-self.addrule("PACMAN_RETCODE=0")
-self.addrule("PKG_EXIST=pkg2")
-self.addrule("PKG_EXIST=pkg3")
-self.addrule("!PKG_EXIST=pkg1")
diff --git a/pactest/tests/sync1006.py b/pactest/tests/sync1006.py
deleted file mode 100644
index c331f42e..00000000
--- a/pactest/tests/sync1006.py
+++ /dev/null
@@ -1,14 +0,0 @@
-self.description = "Conflicting package names in sync repos (diff versions)"
-
-sp1 = pmpkg("pkg", "1.0-1")
-sp1.provides = [ "provision1" ]
-self.addpkg2db("sync1", sp1)
-
-sp2 = pmpkg("pkg", "2.0-1")
-sp2.provides = [ "provision2" ]
-self.addpkg2db("sync2", sp2)
-
-self.args = "-S provision1 provision2"
-
-self.addrule("PACMAN_RETCODE=1")
-self.addrule("!PKG_EXIST=pkg")
diff --git a/pactest/tests/sync1005.py b/pactest/tests/sync1008.py
index 4fa82478..a6064597 100644
--- a/pactest/tests/sync1005.py
+++ b/pactest/tests/sync1008.py
@@ -1,14 +1,19 @@
self.description = "Conflicting package names in sync repos"
-sp1 = pmpkg("pkg")
+sp1 = pmpkg("cpkg", "1.0-1")
sp1.provides = [ "provision1" ]
self.addpkg2db("sync1", sp1)
-sp2 = pmpkg("pkg")
+sp2 = pmpkg("cpkg", "2.0-1")
sp2.provides = [ "provision2" ]
self.addpkg2db("sync2", sp2)
-self.args = "-S provision1 provision2"
+sp3 = pmpkg("pkg")
+sp3.depends = [ "provision1" , "provision2" ]
+self.addpkg2db("sync1", sp3)
+
+self.args = "-S pkg"
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg")
+self.addrule("!PKG_EXIST=cpkg")
diff --git a/pactest/tests/sync1101.py b/pactest/tests/sync1101.py
index ba2ad44f..e3ed0f0f 100644
--- a/pactest/tests/sync1101.py
+++ b/pactest/tests/sync1101.py
@@ -1,6 +1,7 @@
self.description = "Search for package from a sync db"
sp = pmpkg("dummy")
+sp.groups = ["group1", "group2"]
sp.files = ["bin/dummy",
"usr/man/man1/dummy.1"]
self.addpkg2db("sync", sp)
diff --git a/pactest/tests/sync120.py b/pactest/tests/sync120.py
index b8fc6747..994e440e 100644
--- a/pactest/tests/sync120.py
+++ b/pactest/tests/sync120.py
@@ -12,7 +12,7 @@ lp2 = pmpkg("pkg2")
for p in lp1, lp2:
self.addpkg2db("local", p)
-self.option["ignorepkg"] = ["pkg2"]
+self.option["IgnorePkg"] = ["pkg2"]
self.args = "-Su"
diff --git a/pactest/tests/sync133.py b/pactest/tests/sync133.py
index b852a7fc..cea603b8 100644
--- a/pactest/tests/sync133.py
+++ b/pactest/tests/sync133.py
@@ -9,7 +9,7 @@ lp = pmpkg("pkg1")
self.addpkg2db("local", lp)
-self.option["ignorepkg"] = ["pkg1"]
+self.option["IgnorePkg"] = ["pkg1"]
self.args = "-Su"
diff --git a/pactest/tests/sync138.py b/pactest/tests/sync138.py
index 410c7f07..e67c4f46 100644
--- a/pactest/tests/sync138.py
+++ b/pactest/tests/sync138.py
@@ -13,7 +13,7 @@ lp2 = pmpkg("pkg2")
for p in lp1, lp2:
self.addpkg2db("local", p)
-self.option["ignoregroup"] = ["grp"]
+self.option["IgnoreGroup"] = ["grp"]
self.args = "-Su"
diff --git a/pactest/tests/sync893.py b/pactest/tests/sync893.py
index 9420b74c..1c8494a3 100644
--- a/pactest/tests/sync893.py
+++ b/pactest/tests/sync893.py
@@ -15,6 +15,6 @@ self.addpkg2db("local", lp2)
self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
-self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_RETCODE=1")
self.addrule("PKG_EXIST=pkg1")
-self.addrule("!PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg2")
diff --git a/pactest/tests/sync897.py b/pactest/tests/sync897.py
index 3cf43929..f7bd3d71 100644
--- a/pactest/tests/sync897.py
+++ b/pactest/tests/sync897.py
@@ -18,7 +18,7 @@ self.addpkg2db("local", lp3)
self.args = "-Su"
-self.addrule("PACMAN_RETCODE=0")
+self.addrule("PACMAN_RETCODE=1")
self.addrule("PKG_EXIST=pkg1")
-self.addrule("!PKG_EXIST=pkg2")
-self.addrule("!PKG_EXIST=pkg3")
+self.addrule("PKG_EXIST=pkg2")
+self.addrule("PKG_EXIST=pkg3")
diff --git a/pactest/tests/add003.py b/pactest/tests/upgrade005.py
index 4f8ae600..0f8c13ef 100644
--- a/pactest/tests/add003.py
+++ b/pactest/tests/upgrade005.py
@@ -14,7 +14,7 @@ p3.files = ["bin/pkg3", "usr/man/man1/pkg3.1"]
for p in p1, p2, p3:
self.addpkg(p)
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2, p3])
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2, p3])
self.addrule("PACMAN_RETCODE=0")
for p in p1, p2, p3:
diff --git a/pactest/tests/upgrade010.py b/pactest/tests/upgrade010.py
index 633ef7e4..3d8b21e1 100644
--- a/pactest/tests/upgrade010.py
+++ b/pactest/tests/upgrade010.py
@@ -8,7 +8,7 @@ p = pmpkg("dummy", "1.0-2")
p.files = ["etc/dummy.conf"]
self.addpkg(p)
-self.option["noupgrade"] = ["etc/dummy.conf"]
+self.option["NoUpgrade"] = ["etc/dummy.conf"]
self.args = "-U %s" % p.filename()
diff --git a/pactest/tests/add011.py b/pactest/tests/upgrade012.py
index 5d2ae43f..dba8dc18 100644
--- a/pactest/tests/add011.py
+++ b/pactest/tests/upgrade012.py
@@ -6,7 +6,7 @@ self.addpkg(p)
self.filesystem = ["bin/dummy"]
-self.args = "-Af %s" % p.filename()
+self.args = "-Uf %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
diff --git a/pactest/tests/add012.py b/pactest/tests/upgrade013.py
index 291d1fba..5a327599 100644
--- a/pactest/tests/add012.py
+++ b/pactest/tests/upgrade013.py
@@ -13,7 +13,7 @@ p2.files = ["bin/foobar",
for p in p1, p2:
self.addpkg(p)
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2])
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2])
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=dummy")
diff --git a/pactest/tests/add013.py b/pactest/tests/upgrade014.py
index 547ce001..1632dd36 100644
--- a/pactest/tests/add013.py
+++ b/pactest/tests/upgrade014.py
@@ -13,7 +13,7 @@ p2.files = ["bin/foobar",
for p in p1, p2:
self.addpkg(p)
-self.args = "-Af %s" % " ".join([p.filename() for p in p1, p2])
+self.args = "-Uf %s" % " ".join([p.filename() for p in p1, p2])
self.addrule("PACMAN_RETCODE=0")
for p in p1, p2:
diff --git a/pactest/tests/add020.py b/pactest/tests/upgrade015.py
index 8a2f4a71..22f7c36b 100644
--- a/pactest/tests/add020.py
+++ b/pactest/tests/upgrade015.py
@@ -6,7 +6,7 @@ self.addpkg(p)
self.filesystem = ["etc/dummy.conf"]
-self.args = "-Af %s" % p.filename()
+self.args = "-Uf %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
diff --git a/pactest/tests/add021.py b/pactest/tests/upgrade016.py
index a6dda963..dd31c9ab 100644
--- a/pactest/tests/add021.py
+++ b/pactest/tests/upgrade016.py
@@ -7,7 +7,7 @@ self.addpkg(p)
self.filesystem = ["etc/dummy.conf"]
-self.args = "-Af %s" % p.filename()
+self.args = "-Uf %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
diff --git a/pactest/tests/upgrade032.py b/pactest/tests/upgrade032.py
new file mode 100644
index 00000000..85e048e0
--- /dev/null
+++ b/pactest/tests/upgrade032.py
@@ -0,0 +1,19 @@
+self.description = "Install packages explicitly"
+
+lp1 = pmpkg("pkg1")
+lp1.reason = 1
+self.addpkg2db("local", lp1)
+
+p1 = pmpkg("pkg1", "1.0-2")
+p2 = pmpkg("pkg2", "1.0-2")
+
+for p in p1, p2:
+ self.addpkg(p)
+
+self.args = "-U --asexplicit %s" % " ".join([p.filename() for p in p1, p2])
+
+self.addrule("PACMAN_RETCODE=0")
+self.addrule("PKG_VERSION=pkg1|1.0-2")
+self.addrule("PKG_VERSION=pkg2|1.0-2")
+self.addrule("PKG_REASON=pkg1|0")
+self.addrule("PKG_REASON=pkg2|0")
diff --git a/pactest/tests/add060.py b/pactest/tests/upgrade070.py
index 4c5f17da..01f0ba48 100644
--- a/pactest/tests/add060.py
+++ b/pactest/tests/upgrade070.py
@@ -5,9 +5,9 @@ p.files = ["bin/dummy",
"usr/man/man1/dummy.1"]
self.addpkg(p)
-self.option["noextract"] = ["usr/man/man1/dummy.1"]
+self.option["NoExtract"] = ["usr/man/man1/dummy.1"]
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
diff --git a/pactest/tests/add040.py b/pactest/tests/upgrade071.py
index 6d6da602..1f21c558 100644
--- a/pactest/tests/add040.py
+++ b/pactest/tests/upgrade071.py
@@ -6,7 +6,7 @@ p.files = ["bin/dummy",
p.depends = ["dep1"]
self.addpkg(p)
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=dummy")
diff --git a/pactest/tests/add041.py b/pactest/tests/upgrade072.py
index af3ffe46..f88e150c 100644
--- a/pactest/tests/add041.py
+++ b/pactest/tests/upgrade072.py
@@ -6,7 +6,7 @@ p.files = ["bin/dummy",
p.depends = ["dep1"]
self.addpkg(p)
-self.args = "-Ad %s" % p.filename()
+self.args = "-Ud %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=dummy")
diff --git a/pactest/tests/add042.py b/pactest/tests/upgrade073.py
index 48104b0c..3486c417 100644
--- a/pactest/tests/add042.py
+++ b/pactest/tests/upgrade073.py
@@ -15,7 +15,7 @@ p3.files = ["bin/dep2"]
for p in p1, p2, p3:
self.addpkg(p)
-self.args = "-A %s" % " ".join([p.filename() for p in p1, p2, p3])
+self.args = "-U %s" % " ".join([p.filename() for p in p1, p2, p3])
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_VERSION=dummy|1.0-2")
diff --git a/pactest/tests/add046.py b/pactest/tests/upgrade074.py
index 5f967cbe..ca052855 100644
--- a/pactest/tests/add046.py
+++ b/pactest/tests/upgrade074.py
@@ -7,7 +7,7 @@ self.addpkg(p)
lp = pmpkg("pkg2", "1.9b-3")
self.addpkg2db("local", lp)
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=0")
self.addrule("PKG_EXIST=pkg1")
diff --git a/pactest/tests/add047.py b/pactest/tests/upgrade075.py
index 153364a5..8d2f3fc4 100644
--- a/pactest/tests/add047.py
+++ b/pactest/tests/upgrade075.py
@@ -7,7 +7,7 @@ self.addpkg(p)
lp = pmpkg("pkg2", "2.0-3")
self.addpkg2db("local", lp)
-self.args = "-A %s" % p.filename()
+self.args = "-U %s" % p.filename()
self.addrule("PACMAN_RETCODE=1")
self.addrule("!PKG_EXIST=pkg1")
diff --git a/pactest/tests/xfercommand001.py b/pactest/tests/xfercommand001.py
index a9c41d8c..a645cf7f 100644
--- a/pactest/tests/xfercommand001.py
+++ b/pactest/tests/xfercommand001.py
@@ -3,7 +3,7 @@ self.description = "Quick check for using XferCommand"
# this setting forces us to download packages
self.cachepkgs = False
#wget doesn't support file:// urls. curl does
-self.option['xfercommand'] = ['/usr/bin/curl %u > %o']
+self.option['XferCommand'] = ['/usr/bin/curl %u > %o']
numpkgs = 10
pkgnames = []
diff --git a/pactest/util.py b/pactest/util.py
index 2a6ff4e7..3f0b096a 100755
--- a/pactest/util.py
+++ b/pactest/util.py
@@ -181,7 +181,7 @@ def mkcfgfile(filename, root, option, db):
# Repositories
data.extend(["[%s]\n" \
- "server = file://%s\n" \
+ "Server = file://%s\n" \
% (value.treename, \
os.path.join(root, SYNCREPO, value.treename)) \
for key, value in db.iteritems() if key != "local"])
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 359a8041..cf6e9506 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,7 +1,6 @@
# List of source files with translatable strings
# pacman frontend source files
-src/pacman/add.c
src/pacman/callback.c
src/pacman/conf.c
src/pacman/deptest.c
@@ -11,11 +10,10 @@ src/pacman/query.c
src/pacman/remove.c
src/pacman/sync.c
src/pacman/util.c
+src/pacman/upgrade.c
# scripts with gettext translations
-scripts/gensync.sh.in
scripts/makepkg.sh.in
scripts/pacman-optimize.sh.in
scripts/repo-add.sh.in
scripts/repo-remove.sh.in
-scripts/updatesync.sh.in
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 53164a41..f2f19fd8 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,7 +1,5 @@
-gensync
makepkg
pacman-optimize
rankmirrors
repo-add
repo-remove
-updatesync
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 24b9c12d..3185a476 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -2,22 +2,18 @@
AUTOMAKE_OPTIONS = std-options
bin_SCRIPTS = \
- gensync \
makepkg \
pacman-optimize \
rankmirrors \
repo-add \
- repo-remove \
- updatesync
+ repo-remove
EXTRA_DIST = \
- gensync.sh.in \
makepkg.sh.in \
pacman-optimize.sh.in \
rankmirrors.py.in \
repo-add.sh.in \
- repo-remove.sh.in \
- updatesync.sh.in
+ repo-remove.sh.in
# Files that should be removed, but which Automake does not know.
MOSTLYCLEANFILES = $(bin_SCRIPTS) *.tmp
@@ -48,13 +44,11 @@ $(bin_SCRIPTS): Makefile
chmod a-w $@.tmp
mv $@.tmp $@
-gensync: $(srcdir)/gensync.sh.in
makepkg: $(srcdir)/makepkg.sh.in
pacman-optimize: $(srcdir)/pacman-optimize.sh.in
rankmirrors: $(srcdir)/rankmirrors.py.in
repo-add: $(srcdir)/repo-add.sh.in
repo-remove: $(srcdir)/repo-remove.sh.in
re-pacman: $(srcdir)/re-pacman.sh.in
-updatesync: $(srcdir)/updatesync.sh.in
# vim:set ts=2 sw=2 noet:
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 79c3fd17..1eb3d3a7 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -299,6 +299,20 @@ get_downloadclient() {
echo "$agent"
}
+get_downloadcmd() {
+ local dlagent=$1
+ local netfile=$2
+ local file=$3
+
+ if echo "$dlagent" | grep -q "%u" ; then
+ local dlcmd=$(echo "$dlagent" | sed "s|%o|$file.part|" | sed "s|%u|$netfile|")
+ else
+ local dlcmd="$dlagent $netfile"
+ fi
+
+ echo "$dlcmd"
+}
+
check_deps() {
[ $# -gt 0 ] || return
@@ -471,17 +485,20 @@ download_sources() {
fi
# find the client we should use for this URL
- local dlclient=$(get_downloadclient $netfile) || exit $?
+ local dlclient=$(get_downloadclient "$netfile") || exit $?
msg2 "$(gettext "Downloading %s...")" "$file"
# fix flyspray bug #3289
local ret=0
- $dlclient "$netfile" || ret=$?
+ $(get_downloadcmd "$dlclient" "$netfile" "$file") || ret=$?
if [ $ret -gt 0 ]; then
error "$(gettext "Failure while downloading %s")" "$file"
plain "$(gettext "Aborting...")"
exit 1
fi
+ if echo "$dlclient" | grep -q "%o" ; then
+ mv -f "$SRCDEST/$file.part" "$SRCDEST/$file"
+ fi
cp -s --remove-destination "$SRCDEST/$file" "$srcdir/"
done
@@ -716,37 +733,41 @@ tidy_install() {
rm -rf ${DOC_DIRS[@]}
fi
- msg2 "$(gettext "Compressing man pages...")"
- local manpage mandirs ext file link hardlinks hl
- mandirs="usr/man usr/share/man usr/local/man usr/local/share/man opt/*/man"
- find ${mandirs} -type f 2>/dev/null | while read manpage ; do
- # check file still exists (potentially compressed with hard link)
- if [ -f ${manpage} ]; then
- ext="${manpage##*.}"
- file="${manpage##*/}"
- if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
- # update symlinks to this manpage
- find ${mandirs} -lname "$file" 2>/dev/null | while read link ; do
- rm -f "$link"
- ln -sf "${file}.gz" "${link}.gz"
- done
- # find hard links and remove them
- # the '|| true' part keeps the script from bailing if find returned an
- # error, such as when one of the man directories doesn't exist
- hardlinks="$(find ${mandirs} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
- for hl in ${hardlinks}; do
- rm -f "${hl}";
- done
- # compress the original
- gzip -9 "$manpage"
- # recreate hard links removed earlier
- for hl in ${hardlinks}; do
- ln "${manpage}.gz" "${hl}.gz"
- chmod 644 ${hl}.gz
- done
+ if [ "$(check_option zipman)" = "y" ]; then
+ msg2 "$(gettext "Compressing man pages...")"
+ local manpage mandirs ext file link hardlinks hl
+ mandirs="usr/man usr/share/man usr/local/man usr/local/share/man opt/*/man"
+ find ${mandirs} -type f 2>/dev/null |
+ while read manpage ; do
+ # check file still exists (potentially compressed with hard link)
+ if [ -f ${manpage} ]; then
+ ext="${manpage##*.}"
+ file="${manpage##*/}"
+ if [ "$ext" != "gz" -a "$ext" != "bz2" ]; then
+ # update symlinks to this manpage
+ find ${mandirs} -lname "$file" 2>/dev/null |
+ while read link ; do
+ rm -f "$link"
+ ln -sf "${file}.gz" "${link}.gz"
+ done
+ # find hard links and remove them
+ # the '|| true' part keeps the script from bailing if find returned an
+ # error, such as when one of the man directories doesn't exist
+ hardlinks="$(find ${mandirs} \! -name "$file" -samefile "$manpage" 2>/dev/null)" || true
+ for hl in ${hardlinks}; do
+ rm -f "${hl}";
+ done
+ # compress the original
+ gzip -9 "$manpage"
+ # recreate hard links removed earlier
+ for hl in ${hardlinks}; do
+ ln "${manpage}.gz" "${hl}.gz"
+ chmod 644 ${hl}.gz
+ done
+ fi
fi
- fi
- done
+ done
+ fi
if [ "$(check_option strip)" = "y" ]; then
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index 63d94d37..f837262d 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -25,7 +25,6 @@ export TEXTDOMAINDIR='@localedir@'
myver='@PACKAGE_VERSION@'
confdir='@sysconfdir@'
-FORCE=0
REPO_DB_FILE=""
# ensure we have a sane umask set
@@ -54,14 +53,10 @@ error() {
# print usage instructions
usage() {
printf "repo-add (pacman) %s\n\n" "$myver"
- printf "$(gettext "Usage: %s <path-to-db> [--force] <package> ...\n\n")" "$0"
+ printf "$(gettext "Usage: %s <path-to-db> <package> ...\n\n")" "$0"
printf "$(gettext "\
repo-add will update a package database by reading a package file.\n\
Multiple packages to add can be specified on the command line.\n\n")"
- printf "$(gettext "\
-The --force flag will add a 'force' entry to the sync database, which\n\
-tells pacman to skip its internal version number checking and update\n\
-the package regardless.\n\n")"
echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")"
}
@@ -209,7 +204,7 @@ db_write_entry()
[ -n "$builddate" ] && echo -e "%BUILDDATE%\n$builddate\n" >>desc
[ -n "$packager" ] && echo -e "%PACKAGER%\n$packager\n" >>desc
write_list_entry "REPLACES" "$_replaces" "desc"
- [ $FORCE -eq 1 -o -n "$force" ] && echo -e "%FORCE%\n" >>desc
+ [ -n "$force" ] && echo -e "%FORCE%\n" >>desc
# create depends entry
msg2 "$(gettext "Creating 'depends' db entry...")"
@@ -298,7 +293,8 @@ success=0
# parse arguments
for arg in "$@"; do
if [ "$arg" == "--force" -o "$arg" == "-f" ]; then
- FORCE=1
+ warning "$(gettext "the -f and --force options are no longer recognized")"
+ msg2 "$(gettext "use options=(force) in the PKGBUILD instead")"
elif [ -z "$REPO_DB_FILE" ]; then
REPO_DB_FILE=$(readlink -f "$arg")
if ! test_repo_db_file; then
diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am
index 5e287404..5d6fef3c 100644
--- a/src/pacman/Makefile.am
+++ b/src/pacman/Makefile.am
@@ -22,7 +22,6 @@ INCLUDES = -I$(top_srcdir)/lib/libalpm
AM_CFLAGS = -pedantic -D_GNU_SOURCE
pacman_SOURCES = \
- add.c \
conf.h conf.c \
deptest.c \
package.h package.c \
@@ -31,6 +30,7 @@ pacman_SOURCES = \
remove.c \
sync.c \
callback.h callback.c \
+ upgrade.c \
util.h util.c
LDADD = $(LTLIBINTL) $(top_builddir)/lib/libalpm/.libs/libalpm.la
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index a7686483..8a7af5c5 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -34,9 +34,6 @@
#include "util.h"
#include "conf.h"
-/* TODO this should not have to be defined twice- trans.c & log.c */
-#define LOG_STR_LEN 256
-
/* download progress bar */
static float rate_last;
static int xfered_last;
@@ -86,17 +83,14 @@ static float get_update_timediff(int first_call)
}
/* refactored from cb_trans_progress */
-static void fill_progress(const int graph_percent, const int display_percent,
- const int proglen)
+static void fill_progress(const int percent, const int proglen)
{
const unsigned int hashlen = proglen - 8;
- const unsigned int hash = graph_percent * hashlen / 100;
+ const unsigned int hash = percent * hashlen / 100;
static unsigned int lasthash = 0, mouth = 0;
unsigned int i;
- /* printf("\ndebug: proglen: %i\n", proglen); DEBUG*/
-
- if(graph_percent == 0) {
+ if(percent == 0) {
lasthash = 0;
mouth = 0;
}
@@ -141,10 +135,10 @@ static void fill_progress(const int graph_percent, const int display_percent,
}
/* print percent after progress bar */
if(proglen > 5) {
- printf(" %3d%%", display_percent);
+ printf(" %3d%%", percent);
}
- if(graph_percent == 100) {
+ if(percent == 100) {
printf("\n");
} else {
printf("\r");
@@ -157,8 +151,6 @@ static void fill_progress(const int graph_percent, const int display_percent,
/* callback to handle messages/notifications from libalpm transactions */
void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
{
- char str[LOG_STR_LEN] = "";
-
switch(event) {
case PM_TRANS_EVT_CHECKDEPS_START:
printf(_("checking dependencies...\n"));
@@ -180,10 +172,9 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
}
break;
case PM_TRANS_EVT_ADD_DONE:
- snprintf(str, LOG_STR_LEN, "installed %s (%s)\n",
+ alpm_logaction("installed %s (%s)\n",
alpm_pkg_get_name(data1),
alpm_pkg_get_version(data1));
- alpm_logaction(str);
break;
case PM_TRANS_EVT_REMOVE_START:
if(config->noprogressbar) {
@@ -191,10 +182,9 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
}
break;
case PM_TRANS_EVT_REMOVE_DONE:
- snprintf(str, LOG_STR_LEN, "removed %s (%s)\n",
+ alpm_logaction("removed %s (%s)\n",
alpm_pkg_get_name(data1),
alpm_pkg_get_version(data1));
- alpm_logaction(str);
break;
case PM_TRANS_EVT_UPGRADE_START:
if(config->noprogressbar) {
@@ -202,11 +192,10 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
}
break;
case PM_TRANS_EVT_UPGRADE_DONE:
- snprintf(str, LOG_STR_LEN, "upgraded %s (%s -> %s)\n",
+ alpm_logaction("upgraded %s (%s -> %s)\n",
(char *)alpm_pkg_get_name(data1),
(char *)alpm_pkg_get_version(data2),
(char *)alpm_pkg_get_version(data1));
- alpm_logaction(str);
break;
case PM_TRANS_EVT_INTEGRITY_START:
printf(_("checking package integrity...\n"));
@@ -255,67 +244,46 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,
void *data3, int *response)
{
- char str[LOG_STR_LEN] = "";
-
switch(event) {
case PM_TRANS_CONV_INSTALL_IGNOREPKG:
if(data2) {
/* TODO we take this route based on data2 being not null? WTF */
- snprintf(str, LOG_STR_LEN, _(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "),
+ *response = yesno(1, _(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway?"),
alpm_pkg_get_name(data1),
alpm_pkg_get_name(data2));
- *response = yesno(str);
} else {
- snprintf(str, LOG_STR_LEN, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway? [Y/n] "),
+ *response = yesno(1, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),
alpm_pkg_get_name(data1));
- *response = yesno(str);
}
break;
case PM_TRANS_CONV_REMOVE_HOLDPKG:
- snprintf(str, LOG_STR_LEN, _(":: %s is designated as a HoldPkg. Remove anyway? [Y/n] "),
+ *response = yesno(1, _(":: %s is designated as a HoldPkg. Remove anyway?"),
alpm_pkg_get_name(data1));
- *response = yesno(str);
break;
case PM_TRANS_CONV_REPLACE_PKG:
- if(!config->noconfirm) {
- snprintf(str, LOG_STR_LEN, _(":: Replace %s with %s/%s? [Y/n] "),
- alpm_pkg_get_name(data1),
- (char *)data3,
- alpm_pkg_get_name(data2));
- *response = yesno(str);
- } else {
- printf(_("Replacing %s with %s/%s\n"),
- alpm_pkg_get_name(data1),
- (char *)data3,
- alpm_pkg_get_name(data2));
- *response = 1;
- }
+ *response = yesno(1, _(":: Replace %s with %s/%s?"),
+ alpm_pkg_get_name(data1),
+ (char *)data3,
+ alpm_pkg_get_name(data2));
break;
case PM_TRANS_CONV_CONFLICT_PKG:
- snprintf(str, LOG_STR_LEN, _(":: %s conflicts with %s. Remove %s? [Y/n] "),
+ *response = yesno(1, _(":: %s conflicts with %s. Remove %s?"),
(char *)data1,
(char *)data2,
(char *)data2);
- *response = yesno(str);
break;
case PM_TRANS_CONV_LOCAL_NEWER:
if(!config->op_s_downloadonly) {
- snprintf(str, LOG_STR_LEN, _(":: %s-%s: local version is newer. Upgrade anyway? [Y/n] "),
+ *response = yesno(1, _(":: %s-%s: local version is newer. Upgrade anyway?"),
alpm_pkg_get_name(data1),
alpm_pkg_get_version(data1));
- *response = yesno(str);
} else {
*response = 1;
}
break;
case PM_TRANS_CONV_CORRUPTED_PKG:
- if(!config->noconfirm) {
- snprintf(str, LOG_STR_LEN, _(":: File %s is corrupted. Do you want to delete it? [Y/n] "),
- (char *)data1);
- *response = yesno(str);
- } else {
- *response = 1;
- }
+ *response = yesno(1, _(":: File %s is corrupted. Do you want to delete it?"),
+ (char *)data1);
break;
}
}
@@ -427,7 +395,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
free(wcstr);
/* call refactored fill progress function */
- fill_progress(percent, percent, getcols() - infolen);
+ fill_progress(percent, getcols() - infolen);
if(percent == 100) {
alpm_list_t *i = NULL;
@@ -443,8 +411,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
}
/* callback to handle display of download progress */
-void cb_dl_progress(const char *filename, int file_xfered, int file_total,
- int list_xfered, int list_total)
+void cb_dl_progress(const char *filename, int xfered, int total)
{
const int infolen = 50;
const int filenamelen = infolen - 27;
@@ -455,43 +422,22 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,
float rate = 0.0, timediff = 0.0, f_xfered = 0.0;
unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
- int graph_percent = 0, display_percent = 0;
+ int percent;
char rate_size = 'K', xfered_size = 'K';
- int xfered = 0, total = 0;
-
- /* Need this variable when TotalDownload is set to know if we should
- * reset xfered_last and rate_last. */
- static int has_init = 0;
if(config->noprogressbar) {
return;
}
- /* Choose how to display the amount downloaded, rate, ETA, and
- * percentage depending on the TotalDownload option. */
- if (config->totaldownload && list_total > 0) {
- xfered = list_xfered;
- total = list_total;
- } else {
- xfered = file_xfered;
- total = file_total;
- }
-
/* this is basically a switch on file_xferred: 0, file_total, and
* anything else */
- if(file_xfered == 0) {
- /* set default starting values, but only once for TotalDownload */
- if (!(config->totaldownload && list_total > 0) ||
- (config->totaldownload && list_total > 0 && !has_init)) {
- gettimeofday(&initial_time, NULL);
- timediff = get_update_timediff(1);
- xfered_last = 0;
- rate_last = 0.0;
- has_init = 1;
- }
- rate = 0.0;
- eta_s = 0;
- } else if(file_xfered == file_total) {
+ if(xfered == 0) {
+ /* set default starting values */
+ gettimeofday(&initial_time, NULL);
+ xfered_last = 0;
+ rate_last = 0.0;
+ timediff = get_update_timediff(1);
+ } else if(xfered == total) {
/* compute final values */
struct timeval current_time;
float diff_sec, diff_usec;
@@ -500,7 +446,7 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,
diff_sec = current_time.tv_sec - initial_time.tv_sec;
diff_usec = current_time.tv_usec - initial_time.tv_usec;
timediff = diff_sec + (diff_usec / 1000000.0);
- rate = xfered / (timediff * 1024.0);
+ rate = total / (timediff * 1024.0);
/* round elapsed time to the nearest second */
eta_s = (int)(timediff + 0.5);
@@ -514,12 +460,14 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,
}
rate = (xfered - xfered_last) / (timediff * 1024.0);
/* average rate to reduce jumpiness */
- rate = (rate + 2*rate_last) / 3;
+ rate = (rate + 2 * rate_last) / 3;
eta_s = (total - xfered) / (rate * 1024.0);
rate_last = rate;
xfered_last = xfered;
}
+ percent = (int)((float)xfered) / ((float)total) * 100;
+
/* fix up time for display */
eta_h = eta_s / 3600;
eta_s -= eta_h * 3600;
@@ -591,11 +539,7 @@ void cb_dl_progress(const char *filename, int file_xfered, int file_total,
free(fname);
free(wcfname);
- /* The progress bar is based on the file percent regardless of the
- * TotalDownload option. */
- graph_percent = (int)((float)file_xfered) / ((float)file_total) * 100;
- display_percent = (int)((float)xfered) / ((float)total) * 100;
- fill_progress(graph_percent, display_percent, getcols() - infolen);
+ fill_progress(percent, getcols() - infolen);
return;
}
diff --git a/src/pacman/callback.h b/src/pacman/callback.h
index aa8d9370..39d59d8b 100644
--- a/src/pacman/callback.h
+++ b/src/pacman/callback.h
@@ -33,8 +33,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent,
int howmany, int remain);
/* callback to handle display of download progress */
-void cb_dl_progress(const char *filename, int file_xfered, int file_total,
- int list_xfered, int list_total);
+void cb_dl_progress(const char *filename, int file_xfered, int file_total);
/* callback to handle messages/notifications from pacman library */
void cb_log(pmloglevel_t level, char *fmt, va_list args);
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index f804f560..28ac4b96 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -27,7 +27,6 @@ typedef struct __config_t {
unsigned short verbose;
unsigned short version;
unsigned short help;
- unsigned short upgrade;
unsigned short noconfirm;
unsigned short noprogressbar;
unsigned short logmask;
@@ -53,7 +52,6 @@ typedef struct __config_t {
unsigned short op_q_upgrade;
unsigned short op_s_clean;
- unsigned short op_s_dependsonly;
unsigned short op_s_downloadonly;
unsigned short op_s_info;
unsigned short op_s_sync;
@@ -67,15 +65,15 @@ typedef struct __config_t {
unsigned short chomp; /* I Love Candy! */
unsigned short usecolor; /* enable colorful output */
unsigned short showsize; /* show individual package sizes */
- unsigned short totaldownload; /* When downloading, display the amount
- downloaded, rate, ETA, and percent
- downloaded of the total download list */
+ /* When downloading, display the amount downloaded, rate, ETA, and percent
+ * downloaded of the total download list */
+ unsigned short totaldownload;
+ unsigned short cleanmethod; /* select -Sc behavior */
} config_t;
/* Operations */
enum {
PM_OP_MAIN = 1,
- PM_OP_ADD,
PM_OP_REMOVE,
PM_OP_UPGRADE,
PM_OP_QUERY,
@@ -83,6 +81,12 @@ enum {
PM_OP_DEPTEST
};
+/* clean method */
+enum {
+ PM_CLEAN_KEEPINST = 0, /* default */
+ PM_CLEAN_KEEPCUR
+};
+
/* global config variable */
extern config_t *config;
diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c
index 2481c0b6..2feca5c4 100644
--- a/src/pacman/deptest.c
+++ b/src/pacman/deptest.c
@@ -31,53 +31,23 @@
#include "util.h"
#include "conf.h"
-/* TODO: This should use _alpm_checkdeps() */
int pacman_deptest(alpm_list_t *targets)
{
- int retval = 0;
alpm_list_t *i;
- if(targets == NULL) {
+ alpm_list_t *deps = alpm_deptest(alpm_option_get_localdb(), targets);
+ if(deps == NULL) {
return(0);
}
- for(i = targets; i; i = alpm_list_next(i)) {
- int found = 0;
- pmpkg_t *pkg;
- pmdepend_t *dep;
- const char *target;
- alpm_list_t *j, *provides;
+ for(i = deps; i; i = alpm_list_next(i)) {
+ const char *dep;
- target = alpm_list_getdata(i);
- dep = alpm_splitdep(target);
-
- pkg = alpm_db_get_pkg(alpm_option_get_localdb(),
- alpm_dep_get_name(dep));
- if(pkg && alpm_depcmp(pkg, dep)) {
- found = 1;
- } else {
- /* not found, can we find anything that provides this in the local DB? */
- provides = alpm_db_whatprovides(alpm_option_get_localdb(),
- alpm_dep_get_name(dep));
- for(j = provides; j; j = alpm_list_next(j)) {
- pmpkg_t *pkg;
- pkg = alpm_list_getdata(j);
-
- if(pkg && alpm_depcmp(pkg, dep)) {
- found = 1;
- break;
- }
- }
- alpm_list_free(provides);
- }
-
- if(!found) {
- printf("%s\n", target);
- retval = 127;
- }
- free(dep);
+ dep = alpm_list_getdata(i);
+ printf("%s\n", dep);
}
- return(retval);
+ alpm_list_free(deps);
+ return(127);
}
/* vim: set ts=2 sw=2 noet: */
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index c2b61fcd..9468d51c 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -68,31 +68,27 @@ static void usage(int op, const char * const myname)
printf("%s:\n", str_opt);
printf(" %s {-h --help}\n", myname);
printf(" %s {-V --version}\n", myname);
- printf(" %s {-A --add} [%s] <%s>\n", myname, str_opt, str_file);
printf(" %s {-Q --query} [%s] [%s]\n", myname, str_opt, str_pkg);
printf(" %s {-R --remove} [%s] <%s>\n", myname, str_opt, str_pkg);
printf(" %s {-S --sync} [%s] [%s]\n", myname, str_opt, str_pkg);
printf(" %s {-U --upgrade} [%s] <%s>\n", myname, str_opt, str_file);
printf(_("\nuse '%s --help' with other options for more syntax\n"), myname);
} else {
- if(op == PM_OP_ADD) {
- printf("%s: %s {-A --add} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
- printf("%s:\n", str_opt);
- printf(_(" --asdeps install packages as non-explicitly installed\n"));
- printf(_(" -d, --nodeps skip dependency checks\n"));
- printf(_(" -f, --force force install, overwrite conflicting files\n"));
- } else if(op == PM_OP_REMOVE) {
+ if(op == PM_OP_REMOVE) {
printf("%s: %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg);
printf("%s:\n", str_opt);
printf(_(" -c, --cascade remove packages and all packages that depend on them\n"));
printf(_(" -d, --nodeps skip dependency checks\n"));
printf(_(" -k, --dbonly only remove database entry, do not remove files\n"));
printf(_(" -n, --nosave remove configuration files as well\n"));
- printf(_(" -s, --recursive remove dependencies also (that won't break packages)\n"));
+ printf(_(" -s, --recursive remove dependencies also (that won't break packages)\n"
+ " (-ss includes explicitly installed dependencies too)\n"));
+ printf(_(" -u, --unneeded remove unneeded packages (that won't break packages)\n"));
} else if(op == PM_OP_UPGRADE) {
printf("%s: %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
printf("%s:\n", str_opt);
printf(_(" --asdeps install packages as non-explicitly installed\n"));
+ printf(_(" --asexplicit install packages as explicitly installed\n"));
printf(_(" -d, --nodeps skip dependency checks\n"));
printf(_(" -f, --force force install, overwrite conflicting files\n"));
} else if(op == PM_OP_QUERY) {
@@ -115,9 +111,9 @@ static void usage(int op, const char * const myname)
printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
printf("%s:\n", str_opt);
printf(_(" --asdeps install packages as non-explicitly installed\n"));
+ printf(_(" --asexplicit install packages as explicitly installed\n"));
printf(_(" -c, --clean remove old packages from cache directory (-cc for all)\n"));
printf(_(" -d, --nodeps skip dependency checks\n"));
- printf(_(" -e, --dependsonly install dependencies only\n"));
printf(_(" -f, --force force install, overwrite conflicting files\n"));
printf(_(" -g, --groups view all members of a package group\n"));
printf(_(" -i, --info view package information\n"));
@@ -212,7 +208,7 @@ static void cleanup(int ret) {
* in a consistant state.
* @param signum the thrown signal
*/
-static void handler(int signum)
+static RETSIGTYPE handler(int signum)
{
if(signum==SIGSEGV)
{
@@ -305,7 +301,6 @@ static int parseargs(int argc, char *argv[])
int option_index = 0;
static struct option opts[] =
{
- {"add", no_argument, 0, 'A'},
{"query", no_argument, 0, 'Q'},
{"remove", no_argument, 0, 'R'},
{"sync", no_argument, 0, 'S'},
@@ -318,7 +313,6 @@ static int parseargs(int argc, char *argv[])
{"clean", no_argument, 0, 'c'},
{"nodeps", no_argument, 0, 'd'},
{"deps", no_argument, 0, 'd'},
- {"dependsonly",no_argument, 0, 'e'},
{"explicit", no_argument, 0, 'e'},
{"force", no_argument, 0, 'f'},
{"groups", no_argument, 0, 'g'},
@@ -338,6 +332,7 @@ static int parseargs(int argc, char *argv[])
{"unrequired", no_argument, 0, 't'},
{"upgrades", no_argument, 0, 'u'},
{"sysupgrade", no_argument, 0, 'u'},
+ {"unneeded", no_argument, 0, 'u'},
{"verbose", no_argument, 0, 'v'},
{"downloadonly", no_argument, 0, 'w'},
{"refresh", no_argument, 0, 'y'},
@@ -352,10 +347,11 @@ static int parseargs(int argc, char *argv[])
{"logfile", required_argument, 0, 1009},
{"ignoregroup", required_argument, 0, 1010},
{"needed", no_argument, 0, 1011},
+ {"asexplicit", no_argument, 0, 1012},
{0, 0, 0, 0}
};
- while((opt = getopt_long(argc, argv, "ARUFQSTr:b:vkhscVfmnoldepqituwygz", opts, &option_index))) {
+ while((opt = getopt_long(argc, argv, "RUFQSTr:b:vkhscVfmnoldepqituwygz", opts, &option_index))) {
alpm_list_t *list = NULL, *item = NULL; /* lists for splitting strings */
if(opt < 0) {
@@ -423,7 +419,9 @@ static int parseargs(int argc, char *argv[])
FREELIST(list);
break;
case 1011: config->flags |= PM_TRANS_FLAG_NEEDED; break;
- case 'A': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_ADD); break;
+ case 1012:
+ config->flags |= PM_TRANS_FLAG_ALLEXPLICIT;
+ break;
case 'Q': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
case 'R': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_REMOVE); break;
case 'S': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_SYNC); break;
@@ -444,7 +442,6 @@ static int parseargs(int argc, char *argv[])
break;
case 'e':
config->op_q_explicit = 1;
- config->flags |= PM_TRANS_FLAG_DEPENDSONLY;
break;
case 'f': config->flags |= PM_TRANS_FLAG_FORCE; break;
case 'g': (config->group)++; break;
@@ -468,7 +465,11 @@ static int parseargs(int argc, char *argv[])
case 's':
config->op_s_search = 1;
config->op_q_search = 1;
- config->flags |= PM_TRANS_FLAG_RECURSE;
+ if(config->flags & PM_TRANS_FLAG_RECURSE) {
+ config->flags |= PM_TRANS_FLAG_RECURSEALL;
+ } else {
+ config->flags |= PM_TRANS_FLAG_RECURSE;
+ }
break;
case 't':
config->op_q_unrequired = 1;
@@ -476,6 +477,7 @@ static int parseargs(int argc, char *argv[])
case 'u':
config->op_s_upgrade = 1;
config->op_q_upgrade = 1;
+ config->flags |= PM_TRANS_FLAG_UNNEEDED;
break;
case 'v': (config->verbose)++; break;
case 'w':
@@ -599,7 +601,7 @@ static int _parseconfig(const char *file, const char *givensection,
}
} else {
/* directive */
- char *key, *upperkey;
+ char *key;
/* strsep modifies the 'line' string: 'key \0 ptr' */
key = line;
ptr = line;
@@ -612,11 +614,7 @@ static int _parseconfig(const char *file, const char *givensection,
file, linenum);
return(1);
}
- /* For each directive, compare to the uppercase and camelcase string.
- * This prevents issues with certain locales where characters don't
- * follow the toupper() rules we may expect, e.g. tr_TR where i != I.
- */
- upperkey = strtoupper(strdup(key));
+ /* For each directive, compare to the camelcase string. */
if(section == NULL) {
pm_printf(PM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"),
file, linenum);
@@ -624,25 +622,25 @@ static int _parseconfig(const char *file, const char *givensection,
}
if(ptr == NULL && strcmp(section, "options") == 0) {
/* directives without settings, all in [options] */
- if(strcmp(key, "NoPassiveFTP") == 0 || strcmp(upperkey, "NOPASSIVEFTP") == 0) {
+ if(strcmp(key, "NoPassiveFTP") == 0) {
alpm_option_set_nopassiveftp(1);
pm_printf(PM_LOG_DEBUG, "config: nopassiveftp\n");
- } else if(strcmp(key, "UseSyslog") == 0 || strcmp(upperkey, "USESYSLOG") == 0) {
+ } else if(strcmp(key, "UseSyslog") == 0) {
alpm_option_set_usesyslog(1);
pm_printf(PM_LOG_DEBUG, "config: usesyslog\n");
- } else if(strcmp(key, "ILoveCandy") == 0 || strcmp(upperkey, "ILOVECANDY") == 0) {
+ } else if(strcmp(key, "ILoveCandy") == 0) {
config->chomp = 1;
pm_printf(PM_LOG_DEBUG, "config: chomp\n");
- } else if(strcmp(key, "UseColor") == 0 || strcmp(upperkey, "USECOLOR") == 0) {
+ } else if(strcmp(key, "UseColor") == 0) {
config->usecolor = 1;
pm_printf(PM_LOG_DEBUG, "config: usecolor\n");
- } else if(strcmp(key, "ShowSize") == 0 || strcmp(upperkey, "SHOWSIZE") == 0) {
+ } else if(strcmp(key, "ShowSize") == 0) {
config->showsize = 1;
pm_printf(PM_LOG_DEBUG, "config: showsize\n");
- } else if(strcmp(key, "UseDelta") == 0 || strcmp(upperkey, "USEDELTA") == 0) {
+ } else if(strcmp(key, "UseDelta") == 0) {
alpm_option_set_usedelta(1);
pm_printf(PM_LOG_DEBUG, "config: usedelta\n");
- } else if(strcmp(key, "TotalDownload") == 0 || strcmp(upperkey, "TOTALDOWNLOAD") == 0) {
+ } else if(strcmp(key, "TotalDownload") == 0) {
config->totaldownload = 1;
pm_printf(PM_LOG_DEBUG, "config: totaldownload\n");
} else {
@@ -652,59 +650,64 @@ static int _parseconfig(const char *file, const char *givensection,
}
} else {
/* directives with settings */
- if(strcmp(key, "Include") == 0 || strcmp(upperkey, "INCLUDE") == 0) {
+ if(strcmp(key, "Include") == 0) {
pm_printf(PM_LOG_DEBUG, "config: including %s\n", ptr);
_parseconfig(ptr, section, db);
/* Ignore include failures... assume non-critical */
} else if(strcmp(section, "options") == 0) {
- if(strcmp(key, "NoUpgrade") == 0
- || strcmp(upperkey, "NOUPGRADE") == 0) {
+ if(strcmp(key, "NoUpgrade") == 0) {
setrepeatingoption(ptr, "NoUpgrade", alpm_option_add_noupgrade);
- } else if(strcmp(key, "NoExtract") == 0
- || strcmp(upperkey, "NOEXTRACT") == 0) {
+ } else if(strcmp(key, "NoExtract") == 0) {
setrepeatingoption(ptr, "NoExtract", alpm_option_add_noextract);
- } else if(strcmp(key, "IgnorePkg") == 0
- || strcmp(upperkey, "IGNOREPKG") == 0) {
+ } else if(strcmp(key, "IgnorePkg") == 0) {
setrepeatingoption(ptr, "IgnorePkg", alpm_option_add_ignorepkg);
- } else if(strcmp(key, "IgnoreGroup") == 0
- || strcmp(upperkey, "IGNOREGROUP") == 0) {
+ } else if(strcmp(key, "IgnoreGroup") == 0) {
setrepeatingoption(ptr, "IgnoreGroup", alpm_option_add_ignoregrp);
- } else if(strcmp(key, "HoldPkg") == 0
- || strcmp(upperkey, "HOLDPKG") == 0) {
+ } else if(strcmp(key, "HoldPkg") == 0) {
setrepeatingoption(ptr, "HoldPkg", alpm_option_add_holdpkg);
- } else if(strcmp(key, "DBPath") == 0 || strcmp(upperkey, "DBPATH") == 0) {
+ } else if(strcmp(key, "DBPath") == 0) {
/* don't overwrite a path specified on the command line */
if(!config->dbpath) {
config->dbpath = strdup(ptr);
pm_printf(PM_LOG_DEBUG, "config: dbpath: %s\n", ptr);
}
- } else if(strcmp(key, "CacheDir") == 0 || strcmp(upperkey, "CACHEDIR") == 0) {
+ } else if(strcmp(key, "CacheDir") == 0) {
if(alpm_option_add_cachedir(ptr) != 0) {
pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"),
ptr, alpm_strerrorlast());
return(1);
}
pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", ptr);
- } else if(strcmp(key, "RootDir") == 0 || strcmp(upperkey, "ROOTDIR") == 0) {
+ } else if(strcmp(key, "RootDir") == 0) {
/* don't overwrite a path specified on the command line */
if(!config->rootdir) {
config->rootdir = strdup(ptr);
pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", ptr);
}
- } else if (strcmp(key, "LogFile") == 0 || strcmp(upperkey, "LOGFILE") == 0) {
+ } else if (strcmp(key, "LogFile") == 0) {
if(!config->logfile) {
config->logfile = strdup(ptr);
pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", ptr);
}
- } else if (strcmp(key, "XferCommand") == 0 || strcmp(upperkey, "XFERCOMMAND") == 0) {
+ } else if (strcmp(key, "XferCommand") == 0) {
alpm_option_set_xfercommand(ptr);
pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", ptr);
+ } else if (strcmp(key, "CleanMethod") == 0) {
+ if (strcmp(ptr, "KeepInstalled") == 0) {
+ config->cleanmethod = PM_CLEAN_KEEPINST;
+ } else if (strcmp(ptr, "KeepCurrent") == 0) {
+ config->cleanmethod = PM_CLEAN_KEEPCUR;
+ } else {
+ pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), ptr);
+ return(1);
+ }
+ pm_printf(PM_LOG_DEBUG, "config: cleanmethod: %s\n", ptr);
} else {
pm_printf(PM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"),
file, linenum, key);
return(1);
}
- } else if(strcmp(key, "Server") == 0 || strcmp(upperkey, "SERVER") == 0) {
+ } else if(strcmp(key, "Server") == 0) {
/* let's attempt a replacement for the current repo */
char *server = strreplace(ptr, "$repo", section);
@@ -720,7 +723,6 @@ static int _parseconfig(const char *file, const char *givensection,
return(1);
}
}
- free(upperkey);
}
}
fclose(fp);
@@ -867,9 +869,6 @@ int main(int argc, char *argv[])
/* start the requested operation */
switch(config->op) {
- case PM_OP_ADD:
- ret = pacman_add(pm_targets);
- break;
case PM_OP_REMOVE:
ret = pacman_remove(pm_targets);
break;
diff --git a/src/pacman/pacman.h b/src/pacman/pacman.h
index 9d23a89c..97d0301e 100644
--- a/src/pacman/pacman.h
+++ b/src/pacman/pacman.h
@@ -21,15 +21,14 @@
#include <alpm_list.h>
-/* add.c, this should merge with upgrade.c */
-int pacman_add(alpm_list_t *targets);
-int pacman_upgrade(alpm_list_t *targets);
-/* sync.c */
-int pacman_sync(alpm_list_t *targets);
/* query.c */
int pacman_query(alpm_list_t *targets);
/* remove.c */
int pacman_remove(alpm_list_t *targets);
+/* sync.c */
+int pacman_sync(alpm_list_t *targets);
+/* upgrade.c */
+int pacman_upgrade(alpm_list_t *targets);
/* deptest.c */
int pacman_deptest(alpm_list_t *targets);
diff --git a/src/pacman/query.c b/src/pacman/query.c
index e999a328..b40359ed 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -1,7 +1,7 @@
/*
* query.c
*
- * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -119,8 +119,13 @@ static int query_fileowner(alpm_list_t *targets)
free(pdname);
if(ppath && strcmp(ppath, rpath) == 0) {
- printf(_("%s is owned by %s %s\n"), filename,
- alpm_pkg_get_name(info), alpm_pkg_get_version(info));
+ if (!config->quiet) {
+ printf(_("%s is owned by %s %s\n"), filename,
+ alpm_pkg_get_name(info), alpm_pkg_get_version(info));
+ } else {
+ printf("%s %s\n", alpm_pkg_get_name(info),
+ alpm_pkg_get_version(info));
+ }
found = 1;
}
free(ppath);
@@ -155,7 +160,6 @@ static int query_search(alpm_list_t *targets)
}
for(i = searchlist; i; i = alpm_list_next(i)) {
- char *group = NULL;
alpm_list_t *grp;
pmpkg_t *pkg = alpm_list_getdata(i);
@@ -176,8 +180,17 @@ static int query_search(alpm_list_t *targets)
if (!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
- group = alpm_list_getdata(grp);
- printf(" (%s)", (char *)alpm_list_getdata(grp));
+ alpm_list_t *k;
+ printf(" (");
+ for(k = grp; k; k = alpm_list_next(k)) {
+ const char *group = alpm_list_getdata(k);
+ printf("%s", group);
+ if(alpm_list_next(k)) {
+ /* only print a spacer if there are more groups */
+ printf(" ");
+ }
+ }
+ printf(")");
}
/* we need a newline and initial indent first */
@@ -197,33 +210,33 @@ static int query_search(alpm_list_t *targets)
static int query_group(alpm_list_t *targets)
{
alpm_list_t *i, *j;
- char *package = NULL;
+ char *grpname = NULL;
int ret = 0;
if(targets == NULL) {
for(j = alpm_db_getgrpcache(db_local); j; j = alpm_list_next(j)) {
pmgrp_t *grp = alpm_list_getdata(j);
- const alpm_list_t *p, *pkgnames;
+ const alpm_list_t *p, *packages;
const char *grpname;
grpname = alpm_grp_get_name(grp);
- pkgnames = alpm_grp_get_pkgs(grp);
+ packages = alpm_grp_get_pkgs(grp);
- for(p = pkgnames; p; p = alpm_list_next(p)) {
- printf("%s %s\n", grpname, (char *)alpm_list_getdata(p));
+ for(p = packages; p; p = alpm_list_next(p)) {
+ printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p)));
}
}
} else {
for(i = targets; i; i = alpm_list_next(i)) {
pmgrp_t *grp;
- package = alpm_list_getdata(i);
- grp = alpm_db_readgrp(db_local, package);
+ grpname = alpm_list_getdata(i);
+ grp = alpm_db_readgrp(db_local, grpname);
if(grp) {
- const alpm_list_t *p, *pkgnames = alpm_grp_get_pkgs(grp);
- for(p = pkgnames; p; p = alpm_list_next(p)) {
- printf("%s %s\n", package, (char *)alpm_list_getdata(p));
+ const alpm_list_t *p, *packages = alpm_grp_get_pkgs(grp);
+ for(p = packages; p; p = alpm_list_next(p)) {
+ printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p)));
}
} else {
- fprintf(stderr, _("error: group \"%s\" was not found\n"), package);
+ fprintf(stderr, _("error: group \"%s\" was not found\n"), grpname);
ret++;
}
}
diff --git a/src/pacman/remove.c b/src/pacman/remove.c
index e3750e4c..2fb69d35 100644
--- a/src/pacman/remove.c
+++ b/src/pacman/remove.c
@@ -75,11 +75,11 @@ int pacman_remove(alpm_list_t *targets)
printf(_(":: group %s:\n"), alpm_grp_get_name(grp));
list_display(" ", pkgnames);
- all = yesno(_(" Remove whole content? [Y/n] "));
+ all = yesno(1, _(" Remove whole content?"));
for(p = pkgnames; p; p = alpm_list_next(p)) {
char *pkg = alpm_list_getdata(p);
- if(all || yesno(_(":: Remove %s from group %s? [Y/n] "), pkg, (char *)alpm_list_getdata(i))) {
+ if(all || yesno(1, _(":: Remove %s from group %s?"), pkg, (char *)alpm_list_getdata(i))) {
finaltargs = alpm_list_add(finaltargs, strdup(pkg));
}
}
@@ -153,7 +153,7 @@ int pacman_remove(alpm_list_t *targets)
list_display(_("Targets:"), lst);
FREELIST(lst);
/* get confirmation */
- if(yesno(_("\nDo you want to remove these packages? [Y/n] ")) == 0) {
+ if(yesno(1, _("\nDo you want to remove these packages?")) == 0) {
remove_cleanup();
FREELIST(finaltargs);
return(1);
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index e3e87703..c074746f 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -29,9 +29,6 @@
#include <alpm.h>
#include <alpm_list.h>
-#include <download.h> /* downloadLastErrString */
-/* TODO remove above download.h inclusion once we abstract more, and also
- * remove it from Makefile.am on the pacman side */
/* pacman */
#include "pacman.h"
@@ -89,7 +86,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) {
/* We have a directory that doesn't match any syncdb.
* Ask the user if he wants to remove it. */
if(!found) {
- if(!yesno(_("Do you want to remove %s? [Y/n] "), path)) {
+ if(!yesno(1, _("Do you want to remove %s?"), path)) {
continue;
}
@@ -108,7 +105,7 @@ static int sync_cleandb_all(void) {
char newdbpath[PATH_MAX];
printf(_("Database directory: %s\n"), dbpath);
- if(!yesno(_("Do you want to remove unused repositories? [Y/n] "))) {
+ if(!yesno(1, _("Do you want to remove unused repositories?"))) {
return(0);
}
/* The sync dbs were previously put in dbpath/, but are now in dbpath/sync/,
@@ -133,13 +130,23 @@ static int sync_cleancache(int level)
/* incomplete cleanup */
DIR *dir;
struct dirent *ent;
- /* Let's vastly improve the way this is done. Before, we went by package
- * name. Instead, let's only keep packages we have installed. Open up each
- * package and see if it has an entry in the local DB; if not, delete it.
- */
+ /* Open up each package and see if it should be deleted,
+ * depending on the clean method used */
printf(_("Cache directory: %s\n"), cachedir);
- if(!yesno(_("Do you want to remove uninstalled packages from cache? [Y/n] "))) {
- return(0);
+ switch(config->cleanmethod) {
+ case PM_CLEAN_KEEPINST:
+ if(!yesno(1, _("Do you want to remove uninstalled packages from cache?"))) {
+ return(0);
+ }
+ break;
+ case PM_CLEAN_KEEPCUR:
+ if(!yesno(1, _("Do you want to remove outdated packages from cache?"))) {
+ return(0);
+ }
+ break;
+ default:
+ /* this should not happen : the config parsing doesn't set any other value */
+ return(1);
}
printf(_("removing old packages from cache... "));
@@ -153,13 +160,16 @@ static int sync_cleancache(int level)
/* step through the directory one file at a time */
while((ent = readdir(dir)) != NULL) {
char path[PATH_MAX];
- pmpkg_t *localpkg = NULL, *dbpkg = NULL;
+ int delete = 1;
+ pmpkg_t *localpkg = NULL, *pkg = NULL;
+ alpm_list_t *sync_dbs = alpm_option_get_syncdbs();
+ alpm_list_t *j;
if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
continue;
}
/* build the full filepath */
- snprintf(path, PATH_MAX, "%s/%s", cachedir, ent->d_name);
+ snprintf(path, PATH_MAX, "%s%s", cachedir, ent->d_name);
/* attempt to load the package, skip file on failures as we may have
* files here that aren't valid packages. we also don't need a full
@@ -167,25 +177,45 @@ static int sync_cleancache(int level)
if(alpm_pkg_load(path, 0, &localpkg) != 0 || localpkg == NULL) {
continue;
}
- /* check if this package is in the local DB */
- dbpkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg));
- if(dbpkg == NULL) {
- /* delete package, not present in local DB */
- unlink(path);
- } else if(alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
- alpm_pkg_get_version(dbpkg)) != 0) {
- /* delete package, it was found but version differs */
- unlink(path);
+ switch(config->cleanmethod) {
+ case PM_CLEAN_KEEPINST:
+ /* check if this package is in the local DB */
+ pkg = alpm_db_get_pkg(db_local, alpm_pkg_get_name(localpkg));
+ if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
+ alpm_pkg_get_version(pkg)) == 0) {
+ /* package was found in local DB and version matches, keep it */
+ delete = 0;
+ }
+ break;
+ case PM_CLEAN_KEEPCUR:
+ /* check if this package is in a sync DB */
+ for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
+ pmdb_t *db = alpm_list_getdata(j);
+ pkg = alpm_db_get_pkg(db, alpm_pkg_get_name(localpkg));
+ if(pkg != NULL && alpm_pkg_vercmp(alpm_pkg_get_version(localpkg),
+ alpm_pkg_get_version(pkg)) == 0) {
+ /* package was found in a sync DB and version matches, keep it */
+ delete = 0;
+ }
+ }
+ break;
+ default:
+ /* this should not happen : the config parsing doesn't set any other value */
+ delete = 0;
+ break;
}
- /* else version was the same, so keep the package */
/* free the local file package */
alpm_pkg_free(localpkg);
+
+ if(delete) {
+ unlink(path);
+ }
}
printf(_("done.\n"));
} else {
/* full cleanup */
printf(_("Cache directory: %s\n"), cachedir);
- if(!yesno(_("Do you want to remove ALL packages from cache? [Y/n] "))) {
+ if(!yesno(0, _("Do you want to remove ALL packages from cache?"))) {
return(0);
}
printf(_("removing all packages from cache... "));
@@ -232,25 +262,17 @@ static int sync_synctree(int level, alpm_list_t *syncs)
alpm_list_t *i;
int success = 0, ret;
+ if(sync_trans_init(0) == -1) {
+ return(0);
+ }
+
for(i = syncs; i; i = alpm_list_next(i)) {
pmdb_t *db = alpm_list_getdata(i);
ret = alpm_db_update((level < 2 ? 0 : 1), db);
if(ret < 0) {
- if(pm_errno == PM_ERR_DB_SYNC) {
- /* use libdownload error */
- /* TODO breaking abstraction barrier here?
- * pacman -> libalpm -> libdownload
- *
- * Yes. This will be here until we add a nice pacman "pm_errstr" or
- * something, OR add all libdownload error codes into the pm_error enum
- */
- fprintf(stderr, _("error: failed to synchronize %s: %s\n"),
- alpm_db_get_name(db), downloadLastErrString);
- } else {
- fprintf(stderr, _("error: failed to update %s (%s)\n"),
- alpm_db_get_name(db), alpm_strerrorlast());
- }
+ fprintf(stderr, _("error: failed to update %s (%s)\n"),
+ alpm_db_get_name(db), alpm_strerrorlast());
} else if(ret == 1) {
printf(_(" %s is up to date\n"), alpm_db_get_name(db));
success++;
@@ -259,10 +281,16 @@ static int sync_synctree(int level, alpm_list_t *syncs)
}
}
+ if(sync_trans_release() == -1) {
+ return(0);
+ }
/* We should always succeed if at least one DB was upgraded - we may possibly
* fail later with unresolved deps, but that should be rare, and would be
* expected
*/
+ if(!success) {
+ fprintf(stderr, _("error: failed to synchronize any databases\n"));
+ }
return(success > 0);
}
@@ -289,8 +317,6 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
found = 1;
}
for(j = ret; j; j = alpm_list_next(j)) {
- /* print repo/name (group) info about each package in our list */
- char *group = NULL;
alpm_list_t *grp;
pmpkg_t *pkg = alpm_list_getdata(j);
@@ -311,8 +337,17 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
if (!config->quiet) {
if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
- group = alpm_list_getdata(grp);
- printf(" (%s)", (char *)alpm_list_getdata(grp));
+ alpm_list_t *k;
+ printf(" (");
+ for(k = grp; k; k = alpm_list_next(k)) {
+ const char *group = alpm_list_getdata(k);
+ printf("%s", group);
+ if(alpm_list_next(k)) {
+ /* only print a spacer if there are more groups */
+ printf(" ");
+ }
+ }
+ printf(")");
}
/* we need a newline and initial indent first */
@@ -332,7 +367,8 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets)
static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
{
- alpm_list_t *i, *j;
+ alpm_list_t *i, *j, *k;
+ alpm_list_t *pkgnames = NULL;
if(targets) {
for(i = targets; i; i = alpm_list_next(i)) {
@@ -342,9 +378,14 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
pmgrp_t *grp = alpm_db_readgrp(db, grpname);
if(grp) {
- /* TODO this should be a lot cleaner, why two outputs? */
printf("%s\n", (char *)alpm_grp_get_name(grp));
- list_display(" ", alpm_grp_get_pkgs(grp));
+ /* get names of packages in group */
+ for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ alpm_list_free(pkgnames);
}
}
}
@@ -357,7 +398,12 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets)
printf("%s\n", (char *)alpm_grp_get_name(grp));
if(grp && level > 1) {
- list_display(" ", alpm_grp_get_pkgs(grp));
+ for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ alpm_list_free(pkgnames);
}
}
}
@@ -499,7 +545,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets)
return(0);
}
-static int sync_trans(alpm_list_t *targets, int sync_only)
+static int sync_trans(alpm_list_t *targets)
{
int retval = 0;
alpm_list_t *data = NULL;
@@ -510,23 +556,8 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
return(1);
}
- if(config->op_s_sync) {
- /* grab a fresh package list */
- printf(_(":: Synchronizing package databases...\n"));
- alpm_logaction("synchronizing package lists\n");
- if(!sync_synctree(config->op_s_sync, sync_dbs)) {
- fprintf(stderr, _("error: failed to synchronize any databases\n"));
- retval = 1;
- goto cleanup;
- }
- if(sync_only) {
- goto cleanup;
- }
- }
-
if(config->op_s_upgrade) {
alpm_list_t *pkgs, *i;
-
printf(_(":: Starting full system upgrade...\n"));
alpm_logaction("starting full system upgrade\n");
if(alpm_trans_sysupgrade() == -1) {
@@ -550,8 +581,8 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
if(strcmp("pacman", alpm_pkg_get_name(spkg)) == 0) {
printf("\n");
printf(_(":: pacman has detected a newer version of itself.\n"));
- if(yesno(_(":: Do you want to cancel the current operation\n"
- ":: and install the new pacman version now? [Y/n] "))) {
+ if(yesno(1, _(":: Do you want to cancel the current operation\n"
+ ":: and install the new pacman version now?"))) {
if(sync_trans_release() == -1) {
return(1);
}
@@ -594,26 +625,31 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
pmdb_t *db = alpm_list_getdata(j);
grp = alpm_db_readgrp(db, targ);
if(grp) {
- alpm_list_t *k;
+ alpm_list_t *k, *pkgnames = NULL;
found++;
printf(_(":: group %s (including ignored packages):\n"), targ);
/* remove dupe entries in case a package exists in multiple repos */
- const alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);
+ alpm_list_t *grppkgs = alpm_grp_get_pkgs(grp);
alpm_list_t *pkgs = alpm_list_remove_dupes(grppkgs);
- list_display(" ", pkgs);
- if(yesno(_(":: Install whole content? [Y/n] "))) {
- for(k = pkgs; k; k = alpm_list_next(k)) {
+ for(k = pkgs; k; k = alpm_list_next(k)) {
+ pkgnames = alpm_list_add(pkgnames,
+ (char*)alpm_pkg_get_name(k->data));
+ }
+ list_display(" ", pkgnames);
+ if(yesno(1, _(":: Install whole content?"))) {
+ for(k = pkgnames; k; k = alpm_list_next(k)) {
targets = alpm_list_add(targets, strdup(alpm_list_getdata(k)));
}
} else {
- for(k = pkgs; k; k = alpm_list_next(k)) {
+ for(k = pkgnames; k; k = alpm_list_next(k)) {
char *pkgname = alpm_list_getdata(k);
- if(yesno(_(":: Install %s from group %s? [Y/n] "), pkgname, targ)) {
+ if(yesno(1, _(":: Install %s from group %s?"), pkgname, targ)) {
targets = alpm_list_add(targets, strdup(pkgname));
}
}
}
+ alpm_list_free(pkgnames);
alpm_list_free(pkgs);
}
}
@@ -698,19 +734,9 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
printf("\n");
if(config->op_s_downloadonly) {
- if(config->noconfirm) {
- printf(_("Beginning download...\n"));
- confirm = 1;
- } else {
- confirm = yesno(_("Proceed with download? [Y/n] "));
- }
+ confirm = yesno(1, _("Proceed with download?"));
} else {
- if(config->noconfirm) {
- printf(_("Beginning upgrade process...\n"));
- confirm = 1;
- } else {
- confirm = yesno(_("Proceed with installation? [Y/n] "));
- }
+ confirm = yesno(1, _("Proceed with installation?"));
}
if(!confirm) {
goto cleanup;
@@ -741,9 +767,11 @@ static int sync_trans(alpm_list_t *targets, int sync_only)
}
}
break;
- case PM_ERR_PKG_CORRUPTED:
+ case PM_ERR_PKG_INVALID:
+ case PM_ERR_DLT_INVALID:
for(i = data; i; i = alpm_list_next(i)) {
- printf("%s", (char*)alpm_list_getdata(i));
+ char *filename = alpm_list_getdata(i);
+ printf(_("%s is invalid or corrupted\n"), filename);
}
break;
default:
@@ -770,7 +798,6 @@ cleanup:
int pacman_sync(alpm_list_t *targets)
{
alpm_list_t *sync_dbs = NULL;
- int sync_only = 0;
/* clean the cache */
if(config->op_s_clean) {
@@ -797,18 +824,27 @@ int pacman_sync(alpm_list_t *targets)
return(1);
}
- if(config->op_s_search || config->group
- || config->op_s_info || config->op_q_list) {
- sync_only = 1;
- } else if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade)) {
+ if(targets == NULL && !(config->op_s_sync || config->op_s_upgrade
+ || config->op_s_search || config->group
+ || config->op_s_info || config->op_q_list)) {
/* don't proceed here unless we have an operation that doesn't require
* a target list */
pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
return(1);
}
+ if(config->op_s_sync) {
+ /* grab a fresh package list */
+ printf(_(":: Synchronizing package databases...\n"));
+ alpm_logaction("synchronizing package lists\n");
+ if(!sync_synctree(config->op_s_sync, sync_dbs)) {
+ return(1);
+ }
+ config->op_s_sync = 0;
+ }
+
if(needs_transaction()) {
- if(sync_trans(targets, sync_only) == 1) {
+ if(sync_trans(targets) == 1) {
return(1);
}
}
diff --git a/src/pacman/add.c b/src/pacman/upgrade.c
index fd40f005..e5626516 100644
--- a/src/pacman/add.c
+++ b/src/pacman/upgrade.c
@@ -1,5 +1,5 @@
/*
- * add.c
+ * upgrade.c
*
* Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
*
@@ -33,7 +33,7 @@
#include "util.h"
/* Free the current transaction and print an error if unsuccessful */
-static int add_cleanup(void)
+static int upgrade_cleanup(void)
{
int ret = alpm_trans_release();
if(ret != 0) {
@@ -54,23 +54,8 @@ static int add_cleanup(void)
*/
int pacman_upgrade(alpm_list_t *targets)
{
- /* this is basically just a remove-then-add process. pacman_add() will */
- /* handle it */
- config->upgrade = 1;
- return(pacman_add(targets));
-}
-
-/**
- * @brief Add a specified list of packages which cannot already be installed.
- *
- * @param targets a list of packages (as strings) to add
- *
- * @return 0 on success, 1 on failure
- */
-int pacman_add(alpm_list_t *targets)
-{
alpm_list_t *i, *data = NULL;
- pmtranstype_t transtype = PM_TRANS_TYPE_ADD;
+ pmtranstype_t transtype = PM_TRANS_TYPE_UPGRADE;
int retval = 0;
if(targets == NULL) {
@@ -93,11 +78,6 @@ int pacman_add(alpm_list_t *targets)
}
/* Step 1: create a new transaction */
- if(config->upgrade == 1) {
- /* if upgrade flag was set, change this to an upgrade transaction */
- transtype = PM_TRANS_TYPE_UPGRADE;
- }
-
if(alpm_trans_init(transtype, config->flags, cb_trans_evt,
cb_trans_conv, cb_trans_progress) == -1) {
/* TODO: error messages should be in the front end, not the back */
@@ -117,7 +97,7 @@ int pacman_add(alpm_list_t *targets)
if(alpm_trans_addtarget(targ) == -1) {
fprintf(stderr, _("error: '%s': %s\n"),
targ, alpm_strerrorlast());
- add_cleanup();
+ upgrade_cleanup();
return(1);
}
}
@@ -171,7 +151,7 @@ int pacman_add(alpm_list_t *targets)
default:
break;
}
- add_cleanup();
+ upgrade_cleanup();
FREELIST(data);
return(1);
}
@@ -180,11 +160,11 @@ int pacman_add(alpm_list_t *targets)
/* Step 3: perform the installation */
if(alpm_trans_commit(NULL) == -1) {
fprintf(stderr, _("error: failed to commit transaction (%s)\n"), alpm_strerrorlast());
- add_cleanup();
+ upgrade_cleanup();
return(1);
}
- retval = add_cleanup();
+ retval = upgrade_cleanup();
return(retval);
}
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 0facfdd1..ed7669a3 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -234,6 +234,10 @@ void indentprint(const char *str, int indent)
p = wcstr;
cidx = indent;
+ if(!p) {
+ return;
+ }
+
while(*p) {
if(*p == L' ') {
const wchar_t *q, *next;
@@ -464,20 +468,17 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
pmsyncpkg_t *sync = alpm_list_getdata(i);
pmpkg_t *pkg = alpm_sync_get_pkg(sync);
- /* If this sync record is a replacement, the data member contains
- * a list of packages to be removed due to the package that is being
- * installed. */
- if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) {
- alpm_list_t *to_replace = alpm_sync_get_data(sync);
+ /* The removes member contains a list of packages to be removed
+ * due to the package that is being installed. */
+ alpm_list_t *to_replace = alpm_sync_get_removes(sync);
- for(j = to_replace; j; j = alpm_list_next(j)) {
- pmpkg_t *rp = alpm_list_getdata(j);
- const char *name = alpm_pkg_get_name(rp);
+ for(j = to_replace; j; j = alpm_list_next(j)) {
+ pmpkg_t *rp = alpm_list_getdata(j);
+ const char *name = alpm_pkg_get_name(rp);
- if(!alpm_list_find_str(to_remove, name)) {
- rsize += alpm_pkg_get_isize(rp);
- to_remove = alpm_list_add(to_remove, strdup(name));
- }
+ if(!alpm_list_find_str(to_remove, name)) {
+ rsize += alpm_pkg_get_isize(rp);
+ to_remove = alpm_list_add(to_remove, strdup(name));
}
}
@@ -520,38 +521,50 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
printf("\n");
printf(_("Total Download Size: %.2f MB\n"), mbdlsize);
-
- /* TODO because all pkgs don't include isize, this is a crude hack */
- if(mbisize > mbdlsize) {
- printf(_("Total Installed Size: %.2f MB\n"), mbisize);
- }
+ printf(_("Total Installed Size: %.2f MB\n"), mbisize);
FREELIST(targets);
}
/* presents a prompt and gets a Y/N answer */
-/* TODO there must be a better way */
-int yesno(char *fmt, ...)
+int yesno(short preset, char *fmt, ...)
{
char response[32];
va_list args;
+ FILE *stream;
if(config->noconfirm) {
- return(1);
+ stream = stdout;
+ } else {
+ /* Use stderr so questions are always displayed when redirecting output */
+ stream = stderr;
}
va_start(args, fmt);
- /* Use stderr so questions are always displayed when redirecting output */
- vfprintf(stderr, fmt, args);
+ vfprintf(stream, fmt, args);
va_end(args);
+ if(preset) {
+ fprintf(stream, " %s ", _("[Y/n]"));
+ } else {
+ fprintf(stream, " %s ", _("[y/N]"));
+ }
+
+ if(config->noconfirm) {
+ fprintf(stream, "\n");
+ return(preset);
+ }
+
if(fgets(response, 32, stdin)) {
- if(strlen(response) != 0) {
- strtrim(response);
+ strtrim(response);
+ if(strlen(response) == 0) {
+ return(preset);
}
- if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES")) || strlen(response) == 0) {
+ if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES"))) {
return(1);
+ } else if (!strcasecmp(response, _("N")) || !strcasecmp(response, _("NO"))) {
+ return(0);
}
}
return(0);
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 0273512e..f2facbfc 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -50,7 +50,7 @@ alpm_list_t *strsplit(const char *str, const char splitchar);
void string_display(const char *title, const char *string);
void list_display(const char *title, const alpm_list_t *list);
void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local);
-int yesno(char *fmt, ...);
+int yesno(short preset, char *fmt, ...);
int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));
int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...) __attribute__((format(printf,3,4)));
int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args) __attribute__((format(printf,3,0)));
diff --git a/src/util/testdb.c b/src/util/testdb.c
index 122a3fb5..f354ecab 100644
--- a/src/util/testdb.c
+++ b/src/util/testdb.c
@@ -147,6 +147,14 @@ int main(int argc, char **argv)
free(depstring);
}
+ /* check conflicts */
+ data = alpm_checkdbconflicts(db);
+ for(i = data; i; i = i->next) {
+ pmconflict_t *conflict = alpm_list_getdata(i);
+ printf("%s conflicts with %s\n", alpm_conflict_get_package1(conflict),
+ alpm_conflict_get_package2(conflict));
+ }
+
cleanup(retval);
}
diff --git a/src/util/testpkg.c b/src/util/testpkg.c
index 64056ce4..6e8f9d1c 100644
--- a/src/util/testpkg.c
+++ b/src/util/testpkg.c
@@ -63,7 +63,7 @@ int main(int argc, char **argv)
case PM_ERR_PKG_OPEN:
printf("Cannot open the given file.\n");
break;
- case PM_ERR_LIBARCHIVE_ERROR:
+ case PM_ERR_LIBARCHIVE:
case PM_ERR_PKG_INVALID:
printf("Package is invalid.\n");
break;