diff options
91 files changed, 3610 insertions, 1645 deletions
@@ -35,7 +35,7 @@ while(it) { if(fn) { fn(it->data); } else { - return(1); + return 1; } free(it); it = ptr; @@ -67,11 +67,11 @@ alpm_list_t *alpm_list_add(alpm_list_t *list, void *data) NOT // This is a comment -5. Return statements should be written like a function call. +5. Return statements should *not* be written like function calls. - return(0); - NOT return 0; + NOT + return(0); 6. The sizeof() operator should accept a type, not a value. (TODO: in certain cases, it may be better- should this be a set guideline? Read "The Practice @@ -16,8 +16,8 @@ properly build pacman. libarchive http://code.google.com/p/libarchive/ -libfetch -ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/net/libfetch/README.html +libcurl +http://curl.haxx.se/libcurl/ Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following @@ -192,8 +192,8 @@ remove.c and sync.c). The frontend is using a configuration file, usually "/etc/pacman.conf". Some of these options are only useful for the frontend only (mainly the ones used to -control the output like showsize or totaldownload, or the behavior with -cleanmethod and syncfirst). The rest is used to configure the library. +control the output like totaldownload, or the behavior with cleanmethod and +syncfirst). The rest is used to configure the library. [UPGRADE/REMOVE/SYNC] @@ -10,9 +10,6 @@ Pacman 3.1: Downgrade feature - allow users to see cached packages and downgrade to (previous or any?) available options. -Installed size and download size in -Si/Qi output should scale with package -size- KB to MB to GB. We should also get consistancy of K/KB, M/MB, etc. - Extreme similarity between some of the sync and add code...we have to be able to abstract more away from sync actions and add actions to just 'actions' (example: sync,c, add.c, and deptest.c all contain a switch on PM_DEP_MOD_*). @@ -79,9 +76,6 @@ Refine makepkg error codes. Each kind of failure could have its own code: --failed build --etc. -Add utility function to either frontend or backend to convert sizes: e.g. bytes -to KB, MB, GB. - Revamp the downloadprog function a bit. Seems kind of messy. --print-uri option to sync should not require saying yes or no to up to date diff --git a/configure.ac b/configure.ac index 52e375dc..b5fdfff8 100644 --- a/configure.ac +++ b/configure.ac @@ -93,10 +93,8 @@ AC_ARG_WITH(openssl, AS_HELP_STRING([--with-openssl], [use OpenSSL crypto implementations instead of internal routines]), [], [with_openssl=check]) -# Help line for libfetch -AC_ARG_WITH(fetch, - AS_HELP_STRING([--with-fetch], [use libfetch as an internal downloader]), - [], [with_fetch=check]) +# Check for useable libcurl +LIBCURL_CHECK_CONFIG([yes], [7.19.4]) # Help line for documentation AC_ARG_ENABLE(doc, @@ -133,6 +131,9 @@ AC_PATH_PROGS([BASH_SHELL], [bash bash4 bash3], [false]) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION(0.13.1) +AC_CHECK_LIB([m], [fabs], , + AC_MSG_ERROR([libm is needed to compile pacman!])) + # Check for libarchive AC_CHECK_LIB([archive], [archive_read_data], , AC_MSG_ERROR([libarchive is needed to compile pacman!])) @@ -149,29 +150,15 @@ AS_IF([test "x$with_openssl" != "xno"], AC_MSG_RESULT(no)) AM_CONDITIONAL([HAVE_LIBSSL], [test "x$ac_cv_lib_ssl_MD5_Final" = "xyes"]) -# Enable or disable usage of libfetch -AC_MSG_CHECKING(whether to link with libfetch) -AS_IF([test "x$with_fetch" != "xno"], - [AC_MSG_RESULT(yes) - AC_CHECK_LIB([fetch], [fetchParseURL], , - [if test "x$with_fetch" != "xcheck"; then - AC_MSG_FAILURE([--with-fetch was given, but -lfetch was not found]) - fi], - [-lcrypto -ldl]) - # Check if libfetch supports connnection caching which we use - AS_IF([test "x$ac_cv_lib_fetch_fetchParseURL" = "xyes"], - [AC_CHECK_DECL(fetchConnectionCacheInit, , - AC_MSG_ERROR([libfetch must be version 2.28 or greater]), - [#include <fetch.h>]) - ]) - ], - AC_MSG_RESULT(no)) -AM_CONDITIONAL([HAVE_LIBFETCH], [test "x$ac_cv_lib_fetch_fetchParseURL" = "xyes"]) +# Check for gpgme +AC_CHECK_LIB([gpgme], [gpgme_check_version], , + AC_MSG_ERROR([gpgme is needed to compile pacman!])) # Checks for header files. AC_CHECK_HEADERS([fcntl.h glob.h libintl.h locale.h mntent.h string.h \ sys/ioctl.h sys/mount.h sys/param.h sys/statvfs.h \ - sys/time.h sys/types.h sys/ucred.h syslog.h wchar.h]) + sys/time.h sys/types.h sys/ucred.h syslog.h termios.h \ + wchar.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE @@ -190,7 +177,7 @@ AC_FUNC_GETMNTENT AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK AC_FUNC_MKTIME AC_CHECK_FUNCS([geteuid getmntinfo realpath regcomp strcasecmp \ - strndup strrchr strsep swprintf \ + strndup strrchr strsep swprintf tcflush \ wcwidth uname]) # For the diskspace code FS_STATS_TYPE diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 827d9ec0..e9f77940 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -3,8 +3,7 @@ OURSCRIPTS = \ pacdiff \ paclist \ pacscripts \ - pacsearch \ - wget-xdelta.sh + pacsearch OURFILES = \ bash_completion \ @@ -19,7 +18,6 @@ EXTRA_DIST = \ pacscripts.in \ pacsearch.in \ vimprojects \ - wget-xdelta.sh.in \ zsh_completion.in \ README @@ -55,7 +53,6 @@ paclist: $(srcdir)/paclist.in pacscripts: $(srcdir)/pacscripts.in pacsearch: $(srcdir)/pacsearch.in pactree: $(srcdir)/pactree.in -wget-xdelta.sh: $(srcdir)/wget-xdelta.sh.in zsh_completion: $(srcdir)/zsh_completion.in # vim:set ts=2 sw=2 noet: diff --git a/contrib/README b/contrib/README index 4f591012..04b656f3 100644 --- a/contrib/README +++ b/contrib/README @@ -28,6 +28,3 @@ database entries. Useful for reuse, or possible config file extension. 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. diff --git a/contrib/pacscripts.in b/contrib/pacscripts.in index d3664091..8ad5173b 100755 --- a/contrib/pacscripts.in +++ b/contrib/pacscripts.in @@ -61,7 +61,7 @@ spacman() { if [ $EUID -eq 0 ]; then pacman "$@" else - if [ ! "$(type -p sudo)" ]; then + if ! type -p sudo; then error "Cannot find the sudo binary! Is sudo installed?" error "Otherwise try to run the program as root" exit 1 diff --git a/contrib/wget-xdelta.sh.in b/contrib/wget-xdelta.sh.in deleted file mode 100755 index f2ac1c87..00000000 --- a/contrib/wget-xdelta.sh.in +++ /dev/null @@ -1,70 +0,0 @@ -#!@BASH_SHELL@ - -if [ -r "@sysconfdir@/makepkg.conf" ]; then - source @sysconfdir@/makepkg.conf -else - echo "wget-xdelta: Unable to find makepkg.conf" - exit 1 -fi - -if [ -r ~/.makepkg.conf ]; then - source ~/.makepkg.conf -fi - -out_file=$(basename $1) -file_url=$2 - -if ! [[ "$out_file" =~ "pkg.tar.gz" ]]; then - # If it's not a package file download as normal and exit. - #wget --passive-ftp -c -O "$out_file" "$file_url" - exit $? -fi - - -# Get the package name and version -[[ "$out_file" =~ "$CARCH" ]] && arch="-$CARCH" || arch="" -pkg_data=$(echo $out_file | \ - sed "s|^\(.*\)-\([[:alnum:]_\.]*-[[:alnum:]_\.]*\)${arch}${PKGEXT}.part|\1 \2|") -pkgname=$(echo $pkg_data | cut -d ' ' -f 1) -new_version=$(echo $pkg_data | cut -d ' ' -f 2) -base_url=${file_url%/*} - -# Look for the last version -for file in $(ls -r @localstatedir@/cache/pacman/pkg/${pkgname}-*-*{,-$CARCH}$PKGEXT 2>/dev/null); do - [[ "$file" =~ "$CARCH" ]] && arch="-$CARCH" || arch="" - check_version=$(echo $file | \ - sed "s|^.*/${pkgname}-\([[:alnum:]_\.]*-[[:alnum:]_\.]*\)${arch}$PKGEXT$|\1|" | \ - grep -v "^@localstatedir@/cache/pacman/pkg") - - [ "$check_version" = "" ] && continue - - vercmp=$(vercmp "$check_version" "$old_version") - if [ "$check_version" != "$new_version" -a $vercmp -gt 0 ]; then - old_version=$check_version - old_file=$file - fi -done - -if [ "$old_version" != "" -a "$old_version" != "$new_version" ]; then - # Great, we have a cached file, now calculate a patch name from it - delta_name="$pkgname-${old_version}_to_${new_version}-${CARCH}.delta" - - echo "wget-xdelta: Attempting to download delta $delta_name..." >&2 - if wget --passive-ftp -c "$base_url/$delta_name"; then - echo "wget-xdelta: Applying delta..." - if xdelta patch "$delta_name" "$old_file" "$out_file"; then - echo "wget-xdelta: Delta applied successfully!" - rm "$delta_name" - exit 0 - else - echo "wget-xdelta: Failed to apply delta!" - rm $delta_name - fi - fi - fi - -echo "wget-xdelta: Downloading new package..." -wget --passive-ftp -c -O "$out_file" "$file_url" -exit $? - -# vim:set ts=4 sw=4 noet: diff --git a/doc/.gitignore b/doc/.gitignore index a6f4df7f..a7f33e55 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -3,7 +3,9 @@ libalpm.3 makepkg.8 makepkg.conf.5 pacman.8 +pacman-key.8 pacman.conf.5 +pkgdelta.8 repo-add.8 repo-remove.8 vercmp.8 diff --git a/doc/Makefile.am b/doc/Makefile.am index 00a0e88d..def58c4e 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -8,6 +8,8 @@ ASCIIDOC_MANS = \ makepkg.8 \ repo-add.8 \ vercmp.8 \ + pkgdelta.8 \ + pacman-key.8 \ PKGBUILD.5 \ makepkg.conf.5 \ pacman.conf.5 \ @@ -20,6 +22,8 @@ HTML_MANPAGES = \ makepkg.8.html \ repo-add.8.html \ vercmp.8.html \ + pkgdelta.8.html \ + pacman-key.8.html \ PKGBUILD.5.html \ makepkg.conf.5.html \ pacman.conf.5.html \ @@ -41,6 +45,8 @@ EXTRA_DIST = \ makepkg.8.txt \ repo-add.8.txt \ vercmp.8.txt \ + pkgdelta.8.txt \ + pacman-key.8.txt \ PKGBUILD.5.txt \ PKGBUILD-example.txt \ makepkg.conf.5.txt \ @@ -133,6 +139,8 @@ pacman.8 pacman.8.html: pacman.8.txt makepkg.8 makepkg.8.html: makepkg.8.txt repo-add.8 repo-add.8.html: repo-add.8.txt vercmp.8 vercmp.8.html: vercmp.8.txt +pkgdelta.8 pkgdelta.8.html: pkgdelta.8.txt +pacman-key.8 pacman-key.8.html: pacman-key.8.txt PKGBUILD.5 PKGBUILD.5.html: PKGBUILD.5.txt PKGBUILD-example.txt makepkg.conf.5 makepkg.conf.5.html: makepkg.conf.5.txt pacman.conf.5 pacman.conf.5.html: pacman.conf.5.txt diff --git a/doc/index.txt b/doc/index.txt index c04ca8a9..4cc83132 100644 --- a/doc/index.txt +++ b/doc/index.txt @@ -41,7 +41,9 @@ configuration files dealing with pacman. * linkman:makepkg[8] * linkman:makepkg.conf[5] * linkman:pacman[8] +* linkman:pacman-key[8] * linkman:pacman.conf[5] +* linkman:pkgdelta[8] * linkman:repo-add[8] * linkman:vercmp[8] diff --git a/doc/makepkg.8.txt b/doc/makepkg.8.txt index c59800c6..1a2dcd04 100644 --- a/doc/makepkg.8.txt +++ b/doc/makepkg.8.txt @@ -11,24 +11,24 @@ makepkg - package build utility Synopsis -------- -makepkg [options] +'makepkg' [options] Description ----------- -makepkg is a script to automate the building of packages. The requirements for +'makepkg' is a script to automate the building of packages. The requirements for using the script are a build-capable \*nix platform and a custom build script for each package you wish to build (known as a PKGBUILD). See linkman:PKGBUILD[5] for details on creating your own build scripts. The advantage to a script-based build is that the work is only done once. Once -you have the build script for a package, makepkg will do the rest: download and +you have the build script for a package, 'makepkg' will do the rest: download and validate source files, check dependencies, configure the build-time settings, build the package, install the package into a temporary root, make customizations, generate meta-info, and package the whole thing up for pacman to use. -NOTE: makepkg uses your current locale by default and does not unset it when +NOTE: 'makepkg' uses your current locale by default and does not unset it when building packages. If you wish to share your build output with others when seeking help or for other purposes, you may wish to run "`LC_ALL=C makepkg`" so your logs and output are not localized. @@ -161,6 +161,18 @@ Options *\--nocheck*:: Do not run the check() function in the PKGBUILD or handle the checkdepends. +*\--sign*:: + Sign the resulting package with gpg, overriding the setting in + linkman:makepkg.conf[5]. + +*\--nosign*:: + Do not create a signature for the built package. + +*\--key* <key>:: + Specify a key to use when signing packages, overriding the GPGKEY setting + in linkman:makepkg.conf[5]. If not specified in either location, the + default key from the keyring will be used. + *\--noconfirm*:: (Passed to pacman) Prevent pacman from waiting for user input before proceeding with operations. diff --git a/doc/makepkg.conf.5.txt b/doc/makepkg.conf.5.txt index 61302492..9d3ad0a1 100644 --- a/doc/makepkg.conf.5.txt +++ b/doc/makepkg.conf.5.txt @@ -70,7 +70,7 @@ Options This is often used to set the number of jobs used, for example, `-j2`. Other flags that make accepts can also be passed. -**BUILDENV=(**fakeroot !distcc color !ccache**)**:: +**BUILDENV=(**fakeroot !distcc color !ccache !sign**)**:: This array contains options that affect the build environment, 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 @@ -98,11 +98,22 @@ Options enabled or disabled for individual packages through the use of makepkg's `--check` and `--nocheck` options respectively. + *sign*;; + Generate a PGP signature file using GnuPG. This will execute `gpg + --detach-sign --use-agent` on the built package to generate a detached + signature file, using the GPG agent if it is available. The signature + file will be the entire filename of the package with a ``.sig'' + extension. + **DISTCC_HOSTS=**"host1 ...":: If using DistCC, this is used to specify a space-delimited list of hosts running in the DistCC cluster. In addition, you will want to modify your `MAKEFLAGS`. +**GPGKEY=**"":: + Specify a key to use for gpg signing instead of the default key in the + keyring. Can be overridden with makepkg's `--key` option. + **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 diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt new file mode 100644 index 00000000..8a08480f --- /dev/null +++ b/doc/pacman-key.8.txt @@ -0,0 +1,85 @@ +///// +vim:set ts=4 sw=4 syntax=asciidoc noet: +///// +pacman-key(8) +============= + + +Name +---- +pacman-key - manage pacman's list of trusted keys + + +Synopsis +-------- +'pacman-key' [options] <command> [arguments] + + +Description +----------- +'pacman-key' is a script used to manage pacman's keyring, which is the collection +of GnuPG keys used to check signed packages. It provides the ability to import +and export keys, fetch keys from keyservers and update the key trust database. + + +Options +------- +*\--config* <file>:: + Use an alternate config file instead of the `{sysconfdir}/pacman.conf` + default. + +*\--gpgdir* <dir>:: + Set an alternate home directory for GnuPG. If unspecified, the value is + read from `{sysconfdir}/pacman.conf`. + + +Commands +------- +*-a, \--add* file ...:: + Add the key(s) contained in the specified file or files to pacman's + keyring. If a key already exists, update it. + +*\--adv* param ...:: + Use this option to issue particular GnuPG actions to pacman's keyring. This + option should be used with care as it can modify pacman's trust in + packages' signatures. + +*-d, \--del* keyid ...:: + Remove the key(s) identified by the specified keyid or keyids from pacman's + keyring. + +*-e, \--export* [keyid ...]:: + Export key(s) identified by the specified keyid to 'stdout'. If no keyid is + specified, all keys will be exported. + +*-f, \--finger* [keyid ...]:: + List a fingerprint for each specified keyid, or for all known keys if no + keyids are specified. + +*-h, \--help*:: + Output syntax and command line options. + +*-l, \--list*:: + Equivalent to --list-sigs from GnuPG. + +*-r, \--receive* keyserver keyid ...:: + Fetch the specified keyids from the specified key server URL. + +*\--reload*:: + Reloads the keys from the keyring package. + +*-t, \--trust* keyid:: + Set the trust level of the given key. + +*-u, \--updatedb*:: + Equivalent to \--check-trustdb in GnuPG. + +*-v, \--version*:: + Displays the program version. + + +See Also +-------- +linkman:pacman[8], linkman:pacman.conf[5] + +include::footer.txt[] diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index a9abb3f4..d1b8a731 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -149,6 +149,13 @@ Options Display debug messages. When reporting bugs, this option is recommended to be used. +*\--gpgdir* <dir>:: + Specify a directory of files used by GnuPG to verify package signatures. + This directory should contain two files: `pubring.gpg` and `trustdb.gpg`. + `pubring.gpg` holds the public keys of all packagers. `trustdb.gpg` + contains a so-called trust database, which specifies that the keys are + authentic and trusted. + *\--logfile* <file>:: Specify an alternate log file. This is an absolute path, regardless of the installation root setting. diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt index bfa07458..99fb0fa4 100644 --- a/doc/pacman.conf.5.txt +++ b/doc/pacman.conf.5.txt @@ -69,6 +69,15 @@ Options to the first cache directory with write access. *NOTE*: this is an absolute path, the root path is not automatically prepended. +*GPGDir =* path/to/gpg/dir:: + Overrides the default location of the directory containing configuration + files for GnuPG. A typical default is `{sysconfdir}/pacman.d/gnupg/`. + This directory should contain two files: `pubring.gpg` and `trustdb.gpg`. + `pubring.gpg` holds the public keys of all packagers. `trustdb.gpg` + contains a so-called trust database, which specifies that the keys are + authentic and trusted. + *NOTE*: this is an absolute path, the root path is not automatically + prepended. *LogFile =* '/path/to/file':: Overrides the default location of the pacman log file. A typical default @@ -151,9 +160,6 @@ Options Log action messages through syslog(). This will insert log entries into `{localstatedir}/log/messages` or equivalent. -*ShowSize*:: - Display the size of individual packages for '\--sync' and '\--query' modes. - *UseDelta*:: Download delta files instead of complete packages if possible. Requires the xdelta3 program to be installed. @@ -168,6 +174,10 @@ Options Performs an approximate check for adequate available disk space before installing packages. +*VerbosePkgLists*:: + Displays name, version and size of target packages formatted + as a table for upgrade, sync and remove operations. + Repository Sections ------------------- Each repository section defines a section name and at least one location where diff --git a/doc/pkgdelta.8.txt b/doc/pkgdelta.8.txt new file mode 100644 index 00000000..2d99a87f --- /dev/null +++ b/doc/pkgdelta.8.txt @@ -0,0 +1,42 @@ +///// +vim:set ts=4 sw=4 syntax=asciidoc noet: +///// +pkgdelta(8) +========= + +Name +---- +pkgdelta - package delta generation utility + + +Synopsis +-------- +'pkgdelta' [-q] <package1> <package2> + + +Description +----------- +'pkgdelta' is used to create package delta files between two versions of the +same package. These files are essentially binary patches. linkman:pacman[8] can +download deltas instead of full package upgrades, and use them with the +previous versions of packages (in the package cache) to synthesize the upgraded +version of the packages. This likely reduces download sizes for upgrades +significantly. + +'pkgdelta' requires linkman:xdelta3[1] to do its job. + +Options +------- +*-q, \--quiet*:: + Be quiet. Do not output anything but warnings and errors. + +Examples +-------- + + $ pkgdelta libreoffice-3.3.2-1-x86_64.pkg.tar.xz libreoffice-3.3.2-2-x86_64.pkg.tar.xz + +See Also +-------- +linkman:pacman[8], linkman:xdelta3[1] + +include::footer.txt[] diff --git a/doc/repo-add.8.txt b/doc/repo-add.8.txt index 75f49ef5..24e2fe6c 100644 --- a/doc/repo-add.8.txt +++ b/doc/repo-add.8.txt @@ -10,26 +10,45 @@ repo-add - package database maintenance utility Synopsis -------- -repo-add [-d] [-f] [-q] <path-to-db> <package1> [<package2> ...] +'repo-add' [-d] [-f] [-q] [-s] [-v] <path-to-db> <package|delta> [<package|delta> ...] -repo-remove [-q] <path-to-db> <packagename> [<packagename2> ...] +'repo-remove' [-q] [-s] [-v] <path-to-db> <packagename|delta> [<packagename|delta> ...] Description ----------- -repo-add and repo-remove are two scripts to help build a package database for +'repo-add' and 'repo-remove' are two scripts to help build a package database for packages built with linkman:makepkg[8] and installed with linkman:pacman[8]. +They also handle package deltas produced by linkman:pkgdelta[8]. -repo-add will update a package database by reading a built package file. -Multiple packages to add can be specified on the command line. +'repo-add' will update a package database by reading a built package or package +delta file. Multiple packages and/or deltas to add can be specified on the +command line. -repo-remove will update a package database by removing the package name -specified on the command line. Multiple packages to remove can be specified -on the command line. +'repo-remove' will update a package database by removing the package name or +delta specified on the command line. Multiple packages and/or delta to remove +can be specified on the command line. -Options -------- +Common Options +-------------- +*-q, \--quiet*:: + Force this program to keep quiet and run silent except for warning and + error messages. + +*-s, \--sign*:: + Generate a PGP signature file using GnuPG. This will execute `gpg + --detach-sign --use-agent` on the generated database to generate a detached + signature file, using the GPG agent if it is available. The signature file + will be the entire filename of the database with a ``.sig'' extension. + +*-v, \--verify*:: + Verify the PGP signature of the database before updating the database. + If the signature is invalid, an error is produced and the update does not + proceed. + +repo-add Options +---------------- *-d, \--delta*:: Automatically generate and add a delta file between the old entry and the new one, if the old package file is found next to the new one. @@ -39,12 +58,8 @@ Options specified packages. This is useful for creating databases listing all files in a given sync repository for tools that may use this information. -*-q, \--quiet*:: - Force this program to keep quiet and run silent except for warning and - error messages. - See Also -------- -linkman:makepkg[8], linkman:pacman[8] +linkman:makepkg[8], linkman:pacman[8], linkman:pkgdelta[8] include::footer.txt[] diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in index 81a11b1d..9a790fcf 100644 --- a/etc/makepkg.conf.in +++ b/etc/makepkg.conf.in @@ -8,9 +8,9 @@ # #-- 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 -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' +DLAGENTS=('ftp::/usr/bin/curl -fC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u' + 'http::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u' + 'https::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u' 'rsync::/usr/bin/rsync -z %u %o' 'scp::/usr/bin/scp -C %u %o') @@ -39,7 +39,7 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe" # BUILD ENVIRONMENT ######################################################################### # -# Defaults: BUILDENV=(fakeroot !distcc color !ccache check) +# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign) # A negated environment option will do the opposite of the comments below. # #-- fakeroot: Allow building packages as a non-root user @@ -47,8 +47,9 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe" #-- color: Colorize output messages #-- ccache: Use ccache to cache compilation #-- check: Run the check() function if present in the PKGBUILD +#-- sign: Generate PGP signature file # -BUILDENV=(fakeroot !distcc color !ccache check) +BUILDENV=(fakeroot !distcc color !ccache check !sign) # #-- If using DistCC, your MAKEFLAGS will also need modification. In addition, #-- specify a space-delimited list of hosts running in the DistCC cluster. @@ -100,6 +101,8 @@ PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod) #SRCPKGDEST=/home/srcpackages #-- Packager: name/email of the person or organization building packages #PACKAGER="John Doe <john@doe.com>" +#-- Specify a key to use for package signing +#GPGKEY="" ######################################################################### # EXTENSION DEFAULTS diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in index 1105db94..7b8501c7 100644 --- a/etc/pacman.conf.in +++ b/etc/pacman.conf.in @@ -30,10 +30,10 @@ Architecture = auto # Misc options (all disabled by default) #UseSyslog -#ShowSize #UseDelta #TotalDownload #CheckSpace +#VerbosePkgLists # # REPOSITORIES diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 1bda5714..080ac195 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -25,6 +25,7 @@ libalpm_la_SOURCES = \ alpm.h alpm.c \ alpm_list.h alpm_list.c \ backup.h backup.c \ + base64.h base64.c \ be_local.c \ be_package.c \ be_sync.c \ @@ -35,13 +36,14 @@ libalpm_la_SOURCES = \ diskspace.h diskspace.c \ dload.h dload.c \ error.c \ - graph.h \ + graph.h graph.c \ group.h group.c \ handle.h handle.c \ log.h log.c \ package.h package.c \ pkghash.h pkghash.c \ remove.h remove.c \ + signing.c signing.h \ sync.h sync.c \ trans.h trans.c \ util.h util.c \ @@ -52,7 +54,7 @@ libalpm_la_SOURCES += \ md5.h md5.c endif -libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) +libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) @LIBCURL@ libalpm_la_LIBADD = $(LTLIBINTL) # vim:set ts=2 sw=2 noet: diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 702b12e9..ee56e876 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -44,15 +44,10 @@ #include "backup.h" #include "package.h" #include "db.h" -#include "conflict.h" -#include "deps.h" #include "remove.h" #include "handle.h" -/** Add a package to the transaction. - * @param pkg the package to add - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ +/** Add a package to the transaction. */ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) { const char *pkgname, *pkgver; @@ -68,11 +63,10 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) trans = handle->trans; ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); - ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); db_local = handle->db_local; - pkgname = alpm_pkg_get_name(pkg); - pkgver = alpm_pkg_get_version(pkg); + pkgname = pkg->name; + pkgver = pkg->version; _alpm_log(PM_LOG_DEBUG, "adding package '%s'\n", pkgname); @@ -91,7 +85,7 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) /* with the NEEDED flag, packages up to date are not reinstalled */ _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- skipping\n"), localpkgname, localpkgver); - return(0); + return 0; } else { _alpm_log(PM_LOG_WARNING, _("%s-%s is up to date -- reinstalling\n"), localpkgname, localpkgver); @@ -105,11 +99,11 @@ int SYMEXPORT alpm_add_pkg(pmpkg_t *pkg) /* add the package to the transaction */ pkg->reason = PM_PKG_REASON_EXPLICIT; - _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n", + _alpm_log(PM_LOG_DEBUG, "adding package %s-%s to the transaction add list\n", pkgname, pkgver); trans->add = alpm_list_add(trans->add, pkg); - return(0); + return 0; } static int perform_extraction(struct archive *archive, @@ -132,9 +126,9 @@ static int perform_extraction(struct archive *archive, origname, archive_error_string(archive)); alpm_logaction("error: could not extract %s (%s)\n", origname, archive_error_string(archive)); - return(1); + return 1; } - return(0); + return 0; } static int extract_single_file(struct archive *archive, @@ -169,7 +163,7 @@ static int extract_single_file(struct archive *archive, * already been handled (for future possibilities) */ _alpm_log(PM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* build the new entryname relative to handle->root */ snprintf(filename, PATH_MAX, "%s%s", handle->root, entryname); @@ -182,7 +176,7 @@ static int extract_single_file(struct archive *archive, alpm_logaction("note: %s is in NoExtract, skipping extraction\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } /* Check for file existence. This is one of the more crucial parts @@ -226,13 +220,13 @@ static int extract_single_file(struct archive *archive, _alpm_log(PM_LOG_DEBUG, "extract: skipping dir extraction of %s\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* case 10/11: trying to overwrite dir with file/symlink, don't allow it */ _alpm_log(PM_LOG_ERROR, _("extract: not overwriting dir with file %s\n"), entryname); archive_read_data_skip(archive); - return(1); + return 1; } } else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(entrymode)) { /* case 9: existing symlink, dir in package */ @@ -241,13 +235,13 @@ static int extract_single_file(struct archive *archive, _alpm_log(PM_LOG_DEBUG, "extract: skipping symlink overwrite of %s\n", entryname); archive_read_data_skip(archive); - return(0); + return 0; } else { /* this is BAD. symlink was not to a directory */ _alpm_log(PM_LOG_ERROR, _("extract: symlink %s does not point to dir\n"), entryname); archive_read_data_skip(archive); - return(1); + return 1; } } else if(S_ISREG(lsbuf.st_mode) && S_ISDIR(entrymode)) { /* case 6: trying to overwrite file with dir */ @@ -299,7 +293,7 @@ static int extract_single_file(struct archive *archive, /* error */ FREE(hash_orig); FREE(entryname_orig); - return(1); + return 1; } hash_local = alpm_compute_md5sum(filename); @@ -442,7 +436,7 @@ static int extract_single_file(struct archive *archive, if(ret == 1) { /* error */ FREE(entryname_orig); - return(1); + return 1; } /* calculate an hash if this is in newpkg's backup */ @@ -469,7 +463,7 @@ static int extract_single_file(struct archive *archive, } } FREE(entryname_orig); - return(errors); + return errors; } static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, @@ -559,7 +553,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, _alpm_log(PM_LOG_DEBUG, "extracting files\n"); - if ((archive = archive_read_new()) == NULL) { + if((archive = archive_read_new()) == NULL) { pm_errno = PM_ERR_LIBARCHIVE; ret = -1; goto cleanup; @@ -705,7 +699,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, size_t pkg_current, cleanup: _alpm_pkg_free(oldpkg); - return(ret); + return ret; } int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) @@ -720,7 +714,7 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); if(trans->add == NULL) { - return(0); + return 0; } pkg_count = alpm_list_count(trans->add); @@ -729,7 +723,7 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) /* loop through our package list adding/upgrading one at a time */ for(targ = trans->add; targ; targ = targ->next) { if(handle->trans->state == STATE_INTERRUPTED) { - return(ret); + return ret; } pmpkg_t *newpkg = (pmpkg_t *)targ->data; @@ -750,7 +744,7 @@ int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db) _alpm_ldconfig(handle->root); } - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index a60a4bb6..bafd922b 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -23,9 +23,8 @@ #include "config.h" -/* connection caching setup */ -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ @@ -58,18 +57,19 @@ int SYMEXPORT alpm_initialize(void) /* error code should be set */ _alpm_handle_free(handle); handle = NULL; - return(-1); + return -1; } #ifdef ENABLE_NLS bindtextdomain("libalpm", LOCALEDIR); #endif -#ifdef HAVE_LIBFETCH - fetchConnectionCacheInit(5, 1); +#ifdef HAVE_LIBCURL + curl_global_init(CURL_GLOBAL_SSL); + handle->curl = curl_easy_init(); #endif - return(0); + return 0; } /** Release the library. This should be the last alpm call you make. @@ -91,17 +91,17 @@ int SYMEXPORT alpm_release(void) } if(alpm_db_unregister_all() == -1) { - return(-1); + return -1; } _alpm_handle_free(handle); handle = NULL; -#ifdef HAVE_LIBFETCH - fetchConnectionCacheClose(); +#ifdef HAVE_LIBCURL + curl_global_cleanup(); #endif - return(0); + return 0; } /** @} */ @@ -112,7 +112,7 @@ int SYMEXPORT alpm_release(void) /* Get the version of library */ const char SYMEXPORT *alpm_version(void) { - return(LIB_VERSION); + return LIB_VERSION; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index cb643d29..e095148c 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -45,11 +45,38 @@ extern "C" { */ /* + * Enumerations + * These ones are used in multiple contexts, so are forward-declared. + */ + +/** + * Install reasons + * Why the package was installed. + */ +typedef enum _pmpkgreason_t { + /** Explicitly requested by the user. */ + PM_PKG_REASON_EXPLICIT = 0, + /** Installed as a dependency for another package. */ + PM_PKG_REASON_DEPEND = 1 +} pmpkgreason_t; + +/** + * GPG signature verification options + */ +typedef enum _pgp_verify_t { + PM_PGP_VERIFY_UNKNOWN, + PM_PGP_VERIFY_NEVER, + PM_PGP_VERIFY_OPTIONAL, + PM_PGP_VERIFY_ALWAYS +} pgp_verify_t; + +/* * Structures */ typedef struct __pmdb_t pmdb_t; typedef struct __pmpkg_t pmpkg_t; +typedef struct __pmpgpsig_t pmpgpsig_t; typedef struct __pmdelta_t pmdelta_t; typedef struct __pmgrp_t pmgrp_t; typedef struct __pmtrans_t pmtrans_t; @@ -70,7 +97,9 @@ const char *alpm_version(void); * Logging facilities */ -/* Levels */ +/** + * Logging Levels + */ typedef enum _pmloglevel_t { PM_LOG_ERROR = 1, PM_LOG_WARNING = (1 << 1), @@ -85,9 +114,16 @@ int alpm_logaction(const char *fmt, ...); * Downloading */ +/** Type of download progress callbacks. + * @param filename the name of the file being downloaded + * @param xfered the number of transferred bytes + * @param total the total number of bytes to transfer + */ typedef void (*alpm_cb_download)(const char *filename, off_t xfered, off_t total); + typedef void (*alpm_cb_totaldl)(off_t total); + /** A callback for downloading files * @param url the URL of the file to be downloaded * @param localpath the directory to which the file should be downloaded @@ -109,44 +145,48 @@ char *alpm_fetch_pkgurl(const char *url); * @{ */ -/** @name The logging callback. */ -/* @{ */ +/** Returns the callback used for logging. */ alpm_cb_log alpm_option_get_logcb(void); -void alpm_option_set_logcb(alpm_cb_log cb); -/* @} */ +/** Sets the callback used for logging. */ +int alpm_option_set_logcb(alpm_cb_log cb); -/** Get/set the download progress callback. */ +/** Returns the callback used to report download progress. */ alpm_cb_download alpm_option_get_dlcb(void); -void alpm_option_set_dlcb(alpm_cb_download cb); +/** Sets the callback used to report download progress. */ +int alpm_option_set_dlcb(alpm_cb_download cb); -/** Get/set the downloader callback. */ +/** Returns the downloading callback. */ alpm_cb_fetch alpm_option_get_fetchcb(void); -void alpm_option_set_fetchcb(alpm_cb_fetch cb); +/** Sets the downloading callback. */ +int alpm_option_set_fetchcb(alpm_cb_fetch cb); -/** Get/set the callback used when download size is known. */ +/** Returns the callback used to report total download size. */ alpm_cb_totaldl alpm_option_get_totaldlcb(void); -void alpm_option_set_totaldlcb(alpm_cb_totaldl cb); +/** Sets the callback used to report total download size. */ +int alpm_option_set_totaldlcb(alpm_cb_totaldl cb); -/** Get/set the root of the destination filesystem. */ +/** Returns the root of the destination filesystem. */ const char *alpm_option_get_root(void); +/** Sets the root of the destination filesystem. */ int alpm_option_set_root(const char *root); -/** Get/set the path to the database directory. */ +/** Returns the path to the database directory. */ const char *alpm_option_get_dbpath(void); +/** Sets the path to the database directory. */ int alpm_option_set_dbpath(const char *dbpath); -/** Get/set the list of package cache directories. */ +/** @name Accessors to the list of package cache directories + * @{ + */ alpm_list_t *alpm_option_get_cachedirs(void); -void alpm_option_set_cachedirs(alpm_list_t *cachedirs); - -/** Add a single directory to the package cache paths. */ +int alpm_option_set_cachedirs(alpm_list_t *cachedirs); int alpm_option_add_cachedir(const char *cachedir); - -/** Remove a single directory from the package cache paths. */ int alpm_option_remove_cachedir(const char *cachedir); +/** @} */ -/** Get/set the logfile name. */ +/** Returns the logfile name. */ const char *alpm_option_get_logfile(void); +/** Sets the logfile name. */ int alpm_option_set_logfile(const char *logfile); /** Get the name of the database lock file. @@ -158,51 +198,76 @@ int alpm_option_set_logfile(const char *logfile); */ const char *alpm_option_get_lockfile(void); -/** Get/set whether to use syslog (0 is FALSE, TRUE otherwise). */ +/** Returns the signature directory path. */ +const char *alpm_option_get_signaturedir(void); +/** Sets the signature directory path. */ +int alpm_option_set_signaturedir(const char *signaturedir); + +/** Returns whether to use syslog (0 is FALSE, TRUE otherwise). */ int alpm_option_get_usesyslog(void); -void alpm_option_set_usesyslog(int usesyslog); +/** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */ +int alpm_option_set_usesyslog(int usesyslog); +/** @name Accessors to the list of no-upgrade files. + * These functions modify the list of files which should + * not be updated by package installation. + * @{ + */ alpm_list_t *alpm_option_get_noupgrades(void); -void alpm_option_add_noupgrade(const char *pkg); -void alpm_option_set_noupgrades(alpm_list_t *noupgrade); +int alpm_option_add_noupgrade(const char *pkg); +int alpm_option_set_noupgrades(alpm_list_t *noupgrade); int alpm_option_remove_noupgrade(const char *pkg); +/** @} */ +/** @name Accessors to the list of no-extract files. + * These functions modify the list of filenames which should + * be skipped packages which should + * not be upgraded by a sysupgrade operation. + * @{ + */ alpm_list_t *alpm_option_get_noextracts(void); -void alpm_option_add_noextract(const char *pkg); -void alpm_option_set_noextracts(alpm_list_t *noextract); +int alpm_option_add_noextract(const char *pkg); +int alpm_option_set_noextracts(alpm_list_t *noextract); int alpm_option_remove_noextract(const char *pkg); +/** @} */ +/** @name Accessors to the list of ignored packages. + * These functions modify the list of packages that + * should be ignored by a sysupgrade. + * @{ + */ alpm_list_t *alpm_option_get_ignorepkgs(void); -void alpm_option_add_ignorepkg(const char *pkg); -void alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs); +int alpm_option_add_ignorepkg(const char *pkg); +int alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs); int alpm_option_remove_ignorepkg(const char *pkg); +/** @} */ +/** @name Accessors to the list of ignored groups. + * These functions modify the list of groups whose packages + * should be ignored by a sysupgrade. + * @{ + */ alpm_list_t *alpm_option_get_ignoregrps(void); -void alpm_option_add_ignoregrp(const char *grp); -void alpm_option_set_ignoregrps(alpm_list_t *ignoregrps); +int alpm_option_add_ignoregrp(const char *grp); +int alpm_option_set_ignoregrps(alpm_list_t *ignoregrps); int alpm_option_remove_ignoregrp(const char *grp); +/** @} */ -/** Get/set the targeted architecture. */ +/** Returns the targeted architecture. */ const char *alpm_option_get_arch(void); -void alpm_option_set_arch(const char *arch); +/** Sets the targeted architecture. */ +int alpm_option_set_arch(const char *arch); int alpm_option_get_usedelta(void); -void alpm_option_set_usedelta(int usedelta); +int alpm_option_set_usedelta(int usedelta); int alpm_option_get_checkspace(void); -void alpm_option_set_checkspace(int checkspace); +int alpm_option_set_checkspace(int checkspace); -/** @} */ +pgp_verify_t alpm_option_get_default_sigverify(void); +int alpm_option_set_default_sigverify(pgp_verify_t level); -/** Install reasons - * Why the package was installed. - */ -typedef enum _pmpkgreason_t { - /** Explicitly requested by the user. */ - PM_PKG_REASON_EXPLICIT = 0, - /** Installed as a dependency for another package. */ - PM_PKG_REASON_DEPEND = 1 -} pmpkgreason_t; +/** @} */ /** @addtogroup alpm_api_databases Database Functions * Functions to query and manipulate the database of libalpm. @@ -253,7 +318,8 @@ const char *alpm_db_get_name(const pmdb_t *db); */ const char *alpm_db_get_url(const pmdb_t *db); -/** Set the serverlist of a database. +/** Add a new server for a database. + * An empty string or NULL can be passed to empty the current server list. * @param db database pointer * @param url url of the server * @return 0 on success, -1 on error (pm_errno is set accordingly) @@ -288,10 +354,10 @@ pmgrp_t *alpm_db_readgrp(pmdb_t *db, const char *name); */ alpm_list_t *alpm_db_get_grpcache(pmdb_t *db); -/** Searches a database. +/** Searches a database with regular expressions. * @param db pointer to the package database to search in - * @param needles the list of strings to search for - * @return the list of packages on success, NULL on error + * @param needles a list of regular expressions to search for + * @return the list of packages matching all regular expressions on success, NULL on error */ alpm_list_t *alpm_db_search(pmdb_t *db, const alpm_list_t* needles); @@ -313,7 +379,8 @@ int alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t reason); /** Create a package from a file. * If full is false, the archive is read only until all necessary * metadata is found. If it is true, the entire archive is read, which - * serves as a verfication of integrity and the filelist can be created. + * serves as a verification of integrity and the filelist can be created. + * The allocated structure should be freed using alpm_pkg_free(). * @param filename location of the package tarball * @param full whether to stop the load after metadata is read or continue * through the full archive @@ -409,6 +476,8 @@ const char *alpm_pkg_get_packager(pmpkg_t *pkg); */ const char *alpm_pkg_get_md5sum(pmpkg_t *pkg); +const pmpgpsig_t *alpm_pkg_get_pgpsig(pmpkg_t *pkg); + /** Returns the architecture for which the package was built. * @param pkg a pointer to package * @return a reference to an internal string @@ -534,6 +603,9 @@ size_t alpm_pkg_changelog_read(void *ptr, size_t size, int alpm_pkg_changelog_close(const pmpkg_t *pkg, void *fp); +/** Returns whether the package has an install scriptlet. + * @return 0 if FALSE, TRUE otherwise + */ int alpm_pkg_has_scriptlet(pmpkg_t *pkg); /** Returns the size of download. @@ -550,6 +622,15 @@ alpm_list_t *alpm_pkg_unused_deltas(pmpkg_t *pkg); /** @} */ /* + * Signatures + */ + +int alpm_pkg_check_pgp_signature(pmpkg_t *pkg); + +int alpm_db_check_pgp_signature(pmdb_t *db); +int alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify); + +/* * Deltas */ @@ -726,6 +807,9 @@ typedef void (*alpm_trans_cb_conv)(pmtransconv_t, void *, void *, /** Transaction Progress callback */ typedef void (*alpm_trans_cb_progress)(pmtransprog_t, const char *, int, size_t, size_t); +/** Returns the bitfield of flags for the current transaction. + * @sa _pmtransflag_t + */ int alpm_trans_get_flags(void); /** Returns a list of packages added by the transaction. @@ -776,9 +860,27 @@ int alpm_trans_release(void); /** @name Common Transactions */ /** @{ */ + +/** Search for packages to upgrade and add them to the transaction. + * @param enable_downgrade allow downgrading of packages if the remote version is lower + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_sync_sysupgrade(int enable_downgrade); + +/** Add a package to the transaction. + * If the package was loaded by alpm_pkg_load(), it will be freed upon + * alpm_trans_release() invocation. + * @param pkg the package to add + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_add_pkg(pmpkg_t *pkg); + +/** Add a package removal action to the transaction. + * @param pkg the package to uninstall + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ int alpm_remove_pkg(pmpkg_t *pkg); + /** @} */ /** @addtogroup alpm_api_depends Dependency Functions @@ -916,6 +1018,10 @@ enum _pmerrno_t { PM_ERR_PKG_INVALID_NAME, PM_ERR_PKG_INVALID_ARCH, PM_ERR_PKG_REPO_NOT_FOUND, + /* Signatures */ + PM_ERR_SIG_MISSINGDIR, + PM_ERR_SIG_INVALID, + PM_ERR_SIG_UNKNOWN, /* Deltas */ PM_ERR_DLT_INVALID, PM_ERR_DLT_PATCHFAILED, @@ -929,8 +1035,9 @@ enum _pmerrno_t { PM_ERR_INVALID_REGEX, /* External library errors */ PM_ERR_LIBARCHIVE, - PM_ERR_LIBFETCH, - PM_ERR_EXTERNAL_DOWNLOAD + PM_ERR_LIBCURL, + PM_ERR_EXTERNAL_DOWNLOAD, + PM_ERR_GPGME }; /** The number of the last error that occurred. */ diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c index f0619bcd..d2e09478 100644 --- a/lib/libalpm/alpm_list.c +++ b/lib/libalpm/alpm_list.c @@ -20,7 +20,6 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> /* libalpm */ #include "alpm_list.h" @@ -92,7 +91,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) ptr = calloc(1, sizeof(alpm_list_t)); if(ptr == NULL) { - return(list); + return list; } ptr->data = data; @@ -101,7 +100,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) /* Special case: the input list is empty */ if(list == NULL) { ptr->prev = ptr; - return(ptr); + return ptr; } lp = alpm_list_last(list); @@ -109,7 +108,7 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data) ptr->prev = lp; list->prev = ptr; - return(list); + return list; } /** @@ -124,13 +123,13 @@ 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 || !list) { - return(alpm_list_add(list, data)); + return alpm_list_add(list, data); } else { alpm_list_t *add = NULL, *prev = NULL, *next = list; add = calloc(1, sizeof(alpm_list_t)); if(add == NULL) { - return(list); + return list; } add->data = data; @@ -146,19 +145,19 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_ add->prev = list->prev; /* list != NULL */ add->next = list; list->prev = add; - return(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); + return list; } else { add->prev = prev; add->next = next; next->prev = add; prev->next = add; - return(list); + return list; } } } @@ -178,11 +177,11 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second) { alpm_list_t *tmp; - if (first == NULL) { - return(second); + if(first == NULL) { + return second; } - if (second == NULL) { - return(first); + if(second == NULL) { + return first; } /* tmp is the last element of the first list */ tmp = first->prev; @@ -193,7 +192,7 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second) /* set the back reference to the tail */ second->prev = tmp; - return(first); + return first; } /** @@ -209,12 +208,12 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a { alpm_list_t *newlist, *lp; - if (left == NULL) + if(left == NULL) return right; - if (right == NULL) + if(right == NULL) return left; - if (fn(left->data, right->data) <= 0) { + if(fn(left->data, right->data) <= 0) { newlist = left; left = left->next; } @@ -226,8 +225,8 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a newlist->next = NULL; lp = newlist; - while ((left != NULL) && (right != NULL)) { - if (fn(left->data, right->data) <= 0) { + while((left != NULL) && (right != NULL)) { + if(fn(left->data, right->data) <= 0) { lp->next = left; left->prev = lp; left = left->next; @@ -240,11 +239,11 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a lp = lp->next; lp->next = NULL; } - if (left != NULL) { + if(left != NULL) { lp->next = left; left->prev = lp; } - else if (right != NULL) { + else if(right != NULL) { lp->next = right; right->prev = lp; } @@ -257,7 +256,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a } newlist->prev = lp; - return(newlist); + return newlist; } /** @@ -271,7 +270,7 @@ alpm_list_t SYMEXPORT *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, a */ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn) { - if (n > 1) { + if(n > 1) { alpm_list_t *left = list; alpm_list_t *lastleft = alpm_list_nth(list, n/2 - 1); alpm_list_t *right = lastleft->next; @@ -282,7 +281,7 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn right = alpm_list_msort(right, n - (n/2), fn); list = alpm_list_mmerge(left, right, fn); } - return(list); + return list; } /** @@ -298,7 +297,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack, alpm_list_t *item) { if(haystack == NULL || item == NULL) { - return(haystack); + return haystack; } if(item == haystack) { @@ -328,7 +327,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack, } } - return(haystack); + return haystack; } @@ -352,7 +351,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, } if(needle == NULL) { - return(haystack); + return haystack; } while(i) { @@ -373,7 +372,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, } } - return(haystack); + return haystack; } /** @@ -388,8 +387,8 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data) { - return(alpm_list_remove(haystack, (const void *)needle, - (alpm_list_fn_cmp)strcmp, (void **)data)); + return alpm_list_remove(haystack, (const void *)needle, + (alpm_list_fn_cmp)strcmp, (void **)data); } /** @@ -411,7 +410,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove_dupes(const alpm_list_t *list) } lp = lp->next; } - return(newlist); + return newlist; } /** @@ -429,7 +428,7 @@ alpm_list_t SYMEXPORT *alpm_list_strdup(const alpm_list_t *list) newlist = alpm_list_add(newlist, strdup(lp->data)); lp = lp->next; } - return(newlist); + return newlist; } /** @@ -447,7 +446,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy(const alpm_list_t *list) newlist = alpm_list_add(newlist, lp->data); lp = lp->next; } - return(newlist); + return newlist; } /** @@ -473,7 +472,7 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list, lp = lp->next; } } - return(newlist); + return newlist; } /** @@ -489,7 +488,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) alpm_list_t *newlist = NULL, *backup; if(list == NULL) { - return(NULL); + return NULL; } lp = alpm_list_last(list); @@ -502,7 +501,7 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) lp = lp->prev; } list->prev = backup; /* restore tail pointer */ - return(newlist); + return newlist; } /* Accessors */ @@ -517,9 +516,9 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list) inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list) { if(list) { - return((alpm_list_t*)list); + return (alpm_list_t *)list; } else { - return(NULL); + return NULL; } } @@ -537,7 +536,7 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n) while(n--) { i = i->next; } - return((alpm_list_t*)i); + return (alpm_list_t *)i; } /** @@ -550,9 +549,9 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, size_t n) inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node) { if(node) { - return(node->next); + return node->next; } else { - return(NULL); + return NULL; } } @@ -566,9 +565,9 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node) alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list) { if(list) { - return(list->prev); + return list->prev; } else { - return(NULL); + return NULL; } } @@ -581,8 +580,8 @@ alpm_list_t SYMEXPORT *alpm_list_last(const alpm_list_t *list) */ void SYMEXPORT *alpm_list_getdata(const alpm_list_t *node) { - if(node == NULL) return(NULL); - return(node->data); + if(node == NULL) return NULL; + return node->data; } /* Misc */ @@ -602,7 +601,7 @@ size_t SYMEXPORT alpm_list_count(const alpm_list_t *list) ++i; lp = lp->next; } - return(i); + return i; } /** @@ -620,17 +619,17 @@ void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle, const alpm_list_t *lp = haystack; while(lp) { if(lp->data && fn(lp->data, needle) == 0) { - return(lp->data); + return lp->data; } lp = lp->next; } - return(NULL); + return NULL; } /* trivial helper function for alpm_list_find_ptr */ static int ptr_cmp(const void *p, const void *q) { - return(p != q); + return (p != q); } /** @@ -643,9 +642,10 @@ static int ptr_cmp(const void *p, const void *q) * * @return `needle` if found, NULL otherwise */ -void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle) +void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, + const void *needle) { - return(alpm_list_find(haystack, needle, ptr_cmp)); + return alpm_list_find(haystack, needle, ptr_cmp); } /** @@ -659,8 +659,8 @@ void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *need char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack, const char *needle) { - return((char *)alpm_list_find(haystack, (const void*)needle, - (alpm_list_fn_cmp)strcmp)); + return (char *)alpm_list_find(haystack, (const void *)needle, + (alpm_list_fn_cmp)strcmp); } /** @@ -688,7 +688,7 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left, return; } - while (l != NULL && r != NULL) { + while(l != NULL && r != NULL) { int cmp = fn(l->data, r->data); if(cmp < 0) { if(onlyleft) { @@ -706,13 +706,13 @@ void SYMEXPORT alpm_list_diff_sorted(const alpm_list_t *left, r = r->next; } } - while (l != NULL) { + while(l != NULL) { if(onlyleft) { *onlyleft = alpm_list_add(*onlyleft, l->data); } l = l->next; } - while (r != NULL) { + while(r != NULL) { if(onlyright) { *onlyright = alpm_list_add(*onlyright, r->data); } @@ -745,7 +745,7 @@ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs, alpm_list_free(left); alpm_list_free(right); - return(ret); + return ret; } /** @} */ diff --git a/lib/libalpm/backup.c b/lib/libalpm/backup.c index ca955ca4..7df97471 100644 --- a/lib/libalpm/backup.c +++ b/lib/libalpm/backup.c @@ -47,7 +47,7 @@ static int backup_split(const char *string, char **file, char **hash) /* don't need our dup as the fname wasn't requested, so free it */ FREE(str); } - return(0); + return 0; } *ptr = '\0'; ptr++; @@ -59,21 +59,21 @@ static int backup_split(const char *string, char **file, char **hash) *hash = strdup(ptr); } FREE(str); - return(1); + return 1; } char *_alpm_backup_file(const char *string) { char *file = NULL; backup_split(string, &file, NULL); - return(file); + return file; } char *_alpm_backup_hash(const char *string) { char *hash = NULL; backup_split(string, NULL, &hash); - return(hash); + return hash; } /* Look for a filename in a pmpkg_t.backup list. If we find it, @@ -86,7 +86,7 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup) ALPM_LOG_FUNC; if(file == NULL || backup == NULL) { - return(NULL); + return NULL; } /* run through the backup list and parse out the hash for our file */ @@ -101,13 +101,13 @@ char *_alpm_needbackup(const char *file, const alpm_list_t *backup) } if(strcmp(file, filename) == 0) { FREE(filename); - return(hash); + return hash; } FREE(filename); FREE(hash); } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/base64.c b/lib/libalpm/base64.c new file mode 100644 index 00000000..fa8bec5c --- /dev/null +++ b/lib/libalpm/base64.c @@ -0,0 +1,190 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * 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/>. + */ +/* + * Pacman Notes: + * + * Taken from the PolarSSL project at www.polarssl.org under terms of the + * GPL. This is from version 0.14.2 of the library, and has been modified + * as following, which may be helpful for future updates: + * * remove "polarssl/config.h" include + * * change include from "polarssl/base64.h" to "base64.h" + * * removal of SELF_TEST code + */ + +#include "base64.h" + +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +int base64_encode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ) +{ + int i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + return( 0 ); + + n = (slen << 3) / 6; + + switch( (slen << 3) - (n * 6) ) + { + case 2: n += 3; break; + case 4: n += 2; break; + default: break; + } + + if( *dlen < n + 1 ) + { + *dlen = n + 1; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = (slen / 3) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ((i + 1) < slen) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( (i + 1) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *dlen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int base64_decode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ) +{ + int i, j, n; + unsigned long x; + unsigned char *p; + + for( i = j = n = 0; i < slen; i++ ) + { + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + if( src[i] == '=' && ++j > 2 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + return( 0 ); + + n = ((n * 6) + 7) >> 3; + + if( *dlen < n ) + { + *dlen = n; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = (x << 6) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *dlen = p - dst; + + return( 0 ); +} diff --git a/lib/libalpm/base64.h b/lib/libalpm/base64.h new file mode 100644 index 00000000..0ae9612c --- /dev/null +++ b/lib/libalpm/base64.h @@ -0,0 +1,68 @@ +/** + * \file base64.h + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * 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 _BASE64_H +#define _BASE64_H + +#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010 +#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012 + +/** + * \brief Encode a buffer into base64 format + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be encoded + * + * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. + * *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_encode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ); + +/** + * \brief Decode a base64-formatted buffer + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be decoded + * + * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or + * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not + * correct. *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_decode( unsigned char *dst, int *dlen, + const unsigned char *src, int slen ); + +#endif /* base64.h */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index edb62054..e5a8c7b1 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -31,10 +31,6 @@ #include <time.h> #include <limits.h> /* PATH_MAX */ -/* libarchive */ -#include <archive.h> -#include <archive_entry.h> - /* libalpm */ #include "db.h" #include "alpm_list.h" @@ -43,16 +39,13 @@ #include "alpm.h" #include "handle.h" #include "package.h" -#include "group.h" #include "deps.h" -#include "dload.h" #define LAZY_LOAD(info, errret) \ do { \ ALPM_LOG_FUNC; \ - ASSERT(handle != NULL, return(errret)); \ - ASSERT(pkg != NULL, return(errret)); \ + ASSERT(handle != NULL, return (errret)); \ if(pkg->origin != PKG_FROM_FILE && !(pkg->infolevel & info)) { \ _alpm_local_db_read(pkg->origin_data.db, pkg, info); \ } \ @@ -71,18 +64,6 @@ static const char *_cache_get_filename(pmpkg_t *pkg) return pkg->filename; } -static const char *_cache_get_name(pmpkg_t *pkg) -{ - ASSERT(pkg != NULL, return(NULL)); - return pkg->name; -} - -static const char *_cache_get_version(pmpkg_t *pkg) -{ - ASSERT(pkg != NULL, return(NULL)); - return pkg->version; -} - static const char *_cache_get_desc(pmpkg_t *pkg) { LAZY_LOAD(INFRQ_DESC, NULL); @@ -160,8 +141,7 @@ static int _cache_has_scriptlet(pmpkg_t *pkg) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(pkg != NULL, return(-1)); + ASSERT(handle != NULL, return -1); if(!(pkg->infolevel & INFRQ_SCRIPTLET)) { _alpm_local_db_read(pkg->origin_data.db, pkg, INFRQ_SCRIPTLET); @@ -210,8 +190,7 @@ static alpm_list_t *_cache_get_files(pmpkg_t *pkg) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); if(pkg->origin == PKG_FROM_LOCALDB && !(pkg->infolevel & INFRQ_FILES)) { @@ -225,8 +204,7 @@ static alpm_list_t *_cache_get_backup(pmpkg_t *pkg) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); if(pkg->origin == PKG_FROM_LOCALDB && !(pkg->infolevel & INFRQ_FILES)) { @@ -246,8 +224,7 @@ static void *_cache_changelog_open(pmpkg_t *pkg) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(pkg != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); char clfile[PATH_MAX]; snprintf(clfile, PATH_MAX, "%s/%s/%s-%s/changelog", @@ -270,15 +247,8 @@ static void *_cache_changelog_open(pmpkg_t *pkg) static size_t _cache_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { - return ( fread(ptr, 1, size, (FILE*)fp) ); -} - -/* -static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp) -{ - return( feof((FILE*)fp) ); + return fread(ptr, 1, size, (FILE *)fp); } -*/ /** * Close a package changelog for reading. Similar to fclose in functionality, @@ -289,7 +259,7 @@ static int _cache_changelog_feof(const pmpkg_t *pkg, void *fp) */ static int _cache_changelog_close(const pmpkg_t *pkg, void *fp) { - return( fclose((FILE*)fp) ); + return fclose((FILE *)fp); } @@ -299,8 +269,6 @@ static int _cache_changelog_close(const pmpkg_t *pkg, void *fp) */ static struct pkg_operations local_pkg_ops = { .get_filename = _cache_get_filename, - .get_name = _cache_get_name, - .get_version = _cache_get_version, .get_desc = _cache_get_desc, .get_url = _cache_get_url, .get_builddate = _cache_get_builddate, @@ -345,14 +313,14 @@ static int checkdbdir(pmdb_t *db) RET_ERR(PM_ERR_SYSTEM, -1); } } - return(0); + return 0; } static int is_dir(const char *path, struct dirent *entry) { #ifdef HAVE_STRUCT_DIRENT_D_TYPE if(entry->d_type != DT_UNKNOWN) { - return(entry->d_type == DT_DIR); + return (entry->d_type == DT_DIR); } #endif { @@ -361,12 +329,12 @@ static int is_dir(const char *path, struct dirent *entry) snprintf(buffer, PATH_MAX, "%s/%s", path, entry->d_name); - if (!stat(buffer, &sbuf)) { - return(S_ISDIR(sbuf.st_mode)); + if(!stat(buffer, &sbuf)) { + return S_ISDIR(sbuf.st_mode); } } - return(0); + return 0; } static int local_db_populate(pmdb_t *db) @@ -390,7 +358,7 @@ static int local_db_populate(pmdb_t *db) if(dbdir == NULL) { if(errno == ENOENT) { /* no database existing yet is not an error */ - return(0); + return 0; } RET_ERR(PM_ERR_DB_OPEN, -1); } @@ -476,7 +444,7 @@ static int local_db_populate(pmdb_t *db) if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } - return(count); + return count; } /* Note: the return value must be freed by the caller */ @@ -490,7 +458,7 @@ static char *get_pkgpath(pmdb_t *db, pmpkg_t *info) len = strlen(dbpath) + strlen(info->name) + strlen(info->version) + 3; MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL)); sprintf(pkgpath, "%s%s-%s/", dbpath, info->name, info->version); - return(pkgpath); + return pkgpath; } @@ -509,14 +477,14 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(info == NULL || info->name == NULL || info->version == NULL) { _alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_local_db_read, skipping\n"); - return(-1); + return -1; } if(info->origin != PKG_FROM_LOCALDB) { _alpm_log(PM_LOG_DEBUG, "request to read info for a non-local package '%s', skipping...\n", info->name); - return(-1); + return -1; } /* bitmask logic here: @@ -526,7 +494,7 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) * == to inforeq? nope, we need to load more info. */ if((info->infolevel & inforeq) == inforeq) { /* already loaded all of this info, do nothing */ - return(0); + return 0; } _alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n", info->name, inforeq); @@ -706,14 +674,14 @@ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) info->infolevel |= inforeq; free(pkgpath); - return(0); + return 0; error: free(pkgpath); if(fp) { fclose(fp); } - return(-1); + return -1; } int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) @@ -723,7 +691,7 @@ int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) char *pkgpath = NULL; if(checkdbdir(db) != 0) { - return(-1); + return -1; } oldmask = umask(0000); @@ -737,7 +705,7 @@ int _alpm_local_db_prepare(pmdb_t *db, pmpkg_t *info) free(pkgpath); umask(oldmask); - return(retval); + return retval; } int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) @@ -752,7 +720,7 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) ALPM_LOG_FUNC; if(db == NULL || info == NULL) { - return(-1); + return -1; } pkgpath = get_pkgpath(db, info); @@ -761,7 +729,7 @@ int _alpm_local_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) oldmask = umask(0022); if(strcmp(db->treename, "local") != 0) { - return(-1); + return -1; } /* DESC */ @@ -904,7 +872,7 @@ cleanup: fclose(fp); } - return(retval); + return retval; } int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) @@ -925,7 +893,7 @@ int _alpm_local_db_remove(pmdb_t *db, pmpkg_t *info) if(ret != 0) { ret = -1; } - return(ret); + return ret; } static int local_db_version(pmdb_t *db) @@ -977,7 +945,7 @@ done: } _alpm_log(PM_LOG_DEBUG, "local database version %d\n", version); - return(version); + return version; } struct db_operations local_db_ops = { @@ -1001,7 +969,7 @@ pmdb_t *_alpm_db_register_local(void) db->ops = &local_db_ops; handle->db_local = db; - return(db); + return db; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 6dfddd61..8a6ed6c4 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -20,10 +20,8 @@ #include "config.h" -#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <limits.h> #include <errno.h> /* libarchive */ @@ -47,7 +45,7 @@ static void *_package_changelog_open(pmpkg_t *pkg) { ALPM_LOG_FUNC; - ASSERT(pkg != NULL, return(NULL)); + ASSERT(pkg != NULL, return NULL); struct archive *archive = NULL; struct archive_entry *entry; @@ -60,7 +58,7 @@ static void *_package_changelog_open(pmpkg_t *pkg) archive_read_support_compression_all(archive); archive_read_support_format_all(archive); - if (archive_read_open_filename(archive, pkgfile, + if(archive_read_open_filename(archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { RET_ERR(PM_ERR_PKG_OPEN, NULL); } @@ -69,14 +67,14 @@ static void *_package_changelog_open(pmpkg_t *pkg) const char *entry_name = archive_entry_pathname(entry); if(strcmp(entry_name, ".CHANGELOG") == 0) { - return(archive); + return archive; } } /* we didn't find a changelog */ archive_read_finish(archive); errno = ENOENT; - return(NULL); + return NULL; } /** @@ -91,24 +89,16 @@ static void *_package_changelog_open(pmpkg_t *pkg) static size_t _package_changelog_read(void *ptr, size_t size, const pmpkg_t *pkg, const void *fp) { - ssize_t sret = archive_read_data((struct archive*)fp, ptr, size); + ssize_t sret = archive_read_data((struct archive *)fp, ptr, size); /* Report error (negative values) */ if(sret < 0) { pm_errno = PM_ERR_LIBARCHIVE; - return(0); + return 0; } else { - return((size_t)sret); + return (size_t)sret; } } -/* -static int _package_changelog_feof(const pmpkg_t *pkg, void *fp) -{ - // note: this doesn't quite work, no feof in libarchive - return( archive_read_data((struct archive*)fp, NULL, 0) ); -} -*/ - /** * Close a package changelog for reading. Similar to fclose in functionality, * except that the 'file stream' is from an archive. @@ -118,7 +108,7 @@ static int _package_changelog_feof(const pmpkg_t *pkg, void *fp) */ static int _package_changelog_close(const pmpkg_t *pkg, void *fp) { - return( archive_read_finish((struct archive *)fp) ); + return archive_read_finish((struct archive *)fp); } /** Package file operations struct accessor. We implement this as a method @@ -137,7 +127,7 @@ static struct pkg_operations *get_file_pkg_ops(void) file_pkg_ops.changelog_close = _package_changelog_close; file_pkg_ops_initialized = 1; } - return(&file_pkg_ops); + return &file_pkg_ops; } /** @@ -226,7 +216,7 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) line[0] = '\0'; } - return(0); + return 0; } /** @@ -251,31 +241,39 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full) RET_ERR(PM_ERR_WRONG_ARGS, NULL); } - if(stat(pkgfile, &st) != 0) { + /* attempt to stat the package file, ensure it exists */ + if(stat(pkgfile, &st) == 0) { + int sig_ret; + + newpkg = _alpm_pkg_new(); + if(newpkg == NULL) { + RET_ERR(PM_ERR_MEMORY, NULL); + } + newpkg->filename = strdup(pkgfile); + newpkg->size = st.st_size; + + /* TODO: do something with ret value */ + sig_ret = _alpm_load_signature(pkgfile, &(newpkg->pgpsig)); + (void)sig_ret; + } else { + /* couldn't stat the pkgfile, return an error */ RET_ERR(PM_ERR_PKG_OPEN, NULL); } if((archive = archive_read_new()) == NULL) { + alpm_pkg_free(newpkg); RET_ERR(PM_ERR_LIBARCHIVE, NULL); } archive_read_support_compression_all(archive); archive_read_support_format_all(archive); - if (archive_read_open_filename(archive, pkgfile, + if(archive_read_open_filename(archive, pkgfile, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { + alpm_pkg_free(newpkg); RET_ERR(PM_ERR_PKG_OPEN, NULL); } - newpkg = _alpm_pkg_new(); - if(newpkg == NULL) { - archive_read_finish(archive); - RET_ERR(PM_ERR_MEMORY, NULL); - } - - newpkg->filename = strdup(pkgfile); - newpkg->size = st.st_size; - _alpm_log(PM_LOG_DEBUG, "starting package load for %s\n", pkgfile); /* If full is false, only read through the archive until we find our needed @@ -356,7 +354,7 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full) newpkg->infolevel = INFRQ_BASE | INFRQ_DESC; } - return(newpkg); + return newpkg; pkg_invalid: pm_errno = PM_ERR_PKG_INVALID; @@ -364,7 +362,7 @@ error: _alpm_pkg_free(newpkg); archive_read_finish(archive); - return(NULL); + return NULL; } int SYMEXPORT alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg) @@ -379,10 +377,10 @@ int SYMEXPORT alpm_pkg_load(const char *filename, int full, pmpkg_t **pkg) *pkg = pkg_load(filename, full); if(*pkg == NULL) { /* pm_errno is set by pkg_load */ - return(-1); + return -1; } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index c2c62aa2..d4841854 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -20,8 +20,7 @@ #include "config.h" -#include <errno.h> -#include <limits.h> +#include <sys/stat.h> /* libarchive */ #include <archive.h> @@ -85,6 +84,7 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) size_t len; int ret; mode_t oldmask; + pgp_verify_t check_sig; ALPM_LOG_FUNC; @@ -126,24 +126,65 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) } ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force); - free(dbfile); - free(syncpath); - umask(oldmask); if(ret == 1) { /* files match, do nothing */ pm_errno = 0; - return(1); + goto cleanup; } else if(ret == -1) { /* pm_errno was set by the download code */ _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast()); - return(-1); + goto cleanup; + } + + check_sig = _alpm_db_get_sigverify_level(db); + + /* Download and check the signature of the database if needed */ + if(check_sig != PM_PGP_VERIFY_NEVER) { + char *sigfile, *sigfilepath; + int sigret; + + len = strlen(dbfile) + 5; + MALLOC(sigfile, len, RET_ERR(PM_ERR_MEMORY, -1)); + sprintf(sigfile, "%s.sig", dbfile); + + /* prevent old signature being used if the following download fails */ + len = strlen(syncpath) + strlen(sigfile) + 1; + MALLOC(sigfilepath, len, RET_ERR(PM_ERR_MEMORY, -1)); + sprintf(sigfilepath, "%s%s", syncpath, sigfile); + _alpm_rmrf(sigfilepath); + free(sigfilepath); + + sigret = _alpm_download_single_file(sigfile, db->servers, syncpath, 0); + free(sigfile); + + if(sigret == -1 && check_sig == PM_PGP_VERIFY_ALWAYS) { + _alpm_log(PM_LOG_ERROR, _("Failed to download signature for db: %s\n"), + alpm_strerrorlast()); + pm_errno = PM_ERR_SIG_INVALID; + ret = -1; + goto cleanup; + } + + sigret = alpm_db_check_pgp_signature(db); + if((check_sig == PM_PGP_VERIFY_ALWAYS && sigret != 0) || + (check_sig == PM_PGP_VERIFY_OPTIONAL && sigret == 1)) { + /* pm_errno was set by the checking code */ + /* TODO: should we just leave the unverified database */ + ret = -1; + goto cleanup; + } } /* Cache needs to be rebuilt */ _alpm_db_free_pkgcache(db); - return(0); +cleanup: + + free(dbfile); + free(syncpath); + umask(oldmask); + return ret; } /* Forward decl so I don't reorganize the whole file right now */ @@ -206,7 +247,7 @@ static size_t estimate_package_count(struct stat *st, struct archive *archive) /* assume it is at least somewhat compressed */ per_package = 200; } - return((size_t)(st->st_size / per_package) + 1); + return (size_t)((st->st_size / per_package) + 1); } static int sync_db_populate(pmdb_t *db) @@ -305,7 +346,7 @@ static int sync_db_populate(pmdb_t *db) } archive_read_finish(archive); - return(count); + return count; } #define READ_NEXT(s) do { \ @@ -345,7 +386,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, } if(entryname == NULL) { _alpm_log(PM_LOG_DEBUG, "invalid archive entry provided to _alpm_sync_db_read, skipping\n"); - return(-1); + return -1; } _alpm_log(PM_LOG_FUNCTION, "loading package data from archive entry %s\n", @@ -376,7 +417,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, if(pkg == NULL) { _alpm_log(PM_LOG_DEBUG, "package %s not found in %s sync database", pkgname, db->treename); - return(-1); + return -1; } if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0 @@ -433,8 +474,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, /* we don't do anything with this value right now */ READ_NEXT(line); } else if(strcmp(line, "%PGPSIG%") == 0) { - /* we don't do anything with this value right now */ - READ_NEXT(line); + READ_AND_STORE(pkg->pgpsig.base64_data); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_STORE_ALL(pkg->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { @@ -469,12 +509,12 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, error: FREE(pkgname); /* TODO: return 0 always? */ - return(0); + return 0; } static int sync_db_version(pmdb_t *db) { - return(2); + return 2; } struct db_operations sync_db_ops = { @@ -507,7 +547,7 @@ pmdb_t *_alpm_db_register_sync(const char *treename) db->ops = &sync_db_ops; handle->dbs_sync = alpm_list_add(handle->dbs_sync, db); - return(db); + return db; } diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6faced16..319e49d6 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -53,7 +53,7 @@ pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(conflict); + return conflict; } void _alpm_conflict_free(pmconflict_t *conflict) @@ -73,7 +73,7 @@ pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict) STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(newconflict); + return newconflict; } static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) @@ -90,11 +90,11 @@ static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) const char *cpkg2 = conflict->package2; if((strcmp(cpkg1, npkg1) == 0 && strcmp(cpkg2, npkg2) == 0) || (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) { - return(1); + return 1; } } - return(0); + return 0; } /** Adds the pkg1/pkg2 conflict to the baddeps list @@ -173,7 +173,7 @@ alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages) _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); check_conflict(packages, packages, &baddeps, 0); - return(baddeps); + return baddeps; } /* Check for target vs (db - target) conflicts @@ -187,7 +187,7 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) ALPM_LOG_FUNC; if(db == NULL) { - return(NULL); + return NULL; } alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db), @@ -200,7 +200,7 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) check_conflict(dblist, packages, &baddeps, -1); alpm_list_free(dblist); - return(baddeps); + return baddeps; } /** Check the package conflicts in a database @@ -209,14 +209,20 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) * @return an alpm_list_t of pmconflict_t */ alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) { - return(_alpm_innerconflicts(pkglist)); + return _alpm_innerconflicts(pkglist); } -/* Returns a alpm_list_t* of file conflicts. - * Hooray for set-intersects! - * Pre-condition: both lists are sorted! +static const int DIFFERENCE = 0; +static const int INTERSECT = 1; +/* Returns a set operation on the provided two lists of files. + * Pre-condition: both lists are sorted! + * + * Operations: + * DIFFERENCE - a difference operation is performed. filesA - filesB. + * INTERSECT - an intersection operation is performed. filesA & filesB. */ -static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) +static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, + int operation) { alpm_list_t *ret = NULL; alpm_list_t *pA = filesA, *pB = filesB; @@ -224,7 +230,7 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) while(pA && pB) { const char *strA = pA->data; const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ + /* skip directories, we don't care about them */ if(strA[strlen(strA)-1] == '/') { pA = pA->next; } else if(strB[strlen(strB)-1] == '/') { @@ -232,59 +238,26 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) } else { int cmp = strcmp(strA, strB); if(cmp < 0) { - /* item only in filesA, ignore it */ + if(operation == DIFFERENCE) { + /* item only in filesA, qualifies as a difference */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; } else if(cmp > 0) { - /* item only in filesB, ignore it */ pB = pB->next; } else { - /* item in both, record it */ - ret = alpm_list_add(ret, strdup(strA)); + if(operation == INTERSECT) { + /* item in both, qualifies as an intersect */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; pB = pB->next; } } } - return(ret); -} - -/* Returns a alpm_list_t* of files that are in filesA but *NOT* in filesB - * This is an 'A minus B' set operation - * Pre-condition: both lists are sorted! - */ -static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) -{ - alpm_list_t *ret = NULL; - alpm_list_t *pA = filesA, *pB = filesB; - - /* if both filesA and filesB have entries, do this loop */ - while(pA && pB) { - const char *strA = pA->data; - const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ - if(strA[strlen(strA)-1] == '/') { - pA = pA->next; - } else if(strB[strlen(strB)-1] == '/') { - pB = pB->next; - } else { - int cmp = strcmp(strA, strB); - if(cmp < 0) { - /* item only in filesA, record it */ - ret = alpm_list_add(ret, strdup(strA)); - pA = pA->next; - } else if(cmp > 0) { - /* item only in fileB, but this means nothing */ - pB = pB->next; - } else { - /* item in both, ignore it */ - pA = pA->next; - pB = pB->next; - } - } - } - /* ensure we have completely emptied pA */ - while(pA) { + /* if doing a difference, ensure we have completely emptied pA */ + while(operation == DIFFERENCE && pA) { const char *strA = pA->data; /* skip directories */ if(strA[strlen(strA)-1] != '/') { @@ -293,7 +266,7 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) pA = pA->next; } - return(ret); + return ret; } /* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either @@ -321,7 +294,7 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts, _alpm_log(PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n", filestr, name1, name2 ? name2 : "(filesystem)"); - return(conflicts); + return conflicts; } void _alpm_fileconflict_free(pmfileconflict_t *conflict) @@ -345,7 +318,7 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) snprintf(abspath, PATH_MAX, "%s%s", handle->root, dirpath); dir = opendir(abspath); if(dir == NULL) { - return(1); + return 1; } while((ent = readdir(dir)) != NULL) { const char *name = ent->d_name; @@ -363,19 +336,19 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) continue; } else { closedir(dir); - return(0); + return 0; } } else { if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) { continue; } else { closedir(dir); - return(0); + return 0; } } } closedir(dir); - return(1); + return 1; } /* Find file conflicts that may occur during the transaction with two checks: @@ -391,7 +364,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, ALPM_LOG_FUNC; if(db == NULL || upgrade == NULL || trans == NULL) { - return(NULL); + return NULL; } /* TODO this whole function needs a huge change, which hopefully will @@ -419,7 +392,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, if(!p2) { continue; } - tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); + tmpfiles = filelist_operation( alpm_pkg_get_files(p1), + alpm_pkg_get_files(p2), INTERSECT); if(tmpfiles) { for(k = tmpfiles; k; k = k->next) { @@ -444,8 +418,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, * is not currently installed, then simply stat the whole filelist */ if(dbpkg) { /* older ver of package currently installed */ - tmpfiles = chk_filedifference(alpm_pkg_get_files(p1), - alpm_pkg_get_files(dbpkg)); + tmpfiles = filelist_operation(alpm_pkg_get_files(p1), + alpm_pkg_get_files(dbpkg), DIFFERENCE); } else { /* no version of package currently installed */ tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1)); @@ -540,7 +514,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100, numtargs, current); - return(conflicts); + return conflicts; } const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict) @@ -548,8 +522,8 @@ const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->package1; } @@ -559,8 +533,8 @@ const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->package2; } @@ -570,8 +544,8 @@ const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->reason; } @@ -581,8 +555,8 @@ const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->target; } @@ -592,8 +566,8 @@ pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conf ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(conflict != NULL, return(-1)); + ASSERT(handle != NULL, return -1); + ASSERT(conflict != NULL, return -1); return conflict->type; } @@ -603,8 +577,8 @@ const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->file; } @@ -614,8 +588,8 @@ const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(conflict != NULL, return NULL); return conflict->ctarget; } diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 1a3168b4..f5e7a25f 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -26,11 +26,8 @@ #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include <string.h> -#include <sys/stat.h> #include <regex.h> -#include <time.h> /* libalpm */ #include "db.h" @@ -58,7 +55,7 @@ pmdb_t SYMEXPORT *alpm_db_register_sync(const char *treename) /* Do not register a database if a transaction is on-going */ ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, NULL)); - return(_alpm_db_register_sync(treename)); + return _alpm_db_register_sync(treename); } /* Helper function for alpm_db_unregister{_all} */ @@ -92,7 +89,7 @@ int SYMEXPORT alpm_db_unregister_all(void) i->data = NULL; } FREELIST(handle->dbs_sync); - return(0); + return 0; } /** Unregister a package database. */ @@ -129,14 +126,12 @@ int SYMEXPORT alpm_db_unregister(pmdb_t *db) } db->ops->unregister(db); - return(0); + return 0; } /** Set the serverlist of a database. */ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) { - alpm_list_t *i; - int found = 0; char *newurl; size_t len = 0; @@ -145,16 +140,6 @@ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) /* Sanity checks */ ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); - for(i = handle->dbs_sync; i && !found; i = i->next) { - pmdb_t *sdb = i->data; - if(strcmp(db->treename, sdb->treename) == 0) { - found = 1; - } - } - if(!found) { - RET_ERR(PM_ERR_DB_NOT_FOUND, -1); - } - if(url) { len = strlen(url); } @@ -172,6 +157,24 @@ int SYMEXPORT alpm_db_setserver(pmdb_t *db, const char *url) _alpm_log(PM_LOG_DEBUG, "serverlist flushed for '%s'\n", db->treename); } + return 0; +} +/** Set the verify gpg signature option for a database. + * @param db database pointer + * @param verify enum pgp_verify_t + * @return 0 on success, -1 on error (pm_errno is set accordingly) + */ +int SYMEXPORT alpm_db_set_pgp_verify(pmdb_t *db, pgp_verify_t verify) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); + + db->pgp_verify = verify; + _alpm_log(PM_LOG_DEBUG, "adding VerifySig option to database '%s': %d\n", + db->treename, verify); + return(0); } @@ -181,8 +184,8 @@ const char SYMEXPORT *alpm_db_get_name(const pmdb_t *db) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); return db->treename; } @@ -195,13 +198,13 @@ const char SYMEXPORT *alpm_db_get_url(const pmdb_t *db) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(db->servers != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); + ASSERT(db->servers != NULL, return NULL); - url = (char*)db->servers->data; + url = (char *)db->servers->data; - return(url); + return url; } @@ -211,11 +214,11 @@ pmpkg_t SYMEXPORT *alpm_db_get_pkg(pmdb_t *db, const char *name) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(name != NULL && strlen(name) != 0, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); + ASSERT(name != NULL && strlen(name) != 0, return NULL); - return(_alpm_db_get_pkgfromcache(db, name)); + return _alpm_db_get_pkgfromcache(db, name); } /** Get the package cache of a package database. */ @@ -224,10 +227,10 @@ alpm_list_t SYMEXPORT *alpm_db_get_pkgcache(pmdb_t *db) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); - return(_alpm_db_get_pkgcache(db)); + return _alpm_db_get_pkgcache(db); } /** Get a group entry from a package database. */ @@ -236,11 +239,11 @@ pmgrp_t SYMEXPORT *alpm_db_readgrp(pmdb_t *db, const char *name) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); - ASSERT(name != NULL && strlen(name) != 0, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); + ASSERT(name != NULL && strlen(name) != 0, return NULL); - return(_alpm_db_get_grpfromcache(db, name)); + return _alpm_db_get_grpfromcache(db, name); } /** Get the group cache of a package database. */ @@ -249,10 +252,10 @@ alpm_list_t SYMEXPORT *alpm_db_get_grpcache(pmdb_t *db) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); - return(_alpm_db_get_grpcache(db)); + return _alpm_db_get_grpcache(db); } /** Searches a database. */ @@ -261,10 +264,10 @@ alpm_list_t SYMEXPORT *alpm_db_search(pmdb_t *db, const alpm_list_t* needles) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(db != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(db != NULL, return NULL); - return(_alpm_db_search(db, needles)); + return _alpm_db_search(db, needles); } /** Set install reason for a package in db. */ @@ -284,7 +287,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t _alpm_log(PM_LOG_DEBUG, "setting install reason %u for %s/%s\n", reason, db->treename, name); if(alpm_pkg_get_reason(pkg) == reason) { /* we are done */ - return(0); + return 0; } /* set reason (in pkgcache) */ pkg->reason = reason; @@ -293,7 +296,7 @@ int SYMEXPORT alpm_db_set_pkgreason(pmdb_t *db, const char *name, pmpkgreason_t RET_ERR(PM_ERR_DB_WRITE, -1); } - return(0); + return 0; } /** @} */ @@ -308,7 +311,28 @@ pmdb_t *_alpm_db_new(const char *treename, int is_local) STRDUP(db->treename, treename, RET_ERR(PM_ERR_MEMORY, NULL)); db->is_local = is_local; - return(db); + return db; +} + +const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(db != NULL, return(NULL)); + + if(db->pgpsig.data == NULL) { + const char *dbfile; + int ret; + + dbfile = _alpm_db_path(db); + + /* TODO: do something with ret value */ + ret = _alpm_load_signature(dbfile, &(db->pgpsig)); + (void)ret; + } + + return &(db->pgpsig); } void _alpm_db_free(pmdb_t *db) @@ -319,6 +343,8 @@ void _alpm_db_free(pmdb_t *db) _alpm_db_free_pkgcache(db); /* cleanup server list */ FREELIST(db->servers); + /* only need to free data */ + FREE(db->pgpsig.data); FREE(db->_path); FREE(db->treename); FREE(db); @@ -329,7 +355,7 @@ void _alpm_db_free(pmdb_t *db) const char *_alpm_db_path(pmdb_t *db) { if(!db) { - return(NULL); + return NULL; } if(!db->_path) { const char *dbpath; @@ -354,22 +380,22 @@ const char *_alpm_db_path(pmdb_t *db) _alpm_log(PM_LOG_DEBUG, "database path for tree %s set to %s\n", db->treename, db->_path); } - return(db->_path); + return db->_path; } int _alpm_db_version(pmdb_t *db) { if(!db) { - return(-1); + return -1; } - return(db->ops->version(db)); + return db->ops->version(db); } int _alpm_db_cmp(const void *d1, const void *d2) { pmdb_t *db1 = (pmdb_t *)d1; pmdb_t *db2 = (pmdb_t *)d2; - return(strcmp(db1->treename, db2->treename)); + return strcmp(db1->treename, db2->treename); } alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) @@ -407,7 +433,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) matched = name; } /* check desc */ - else if (desc && regexec(®, desc, 0, 0, 0) == 0) { + else if(desc && regexec(®, desc, 0, 0, 0) == 0) { matched = desc; } /* TODO: should we be doing this, and should we print something @@ -415,7 +441,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) if(!matched) { /* check provides */ for(k = alpm_pkg_get_provides(pkg); k; k = k->next) { - if (regexec(®, k->data, 0, 0, 0) == 0) { + if(regexec(®, k->data, 0, 0, 0) == 0) { matched = k->data; break; } @@ -424,7 +450,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) if(!matched) { /* check groups */ for(k = alpm_pkg_get_groups(pkg); k; k = k->next) { - if (regexec(®, k->data, 0, 0, 0) == 0) { + if(regexec(®, k->data, 0, 0, 0) == 0) { matched = k->data; break; } @@ -445,7 +471,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles) regfree(®); } - return(ret); + return ret; } /* Returns a new package cache from db. @@ -456,7 +482,7 @@ int _alpm_db_load_pkgcache(pmdb_t *db) ALPM_LOG_FUNC; if(db == NULL) { - return(-1); + return -1; } _alpm_db_free_pkgcache(db); @@ -465,11 +491,11 @@ int _alpm_db_load_pkgcache(pmdb_t *db) if(db->ops->populate(db) == -1) { _alpm_log(PM_LOG_DEBUG, "failed to load package cache for repository '%s'\n", db->treename); - return(-1); + return -1; } db->pkgcache_loaded = 1; - return(0); + return 0; } void _alpm_db_free_pkgcache(pmdb_t *db) @@ -496,7 +522,7 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db) ALPM_LOG_FUNC; if(db == NULL) { - return(NULL); + return NULL; } if(!db->pkgcache_loaded) { @@ -508,7 +534,7 @@ pmpkghash_t *_alpm_db_get_pkgcache_hash(pmdb_t *db) _alpm_log(PM_LOG_DEBUG, "warning: pkgcache is NULL for db '%s'\n", db->treename); } - return(db->pkgcache); + return db->pkgcache; } alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db) @@ -518,10 +544,10 @@ alpm_list_t *_alpm_db_get_pkgcache(pmdb_t *db) pmpkghash_t *hash = _alpm_db_get_pkgcache_hash(db); if(hash == NULL) { - return(NULL); + return NULL; } - return(hash->list); + return hash->list; } /* "duplicate" pkg then add it to pkgcache */ @@ -532,12 +558,12 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg) ALPM_LOG_FUNC; if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { - return(-1); + return -1; } newpkg = _alpm_pkg_dup(pkg); if(newpkg == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "adding entry '%s' in '%s' cache\n", @@ -546,7 +572,7 @@ int _alpm_db_add_pkgincache(pmdb_t *db, pmpkg_t *pkg) _alpm_db_free_grpcache(db); - return(0); + return 0; } int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) @@ -556,7 +582,7 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) ALPM_LOG_FUNC; if(db == NULL || !db->pkgcache_loaded || pkg == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "removing entry '%s' from '%s' cache\n", @@ -567,14 +593,14 @@ int _alpm_db_remove_pkgfromcache(pmdb_t *db, pmpkg_t *pkg) /* package not found */ _alpm_log(PM_LOG_DEBUG, "cannot remove entry '%s' from '%s' cache: not found\n", alpm_pkg_get_name(pkg), db->treename); - return(-1); + return -1; } _alpm_pkg_free(data); _alpm_db_free_grpcache(db); - return(0); + return 0; } pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target) @@ -582,17 +608,17 @@ pmpkg_t *_alpm_db_get_pkgfromcache(pmdb_t *db, const char *target) ALPM_LOG_FUNC; if(db == NULL) { - return(NULL); + return NULL; } pmpkghash_t *pkgcache = _alpm_db_get_pkgcache_hash(db); if(!pkgcache) { _alpm_log(PM_LOG_DEBUG, "warning: failed to get '%s' from NULL pkgcache\n", target); - return(NULL); + return NULL; } - return(_alpm_pkghash_find(pkgcache, target)); + return _alpm_pkghash_find(pkgcache, target); } /* Returns a new group cache from db. @@ -604,7 +630,7 @@ int _alpm_db_load_grpcache(pmdb_t *db) ALPM_LOG_FUNC; if(db == NULL) { - return(-1); + return -1; } _alpm_log(PM_LOG_DEBUG, "loading group cache for repository '%s'\n", @@ -642,7 +668,7 @@ int _alpm_db_load_grpcache(pmdb_t *db) } db->grpcache_loaded = 1; - return(0); + return 0; } void _alpm_db_free_grpcache(pmdb_t *db) @@ -671,14 +697,14 @@ alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db) ALPM_LOG_FUNC; if(db == NULL) { - return(NULL); + return NULL; } if(!db->grpcache_loaded) { _alpm_db_load_grpcache(db); } - return(db->grpcache); + return db->grpcache; } pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target) @@ -688,18 +714,18 @@ pmgrp_t *_alpm_db_get_grpfromcache(pmdb_t *db, const char *target) ALPM_LOG_FUNC; if(db == NULL || target == NULL || strlen(target) == 0) { - return(NULL); + return NULL; } for(i = _alpm_db_get_grpcache(db); i; i = i->next) { pmgrp_t *info = i->data; if(strcmp(info->name, target) == 0) { - return(info); + return info; } } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 75776d71..204a0be0 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -31,6 +31,9 @@ #include <archive.h> #include <archive_entry.h> +#include "alpm.h" +#include "signing.h" + /* Database entries */ typedef enum _pmdbinfrq_t { INFRQ_BASE = 1, @@ -60,6 +63,9 @@ struct __pmdb_t { pmpkghash_t *pkgcache; alpm_list_t *grpcache; alpm_list_t *servers; + /* do not access directly, use _alpm_db_pgpsig(db) for lazy access */ + pmpgpsig_t pgpsig; + pgp_verify_t pgp_verify; struct db_operations *ops; }; @@ -75,6 +81,7 @@ alpm_list_t *_alpm_db_search(pmdb_t *db, const alpm_list_t *needles); pmdb_t *_alpm_db_register_local(void); pmdb_t *_alpm_db_register_sync(const char *treename); void _alpm_db_unregister(pmdb_t *db); +const pmpgpsig_t *_alpm_db_pgpsig(pmdb_t *db); /* be_*.c, backend specific calls */ int _alpm_local_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq); diff --git a/lib/libalpm/delta.c b/lib/libalpm/delta.c index 10c982f2..d3213fd1 100644 --- a/lib/libalpm/delta.c +++ b/lib/libalpm/delta.c @@ -41,32 +41,32 @@ const char SYMEXPORT *alpm_delta_get_from(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->from); + ASSERT(delta != NULL, return NULL); + return delta->from; } const char SYMEXPORT *alpm_delta_get_to(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->to); + ASSERT(delta != NULL, return NULL); + return delta->to; } const char SYMEXPORT *alpm_delta_get_filename(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->delta); + ASSERT(delta != NULL, return NULL); + return delta->delta; } const char SYMEXPORT *alpm_delta_get_md5sum(pmdelta_t *delta) { - ASSERT(delta != NULL, return(NULL)); - return(delta->delta_md5); + ASSERT(delta != NULL, return NULL); + return delta->delta_md5; } off_t SYMEXPORT alpm_delta_get_size(pmdelta_t *delta) { - ASSERT(delta != NULL, return(-1)); - return(delta->delta_size); + ASSERT(delta != NULL, return -1); + return delta->delta_size; } /** @} */ @@ -108,7 +108,7 @@ static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse) } v_i->childptr = v_i->children; } - return(vertices); + return vertices; } static void graph_init_size(alpm_list_t *vertices) @@ -205,7 +205,7 @@ static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t ** *path = alpm_list_reverse(rpath); alpm_list_free(rpath); - return(bestsize); + return bestsize; } /** Calculates the shortest path from one version to another. @@ -229,7 +229,7 @@ off_t _alpm_shortest_delta_path(alpm_list_t *deltas, if(deltas == NULL) { *path = NULL; - return(bestsize); + return bestsize; } _alpm_log(PM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to); @@ -245,7 +245,7 @@ off_t _alpm_shortest_delta_path(alpm_list_t *deltas, alpm_list_free(vertices); *path = bestpath; - return(bestsize); + return bestsize; } static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota) @@ -273,7 +273,7 @@ static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota } alpm_list_free_inner(vertices, _alpm_graph_free); alpm_list_free(vertices); - return(unused); + return unused; } alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg) @@ -283,7 +283,7 @@ alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(pmpkg_t *pkg) alpm_pkg_get_deltas(pkg), alpm_pkg_get_filename(pkg), pkgsize * MAX_DELTA_RATIO); - return(unused); + return unused; } @@ -308,7 +308,7 @@ pmdelta_t *_alpm_delta_parse(char *line) if(regexec(®, line, 0, 0, 0) != 0) { /* delta line is invalid, return NULL */ regfree(®); - return(NULL); + return NULL; } regfree(®); @@ -339,7 +339,7 @@ pmdelta_t *_alpm_delta_parse(char *line) _alpm_log(PM_LOG_DEBUG, "delta : %s %s '%jd'\n", delta->from, delta->to, (intmax_t)delta->delta_size); - return(delta); + return delta; } void _alpm_delta_free(pmdelta_t *delta) diff --git a/lib/libalpm/delta.h b/lib/libalpm/delta.h index d7a81c47..bd196bab 100644 --- a/lib/libalpm/delta.h +++ b/lib/libalpm/delta.h @@ -20,6 +20,8 @@ #ifndef _ALPM_DELTA_H #define _ALPM_DELTA_H +#include "config.h" /* ensure off_t is correct length */ + #include <sys/types.h> /* off_t */ #include "alpm.h" @@ -29,12 +31,12 @@ struct __pmdelta_t { char *delta; /** md5sum of the delta file */ char *delta_md5; - /** filesize of the delta file */ - off_t delta_size; /** filename of the 'before' file */ char *from; /** filename of the 'after' file */ char *to; + /** filesize of the delta file */ + off_t delta_size; /** download filesize of the delta file */ off_t download_size; }; diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 36d6e1aa..c5fb92ef 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -56,7 +56,7 @@ static pmdepmissing_t *depmiss_new(const char *target, pmdepend_t *dep, miss->depend = _alpm_dep_dup(dep); STRDUP(miss->causingpkg, causingpkg, RET_ERR(PM_ERR_MEMORY, NULL)); - return(miss); + return miss; } void _alpm_depmiss_free(pmdepmissing_t *miss) @@ -73,10 +73,10 @@ static int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2) alpm_list_t *i; for(i = alpm_pkg_get_depends(pkg1); i; i = i->next) { if(_alpm_depcmp(pkg2, i->data)) { - return(1); + return 1; } } - return(0); + return 0; } /* Convert a list of pmpkg_t * to a graph structure, @@ -110,7 +110,7 @@ static alpm_list_t *dep_graph_init(alpm_list_t *targets) } vertex_i->childptr = vertex_i->children; } - return(vertices); + return vertices; } /* Re-order a list of target packages with respect to their dependencies. @@ -137,7 +137,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) ALPM_LOG_FUNC; if(targets == NULL) { - return(NULL); + return NULL; } _alpm_log(PM_LOG_DEBUG, "started sorting dependencies\n"); @@ -153,7 +153,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) while(vertex->childptr && !found) { pmgraph_t *nextchild = vertex->childptr->data; vertex->childptr = vertex->childptr->next; - if (nextchild->state == 0) { + if(nextchild->state == 0) { found = 1; nextchild->parent = vertex; vertex = nextchild; @@ -181,7 +181,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) vptr = vptr->next; while(vptr) { vertex = vptr->data; - if (vertex->state == 0) break; + if(vertex->state == 0) break; vptr = vptr->next; } } @@ -201,7 +201,7 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse) alpm_list_free_inner(vertices, _alpm_graph_free); alpm_list_free(vertices); - return(newtargs); + return newtargs; } static int no_dep_version(void) @@ -214,7 +214,7 @@ static pmdepend_t *filtered_depend(pmdepend_t *dep, int nodepversion) { if(nodepversion) { pmdepend_t *newdep = _alpm_dep_dup(dep); - ASSERT(newdep, return(dep)); + ASSERT(newdep, return dep); newdep->mod = PM_DEP_MOD_ANY; dep = newdep; } @@ -235,10 +235,10 @@ static pmpkg_t *find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep) for(i = pkgs; i; i = alpm_list_next(i)) { pmpkg_t *pkg = i->data; if(_alpm_depcmp(pkg, dep)) { - return(pkg); + return pkg; } } - return(NULL); + return NULL; } /** Find a package satisfying a specified dependency. @@ -252,7 +252,7 @@ pmpkg_t SYMEXPORT *alpm_find_satisfier(alpm_list_t *pkgs, const char *depstring) pmdepend_t *dep = _alpm_splitdep(depstring); pmpkg_t *pkg = find_dep_satisfier(pkgs, dep); _alpm_dep_free(dep); - return(pkg); + return pkg; } /** Checks dependencies and returns missing ones in a list. @@ -343,7 +343,7 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_list_t *pkglist, int reversedeps, alpm_list_free(modified); alpm_list_free(dblist); - return(baddeps); + return baddeps; } static int dep_vercmp(const char *version1, pmdepmod_t mod, @@ -364,7 +364,7 @@ static int dep_vercmp(const char *version1, pmdepmod_t mod, default: equal = 1; break; } } - return(equal); + return equal; } int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) @@ -380,7 +380,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) satisfy = (strcmp(pkg->name, dep->name) == 0 && dep_vercmp(pkg->version, dep->mod, dep->version)); if(satisfy) { - return(satisfy); + return satisfy; } } @@ -406,7 +406,7 @@ int _alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep) } } - return(satisfy); + return satisfy; } pmdepend_t *_alpm_splitdep(const char *depstring) @@ -415,7 +415,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring) const char *ptr, *version = NULL; if(depstring == NULL) { - return(NULL); + return NULL; } CALLOC(depend, 1, sizeof(pmdepend_t), RET_ERR(PM_ERR_MEMORY, NULL)); @@ -451,7 +451,7 @@ pmdepend_t *_alpm_splitdep(const char *depstring) STRDUP(depend->version, version, RET_ERR(PM_ERR_MEMORY, NULL)); } - return(depend); + return depend; } pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep) @@ -464,7 +464,7 @@ pmdepend_t *_alpm_dep_dup(const pmdepend_t *dep) STRDUP(newdep->version, dep->version, RET_ERR(PM_ERR_MEMORY, NULL)); newdep->mod = dep->mod; - return(newdep); + return newdep; } /* These parameters are messy. We check if this package, given a list of @@ -477,7 +477,7 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, alpm_list_t *i; if(_alpm_pkg_find(targets, alpm_pkg_get_name(pkg))) { - return(0); + return 0; } if(!include_explicit) { @@ -485,7 +485,7 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) { _alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed\n", alpm_pkg_get_name(pkg)); - return(0); + return 0; } } @@ -499,12 +499,12 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets, for(i = _alpm_db_get_pkgcache(db); i; i = i->next) { pmpkg_t *lpkg = i->data; if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) { - return(0); + return 0; } } /* it's ok to remove */ - return(1); + return 1; } /** @@ -569,7 +569,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install = 0; - if (prompt) { + if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { @@ -580,7 +580,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, continue; } } - return(pkg); + return pkg; } } /* 2. satisfiers (skip literals here) */ @@ -591,7 +591,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install = 0; - if (prompt) { + if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { @@ -613,13 +613,13 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, /* first check if one provider is already installed locally */ for(i = providers; i; i = i->next) { pmpkg_t *pkg = i->data; - if (_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { + if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { alpm_list_free(providers); - return(pkg); + return pkg; } } count = alpm_list_count(providers); - if (count >= 1) { + if(count >= 1) { /* default to first provider if there is no QUESTION callback */ int index = 0; if(count > 1) { @@ -630,7 +630,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, if(index >= 0 && index < count) { pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index)); alpm_list_free(providers); - return(pkg); + return pkg; } alpm_list_free(providers); providers = NULL; @@ -641,7 +641,7 @@ static pmpkg_t *resolvedep(pmdepend_t *dep, alpm_list_t *dbs, } else { pm_errno = PM_ERR_PKG_NOT_FOUND; } - return(NULL); + return NULL; } /** Find a package satisfying a specified dependency. @@ -657,13 +657,13 @@ pmpkg_t SYMEXPORT *alpm_find_dbs_satisfier(alpm_list_t *dbs, const char *depstri pmdepend_t *dep; pmpkg_t *pkg; - ASSERT(dbs, return(NULL)); + ASSERT(dbs, return NULL); dep = _alpm_splitdep(depstring); - ASSERT(dep, return(NULL)); + ASSERT(dep, return NULL); pkg = resolvedep(dep, dbs, NULL, 1); _alpm_dep_free(dep); - return(pkg); + return pkg; } /** @@ -699,7 +699,7 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk ALPM_LOG_FUNC; if(_alpm_pkg_find(*packages, pkg->name) != NULL) { - return(0); + return 0; } /* Create a copy of the packages list, so that it can be restored @@ -760,7 +760,7 @@ int _alpm_resolvedeps(alpm_list_t *localpkgs, alpm_list_t *dbs_sync, pmpkg_t *pk alpm_list_free(packages_copy); } _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); - return(ret); + return ret; } const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) @@ -768,9 +768,9 @@ const char SYMEXPORT *alpm_miss_get_target(const pmdepmissing_t *miss) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); - return(miss->target); + return miss->target; } const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss) @@ -778,7 +778,7 @@ const char SYMEXPORT *alpm_miss_get_causingpkg(const pmdepmissing_t *miss) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); return miss->causingpkg; } @@ -788,9 +788,9 @@ pmdepend_t SYMEXPORT *alpm_miss_get_dep(pmdepmissing_t *miss) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(miss != NULL, return(NULL)); + ASSERT(miss != NULL, return NULL); - return(miss->depend); + return miss->depend; } pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep) @@ -798,9 +798,9 @@ pmdepmod_t SYMEXPORT alpm_dep_get_mod(const pmdepend_t *dep) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(dep != NULL, return(-1)); + ASSERT(dep != NULL, return -1); - return(dep->mod); + return dep->mod; } const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep) @@ -808,9 +808,9 @@ const char SYMEXPORT *alpm_dep_get_name(const pmdepend_t *dep) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); - return(dep->name); + return dep->name; } const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) @@ -818,9 +818,9 @@ const char SYMEXPORT *alpm_dep_get_version(const pmdepend_t *dep) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); - return(dep->version); + return dep->version; } /** Reverse of splitdep; make a dep string from a pmdepend_t struct. @@ -837,7 +837,7 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(dep != NULL, return(NULL)); + ASSERT(dep != NULL, return NULL); if(dep->name) { name = dep->name; @@ -882,6 +882,6 @@ char SYMEXPORT *alpm_dep_compute_string(const pmdepend_t *dep) MALLOC(str, len, RET_ERR(PM_ERR_MEMORY, NULL)); snprintf(str, len, "%s%s%s", name, opr, ver); - return(str); + return str; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 066107d7..102b42c6 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -56,7 +56,7 @@ static int mount_point_cmp(const void *p1, const void *p2) const alpm_mountpoint_t *mp1 = p1; const alpm_mountpoint_t *mp2 = p2; /* the negation will sort all mountpoints before their parent */ - return(-strcmp(mp1->mount_dir, mp2->mount_dir)); + return -strcmp(mp1->mount_dir, mp2->mount_dir); } static alpm_list_t *mount_point_list(void) @@ -71,8 +71,8 @@ static alpm_list_t *mount_point_list(void) fp = setmntent(MOUNTED, "r"); - if (fp == NULL) { - return(NULL); + if(fp == NULL) { + return NULL; } while((mnt = getmntent(fp))) { @@ -103,8 +103,8 @@ static alpm_list_t *mount_point_list(void) entries = getmntinfo(&fsp, MNT_NOWAIT); - if (entries < 0) { - return(NULL); + if(entries < 0) { + return NULL; } for(; entries-- > 0; fsp++) { @@ -128,7 +128,7 @@ static alpm_list_t *mount_point_list(void) mp = ptr->data; _alpm_log(PM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir); } - return(mount_points); + return mount_points; } static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, @@ -140,12 +140,12 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points, alpm_mountpoint_t *data = mp->data; if(strncmp(data->mount_dir, real_path, data->mount_dir_len) == 0) { - return(data); + return data; } } /* should not get here... */ - return(NULL); + return NULL; } static int calculate_removed_size(const alpm_list_t *mount_points, @@ -182,7 +182,7 @@ static int calculate_removed_size(const alpm_list_t *mount_points, mp->used |= USED_REMOVE; } - return(0); + return 0; } static int calculate_installed_size(const alpm_list_t *mount_points, @@ -192,7 +192,7 @@ static int calculate_installed_size(const alpm_list_t *mount_points, struct archive *archive; struct archive_entry *entry; - if ((archive = archive_read_new()) == NULL) { + if((archive = archive_read_new()) == NULL) { pm_errno = PM_ERR_LIBARCHIVE; ret = -1; goto cleanup; @@ -254,7 +254,7 @@ static int calculate_installed_size(const alpm_list_t *mount_points, archive_read_finish(archive); cleanup: - return(ret); + return ret; } int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) @@ -269,13 +269,13 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) mount_points = mount_point_list(); if(mount_points == NULL) { _alpm_log(PM_LOG_ERROR, _("could not determine filesystem mount points\n")); - return(-1); + return -1; } root_mp = match_mount_point(mount_points, handle->root); if(root_mp == NULL) { _alpm_log(PM_LOG_ERROR, _("could not determine root mount point %s\n"), handle->root); - return(-1); + return -1; } replaces = alpm_list_count(trans->remove); @@ -352,7 +352,7 @@ int _alpm_check_diskspace(pmtrans_t *trans, pmdb_t *db_local) RET_ERR(PM_ERR_DISK_SPACE, -1); } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index a98d84ac..f7568282 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -29,14 +29,9 @@ #include <sys/types.h> #include <sys/stat.h> #include <signal.h> -/* the following two are needed for FreeBSD's libfetch */ -#include <limits.h> /* PATH_MAX */ -#if defined(HAVE_SYS_PARAM_H) -#include <sys/param.h> /* MAXHOSTNAMELEN */ -#endif -#ifdef HAVE_LIBFETCH -#include <fetch.h> +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ @@ -47,112 +42,185 @@ #include "util.h" #include "handle.h" -static char *get_filename(const char *url) { +#ifdef HAVE_LIBCURL +static double prevprogress; /* last download amount */ +#endif + +static const char *get_filename(const char *url) +{ char *filename = strrchr(url, '/'); if(filename != NULL) { filename++; } - return(filename); + return filename; } -#ifdef HAVE_LIBFETCH -static char *get_destfile(const char *path, const char *filename) { - char *destfile; - /* len = localpath len + filename len + null */ - size_t len = strlen(path) + strlen(filename) + 1; - CALLOC(destfile, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); - snprintf(destfile, len, "%s%s", path, filename); +#ifdef HAVE_LIBCURL +static char *get_fullpath(const char *path, const char *filename, + const char *suffix) +{ + char *filepath; + /* len = localpath len + filename len + suffix len + null */ + size_t len = strlen(path) + strlen(filename) + strlen(suffix) + 1; + CALLOC(filepath, len, sizeof(char), RET_ERR(PM_ERR_MEMORY, NULL)); + snprintf(filepath, len, "%s%s%s", path, filename, suffix); - return(destfile); + return filepath; } -static char *get_tempfile(const char *path, const char *filename) { - char *tempfile; - /* len = localpath len + filename len + '.part' len + null */ - size_t 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); +#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } +enum sighandlers { OLD = 0, NEW = 1 }; - return(tempfile); +static int dload_interrupted; +static void inthandler(int signum) +{ + (void)signum; + dload_interrupted = 1; } -static const char *gethost(struct url *fileurl) +static int curl_progress(void *file, double dltotal, double dlnow, + double ultotal, double ulnow) { - const char *host = _("disk"); - if(strcmp(SCHEME_FILE, fileurl->scheme) != 0) { - host = fileurl->host; + struct fileinfo *dlfile = (struct fileinfo *)file; + double current_size, total_size; + + /* unused parameters */ + (void)ultotal; + (void)ulnow; + + /* SIGINT sent, abort by alerting curl */ + if(dload_interrupted) { + return 1; } - return(host); + + /* none of what follows matters if the front end has no callback */ + if(handle->dlcb == NULL) { + return 0; + } + + current_size = dlfile->initial_size + dlnow; + total_size = dlfile->initial_size + dltotal; + + if(DOUBLE_EQ(dltotal, 0) || DOUBLE_EQ(prevprogress, total_size)) { + return 0; + } + + /* initialize the progress bar here to avoid displaying it when + * a repo is up to date and nothing gets downloaded */ + if(DOUBLE_EQ(prevprogress, 0)) { + handle->dlcb(dlfile->filename, 0, (long)dltotal); + } + + handle->dlcb(dlfile->filename, (long)current_size, (long)total_size); + + prevprogress = current_size; + + return 0; } -int dload_interrupted; -static void inthandler(int signum) +static int curl_gethost(const char *url, char *buffer) { - dload_interrupted = 1; + size_t hostlen; + char *p; + + if(strncmp(url, "file://", 7) == 0) { + strcpy(buffer, _("disk")); + } else { + p = strstr(url, "//"); + if(!p) { + return 1; + } + p += 2; /* jump over the found // */ + hostlen = strcspn(p, "/"); + if(hostlen > 255) { + /* buffer overflow imminent */ + _alpm_log(PM_LOG_ERROR, _("buffer overflow detected")); + return 1; + } + snprintf(buffer, hostlen + 1, "%s", p); + } + + return 0; } -#define check_stop() if(dload_interrupted) { ret = -1; goto cleanup; } -enum sighandlers { OLD = 0, NEW = 1 }; +static int utimes_long(const char *path, long time) +{ + if(time != -1) { + struct timeval tv[2]; + memset(&tv, 0, sizeof(tv)); + tv[0].tv_sec = tv[1].tv_sec = time; + return utimes(path, tv); + } + return 0; +} -static int download_internal(const char *url, const char *localpath, - int force) { + +static int curl_download_internal(const char *url, const char *localpath, + int force) +{ + int ret = -1; FILE *localf = NULL; + const char *useragent; + const char *open_mode = "wb"; + char *destfile, *tempfile; + char hostname[256]; /* RFC1123 states applications should support this length */ struct stat st; - int ret = 0; - off_t dl_thisfile = 0; - ssize_t nread = 0; - char *tempfile, *destfile, *filename; + long httpresp, timecond, remote_time; + double remote_size, bytes_dl; struct sigaction sig_pipe[2], sig_int[2]; + struct fileinfo dlfile; - off_t local_size = 0; - time_t local_time = 0; - - struct url *fileurl; - struct url_stat ust; - fetchIO *dlf = NULL; - - char buffer[PM_DLBUF_LEN]; - - filename = get_filename(url); - if(!filename) { + dlfile.initial_size = 0.0; + dlfile.filename = get_filename(url); + if(!dlfile.filename || curl_gethost(url, hostname) != 0) { _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); RET_ERR(PM_ERR_SERVER_BAD_URL, -1); } - fileurl = fetchParseURL(url); - if(!fileurl) { - _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid\n"), url); - RET_ERR(PM_ERR_LIBFETCH, -1); + destfile = get_fullpath(localpath, dlfile.filename, ""); + tempfile = get_fullpath(localpath, dlfile.filename, ".part"); + if(!destfile || !tempfile) { + goto cleanup; } - destfile = get_destfile(localpath, filename); - tempfile = get_tempfile(localpath, filename); - - if(stat(tempfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { - _alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation\n"); - local_time = fileurl->last_modified = st.st_mtime; - local_size = fileurl->offset = (off_t)st.st_size; - dl_thisfile = st.st_size; - localf = fopen(tempfile, "ab"); - } else if(!force && stat(destfile, &st) == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { - _alpm_log(PM_LOG_DEBUG, "destfile found, using mtime only\n"); - local_time = fileurl->last_modified = st.st_mtime; - local_size = /* no fu->off here */ (off_t)st.st_size; - } else { - _alpm_log(PM_LOG_DEBUG, "no file found matching criteria, starting from scratch\n"); + /* the curl_easy handle is initialized with the alpm handle, so we only need + * to reset the curl handle set parameters for each time it's used. */ + curl_easy_reset(handle->curl); + curl_easy_setopt(handle->curl, CURLOPT_URL, url); + curl_easy_setopt(handle->curl, CURLOPT_FAILONERROR, 1L); + curl_easy_setopt(handle->curl, CURLOPT_CONNECTTIMEOUT, 10L); + curl_easy_setopt(handle->curl, CURLOPT_FILETIME, 1L); + curl_easy_setopt(handle->curl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(handle->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(handle->curl, CURLOPT_PROGRESSFUNCTION, curl_progress); + curl_easy_setopt(handle->curl, CURLOPT_PROGRESSDATA, (void *)&dlfile); + + useragent = getenv("HTTP_USER_AGENT"); + if(useragent != NULL) { + curl_easy_setopt(handle->curl, CURLOPT_USERAGENT, useragent); } - /* pass the raw filename for passing to the callback function */ - _alpm_log(PM_LOG_DEBUG, "using '%s' for download progress\n", filename); + /* TODO: no assuming here. the calling function should tell us what's kosher */ + if(!force && stat(destfile, &st) == 0) { + /* assume its a sync, so we're starting from scratch. but, only download + * our local is out of date. */ + curl_easy_setopt(handle->curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); + curl_easy_setopt(handle->curl, CURLOPT_TIMEVALUE, (long)st.st_mtime); + } else if(stat(tempfile, &st) == 0 && st.st_size > 0) { + /* assume its a partial package download. we do not support resuming of + * transfers on partially downloaded sync DBs. */ + open_mode = "ab"; + curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size); + _alpm_log(PM_LOG_DEBUG, "tempfile found, attempting continuation"); + dlfile.initial_size = (double)st.st_size; + } - /* print proxy info for debug purposes */ - _alpm_log(PM_LOG_DEBUG, "HTTP_PROXY: %s\n", getenv("HTTP_PROXY")); - _alpm_log(PM_LOG_DEBUG, "http_proxy: %s\n", getenv("http_proxy")); - _alpm_log(PM_LOG_DEBUG, "FTP_PROXY: %s\n", getenv("FTP_PROXY")); - _alpm_log(PM_LOG_DEBUG, "ftp_proxy: %s\n", getenv("ftp_proxy")); + localf = fopen(tempfile, open_mode); + if(localf == NULL) { + goto cleanup; + } - /* 10s timeout */ - fetchTimeout = 10; + curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, localf); /* ignore any SIGPIPE signals- these may occur if our FTP socket dies or * something along those lines. Store the old signal handler first. */ @@ -169,168 +237,64 @@ static int download_internal(const char *url, const char *localpath, sigaction(SIGINT, NULL, &sig_int[OLD]); sigaction(SIGINT, &sig_int[NEW], NULL); - /* NOTE: libfetch does not reset the error code, be sure to do it before - * calls into the library */ - - /* TODO: if we call fetchStat() and get a redirect (disabling automagic - * redirect following), we should repeat the file locator stuff and get a new - * filename rather than only base if off the first URL, and then verify - * get_filename() didn't return ''. Of course, libfetch might not even allow - * us to even get that URL...FS#22645. This would allow us to download things - * without totally puking like - * http://www.archlinux.org/packages/community/x86_64/exim/download/ */ - - /* find out the remote size *and* mtime in one go. there is a lot of - * trouble in trying to do both size and "if-modified-since" logic in a - * non-stat request, so avoid it. */ - fetchLastErrCode = 0; - if(fetchStat(fileurl, &ust, "") == -1) { - pm_errno = PM_ERR_LIBFETCH; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), - filename, gethost(fileurl), fetchLastErrString); - ret = -1; - goto cleanup; - } - check_stop(); - - _alpm_log(PM_LOG_DEBUG, "ust.mtime: %ld local_time: %ld compare: %ld\n", - ust.mtime, local_time, local_time - ust.mtime); - _alpm_log(PM_LOG_DEBUG, "ust.size: %jd local_size: %jd compare: %jd\n", - (intmax_t)ust.size, (intmax_t)local_size, (intmax_t)(local_size - ust.size)); - if(!force && ust.mtime && ust.mtime == local_time - && ust.size && ust.size == local_size) { - /* the remote time and size values agreed with what we have, so move on - * because there is nothing more to do. */ - _alpm_log(PM_LOG_DEBUG, "files are identical, skipping %s\n", filename); - ret = 1; - goto cleanup; - } - if(!ust.mtime || ust.mtime != local_time) { - _alpm_log(PM_LOG_DEBUG, "mtimes were different or unavailable, downloading %s from beginning\n", filename); - fileurl->offset = 0; - } - - fetchLastErrCode = 0; - dlf = fetchGet(fileurl, ""); - check_stop(); - - if(fetchLastErrCode != 0 || dlf == NULL) { - pm_errno = PM_ERR_LIBFETCH; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), - filename, gethost(fileurl), fetchLastErrString); - ret = -1; - goto cleanup; - } else { - _alpm_log(PM_LOG_DEBUG, "connected to %s successfully\n", fileurl->host); - } - - if(localf && fileurl->offset == 0) { - _alpm_log(PM_LOG_WARNING, _("resuming download of %s not possible; starting over\n"), filename); - fclose(localf); - localf = NULL; - } else if(fileurl->offset) { - _alpm_log(PM_LOG_DEBUG, "resuming download at position %jd\n", (intmax_t)fileurl->offset); - } - - - if(localf == NULL) { - _alpm_rmrf(tempfile); - fileurl->offset = (off_t)0; - dl_thisfile = 0; - localf = fopen(tempfile, "wb"); - if(localf == NULL) { /* still null? */ - pm_errno = PM_ERR_RETRIEVE; - _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), - tempfile, strerror(errno)); - ret = -1; - goto cleanup; - } - } - /* Progress 0 - initialize */ - if(handle->dlcb) { - handle->dlcb(filename, 0, ust.size); - } + prevprogress = 0; - while((nread = fetchIO_read(dlf, buffer, PM_DLBUF_LEN)) > 0) { - check_stop(); - size_t nwritten = 0; - nwritten = fwrite(buffer, 1, (size_t)nread, localf); - if((nwritten != (size_t)nread) || ferror(localf)) { - pm_errno = PM_ERR_RETRIEVE; - _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), - tempfile, strerror(errno)); - ret = -1; - goto cleanup; - } - dl_thisfile += nread; + /* perform transfer */ + handle->curlerr = curl_easy_perform(handle->curl); - if(handle->dlcb) { - handle->dlcb(filename, dl_thisfile, ust.size); - } + /* retrieve info about the state of the transfer */ + curl_easy_getinfo(handle->curl, CURLINFO_RESPONSE_CODE, &httpresp); + curl_easy_getinfo(handle->curl, CURLINFO_FILETIME, &remote_time); + curl_easy_getinfo(handle->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &remote_size); + curl_easy_getinfo(handle->curl, CURLINFO_SIZE_DOWNLOAD, &bytes_dl); + curl_easy_getinfo(handle->curl, CURLINFO_CONDITION_UNMET, &timecond); + + /* time condition was met and we didn't download anything. we need to + * clean up the 0 byte .part file that's left behind. */ + if(DOUBLE_EQ(bytes_dl, 0) && timecond == 1) { + ret = 1; + unlink(tempfile); + goto cleanup; } - /* did the transfer complete normally? */ - if (nread == -1) { - /* not PM_ERR_LIBFETCH here because libfetch error string might be empty */ - pm_errno = PM_ERR_RETRIEVE; - _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s\n"), - filename, gethost(fileurl)); - ret = -1; + if(handle->curlerr == CURLE_ABORTED_BY_CALLBACK) { + goto cleanup; + } else if(handle->curlerr != CURLE_OK) { + pm_errno = PM_ERR_LIBCURL; + _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s : %s\n"), + dlfile.filename, hostname, curl_easy_strerror(handle->curlerr)); + unlink(tempfile); goto cleanup; } - if (ust.size != -1 && dl_thisfile < ust.size) { + /* remote_size isn't necessarily the full size of the file, just what the + * server reported as remaining to download. compare it to what curl reported + * as actually being transferred during curl_easy_perform() */ + if(!DOUBLE_EQ(remote_size, -1) && !DOUBLE_EQ(bytes_dl, -1) && + !DOUBLE_EQ(bytes_dl, remote_size)) { pm_errno = PM_ERR_RETRIEVE; _alpm_log(PM_LOG_ERROR, _("%s appears to be truncated: %jd/%jd bytes\n"), - filename, (intmax_t)dl_thisfile, (intmax_t)ust.size); - ret = -1; + dlfile.filename, (intmax_t)bytes_dl, (intmax_t)remote_size); goto cleanup; } - /* 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; - fetchIO_close(dlf); - dlf = NULL; - - /* set the times on the file to the same as that of the remote file */ - if(ust.mtime) { - struct timeval tv[2]; - memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = ust.atime; - tv[1].tv_sec = ust.mtime; - utimes(tempfile, tv); - } - if(rename(tempfile, destfile)) { - _alpm_log(PM_LOG_ERROR, _("could not rename %s to %s (%s)\n"), - tempfile, destfile, strerror(errno)); - ret = -1; - } ret = 0; cleanup: - FREE(tempfile); - FREE(destfile); if(localf != NULL) { - /* if we still had a local file open, we got interrupted. set the mtimes on - * the file accordingly. */ - fflush(localf); - if(ust.mtime) { - struct timeval tv[2]; - memset(&tv, 0, sizeof(tv)); - tv[0].tv_sec = ust.atime; - tv[1].tv_sec = ust.mtime; - futimes(fileno(localf), tv); - } fclose(localf); + utimes_long(tempfile, remote_time); } - if(dlf != NULL) { - fetchIO_close(dlf); + + /* TODO: A signature download will need to return success here as well before + * we're willing to rotate the new file into place. */ + if(ret == 0) { + rename(tempfile, destfile); } - fetchFreeURL(fileurl); + + FREE(tempfile); + FREE(destfile); /* restore the old signal handlers */ sigaction(SIGINT, &sig_int[OLD], NULL); @@ -340,15 +304,16 @@ cleanup: raise(SIGINT); } - return(ret); + return ret; } #endif static int download(const char *url, const char *localpath, - int force) { + int force) +{ if(handle->fetchcb == NULL) { -#ifdef HAVE_LIBFETCH - return(download_internal(url, localpath, force)); +#ifdef HAVE_LIBCURL + return curl_download_internal(url, localpath, force); #else RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); #endif @@ -357,7 +322,7 @@ static int download(const char *url, const char *localpath, if(ret == -1) { RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); } - return(ret); + return ret; } } @@ -395,7 +360,7 @@ int _alpm_download_single_file(const char *filename, } } - return(ret); + return ret; } int _alpm_download_files(alpm_list_t *files, @@ -412,14 +377,14 @@ int _alpm_download_files(alpm_list_t *files, } } - return(ret); + return ret; } /** Fetch a remote pkg. */ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) { - char *filename, *filepath; - const char *cachedir; + char *filepath; + const char *filename, *cachedir; int ret; ALPM_LOG_FUNC; @@ -433,13 +398,13 @@ char SYMEXPORT *alpm_fetch_pkgurl(const char *url) ret = download(url, cachedir, 0); if(ret == -1) { _alpm_log(PM_LOG_WARNING, _("failed to download %s\n"), url); - return(NULL); + 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); + return filepath; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/dload.h b/lib/libalpm/dload.h index 63266491..324bd118 100644 --- a/lib/libalpm/dload.h +++ b/lib/libalpm/dload.h @@ -25,7 +25,11 @@ #include <time.h> -#define PM_DLBUF_LEN (1024 * 16) +/* internal structure for communicating with curl progress callback */ +struct fileinfo { + const char *filename; + double initial_size; +}; int _alpm_download_single_file(const char *filename, alpm_list_t *servers, const char *localpath, diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 21fbb48f..4d4a065c 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -20,21 +20,14 @@ #include "config.h" -/* TODO: needed for the libfetch stuff, unfortunately- we should kill it */ -#include <stdio.h> -/* the following two are needed for FreeBSD's libfetch */ -#include <limits.h> /* PATH_MAX */ -#if defined(HAVE_SYS_PARAM_H) -#include <sys/param.h> /* MAXHOSTNAMELEN */ -#endif - -#ifdef HAVE_LIBFETCH -#include <fetch.h> /* fetchLastErrString */ +#ifdef HAVE_LIBCURL +#include <curl/curl.h> #endif /* libalpm */ #include "util.h" #include "alpm.h" +#include "handle.h" const char SYMEXPORT *alpm_strerrorlast(void) { @@ -122,6 +115,13 @@ const char SYMEXPORT *alpm_strerror(int err) return _("package architecture is not valid"); case PM_ERR_PKG_REPO_NOT_FOUND: return _("could not find repository for target"); + /* Signatures */ + case PM_ERR_SIG_MISSINGDIR: + return _("signature directory not configured correctly"); + case PM_ERR_SIG_INVALID: + return _("invalid PGP signature"); + case PM_ERR_SIG_UNKNOWN: + return _("unknown PGP signature"); /* Deltas */ case PM_ERR_DLT_INVALID: return _("invalid or corrupted delta"); @@ -147,13 +147,15 @@ const char SYMEXPORT *alpm_strerror(int err) * requires the archive struct, so we can't. Just use a generic * error string instead. */ return _("libarchive error"); - case PM_ERR_LIBFETCH: -#ifdef HAVE_LIBFETCH - return fetchLastErrString; + case PM_ERR_LIBCURL: +#ifdef HAVE_LIBCURL + return curl_easy_strerror(handle->curlerr); #else /* obviously shouldn't get here... */ return _("download library error"); #endif + case PM_ERR_GPGME: + return _("gpgme error"); case PM_ERR_EXTERNAL_DOWNLOAD: return _("error invoking external downloader"); /* Unknown error! */ diff --git a/lib/libalpm/graph.c b/lib/libalpm/graph.c new file mode 100644 index 00000000..2e2ba236 --- /dev/null +++ b/lib/libalpm/graph.c @@ -0,0 +1,52 @@ +/* + * graph.c - helpful graph structure and setup/teardown methods + * + * Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.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 "graph.h" +#include "util.h" +#include "log.h" + +pmgraph_t *_alpm_graph_new(void) +{ + pmgraph_t *graph = NULL; + + CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); + return graph; +} + +void _alpm_graph_free(void *data) +{ + pmgraph_t *graph = data; + /* make my children forget about me */ + for(alpm_list_t *i = graph->children; i; i = i->next) { + pmgraph_t *child = i->data; + child->parent = NULL; + } + alpm_list_free(graph->children); + /* and make my parents forget about me too */ + if(graph->parent) { + alpm_list_t *me = alpm_list_find_ptr(graph->parent->children, &data); + graph->parent->children = alpm_list_remove_item(graph->parent->children, + me); + } + free(graph); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/graph.h b/lib/libalpm/graph.h index 07986f66..f76c6004 100644 --- a/lib/libalpm/graph.h +++ b/lib/libalpm/graph.h @@ -1,8 +1,7 @@ /* * graph.h - helpful graph structure and setup/teardown methods * - * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> - * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> + * Copyright (c) 2007-2011 Pacman Development Team <pacman-dev@archlinux.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,34 +16,27 @@ * 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_GRAPH_H +#define _ALPM_GRAPH_H + +#include "config.h" /* ensure off_t is correct length */ #include <sys/types.h> /* off_t */ #include "alpm_list.h" -#include "util.h" /* CALLOC() */ -struct __pmgraph_t { +typedef struct __pmgraph_t { char state; /* 0: untouched, -1: entered, other: leaving time */ - void *data; off_t weight; /* weight of the node */ + 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; +} pmgraph_t; - CALLOC(graph, 1, sizeof(pmgraph_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(graph); -} +pmgraph_t *_alpm_graph_new(void); +void _alpm_graph_free(void *data); -static void _alpm_graph_free(void *data) -{ - pmgraph_t *graph = data; - alpm_list_free(graph->children); - free(graph); -} +#endif /* _ALPM_GRAPH_H */ +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/group.c b/lib/libalpm/group.c index 398c2588..dbcc7554 100644 --- a/lib/libalpm/group.c +++ b/lib/libalpm/group.c @@ -21,7 +21,6 @@ #include "config.h" #include <stdlib.h> -#include <stdio.h> #include <string.h> /* libalpm */ @@ -40,7 +39,7 @@ pmgrp_t *_alpm_grp_new(const char *name) CALLOC(grp, 1, sizeof(pmgrp_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(grp->name, name, RET_ERR(PM_ERR_MEMORY, NULL)); - return(grp); + return grp; } void _alpm_grp_free(pmgrp_t *grp) @@ -62,7 +61,7 @@ const char SYMEXPORT *alpm_grp_get_name(const pmgrp_t *grp) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(grp != NULL, return(NULL)); + ASSERT(grp != NULL, return NULL); return grp->name; } @@ -72,7 +71,7 @@ alpm_list_t SYMEXPORT *alpm_grp_get_pkgs(const pmgrp_t *grp) ALPM_LOG_FUNC; /* Sanity checks */ - ASSERT(grp != NULL, return(NULL)); + ASSERT(grp != NULL, return NULL); return grp->packages; } diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index d8ce9fd2..6bc5f27e 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -27,9 +27,7 @@ #include <limits.h> #include <sys/types.h> #include <syslog.h> -#include <time.h> #include <sys/stat.h> -#include <errno.h> /* libalpm */ #include "handle.h" @@ -50,7 +48,9 @@ pmhandle_t *_alpm_handle_new() CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(handle); + handle->sigverify = PM_PGP_VERIFY_OPTIONAL; + + return handle; } void _alpm_handle_free(pmhandle_t *handle) @@ -71,6 +71,11 @@ void _alpm_handle_free(pmhandle_t *handle) closelog(); } +#ifdef HAVE_LIBCURL + /* release curl handle */ + curl_easy_cleanup(handle->curl); +#endif + /* free memory */ _alpm_trans_free(handle->trans); FREE(handle->root); @@ -79,17 +84,19 @@ void _alpm_handle_free(pmhandle_t *handle) FREE(handle->logfile); FREE(handle->lockfile); FREE(handle->arch); + FREE(handle->signaturedir); FREELIST(handle->dbs_sync); FREELIST(handle->noupgrade); FREELIST(handle->noextract); FREELIST(handle->ignorepkg); FREELIST(handle->ignoregrp); FREE(handle); + } alpm_cb_log SYMEXPORT alpm_option_get_logcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -98,7 +105,7 @@ alpm_cb_log SYMEXPORT alpm_option_get_logcb() alpm_cb_download SYMEXPORT alpm_option_get_dlcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -107,7 +114,7 @@ alpm_cb_download SYMEXPORT alpm_option_get_dlcb() alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -116,7 +123,7 @@ alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb() alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -125,7 +132,7 @@ alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb() const char SYMEXPORT *alpm_option_get_root() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -134,7 +141,7 @@ const char SYMEXPORT *alpm_option_get_root() const char SYMEXPORT *alpm_option_get_dbpath() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -143,7 +150,7 @@ const char SYMEXPORT *alpm_option_get_dbpath() alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -152,7 +159,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_cachedirs() const char SYMEXPORT *alpm_option_get_logfile() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -161,16 +168,25 @@ const char SYMEXPORT *alpm_option_get_logfile() const char SYMEXPORT *alpm_option_get_lockfile() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } return handle->lockfile; } +const char SYMEXPORT *alpm_option_get_signaturedir() +{ + if(handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->signaturedir; +} + int SYMEXPORT alpm_option_get_usesyslog() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -179,7 +195,7 @@ int SYMEXPORT alpm_option_get_usesyslog() alpm_list_t SYMEXPORT *alpm_option_get_noupgrades() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -188,7 +204,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_noupgrades() alpm_list_t SYMEXPORT *alpm_option_get_noextracts() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -197,7 +213,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_noextracts() alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -206,7 +222,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs() alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -215,7 +231,7 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() const char SYMEXPORT *alpm_option_get_arch() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -224,7 +240,7 @@ const char SYMEXPORT *alpm_option_get_arch() int SYMEXPORT alpm_option_get_usedelta() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -233,7 +249,7 @@ int SYMEXPORT alpm_option_get_usedelta() int SYMEXPORT alpm_option_get_checkspace() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return -1; } @@ -242,7 +258,7 @@ int SYMEXPORT alpm_option_get_checkspace() pmdb_t SYMEXPORT *alpm_option_get_localdb() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } @@ -251,47 +267,39 @@ pmdb_t SYMEXPORT *alpm_option_get_localdb() alpm_list_t SYMEXPORT *alpm_option_get_syncdbs() { - if (handle == NULL) { + if(handle == NULL) { pm_errno = PM_ERR_HANDLE_NULL; return NULL; } return handle->dbs_sync; } -void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) +int SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->logcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) +int SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->dlcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb) +int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->fetchcb = cb; + return 0; } -void SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) +int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb) { - if (handle == NULL) { - pm_errno = PM_ERR_HANDLE_NULL; - return; - } + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->totaldlcb = cb; + return 0; } int SYMEXPORT alpm_option_set_root(const char *root) @@ -306,18 +314,18 @@ int SYMEXPORT alpm_option_set_root(const char *root) if(!root) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) { pm_errno = PM_ERR_NOT_A_DIR; - return(-1); + return -1; } realroot = calloc(PATH_MAX+1, sizeof(char)); if(!realpath(root, realroot)) { FREE(realroot); pm_errno = PM_ERR_NOT_A_DIR; - return(-1); + return -1; } /* verify root ends in a '/' */ @@ -333,7 +341,7 @@ int SYMEXPORT alpm_option_set_root(const char *root) handle->root[rootlen-1] = '/'; FREE(realroot); _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); - return(0); + return 0; } int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) @@ -347,11 +355,11 @@ int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!dbpath) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { pm_errno = PM_ERR_NOT_A_DIR; - return(-1); + return -1; } /* verify dbpath ends in a '/' */ dbpathlen = strlen(dbpath); @@ -373,7 +381,7 @@ int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) handle->lockfile = calloc(lockfilelen, sizeof(char)); snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); - return(0); + return 0; } int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) @@ -386,7 +394,7 @@ int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!cachedir) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } /* don't stat the cachedir yet, as it may not even be needed. we can * fail later if it is needed and the path is invalid. */ @@ -401,14 +409,15 @@ int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) newcachedir[cachedirlen-1] = '/'; handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir); _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); - return(0); + return 0; } -void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) +int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->cachedirs) FREELIST(handle->cachedirs); if(cachedirs) handle->cachedirs = cachedirs; + return 0; } int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir) @@ -429,9 +438,9 @@ int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir) FREE(newcachedir); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } int SYMEXPORT alpm_option_set_logfile(const char *logfile) @@ -443,7 +452,7 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile) ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(!logfile) { pm_errno = PM_ERR_WRONG_ARGS; - return(-1); + return -1; } handle->logfile = strdup(logfile); @@ -458,26 +467,47 @@ int SYMEXPORT alpm_option_set_logfile(const char *logfile) handle->logstream = NULL; } _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile); - return(0); + return 0; } -void SYMEXPORT alpm_option_set_usesyslog(int usesyslog) +int SYMEXPORT alpm_option_set_signaturedir(const char *signaturedir) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ALPM_LOG_FUNC; + + if(!signaturedir) { + pm_errno = PM_ERR_WRONG_ARGS; + return -1; + } + + if(handle->signaturedir) { + FREE(handle->signaturedir); + } + handle->signaturedir = strdup(signaturedir); + + _alpm_log(PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir); + return 0; +} + +int SYMEXPORT alpm_option_set_usesyslog(int usesyslog) +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->usesyslog = usesyslog; + return 0; } -void SYMEXPORT alpm_option_add_noupgrade(const char *pkg) +int SYMEXPORT alpm_option_add_noupgrade(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) +int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noupgrade) FREELIST(handle->noupgrade); if(noupgrade) handle->noupgrade = noupgrade; + return 0; } int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg) @@ -487,22 +517,24 @@ int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg) handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_noextract(const char *pkg) +int SYMEXPORT alpm_option_add_noextract(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->noextract = alpm_list_add(handle->noextract, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) +int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->noextract) FREELIST(handle->noextract); if(noextract) handle->noextract = noextract; + return 0; } int SYMEXPORT alpm_option_remove_noextract(const char *pkg) @@ -512,22 +544,24 @@ int SYMEXPORT alpm_option_remove_noextract(const char *pkg) handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) +int SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg)); + return 0; } -void SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) +int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignorepkg) FREELIST(handle->ignorepkg); if(ignorepkgs) handle->ignorepkg = ignorepkgs; + return 0; } int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg) @@ -537,22 +571,24 @@ int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg) handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_add_ignoregrp(const char *grp) +int SYMEXPORT alpm_option_add_ignoregrp(const char *grp) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp)); + return 0; } -void SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) +int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->ignoregrp) FREELIST(handle->ignoregrp); if(ignoregrps) handle->ignoregrp = ignoregrps; + return 0; } int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp) @@ -562,28 +598,45 @@ int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp) handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata); if(vdata != NULL) { FREE(vdata); - return(1); + return 1; } - return(0); + return 0; } -void SYMEXPORT alpm_option_set_arch(const char *arch) +int SYMEXPORT alpm_option_set_arch(const char *arch) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); if(handle->arch) FREE(handle->arch); if(arch) handle->arch = strdup(arch); + return 0; } -void SYMEXPORT alpm_option_set_usedelta(int usedelta) +int SYMEXPORT alpm_option_set_usedelta(int usedelta) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->usedelta = usedelta; + return 0; } -void SYMEXPORT alpm_option_set_checkspace(int checkspace) +int SYMEXPORT alpm_option_set_checkspace(int checkspace) { - ASSERT(handle != NULL, RET_ERR_VOID(PM_ERR_HANDLE_NULL)); + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); handle->checkspace = checkspace; + return 0; +} + +int SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level) +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1)); + handle->sigverify = level; + return 0; +} + +pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify() +{ + ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, PM_PGP_VERIFY_UNKNOWN)); + return handle->sigverify; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 2d962fe6..aa00b6f0 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -29,6 +29,10 @@ #include "alpm.h" #include "trans.h" +#ifdef HAVE_LIBCURL +#include <curl/curl.h> +#endif + typedef struct _pmhandle_t { /* internal usage */ pmdb_t *db_local; /* local db pointer */ @@ -37,6 +41,12 @@ typedef struct _pmhandle_t { FILE *lckstream; /* lock file stream pointer if one exists */ pmtrans_t *trans; +#ifdef HAVE_LIBCURL + /* libcurl handle */ + CURL *curl; /* reusable curl_easy handle */ + CURLcode curlerr; /* last error produced by curl */ +#endif + /* callback functions */ alpm_cb_log logcb; /* Log callback function */ alpm_cb_download dlcb; /* Download callback function */ @@ -48,6 +58,7 @@ typedef struct _pmhandle_t { char *dbpath; /* Base path to pacman's DBs */ char *logfile; /* Name of the log file */ char *lockfile; /* Name of the lock file */ + char *signaturedir; /* Directory where GnuPG files are stored */ alpm_list_t *cachedirs; /* Paths to pacman cache directories */ /* package lists */ @@ -57,10 +68,11 @@ typedef struct _pmhandle_t { alpm_list_t *ignoregrp; /* List of groups to ignore */ /* options */ - int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ - char *arch; /* Architecture of packages we should allow */ - int usedelta; /* Download deltas if possible */ - int checkspace; /* Check disk space before installing */ + int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */ + char *arch; /* Architecture of packages we should allow */ + int usedelta; /* Download deltas if possible */ + int checkspace; /* Check disk space before installing */ + pgp_verify_t sigverify; /* Default signature verification level */ } pmhandle_t; /* global handle variable */ diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c index 09c6fb84..9093af7b 100644 --- a/lib/libalpm/log.c +++ b/lib/libalpm/log.c @@ -22,10 +22,7 @@ #include <stdio.h> #include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> #include <errno.h> -#include <time.h> /* libalpm */ #include "log.h" @@ -64,7 +61,7 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...) } else { pm_errno = PM_ERR_SYSTEM; } - return(-1); + return -1; } } @@ -83,7 +80,7 @@ int SYMEXPORT alpm_logaction(const char *fmt, ...) * kpacman: "KPACMAN" * This would allow us to share the log file between several frontends * and know who does what */ - return(ret); + return ret; } /** @} */ diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index f2f15af4..8c927c11 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -23,13 +23,9 @@ #include "config.h" -#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> -#include <errno.h> #include <sys/types.h> -#include <sys/stat.h> /* libalpm */ #include "package.h" @@ -40,6 +36,7 @@ #include "delta.h" #include "handle.h" #include "deps.h" +#include "base64.h" /** \addtogroup alpm_packages Package Functions * @brief Functions to manipulate libalpm packages @@ -58,7 +55,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg) _alpm_pkg_free(pkg); } - return(0); + return 0; } /** Check the integrity (with md5) of a package from the sync cache. */ @@ -78,13 +75,13 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg)); if(retval == 0) { - return(0); - } else if (retval == 1) { + return 0; + } else if(retval == 1) { pm_errno = PM_ERR_PKG_INVALID; retval = -1; } - return(retval); + return retval; } /* Default package accessor functions. These will get overridden by any @@ -92,8 +89,6 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg) * a lazy-load cache. However, the defaults will work just fine for fully- * populated package structures. */ static const char *_pkg_get_filename(pmpkg_t *pkg) { return pkg->filename; } -static const char *_pkg_get_name(pmpkg_t *pkg) { return pkg->name; } -static const char *_pkg_get_version(pmpkg_t *pkg) { return pkg->version; } static const char *_pkg_get_desc(pmpkg_t *pkg) { return pkg->desc; } static const char *_pkg_get_url(pmpkg_t *pkg) { return pkg->url; } static time_t _pkg_get_builddate(pmpkg_t *pkg) { return pkg->builddate; } @@ -126,8 +121,6 @@ static int _pkg_changelog_close(const pmpkg_t *pkg, void *fp) { return EOF; } */ struct pkg_operations default_pkg_ops = { .get_filename = _pkg_get_filename, - .get_name = _pkg_get_name, - .get_version = _pkg_get_version, .get_desc = _pkg_get_desc, .get_url = _pkg_get_url, .get_builddate = _pkg_get_builddate, @@ -166,12 +159,12 @@ const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg) const char SYMEXPORT *alpm_pkg_get_name(pmpkg_t *pkg) { - return pkg->ops->get_name(pkg); + return pkg->name; } const char SYMEXPORT *alpm_pkg_get_version(pmpkg_t *pkg) { - return pkg->ops->get_version(pkg); + return pkg->version; } const char SYMEXPORT *alpm_pkg_get_desc(pmpkg_t *pkg) @@ -204,6 +197,43 @@ const char SYMEXPORT *alpm_pkg_get_md5sum(pmpkg_t *pkg) return pkg->ops->get_md5sum(pkg); } +static int decode_pgpsig(pmpkg_t *pkg) { + const int len = strlen(pkg->pgpsig.base64_data); + const unsigned char *usline = (const unsigned char *)pkg->pgpsig.base64_data; + int ret, destlen = 0; + /* get the necessary size for the buffer by passing 0 */ + ret = base64_decode(NULL, &destlen, usline, len); + /* alloc our memory and repeat the call to decode */ + MALLOC(pkg->pgpsig.data, (size_t)destlen, goto error); + ret = base64_decode(pkg->pgpsig.data, &destlen, usline, len); + pkg->pgpsig.len = destlen; + if(ret != 0) { + goto error; + } + + /* we no longer have a need for this */ + FREE(pkg->pgpsig.base64_data); + return 0; + +error: + FREE(pkg->pgpsig.data); + pkg->pgpsig.len = 0; + return 1; +} + +const pmpgpsig_t SYMEXPORT *alpm_pkg_get_pgpsig(pmpkg_t *pkg) +{ + ALPM_LOG_FUNC; + + /* Sanity checks */ + ASSERT(pkg != NULL, RET_ERR(PM_ERR_WRONG_ARGS, NULL)); + + if(pkg->pgpsig.data == NULL && pkg->pgpsig.base64_data != NULL) { + decode_pgpsig(pkg); + } + return &(pkg->pgpsig); +} + const char SYMEXPORT *alpm_pkg_get_arch(pmpkg_t *pkg) { return pkg->ops->get_arch(pkg); @@ -277,10 +307,10 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_backup(pmpkg_t *pkg) pmdb_t SYMEXPORT *alpm_pkg_get_db(pmpkg_t *pkg) { /* Sanity checks */ - ASSERT(pkg != NULL, return(NULL)); - ASSERT(pkg->origin != PKG_FROM_FILE, return(NULL)); + ASSERT(pkg != NULL, return NULL); + ASSERT(pkg->origin != PKG_FROM_FILE, return NULL); - return(pkg->origin_data.db); + return pkg->origin_data.db; } /** Open a package changelog for reading. */ @@ -356,7 +386,7 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg) reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp); } } - return(reqs); + return reqs; } /** @} */ @@ -369,7 +399,7 @@ pmpkg_t *_alpm_pkg_new(void) CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL)); - return(pkg); + return pkg; } pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) @@ -420,7 +450,7 @@ pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg) } newpkg->infolevel = pkg->infolevel; - return(newpkg); + return newpkg; } void _alpm_pkg_free(pmpkg_t *pkg) @@ -438,6 +468,8 @@ void _alpm_pkg_free(pmpkg_t *pkg) FREE(pkg->url); FREE(pkg->packager); FREE(pkg->md5sum); + FREE(pkg->pgpsig.base64_data); + FREE(pkg->pgpsig.data); FREE(pkg->arch); FREELIST(pkg->licenses); FREELIST(pkg->replaces); @@ -497,7 +529,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2) { pmpkg_t *pkg1 = (pmpkg_t *)p1; pmpkg_t *pkg2 = (pmpkg_t *)p2; - return(strcoll(pkg1->name, pkg2->name)); + return strcoll(pkg1->name, pkg2->name); } /* Test for existence of a package in a alpm_list_t* @@ -511,7 +543,7 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) ALPM_LOG_FUNC; if(needle == NULL || haystack == NULL) { - return(NULL); + return NULL; } needle_hash = _alpm_hash_sdbm(needle); @@ -527,11 +559,11 @@ pmpkg_t *_alpm_pkg_find(alpm_list_t *haystack, const char *needle) /* finally: we had hash match, verify string match */ if(strcmp(info->name, needle) == 0) { - return(info); + return info; } } } - return(NULL); + return NULL; } /** Test if a package should be ignored. @@ -549,18 +581,18 @@ int _alpm_pkg_should_ignore(pmpkg_t *pkg) /* first see if the package is ignored */ if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(pkg))) { - return(1); + return 1; } /* next see if the package is in a group that is ignored */ for(groups = handle->ignoregrp; groups; groups = alpm_list_next(groups)) { char *grp = (char *)alpm_list_getdata(groups); if(alpm_list_find_str(alpm_pkg_get_groups(pkg), grp)) { - return(1); + return 1; } } - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index b161d5f1..c84e2221 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -24,11 +24,14 @@ #ifndef _ALPM_PACKAGE_H #define _ALPM_PACKAGE_H +#include "config.h" /* ensure off_t is correct length */ + #include <sys/types.h> /* off_t */ #include <time.h> /* time_t */ #include "alpm.h" #include "db.h" +#include "signing.h" typedef enum _pmpkgfrom_t { PKG_FROM_FILE = 1, @@ -45,8 +48,6 @@ typedef enum _pmpkgfrom_t { */ struct pkg_operations { const char *(*get_filename) (pmpkg_t *); - const char *(*get_name) (pmpkg_t *); - const char *(*get_version) (pmpkg_t *); const char *(*get_desc) (pmpkg_t *); const char *(*get_url) (pmpkg_t *); time_t (*get_builddate) (pmpkg_t *); @@ -98,6 +99,8 @@ struct __pmpkg_t { char *md5sum; char *arch; + pmpgpsig_t pgpsig; + time_t builddate; time_t installdate; diff --git a/lib/libalpm/pkghash.c b/lib/libalpm/pkghash.c index 6dc43243..f4153300 100644 --- a/lib/libalpm/pkghash.c +++ b/lib/libalpm/pkghash.c @@ -72,13 +72,13 @@ pmpkghash_t *_alpm_pkghash_create(size_t size) if(hash->buckets < size) { _alpm_log(PM_LOG_ERROR, _("database larger than maximum size\n")); free(hash); - return(NULL); + return NULL; } - CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t*), \ + CALLOC(hash->hash_table, hash->buckets, sizeof(alpm_list_t *), \ free(hash); RET_ERR(PM_ERR_MEMORY, NULL)); - return(hash); + return hash; } static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash) @@ -92,7 +92,7 @@ static size_t get_hash_position(unsigned long name_hash, pmpkghash_t *hash) position = (position + 1) % hash->buckets; } - return(position); + return position; } /* Expand the hash table size to the next increment and rebin the entries */ @@ -123,7 +123,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash) newhash = _alpm_pkghash_create(newsize); if(newhash == NULL) { /* creation of newhash failed, stick with old one... */ - return(oldhash); + return oldhash; } newhash->list = oldhash->list; @@ -144,7 +144,7 @@ static pmpkghash_t *rehash(pmpkghash_t *oldhash) _alpm_pkghash_free(oldhash); - return(newhash); + return newhash; } static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) @@ -153,7 +153,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) size_t position; if(pkg == NULL || hash == NULL) { - return(hash); + return hash; } if((hash->entries + 1) / MAX_HASH_LOAD > hash->buckets) { @@ -164,7 +164,7 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) ptr = calloc(1, sizeof(alpm_list_t)); if(ptr == NULL) { - return(hash); + return hash; } ptr->data = pkg; @@ -179,17 +179,17 @@ static pmpkghash_t *pkghash_add_pkg(pmpkghash_t *hash, pmpkg_t *pkg, int sorted) } hash->entries += 1; - return(hash); + return hash; } pmpkghash_t *_alpm_pkghash_add(pmpkghash_t *hash, pmpkg_t *pkg) { - return(pkghash_add_pkg(hash, pkg, 0)); + return pkghash_add_pkg(hash, pkg, 0); } pmpkghash_t *_alpm_pkghash_add_sorted(pmpkghash_t *hash, pmpkg_t *pkg) { - return(pkghash_add_pkg(hash, pkg, 1)); + return pkghash_add_pkg(hash, pkg, 1); } static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end) @@ -217,7 +217,7 @@ static size_t move_one_entry(pmpkghash_t *hash, size_t start, size_t end) * e.g. (47 + 0 - 1) % 47 == 46 */ end = (hash->buckets + end - 1) % hash->buckets; } - return(end); + return end; } /** @@ -240,7 +240,7 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, } if(pkg == NULL || hash == NULL) { - return(hash); + return hash; } position = pkg->name_hash % hash->buckets; @@ -277,13 +277,13 @@ pmpkghash_t *_alpm_pkghash_remove(pmpkghash_t *hash, pmpkg_t *pkg, position = prev; } - return(hash); + return hash; } position = (position + 1) % hash->buckets; } - return(hash); + return hash; } void _alpm_pkghash_free(pmpkghash_t *hash) @@ -307,7 +307,7 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name) ALPM_LOG_FUNC; if(name == NULL || hash == NULL) { - return(NULL); + return NULL; } name_hash = _alpm_hash_sdbm(name); @@ -318,13 +318,13 @@ pmpkg_t *_alpm_pkghash_find(pmpkghash_t *hash, const char *name) pmpkg_t *info = lp->data; if(info->name_hash == name_hash && strcmp(info->name, name) == 0) { - return(info); + return info; } position = (position + 1) % hash->buckets; } - return(NULL); + return NULL; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index 7c8a99fb..cf416d52 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -26,8 +26,6 @@ #include <stdlib.h> #include <errno.h> -#include <time.h> -#include <fcntl.h> #include <string.h> #include <limits.h> #include <unistd.h> @@ -36,6 +34,7 @@ /* libalpm */ #include "remove.h" #include "alpm_list.h" +#include "alpm.h" #include "trans.h" #include "util.h" #include "log.h" @@ -44,7 +43,6 @@ #include "db.h" #include "deps.h" #include "handle.h" -#include "alpm.h" int SYMEXPORT alpm_remove_pkg(pmpkg_t *pkg) { @@ -61,15 +59,16 @@ int SYMEXPORT alpm_remove_pkg(pmpkg_t *pkg) ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); - pkgname = alpm_pkg_get_name(pkg); + pkgname = pkg->name; if(_alpm_pkg_find(trans->remove, pkgname)) { RET_ERR(PM_ERR_TRANS_DUP_TARGET, -1); } - _alpm_log(PM_LOG_DEBUG, "adding %s in the target list\n", pkgname); + _alpm_log(PM_LOG_DEBUG, "adding package %s to the transaction remove list\n", + pkgname); trans->remove = alpm_list_add(trans->remove, _alpm_pkg_dup(pkg)); - return(0); + return 0; } static void remove_prepare_cascade(pmtrans_t *trans, pmdb_t *db, @@ -160,7 +159,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) if(trans->flags & PM_TRANS_FLAG_CASCADE) { remove_prepare_cascade(trans, db, lp); - } else if (trans->flags & PM_TRANS_FLAG_UNNEEDED) { + } else if(trans->flags & PM_TRANS_FLAG_UNNEEDED) { /* Remove needed packages (which would break dependencies) * from target list */ remove_prepare_keep_needed(trans, db, lp); @@ -193,7 +192,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL); } - return(0); + return 0; } static int can_remove_file(const char *path, alpm_list_t *skip) @@ -204,7 +203,7 @@ static int can_remove_file(const char *path, alpm_list_t *skip) if(alpm_list_find_str(skip, file)) { /* return success because we will never actually remove this file */ - return(1); + return 1; } /* If we fail write permissions due to a read-only filesystem, abort. * Assume all other possible failures are covered somewhere else */ @@ -214,11 +213,11 @@ static int can_remove_file(const char *path, alpm_list_t *skip) * it - ignore "chmod -w" simple permission failures */ _alpm_log(PM_LOG_ERROR, _("cannot remove file '%s': %s\n"), file, strerror(errno)); - return(0); + return 0; } } - return(1); + return 1; } /* Helper function for iterating through a package's file and deleting them @@ -359,7 +358,7 @@ db: pkgname); } - return(0); + return 0; } int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) @@ -378,12 +377,12 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) for(targ = trans->remove; targ; targ = targ->next) { int position = 0; char scriptlet[PATH_MAX]; - info = (pmpkg_t*)targ->data; + info = (pmpkg_t *)targ->data; const char *pkgname = NULL; size_t targcount = alpm_list_count(targ); if(handle->trans->state == STATE_INTERRUPTED) { - return(0); + return 0; } /* get the name now so we can use it after package is removed */ @@ -465,7 +464,7 @@ int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db) /* run ldconfig if it exists */ _alpm_ldconfig(handle->root); - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c new file mode 100644 index 00000000..9d4fd076 --- /dev/null +++ b/lib/libalpm/signing.c @@ -0,0 +1,301 @@ +/* + * signing.c + * + * Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.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 <string.h> +#include <locale.h> /* setlocale() */ +#include <gpgme.h> + +/* libalpm */ +#include "signing.h" +#include "package.h" +#include "util.h" +#include "log.h" +#include "alpm.h" + +#define CHECK_ERR(void) do { \ + if(err != GPG_ERR_NO_ERROR) { goto error; } \ + } while(0) + +static int gpgme_init(void) +{ + static int init = 0; + const char *version; + gpgme_error_t err; + gpgme_engine_info_t enginfo; + + ALPM_LOG_FUNC; + + if(init) { + /* we already successfully initialized the library */ + return 0; + } + + if(!alpm_option_get_signaturedir()) { + RET_ERR(PM_ERR_SIG_MISSINGDIR, 1); + } + + /* calling gpgme_check_version() returns the current version and runs + * some internal library setup code */ + version = gpgme_check_version(NULL); + _alpm_log(PM_LOG_DEBUG, "GPGME version: %s\n", version); + gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL)); +#ifdef LC_MESSAGES + gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL)); +#endif + /* NOTE: + * The GPGME library installs a SIGPIPE signal handler automatically if + * the default signal hander is in use. The only time we set a handler + * for SIGPIPE is in dload.c, and we reset it when we are done. Given that + * we do this, we can let GPGME do its automagic. However, if we install + * a library-wide SIGPIPE handler, we will have to be careful. + */ + + /* check for OpenPGP support (should be a no-brainer, but be safe) */ + err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); + CHECK_ERR(); + + /* set and check engine information */ + err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, + alpm_option_get_signaturedir()); + CHECK_ERR(); + err = gpgme_get_engine_info(&enginfo); + CHECK_ERR(); + _alpm_log(PM_LOG_DEBUG, "GPGME engine info: file=%s, home=%s\n", + enginfo->file_name, enginfo->home_dir); + + init = 1; + return 0; + +error: + _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); + RET_ERR(PM_ERR_GPGME, 1); +} + +/** + * Check the PGP package signature for the given file. + * @param path the full path to a file + * @param sig PGP signature data in raw form (already decoded) + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occured) + */ +int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig) +{ + int ret = 0; + gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_data_t filedata, sigdata; + gpgme_verify_result_t result; + gpgme_signature_t gpgsig; + FILE *file = NULL, *sigfile = NULL; + + ALPM_LOG_FUNC; + + if(!sig || !sig->data) { + RET_ERR(PM_ERR_SIG_UNKNOWN, -1); + } + if(!path || access(path, R_OK) != 0) { + RET_ERR(PM_ERR_NOT_A_FILE, -1); + } + if(gpgme_init()) { + /* pm_errno was set in gpgme_init() */ + return -1; + } + + _alpm_log(PM_LOG_DEBUG, "checking signature for %s\n", path); + + memset(&ctx, 0, sizeof(ctx)); + memset(&sigdata, 0, sizeof(sigdata)); + memset(&filedata, 0, sizeof(filedata)); + + err = gpgme_new(&ctx); + CHECK_ERR(); + + /* create our necessary data objects to verify the signature */ + file = fopen(path, "rb"); + if(file == NULL) { + pm_errno = PM_ERR_NOT_A_FILE; + ret = -1; + goto error; + } + err = gpgme_data_new_from_stream(&filedata, file); + CHECK_ERR(); + + /* next create data object for the signature */ + err = gpgme_data_new_from_mem(&sigdata, (char *)sig->data, sig->len, 0); + CHECK_ERR(); + + /* here's where the magic happens */ + err = gpgme_op_verify(ctx, sigdata, filedata, NULL); + CHECK_ERR(); + result = gpgme_op_verify_result(ctx); + gpgsig = result->signatures; + if(!gpgsig || gpgsig->next) { + _alpm_log(PM_LOG_ERROR, _("Unexpected number of signatures\n")); + ret = -1; + goto error; + } + _alpm_log(PM_LOG_DEBUG, "summary=%x\n", gpgsig->summary); + _alpm_log(PM_LOG_DEBUG, "fpr=%s\n", gpgsig->fpr); + _alpm_log(PM_LOG_DEBUG, "status=%d\n", gpgsig->status); + _alpm_log(PM_LOG_DEBUG, "timestamp=%lu\n", gpgsig->timestamp); + _alpm_log(PM_LOG_DEBUG, "wrong_key_usage=%u\n", gpgsig->wrong_key_usage); + _alpm_log(PM_LOG_DEBUG, "pka_trust=%u\n", gpgsig->pka_trust); + _alpm_log(PM_LOG_DEBUG, "chain_model=%u\n", gpgsig->chain_model); + _alpm_log(PM_LOG_DEBUG, "validity=%d\n", gpgsig->validity); + _alpm_log(PM_LOG_DEBUG, "validity_reason=%d\n", gpgsig->validity_reason); + _alpm_log(PM_LOG_DEBUG, "key=%d\n", gpgsig->pubkey_algo); + _alpm_log(PM_LOG_DEBUG, "hash=%d\n", gpgsig->hash_algo); + + if(gpgsig->summary & GPGME_SIGSUM_VALID) { + /* good signature, continue */ + _alpm_log(PM_LOG_DEBUG, _("File %s has a valid signature.\n"), + path); + } else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { + /* 'green' signature, not sure what to do here */ + _alpm_log(PM_LOG_WARNING, _("File %s has a green signature.\n"), + path); + } else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { + pm_errno = PM_ERR_SIG_UNKNOWN; + _alpm_log(PM_LOG_WARNING, _("File %s has a signature from an unknown key.\n"), + path); + ret = -1; + } else { + /* we'll capture everything else here */ + pm_errno = PM_ERR_SIG_INVALID; + _alpm_log(PM_LOG_ERROR, _("File %s has an invalid signature.\n"), + path); + ret = 1; + } + +error: + gpgme_data_release(sigdata); + gpgme_data_release(filedata); + gpgme_release(ctx); + if(sigfile) { + fclose(sigfile); + } + if(file) { + fclose(file); + } + if(err != GPG_ERR_NO_ERROR) { + _alpm_log(PM_LOG_ERROR, _("GPGME error: %s\n"), gpgme_strerror(err)); + RET_ERR(PM_ERR_GPGME, -1); + } + return ret; +} + +/** + * Load the signature from the given path into the provided struct. + * @param sigfile the signature to attempt to load + * @param pgpsig the struct to place the data in + * + * @return 0 on success, 1 on file not found, -1 on error + */ +int _alpm_load_signature(const char *file, pmpgpsig_t *pgpsig) { + struct stat st; + char *sigfile; + int ret = -1; + + /* look around for a PGP signature file; load if available */ + MALLOC(sigfile, strlen(file) + 5, RET_ERR(PM_ERR_MEMORY, -1)); + sprintf(sigfile, "%s.sig", file); + + if(access(sigfile, R_OK) == 0 && stat(sigfile, &st) == 0) { + FILE *f; + size_t bytes_read; + + if(st.st_size > 4096 || (f = fopen(sigfile, "rb")) == NULL) { + free(sigfile); + return ret; + } + CALLOC(pgpsig->data, st.st_size, sizeof(unsigned char), + RET_ERR(PM_ERR_MEMORY, -1)); + bytes_read = fread(pgpsig->data, sizeof(char), st.st_size, f); + if(bytes_read == (size_t)st.st_size) { + pgpsig->len = bytes_read; + _alpm_log(PM_LOG_DEBUG, "loaded gpg signature file, location %s\n", + sigfile); + ret = 0; + } else { + _alpm_log(PM_LOG_WARNING, _("Failed reading PGP signature file %s"), + sigfile); + FREE(pgpsig->data); + } + + fclose(f); + } else { + _alpm_log(PM_LOG_DEBUG, "signature file %s not found\n", sigfile); + /* not fatal...we return a different error code here */ + ret = 1; + } + + free(sigfile); + return ret; +} + +/** + * Determines the necessity of checking for a valid PGP signature + * @param db the sync database to query + * + * @return signature verification level + */ +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db) +{ + ALPM_LOG_FUNC; + ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, PM_PGP_VERIFY_UNKNOWN)); + + if(db->pgp_verify != PM_PGP_VERIFY_UNKNOWN) { + return db->pgp_verify; + } else { + return alpm_option_get_default_sigverify(); + } +} + +/** + * Check the PGP package signature for the given package file. + * @param pkg the package to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_pkg_check_pgp_signature(pmpkg_t *pkg) +{ + ALPM_LOG_FUNC; + ASSERT(pkg != NULL, return 0); + + return _alpm_gpgme_checksig(alpm_pkg_get_filename(pkg), + alpm_pkg_get_pgpsig(pkg)); +} + +/** + * Check the PGP package signature for the given database. + * @param db the database to check + * @return a int value : 0 (valid), 1 (invalid), -1 (an error occurred) + */ +int SYMEXPORT alpm_db_check_pgp_signature(pmdb_t *db) +{ + ALPM_LOG_FUNC; + ASSERT(db != NULL, return 0); + + return _alpm_gpgme_checksig(_alpm_db_path(db), + _alpm_db_pgpsig(db)); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/signing.h b/lib/libalpm/signing.h new file mode 100644 index 00000000..a378fa50 --- /dev/null +++ b/lib/libalpm/signing.h @@ -0,0 +1,40 @@ +/* + * signing.h + * + * Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.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_SIGNING_H +#define _ALPM_SIGNING_H + +#include "alpm.h" + +struct __pmpgpsig_t { + /* we will either store the encoded data or the raw data- + * this way we can decode on an as-needed basis since most + * operations won't require the overhead of base64 decodes + * on all packages in a sync repository. */ + char *base64_data; + unsigned char *data; + size_t len; +}; + +int _alpm_gpgme_checksig(const char *path, const pmpgpsig_t *sig); +int _alpm_load_signature(const char *sigfile, pmpgpsig_t *pgpsig); +pgp_verify_t _alpm_db_get_sigverify_level(pmdb_t *db); + +#endif /* _ALPM_SIGNING_H */ + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index f83b0ef9..63ea2b2d 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -26,11 +26,9 @@ #include <sys/types.h> /* off_t */ #include <stdlib.h> #include <stdio.h> -#include <fcntl.h> #include <string.h> #include <stdint.h> /* intmax_t */ #include <unistd.h> -#include <time.h> #include <limits.h> /* libalpm */ @@ -50,13 +48,14 @@ #include "delta.h" #include "remove.h" #include "diskspace.h" +#include "signing.h" /** 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) { - ASSERT(pkg != NULL, return(NULL)); + ASSERT(pkg != NULL, return NULL); alpm_list_t *i; pmpkg_t *spkg = NULL; @@ -68,7 +67,7 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync) if(spkg == NULL) { _alpm_log(PM_LOG_DEBUG, "'%s' not found in sync db => no upgrade\n", alpm_pkg_get_name(pkg)); - return(NULL); + return NULL; } /* compare versions and see if spkg is an upgrade */ @@ -76,15 +75,13 @@ pmpkg_t SYMEXPORT *alpm_sync_newversion(pmpkg_t *pkg, alpm_list_t *dbs_sync) _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); + return spkg; } /* spkg is not an upgrade */ - return(NULL); + return NULL; } -/** Search for packages to upgrade and add them to the transaction. - * @return 0 on success, -1 on error (pm_errno is set accordingly) - */ +/** Search for packages to upgrade and add them to the transaction. */ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) { alpm_list_t *i, *j, *k; @@ -116,7 +113,8 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) pmdb_t *sdb = j->data; /* Check sdb */ pmpkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name); - if(spkg) { /* 1. literal was found in sdb */ + if(spkg) { + /* 1. literal was found in sdb */ int cmp = _alpm_pkg_compare_versions(spkg, lpkg); if(cmp > 0) { _alpm_log(PM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n", @@ -146,8 +144,10 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) lpkg->name, lpkg->version, sdb->treename, spkg->version); } } - break; /* jump to next local package */ - } else { /* 2. search for replacers in sdb */ + /* jump to next local package */ + break; + } else { + /* 2. search for replacers in sdb */ int found = 0; for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) { spkg = k->data; @@ -183,7 +183,8 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) if(alpm_pkg_get_reason(lpkg) == PM_PKG_REASON_EXPLICIT) { tpkg->reason = PM_PKG_REASON_EXPLICIT; } - } else { /* add spkg to the target list */ + } else { + /* add spkg to the target list */ /* copy over reason */ spkg->reason = alpm_pkg_get_reason(lpkg); spkg->removes = alpm_list_add(NULL, lpkg); @@ -200,7 +201,7 @@ int SYMEXPORT alpm_sync_sysupgrade(int enable_downgrade) } } - return(0); + return 0; } /** Find group members across a list of databases. @@ -242,7 +243,7 @@ alpm_list_t SYMEXPORT *alpm_find_grp_pkgs(alpm_list_t *dbs, } } alpm_list_free(ignorelist); - return(pkgs); + return pkgs; } /** Compute the size of the files that will be downloaded to install a @@ -258,7 +259,7 @@ static int compute_download_size(pmpkg_t *newpkg) if(newpkg->origin != PKG_FROM_SYNCDB) { newpkg->infolevel |= INFRQ_DSIZE; newpkg->download_size = 0; - return(0); + return 0; } fname = alpm_pkg_get_filename(newpkg); @@ -295,7 +296,7 @@ static int compute_download_size(pmpkg_t *newpkg) newpkg->infolevel |= INFRQ_DSIZE; newpkg->download_size = size; - return(0); + return 0; } int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data) @@ -355,7 +356,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync int remove_unresolvable = 0; QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); - if (remove_unresolvable) { + if(remove_unresolvable) { /* User wants to remove the unresolvable packages from the transaction. The packages will be removed from the actual transaction when the transaction packages are replaced with a @@ -551,7 +552,7 @@ cleanup: alpm_list_free(unresolvable); alpm_list_free(remove); - return(ret); + return ret; } /** Returns the size of the files that will be downloaded to install a @@ -564,13 +565,13 @@ off_t SYMEXPORT alpm_pkg_download_size(pmpkg_t *newpkg) if(!(newpkg->infolevel & INFRQ_DSIZE)) { compute_download_size(newpkg); } - return(newpkg->download_size); + return newpkg->download_size; } static int endswith(const char *filename, const char *extension) { const char *s = filename + strlen(filename) - strlen(extension); - return(strcmp(s, extension) == 0); + return strcmp(s, extension) == 0; } /** Applies delta files to create an upgraded package file. @@ -656,7 +657,7 @@ static int apply_deltas(pmtrans_t *trans) } } - return(ret); + return ret; } /** Compares the md5sum of a file to the expected value. @@ -665,33 +666,25 @@ static int apply_deltas(pmtrans_t *trans) * should be deleted. * * @param trans the transaction - * @param filename the filename of the file to test + * @param filename the absolute path of the file to test * @param md5sum the expected md5sum of the file * * @return 0 if the md5sum matched, 1 if not, -1 in case of errors */ -static int test_md5sum(pmtrans_t *trans, const char *filename, +static int test_md5sum(pmtrans_t *trans, const char *filepath, const char *md5sum) { - char *filepath; - int ret; - - filepath = _alpm_filecache_find(filename); - - ret = _alpm_test_md5sum(filepath, md5sum); - + int ret = _alpm_test_md5sum(filepath, md5sum); if(ret == 1) { int doremove = 0; - QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filename, + QUESTION(trans, PM_TRANS_CONV_CORRUPTED_PKG, (char *)filepath, NULL, NULL, &doremove); if(doremove) { unlink(filepath); } } - FREE(filepath); - - return(ret); + return ret; } int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) @@ -767,7 +760,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_RETRIEVE_START, current->treename, NULL); errors = _alpm_download_files(files, current->servers, cachedir); - if (errors) { + if(errors) { _alpm_log(PM_LOG_WARNING, _("failed to retrieve some files from %s\n"), current->treename); if(pm_errno == 0) { @@ -800,12 +793,14 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) for(i = deltas; i; i = i->next) { pmdelta_t *d = alpm_list_getdata(i); const char *filename = alpm_delta_get_filename(d); + char *filepath = _alpm_filecache_find(filename); const char *md5sum = alpm_delta_get_md5sum(d); - if(test_md5sum(trans, filename, md5sum) != 0) { + if(test_md5sum(trans, filepath, md5sum) != 0) { errors++; *data = alpm_list_add(*data, strdup(filename)); } + FREE(filepath); } if(errors) { pm_errno = PM_ERR_DLT_INVALID; @@ -829,6 +824,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) EVENT(trans, PM_TRANS_EVT_INTEGRITY_START, NULL, NULL); errors = 0; + for(i = trans->add; i; i = i->next, current++) { pmpkg_t *spkg = i->data; int percent = (current * 100) / numtargs; @@ -839,17 +835,36 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) numtargs, current); const char *filename = alpm_pkg_get_filename(spkg); + char *filepath = _alpm_filecache_find(filename); const char *md5sum = alpm_pkg_get_md5sum(spkg); + const pmpgpsig_t *pgpsig = alpm_pkg_get_pgpsig(spkg); + pgp_verify_t check_sig; - if(test_md5sum(trans, filename, md5sum) != 0) { + /* check md5sum first */ + if(test_md5sum(trans, filepath, md5sum) != 0) { errors++; *data = alpm_list_add(*data, strdup(filename)); + FREE(filepath); continue; } + /* check PGP signature next */ + pmdb_t *sdb = alpm_pkg_get_db(spkg); + + check_sig = _alpm_db_get_sigverify_level(sdb); + + if(check_sig != PM_PGP_VERIFY_NEVER) { + int ret = _alpm_gpgme_checksig(filepath, pgpsig); + if((check_sig == PM_PGP_VERIFY_ALWAYS && ret != 0) || + (check_sig == PM_PGP_VERIFY_OPTIONAL && ret == 1)) { + errors++; + *data = alpm_list_add(*data, strdup(filename)); + FREE(filepath); + continue; + } + } /* load the package file and replace pkgcache entry with it in the target list */ /* TODO: alpm_pkg_get_db() will not work on this target anymore */ _alpm_log(PM_LOG_DEBUG, "replacing pkgcache entry with package file for target %s\n", spkg->name); - char *filepath = _alpm_filecache_find(filename); pmpkg_t *pkgfile; if(alpm_pkg_load(filepath, 1, &pkgfile) != 0) { _alpm_pkg_free(pkgfile); @@ -863,9 +878,12 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) i->data = pkgfile; _alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */ } + PROGRESS(trans, PM_TRANS_PROGRESS_INTEGRITY_START, "", 100, numtargs, current); EVENT(trans, PM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL); + + if(errors) { pm_errno = PM_ERR_PKG_INVALID; goto error; @@ -935,7 +953,7 @@ int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data) error: FREELIST(files); alpm_list_free(deltas); - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index c5af7c69..6e32054d 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -28,8 +28,6 @@ #include <string.h> #include <unistd.h> #include <sys/types.h> -#include <sys/stat.h> -#include <sys/statvfs.h> #include <errno.h> #include <limits.h> #include <fcntl.h> @@ -41,11 +39,9 @@ #include "util.h" #include "log.h" #include "handle.h" -#include "add.h" #include "remove.h" #include "sync.h" #include "alpm.h" -#include "deps.h" /** \addtogroup alpm_trans Transaction Functions * @brief Functions to manipulate libalpm transactions @@ -66,22 +62,22 @@ static int make_lock(pmhandle_t *handle) } if(_alpm_makepath(dir)) { FREE(dir); - return(-1); + return -1; } FREE(dir); do { fd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL, 0000); - } while (fd == -1 && errno == EINTR); + } while(fd == -1 && errno == EINTR); if(fd > 0) { FILE *f = fdopen(fd, "w"); fprintf(f, "%ld\n", (long)getpid()); fflush(f); fsync(fd); handle->lckstream = f; - return(0); + return 0; } - return(-1); + return -1; } /* Remove a lock file */ @@ -92,9 +88,9 @@ static int remove_lock(pmhandle_t *handle) handle->lckstream = NULL; } if(unlink(handle->lockfile) == -1 && errno != ENOENT) { - return(-1); + return -1; } - return(0); + return 0; } /** Initialize the transaction. */ @@ -142,7 +138,7 @@ int SYMEXPORT alpm_trans_init(pmtransflag_t flags, handle->trans = trans; - return(0); + return 0; } static alpm_list_t *check_arch(alpm_list_t *pkgs) @@ -152,7 +148,7 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs) const char *arch = alpm_option_get_arch(); if(!arch) { - return(NULL); + return NULL; } for(i = pkgs; i; i = i->next) { pmpkg_t *pkg = i->data; @@ -167,7 +163,7 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs) invalid = alpm_list_add(invalid, string); } } - return(invalid); + return invalid; } /** Prepare a transaction. */ @@ -188,7 +184,7 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) /* If there's nothing to do, return without complaining */ if(trans->add == NULL && trans->remove == NULL) { - return(0); + return 0; } alpm_list_t *invalid = check_arch(trans->add); @@ -202,18 +198,18 @@ int SYMEXPORT alpm_trans_prepare(alpm_list_t **data) if(trans->add == NULL) { if(_alpm_remove_prepare(trans, handle->db_local, data) == -1) { /* pm_errno is set by _alpm_remove_prepare() */ - return(-1); + return -1; } } else { if(_alpm_sync_prepare(trans, handle->db_local, handle->dbs_sync, data) == -1) { /* pm_errno is set by _alpm_sync_prepare() */ - return(-1); + return -1; } } trans->state = STATE_PREPARED; - return(0); + return 0; } /** Commit a transaction. */ @@ -235,7 +231,7 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) /* If there's nothing to do, return without complaining */ if(trans->add == NULL && trans->remove == NULL) { - return(0); + return 0; } trans->state = STATE_COMMITING; @@ -243,18 +239,18 @@ int SYMEXPORT alpm_trans_commit(alpm_list_t **data) if(trans->add == NULL) { if(_alpm_remove_packages(trans, handle->db_local) == -1) { /* pm_errno is set by _alpm_remove_commit() */ - return(-1); + return -1; } } else { if(_alpm_sync_commit(trans, handle->db_local, data) == -1) { /* pm_errno is set by _alpm_sync_commit() */ - return(-1); + return -1; } } trans->state = STATE_COMMITED; - return(0); + return 0; } /** Interrupt a transaction. */ @@ -274,7 +270,7 @@ int SYMEXPORT alpm_trans_interrupt(void) trans->state = STATE_INTERRUPTED; - return(0); + return 0; } /** Release a transaction. */ @@ -306,7 +302,7 @@ int SYMEXPORT alpm_trans_release(void) } } - return(0); + return 0; } /** @} */ @@ -320,7 +316,7 @@ pmtrans_t *_alpm_trans_new(void) CALLOC(trans, 1, sizeof(pmtrans_t), RET_ERR(PM_ERR_MEMORY, NULL)); trans->state = STATE_IDLE; - return(trans); + return trans; } void _alpm_trans_free(pmtrans_t *trans) @@ -349,7 +345,7 @@ static int grep(const char *fn, const char *needle) FILE *fp; if((fp = fopen(fn, "r")) == NULL) { - return(0); + return 0; } while(!feof(fp)) { char line[1024]; @@ -360,11 +356,11 @@ static int grep(const char *fn, const char *needle) * ends up being split across line reads */ if(strstr(line, needle)) { fclose(fp); - return(1); + return 1; } } fclose(fp); - return(0); + return 0; } int _alpm_runscriptlet(const char *root, const char *installfn, @@ -384,7 +380,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, if(access(installfn, R_OK)) { /* not found */ _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found\n", installfn); - return(0); + return 0; } /* creates a directory in $root/tmp/ for copying/extracting the scriptlet */ @@ -395,7 +391,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); if(mkdtemp(tmpdir) == NULL) { _alpm_log(PM_LOG_ERROR, _("could not create temp directory\n")); - return(1); + return 1; } else { clean_tmpdir = 1; } @@ -441,7 +437,7 @@ cleanup: _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir); } - return(retval); + return retval; } int SYMEXPORT alpm_trans_get_flags() @@ -456,8 +452,8 @@ int SYMEXPORT alpm_trans_get_flags() alpm_list_t SYMEXPORT * alpm_trans_get_add() { /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(handle->trans != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(handle->trans != NULL, return NULL); return handle->trans->add; } @@ -465,8 +461,8 @@ alpm_list_t SYMEXPORT * alpm_trans_get_add() alpm_list_t SYMEXPORT * alpm_trans_get_remove() { /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(handle->trans != NULL, return(NULL)); + ASSERT(handle != NULL, return NULL); + ASSERT(handle->trans != NULL, return NULL); return handle->trans->remove; } diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 430da92a..99dd3bea 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -53,7 +53,6 @@ /* libalpm */ #include "util.h" #include "log.h" -#include "package.h" #include "alpm.h" #include "alpm_list.h" #include "handle.h" @@ -65,14 +64,14 @@ char* strsep(char** str, const char* delims) { char* token; - if (*str==NULL) { + if(*str==NULL) { /* No more tokens */ return NULL; } token=*str; - while (**str!='\0') { - if (strchr(delims,**str)!=NULL) { + while(**str!='\0') { + if(strchr(delims,**str)!=NULL) { **str='\0'; (*str)++; return token; @@ -87,7 +86,7 @@ char* strsep(char** str, const char* delims) int _alpm_makepath(const char *path) { - return(_alpm_makepath_mode(path, 0755)); + return _alpm_makepath_mode(path, 0755); } /* does the same thing as 'mkdir -p' */ @@ -123,7 +122,7 @@ int _alpm_makepath_mode(const char *path, mode_t mode) free(orig); free(incr); umask(oldmask); - return(ret); + return ret; } #define CPBUFSIZE 8 * 1024 @@ -137,12 +136,12 @@ int _alpm_copyfile(const char *src, const char *dest) in = fopen(src, "rb"); if(in == NULL) { - return(1); + return 1; } out = fopen(dest, "wb"); if(out == NULL) { fclose(in); - return(1); + return 1; } CALLOC(buf, (size_t)CPBUFSIZE, (size_t)1, ret = 1; goto cleanup;); @@ -175,7 +174,7 @@ cleanup: fclose(in); fclose(out); FREE(buf); - return(ret); + return ret; } /* Trim whitespace and newlines from a string @@ -186,7 +185,7 @@ char *_alpm_strtrim(char *str) if(*str == '\0') { /* string is empty, so we're done. */ - return(str); + return str; } while(isspace((unsigned char)*pch)) { @@ -198,7 +197,7 @@ char *_alpm_strtrim(char *str) /* check if there wasn't anything but whitespace in the string. */ if(*str == '\0') { - return(str); + return str; } pch = (str + (strlen(str) - 1)); @@ -207,7 +206,7 @@ char *_alpm_strtrim(char *str) } *++pch = '\0'; - return(str); + return str; } /* Compression functions */ @@ -225,12 +224,12 @@ int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn) alpm_list_t *list = NULL; int ret = 0; if(fn == NULL) { - return(1); + return 1; } list = alpm_list_add(list, (void *)fn); ret = _alpm_unpack(archive, prefix, list, 1); alpm_list_free(list); - return(ret); + return ret; } /** @@ -307,7 +306,7 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int char *found = alpm_list_find_str(list, prefix); free(prefix); if(!found) { - if (archive_read_data_skip(_archive) != ARCHIVE_OK) { + if(archive_read_data_skip(_archive) != ARCHIVE_OK) { ret = 1; goto cleanup; } @@ -341,7 +340,7 @@ cleanup: if(restore_cwd && chdir(cwd) != 0) { _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } - return(ret); + return ret; } /* does the same thing as 'rm -rf' */ @@ -356,18 +355,18 @@ int _alpm_rmrf(const char *path) if(_alpm_lstat(path, &st) == 0) { if(!S_ISDIR(st.st_mode)) { if(!unlink(path)) { - return(0); + return 0; } else { if(errno == ENOENT) { - return(0); + return 0; } else { - return(1); + return 1; } } } else { dirp = opendir(path); if(!dirp) { - return(1); + return 1; } for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if(dp->d_ino) { @@ -382,9 +381,9 @@ int _alpm_rmrf(const char *path) errflag++; } } - return(errflag); + return errflag; } - return(0); + return 0; } int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) @@ -415,7 +414,7 @@ int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) fflush(f); } - return(ret); + return ret; } int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) @@ -532,7 +531,7 @@ cleanup: _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } - return(retval); + return retval; } int _alpm_ldconfig(const char *root) @@ -550,14 +549,14 @@ int _alpm_ldconfig(const char *root) } } - return(0); + return 0; } /* Helper function for comparing strings using the * alpm "compare func" signature */ int _alpm_str_cmp(const void *s1, const void *s2) { - return(strcmp(s1, s2)); + return strcmp(s1, s2); } /** Find a filename in a registered alpm cachedir. @@ -573,12 +572,12 @@ char *_alpm_filecache_find(const char* filename) /* Loop through the cache dirs until we find a matching file */ for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { - snprintf(path, PATH_MAX, "%s%s", (char*)alpm_list_getdata(i), + snprintf(path, PATH_MAX, "%s%s", (char *)alpm_list_getdata(i), filename); if(stat(path, &buf) == 0 && S_ISREG(buf.st_mode)) { retpath = strdup(path); _alpm_log(PM_LOG_DEBUG, "found cached pkg: %s\n", retpath); - return(retpath); + return retpath; } } /* package wasn't found in any cachedir */ @@ -604,11 +603,11 @@ const char *_alpm_filecache_setup(void) cachedir); if(_alpm_makepath(cachedir) == 0) { _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); - return(cachedir); + return cachedir; } } else if(S_ISDIR(buf.st_mode) && (buf.st_mode & S_IWUSR)) { _alpm_log(PM_LOG_DEBUG, "using cachedir: %s\n", cachedir); - return(cachedir); + return cachedir; } } @@ -617,7 +616,7 @@ const char *_alpm_filecache_setup(void) alpm_option_set_cachedirs(tmp); _alpm_log(PM_LOG_DEBUG, "using cachedir: %s", "/tmp/\n"); _alpm_log(PM_LOG_WARNING, _("couldn't create package cache, using /tmp instead\n")); - return(alpm_list_getdata(tmp)); + return alpm_list_getdata(tmp); } /** lstat wrapper that treats /path/dirsymlink/ the same as /path/dirsymlink. @@ -641,7 +640,7 @@ int _alpm_lstat(const char *path, struct stat *buf) ret = lstat(newpath, buf); FREE(newpath); - return(ret); + return ret; } #ifdef HAVE_LIBSSL @@ -652,11 +651,11 @@ static int md5_file(const char *path, unsigned char output[16]) MD5_CTX ctx; unsigned char *buf; - CALLOC(buf, 8192, sizeof(unsigned char), return(1)); + CALLOC(buf, 8192, sizeof(unsigned char), RET_ERR(PM_ERR_MEMORY, 1)); if((f = fopen(path, "rb")) == NULL) { free(buf); - return(1); + return 1; } MD5_Init(&ctx); @@ -672,11 +671,11 @@ static int md5_file(const char *path, unsigned char output[16]) if(ferror(f) != 0) { fclose(f); - return(2); + return 2; } fclose(f); - return(0); + return 0; } #endif @@ -693,14 +692,14 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename) ALPM_LOG_FUNC; - ASSERT(filename != NULL, return(NULL)); + ASSERT(filename != NULL, return NULL); /* allocate 32 chars plus 1 for null */ md5sum = calloc(33, sizeof(char)); /* defined above for OpenSSL, otherwise defined in md5.h */ ret = md5_file(filename, output); - if (ret > 0) { + if(ret > 0) { RET_ERR(PM_ERR_NOT_A_FILE, NULL); } @@ -712,7 +711,7 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename) md5sum[32] = '\0'; _alpm_log(PM_LOG_DEBUG, "md5(%s) = %s\n", filename, md5sum); - return(md5sum); + return md5sum; } int _alpm_test_md5sum(const char *filepath, const char *md5sum) @@ -731,7 +730,7 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum) } FREE(md5sum2); - return(ret); + return ret; } /* Note: does NOT handle sparse files on purpose for speed. */ @@ -753,7 +752,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) } /* zero-copy - this is the entire next block of data. */ - b->ret = archive_read_data_block(a, (void*)&b->block, + b->ret = archive_read_data_block(a, (void *)&b->block, &b->block_size, &offset); b->block_offset = b->block; @@ -804,7 +803,7 @@ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) b->line_offset[len] = '\0'; b->block_offset = ++i; /* this is the main return point; from here you can read b->line */ - return(ARCHIVE_OK); + return ARCHIVE_OK; } else { /* we've looked through the whole block but no newline, copy it */ size_t len = (size_t)(b->block + b->block_size - b->block_offset); @@ -819,7 +818,7 @@ cleanup: int ret = b->ret; FREE(b->line); memset(b, 0, sizeof(b)); - return(ret); + return ret; } } @@ -833,12 +832,12 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) const char *version, *end; if(target == NULL || pkg == NULL) { - return(-1); + return -1; } end = target + strlen(target); /* remove any trailing '/' */ - while (*(end - 1) == '/') { + while(*(end - 1) == '/') { --end; } @@ -847,7 +846,7 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) for(version = end - 1; *version && *version != '-'; version--); for(version = version - 1; *version && *version != '-'; version--); if(*version != '-' || version == target) { - return(-1); + return -1; } /* copy into fields and return */ @@ -865,7 +864,7 @@ int _alpm_splitname(const char *target, pmpkg_t *pkg) STRNDUP(pkg->name, target, version - target, RET_ERR(PM_ERR_MEMORY, -1)); pkg->name_hash = _alpm_hash_sdbm(pkg->name); - return(0); + return 0; } /** @@ -880,13 +879,13 @@ unsigned long _alpm_hash_sdbm(const char *str) int c; if(!str) { - return(hash); + return hash; } while((c = *str++)) { hash = c + (hash << 6) + (hash << 16) - hash; } - return(hash); + return hash; } long _alpm_parsedate(const char *line) @@ -897,9 +896,9 @@ long _alpm_parsedate(const char *line) setlocale(LC_TIME, "C"); strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm); setlocale(LC_TIME, ""); - return(mktime(&tmp_tm)); + return mktime(&tmp_tm); } - return(atol(line)); + return atol(line); } #ifndef HAVE_STRNDUP @@ -908,7 +907,7 @@ static size_t strnlen(const char *s, size_t max) { register const char *p; for(p = s; *p && max--; ++p); - return(p - s); + return (p - s); } char *strndup(const char *s, size_t n) @@ -916,11 +915,11 @@ char *strndup(const char *s, size_t n) size_t len = strnlen(s, n); char *new = (char *) malloc(len + 1); - if (new == NULL) + if(new == NULL) return NULL; new[len] = '\0'; - return (char *) memcpy(new, s, len); + return (char *)memcpy(new, s, len); } #endif diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index c66e9881..eb1cad36 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -36,6 +36,8 @@ #include <time.h> #include <sys/stat.h> /* struct stat */ #include <archive.h> /* struct archive */ +#include <math.h> /* fabs */ +#include <float.h> /* DBL_EPSILON */ #ifdef ENABLE_NLS #include <libintl.h> /* here so it doesn't need to be included elsewhere */ @@ -63,7 +65,9 @@ #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) + return (ret); } while(0) + +#define DOUBLE_EQ(x, y) (fabs((x) - (y)) < DBL_EPSILON) /** * Used as a buffer/state holder for _alpm_archive_fgets(). diff --git a/lib/libalpm/version.c b/lib/libalpm/version.c index eba66210..9f3a9b71 100644 --- a/lib/libalpm/version.c +++ b/lib/libalpm/version.c @@ -93,7 +93,7 @@ static int rpmvercmp(const char *a, const char *b) int ret = 0; /* easy comparison to see if versions are identical */ - if(strcmp(a, b) == 0) return(0); + if(strcmp(a, b) == 0) return 0; str1 = strdup(a); str2 = strdup(b); @@ -209,7 +209,7 @@ static int rpmvercmp(const char *a, const char *b) cleanup: free(str1); free(str2); - return(ret); + return ret; } /** Compare two version strings and determine which one is 'newer'. @@ -235,15 +235,15 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b) /* ensure our strings are not null */ if(!a && !b) { - return(0); + return 0; } else if(!a) { - return(-1); + return -1; } else if(!b) { - return(1); + return 1; } /* another quick shortcut- if full version specs are equal */ if(strcmp(a, b) == 0) { - return(0); + return 0; } /* Parse both versions into [epoch:]version[-release] triplets. We probably @@ -266,7 +266,7 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b) free(full1); free(full2); - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/m4/libcurl.m4 b/m4/libcurl.m4 new file mode 100644 index 00000000..01a0575c --- /dev/null +++ b/m4/libcurl.m4 @@ -0,0 +1,250 @@ +# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], +# [ACTION-IF-YES], [ACTION-IF-NO]) +# ---------------------------------------------------------- +# David Shaw <dshaw@jabberwocky.com> May-09-2006 +# +# Checks for libcurl. DEFAULT-ACTION is the string yes or no to +# specify whether to default to --with-libcurl or --without-libcurl. +# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the +# minimum version of libcurl to accept. Pass the version as a regular +# version number like 7.10.1. If not supplied, any version is +# accepted. ACTION-IF-YES is a list of shell commands to run if +# libcurl was successfully found and passed the various tests. +# ACTION-IF-NO is a list of shell commands that are run otherwise. +# Note that using --without-libcurl does run ACTION-IF-NO. +# +# This macro #defines HAVE_LIBCURL if a working libcurl setup is +# found, and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary +# values. Other useful defines are LIBCURL_FEATURE_xxx where xxx are +# the various features supported by libcurl, and LIBCURL_PROTOCOL_yyy +# where yyy are the various protocols supported by libcurl. Both xxx +# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of +# the macro for the complete list of possible defines. Shell +# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also +# defined to 'yes' for those features and protocols that were found. +# Note that xxx and yyy keep the same capitalization as in the +# curl-config list (e.g. it's "HTTP" and not "http"). +# +# Users may override the detected values by doing something like: +# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure +# +# For the sake of sanity, this macro assumes that any libcurl that is +# found is after version 7.7.2, the first version that included the +# curl-config script. Note that it is very important for people +# packaging binary versions of libcurl to include this script! +# Without curl-config, we can only guess what protocols are available, +# or use curl_version_info to figure it out at runtime. + +AC_DEFUN([LIBCURL_CHECK_CONFIG], +[ + AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) + AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) + AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) + AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) + AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) + AH_TEMPLATE([LIBCURL_FEATURE_IDN],[Defined if libcurl supports IDN]) + AH_TEMPLATE([LIBCURL_FEATURE_SSPI],[Defined if libcurl supports SSPI]) + AH_TEMPLATE([LIBCURL_FEATURE_NTLM],[Defined if libcurl supports NTLM]) + + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) + AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TFTP],[Defined if libcurl supports TFTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_RTSP],[Defined if libcurl supports RTSP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_POP3],[Defined if libcurl supports POP3]) + AH_TEMPLATE([LIBCURL_PROTOCOL_IMAP],[Defined if libcurl supports IMAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP]) + + AC_ARG_WITH(libcurl, + AC_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]), + [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) + + if test "$_libcurl_with" != "no" ; then + + AC_PROG_AWK + + _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + + _libcurl_try_link=yes + + if test -d "$_libcurl_with" ; then + LIBCURL_CPPFLAGS="-I$withval/include" + _libcurl_ldflags="-L$withval/lib" + AC_PATH_PROG([_libcurl_config],[curl-config],[], + ["$withval/bin"]) + else + AC_PATH_PROG([_libcurl_config],[curl-config],[],[$PATH]) + fi + + if test x$_libcurl_config != "x" ; then + AC_CACHE_CHECK([for the version of libcurl], + [libcurl_cv_lib_curl_version], + [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) + + _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` + _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` + + if test $_libcurl_wanted -gt 0 ; then + AC_CACHE_CHECK([for libcurl >= version $2], + [libcurl_cv_lib_version_ok], + [ + if test $_libcurl_version -ge $_libcurl_wanted ; then + libcurl_cv_lib_version_ok=yes + else + libcurl_cv_lib_version_ok=no + fi + ]) + fi + + if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then + if test x"$LIBCURL_CPPFLAGS" = "x" ; then + LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` + fi + if test x"$LIBCURL" = "x" ; then + LIBCURL=`$_libcurl_config --libs` + + # This is so silly, but Apple actually has a bug in their + # curl-config script. Fixed in Tiger, but there are still + # lots of Panther installs around. + case "${host}" in + powerpc-apple-darwin7*) + LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` + ;; + esac + fi + + # All curl-config scripts support --feature + _libcurl_features=`$_libcurl_config --feature` + + # Is it modern enough to have --protocols? (7.12.4) + if test $_libcurl_version -ge 461828 ; then + _libcurl_protocols=`$_libcurl_config --protocols` + fi + else + _libcurl_try_link=no + fi + + unset _libcurl_wanted + fi + + if test $_libcurl_try_link = yes ; then + + # we didn't find curl-config, so let's see if the user-supplied + # link line (or failing that, "-lcurl") is enough. + LIBCURL=${LIBCURL-"$_libcurl_ldflags -lcurl"} + + AC_CACHE_CHECK([whether libcurl is usable], + [libcurl_cv_lib_curl_usable], + [ + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBCURL $LIBS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <curl/curl.h>],[ +/* Try and use a few common options to force a failure if we are + missing symbols or can't link. */ +int x; +curl_easy_setopt(NULL,CURLOPT_URL,NULL); +x=CURL_ERROR_SIZE; +x=CURLOPT_WRITEFUNCTION; +x=CURLOPT_FILE; +x=CURLOPT_ERRORBUFFER; +x=CURLOPT_STDERR; +x=CURLOPT_VERBOSE; +])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + ]) + + if test $libcurl_cv_lib_curl_usable = yes ; then + + # Does curl_free() exist in this version of libcurl? + # If not, fake it with free() + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + AC_CHECK_FUNC(curl_free,, + AC_DEFINE(curl_free,free, + [Define curl_free() as free() if our version of curl lacks curl_free.])) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + + AC_DEFINE(HAVE_LIBCURL,1, + [Define to 1 if you have a functional curl library.]) + AC_SUBST(LIBCURL_CPPFLAGS) + AC_SUBST(LIBCURL) + + for _libcurl_feature in $_libcurl_features ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) + eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes + done + + if test "x$_libcurl_protocols" = "x" ; then + + # We don't have --protocols, so just assume that all + # protocols are available + _libcurl_protocols="HTTP FTP FILE TELNET LDAP DICT TFTP" + + if test x$libcurl_feature_SSL = xyes ; then + _libcurl_protocols="$_libcurl_protocols HTTPS" + + # FTPS wasn't standards-compliant until version + # 7.11.0 (0x070b00 == 461568) + if test $_libcurl_version -ge 461568; then + _libcurl_protocols="$_libcurl_protocols FTPS" + fi + fi + + # RTSP, IMAP, POP3 and SMTP were added in + # 7.20.0 (0x071400 == 463872) + if test $_libcurl_version -ge 463872; then + _libcurl_protocols="$_libcurl_protocols RTSP IMAP POP3 SMTP" + fi + fi + + for _libcurl_protocol in $_libcurl_protocols ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) + eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes + done + else + unset LIBCURL + unset LIBCURL_CPPFLAGS + fi + fi + + unset _libcurl_try_link + unset _libcurl_version_parse + unset _libcurl_config + unset _libcurl_feature + unset _libcurl_features + unset _libcurl_protocol + unset _libcurl_protocols + unset _libcurl_version + unset _libcurl_ldflags + fi + + if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then + # This is the IF-NO path + ifelse([$4],,:,[$4]) + else + # This is the IF-YES path + ifelse([$3],,:,[$3]) + fi + + unset _libcurl_with +])dnl diff --git a/scripts/.gitignore b/scripts/.gitignore index fe4616f2..927b14c8 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -5,3 +5,4 @@ rankmirrors repo-add repo-remove pkgdelta +pacman-key diff --git a/scripts/Makefile.am b/scripts/Makefile.am index ae6ce366..7c64e81c 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -8,6 +8,7 @@ bin_SCRIPTS = \ OURSCRIPTS = \ makepkg \ pacman-db-upgrade \ + pacman-key \ pacman-optimize \ pkgdelta \ rankmirrors \ @@ -16,6 +17,7 @@ OURSCRIPTS = \ EXTRA_DIST = \ makepkg.sh.in \ pacman-db-upgrade.sh.in \ + pacman-key.sh.in \ pacman-optimize.sh.in \ pkgdelta.sh.in \ rankmirrors.sh.in \ @@ -64,6 +66,7 @@ $(OURSCRIPTS): Makefile makepkg: $(srcdir)/makepkg.sh.in pacman-db-upgrade: $(srcdir)/pacman-db-upgrade.sh.in +pacman-key: ${srcdir}/pacman-key.sh.in pacman-optimize: $(srcdir)/pacman-optimize.sh.in pkgdelta: $(srcdir)/pkgdelta.sh.in rankmirrors: $(srcdir)/rankmirrors.sh.in diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 69922c99..3d5184ad 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -28,7 +28,7 @@ # makepkg uses quite a few external programs during its execution. You # need to have at least the following installed for makepkg to function: # awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils), -# gettext, grep, gzip, openssl, sed, tput (ncurses), xz +# gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz # gettext initialization export TEXTDOMAIN='pacman' @@ -75,6 +75,7 @@ CHECKFUNC=0 PKGFUNC=0 SPLITPKG=0 PKGLIST=() +SIGNPKG='' # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call # when dealing with svn/cvs/etc PKGBUILDs. @@ -391,7 +392,7 @@ run_pacman() { local cmd printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@" if (( ! ASROOT )) && [[ ! $1 =~ ^-(T|Qq)$ ]]; then - if [ "$(type -p sudo)" ]; then + if type -p sudo >/dev/null; then cmd="sudo $cmd" else cmd="su root -c '$cmd'" @@ -1065,6 +1066,9 @@ create_package() { local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}" local ret=0 + [[ -f $pkg_file ]] && rm -f "$pkg_file" + [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig" + # when fileglobbing, we want * in an empty directory to expand to # the null string rather than itself shopt -s nullglob @@ -1086,9 +1090,12 @@ create_package() { exit 1 # TODO: error code fi + create_signature "$pkg_file" + if (( ! ret )) && [[ ! "$PKGDEST" -ef "${startdir}" ]]; then ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}" ret=$? + [[ -f $pkg_file.sig ]] && ln -sf "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig" fi if (( ret )); then @@ -1096,6 +1103,33 @@ create_package() { fi } +create_signature() { + if [[ $SIGNPKG != 'y' ]]; then + return + fi + local ret=0 + local filename="$1" + msg "$(gettext "Signing package...")" + if ! type -p gpg >/dev/null; then + error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")" + exit 1 # $E_MISSING_PROGRAM + fi + + local SIGNWITHKEY="" + if [[ -n $GPGKEY ]]; then + SIGNWITHKEY="-u ${GPGKEY}" + fi + # The signature will be generated directly in ascii-friendly format + gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$? + + + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" "$filename.sig" + else + warning "$(gettext "Failed to sign package file.")" + fi +} + create_srcpackage() { cd "$startdir" @@ -1573,7 +1607,7 @@ usage() { echo "$(gettext " -e, --noextract Do not extract source files (use existing src/ dir)")" echo "$(gettext " -f, --force Overwrite existing package")" echo "$(gettext " -g, --geninteg Generate integrity checks for source files")" - echo "$(gettext " -h, --help This help")" + echo "$(gettext " -h, --help Show this help message and exit")" echo "$(gettext " -i, --install Install package after successful build")" echo "$(gettext " -L, --log Log package build process")" echo "$(gettext " -m, --nocolor Disable colorized output messages")" @@ -1587,8 +1621,11 @@ usage() { printf "$(gettext " --check Run the check() function in the %s")\n" "$BUILDSCRIPT" printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$confdir/makepkg.conf" printf "$(gettext " --holdver Prevent automatic version bumping for development %ss")\n" "$BUILDSCRIPT" + echo "$(gettext " --key <key> Specify a key to use for gpg signing instead of the default")" printf "$(gettext " --nocheck Do not run the check() function in the %s")\n" "$BUILDSCRIPT" + echo "$(gettext " --nosign Do not create a signature for the package")" echo "$(gettext " --pkg <list> Only build listed packages from a split package")" + echo "$(gettext " --sign Sign the resulting package with gpg")" echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")" echo "$(gettext " --source Generate a source-only tarball without downloaded sources")" echo @@ -1625,8 +1662,8 @@ ARGLIST=("$@") OPT_SHORT="AcCdefFghiLmop:rRsV" OPT_LONG="allsource,asroot,ignorearch,check,clean,cleancache,nodeps" OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" -OPT_LONG+=",install,log,nocolor,nobuild,nocheck,pkg:,rmdeps" -OPT_LONG+=",repackage,skipinteg,source,syncdeps,version,config:" +OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps" +OPT_LONG+=",repackage,skipinteg,sign,source,syncdeps,version,config:" # Pacman Options OPT_LONG+=",noconfirm,noprogressbar" OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')" @@ -1660,15 +1697,18 @@ while true; do -g|--geninteg) GENINTEG=1 ;; --holdver) HOLDVER=1 ;; -i|--install) INSTALL=1 ;; + --key) shift; GPGKEY=$1 ;; -L|--log) LOGGING=1 ;; -m|--nocolor) USE_COLOR='n' ;; --nocheck) RUN_CHECK='n' ;; + --nosign) SIGNPKG='n' ;; -o|--nobuild) NOBUILD=1 ;; -p) shift; BUILDFILE=$1 ;; --pkg) shift; PKGLIST=($1) ;; -r|--rmdeps) RMDEPS=1 ;; -R|--repackage) REPKG=1 ;; --skipinteg) SKIPINTEG=1 ;; + --sign) SIGNPKG='y' ;; --source) SOURCEONLY=1 ;; -s|--syncdeps) DEP_BIN=1 ;; @@ -1685,6 +1725,9 @@ done [[ -n ${PKGDEST} ]] && _PKGDEST=$(canonicalize_path ${PKGDEST}) [[ -n ${SRCDEST} ]] && _SRCDEST=$(canonicalize_path ${SRCDEST}) [[ -n ${SRCPKGDEST} ]] && _SRCPKGDEST=$(canonicalize_path ${SRCPKGDEST}) +[[ -n ${PKGEXT} ]] && _PKGEXT=${PKGEXT} +[[ -n ${SRCEXT} ]] && _SRCEXT=${SRCEXT} +[[ -n ${GPGKEY} ]] && _GPGKEY=${GPGKEY} # default config is makepkg.conf MAKEPKG_CONF=${MAKEPKG_CONF:-$confdir/makepkg.conf} @@ -1748,6 +1791,9 @@ fi SRCPKGDEST=${_SRCPKGDEST:-$SRCPKGDEST} SRCPKGDEST=${SRCPKGDEST:-$startdir} #default to $startdir if undefined +PKGEXT=${_PKGEXT:-$PKGEXT} +SRCEXT=${_SRCEXT:-$SRCEXT} +GPGKEY=${_GPGKEY:-$GPGKEY} if (( HOLDVER )) && [[ -n $FORCE_VER ]]; then # The '\\0' is here to prevent gettext from thinking --holdver is an option @@ -1899,6 +1945,22 @@ if [[ -n "${PKGLIST[@]}" ]]; then pkgname=("${PKGLIST[@]}") fi +# check if gpg signature is to be created and if signing key is valid +if [[ -z "$SIGNPKG" && $(check_buildenv sign) == 'y' ]]; then + SIGNPKG='y' +fi +if [[ $SIGNPKG == 'y' ]]; then + if ! gpg --list-key ${GPGKEY} &>/dev/null; then + if [[ ! -z $GPGKEY ]]; then + error "$(gettext "The key ${GPGKEY} does not exist in your keyring.")" + else + error "$(gettext "There is no key in your keyring.")" + fi + exit 1 + fi +fi + + if (( ! SPLITPKG )); then fullver=$(get_full_version $epoch $pkgver $pkgrel) if [[ -f $PKGDEST/${pkgname}-${fullver}-${CARCH}${PKGEXT} \ diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in new file mode 100644 index 00000000..c0929897 --- /dev/null +++ b/scripts/pacman-key.sh.in @@ -0,0 +1,330 @@ +#!@BASH_SHELL@ -e +# +# pacman-key - manages pacman's keyring +# Based on apt-key, from Debian +# @configure_input@ +# +# Copyright (c) 2010 - Pacman Development Team <pacman-dev@archlinux.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/>. +# + +# gettext initialization +export TEXTDOMAIN='pacman' +export TEXTDOMAINDIR='@localedir@' + +myver="@PACKAGE_VERSION@" + +msg() { + local mesg=$1; shift + printf "==> ${mesg}\n" "$@" >&1 +} + +msg2() { + (( QUIET )) && return + local mesg=$1; shift + printf " -> ${mesg}\n" "$@" >&1 +} + +warning() { + local mesg=$1; shift + printf "==> $(gettext "WARNING:") ${mesg}\n" "$@" >&2 +} + +error() { + local mesg=$1; shift + printf "==> $(gettext "ERROR:") ${mesg}\n" "$@" >&2 +} + +usage() { + printf "pacman-key (pacman) %s\n" ${myver} + echo + printf "$(gettext "Usage: %s [options] <command> [arguments]")\n" $(basename $0) + echo + echo "$(gettext "Manage pacman's list of trusted keys")" + echo + echo "$(gettext "Options must be placed before commands. The available options are:")" + printf "$(gettext " --config <file> Use an alternate config file (instead of '%s')")\n" "$CONFIG" + echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" + echo + echo "$(gettext "The available commands are:")" + echo "$(gettext " -a, --add [<file(s)>] Add the specified keys (empty for stdin)")" + echo "$(gettext " -d, --del <keyid(s)> Remove the specified keyids")" + echo "$(gettext " -e, --export <keyid(s)> Export the specified keyids")" + echo "$(gettext " -f, --finger [<keyid(s)>] List fingerprint for specified or all keyids")" + echo "$(gettext " -h, --help Show this help message and exit")" + echo "$(gettext " -l, --list List keys")" + echo "$(gettext " -r, --receive <keyserver> <keyid(s)> Fetch the specified keyids")" + echo "$(gettext " -t, --trust <keyid(s)> Set the trust level of the given keyids")" + echo "$(gettext " -u, --updatedb Update the trustdb of pacman")" + echo "$(gettext " -V, --version Show program version")" + echo "$(gettext " --adv <params> Use pacman's keyring with advanced gpg commands")" + printf "$(gettext " --reload Reload the default keys")" + echo +} + +version() { + printf "pacman-key (pacman) %s\n" "${myver}" + printf "$(gettext "\ +Copyright (c) 2010-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\ +This is free software; see the source for copying conditions.\n\ +There is NO WARRANTY, to the extent permitted by law.\n")" +} + +# Read provided file and search for values matching the given key +# The contents of the file are expected to be in this format: key = value +# 'key', 'equal sign' and 'value' can be surrounded by random whitespace +# Usage: get_from "$file" "$key" # returns the value for the first matching key in the file +get_from() { + while read key _ value; do + if [[ $key = $2 ]]; then + echo "$value" + break + fi + done < "$1" +} + +reload_keyring() { + local PACMAN_SHARE_DIR='@prefix@/share/pacman' + local GPG_NOKEYRING="gpg --batch --quiet --ignore-time-conflict --no-options --no-default-keyring --homedir ${PACMAN_KEYRING_DIR}" + + # Variable used for iterating on keyrings + local key + local key_id + + # Keyring with keys to be added to the keyring + local ADDED_KEYS="${PACMAN_SHARE_DIR}/addedkeys.gpg" + + # Keyring with keys that were deprecated and will eventually be deleted + local DEPRECATED_KEYS="${PACMAN_SHARE_DIR}/deprecatedkeys.gpg" + + # List of keys removed from the keyring. This file is not a keyring, unlike the others. + # It is a textual list of values that gpg recogniezes as identifiers for keys. + local REMOVED_KEYS="${PACMAN_SHARE_DIR}/removedkeys" + + # Verify signatures of related files, if they exist + if [[ -r "${ADDED_KEYS}" ]]; then + msg "$(gettext "Verifying official keys file signature...")" + if ! ${GPG_PACMAN} --quiet --batch --verify "${ADDED_KEYS}.sig" 1>/dev/null; then + error "$(gettext "The signature of file %s is not valid.")" "${ADDED_KEYS}" + exit 1 + fi + fi + + if [[ -r "${DEPRECATED_KEYS}" ]]; then + msg "$(gettext "Verifying deprecated keys file signature...")" + if ! ${GPG_PACMAN} --quiet --batch --verify "${DEPRECATED_KEYS}.sig" 1>/dev/null; then + error "$(gettext "The signature of file %s is not valid.")" "${DEPRECATED_KEYS}" + exit 1 + fi + fi + + if [[ -r "${REMOVED_KEYS}" ]]; then + msg "$(gettext "Verifying deleted keys file signature...")" + if ! ${GPG_PACMAN} --quiet --batch --verify "${REMOVED_KEYS}.sig"; then + error "$(gettext "The signature of file %s is not valid.")" "${REMOVED_KEYS}" + exit 1 + fi + fi + + # Read the key ids to an array. The conversion from whatever is inside the file + # to key ids is important, because key ids are the only guarantee of identification + # for the keys. + local -A removed_ids + if [[ -r "${REMOVED_KEYS}" ]]; then + while read key; do + local key_values name + key_values=$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5,10 --output-delimiter=' ') + if [[ -n $key_values ]]; then + # The first word is the key_id + key_id=${key_values%% *} + # the rest if the name of the owner + name=${key_values#* } + if [[ -n ${key_id} ]]; then + # Mark this key to be deleted + removed_ids[$key_id]="$name" + fi + fi + done < "${REMOVED_KEYS}" + fi + + # List of keys that must be kept installed, even if in the list of keys to be removed + local HOLD_KEYS=$(get_from "$CONFIG" "HoldKeys") + + # Remove the keys that must be kept from the set of keys that should be removed + if [[ -n ${HOLD_KEYS} ]]; then + for key in ${HOLD_KEYS}; do + key_id=$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5) + if [[ -n "${removed_ids[$key_id]}" ]]; then + unset removed_ids[$key_id] + fi + done + fi + + # Add keys from the current set of keys from pacman-keyring package. The web of trust will + # be updated automatically. + if [[ -r "${ADDED_KEYS}" ]]; then + msg "$(gettext "Appending official keys...")" + local add_keys=$(${GPG_NOKEYRING} --keyring "${ADDED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5) + for key_id in ${add_keys}; do + # There is no point in adding a key that will be deleted right after + if [[ -z "${removed_ids[$key_id]}" ]]; then + ${GPG_NOKEYRING} --keyring "${ADDED_KEYS}" --export "${key_id}" | ${GPG_PACMAN} --import + fi + done + fi + + if [[ -r "${DEPRECATED_KEYS}" ]]; then + msg "$(gettext "Appending deprecated keys...")" + local add_keys=$(${GPG_NOKEYRING} --keyring "${DEPRECATED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5) + for key_id in ${add_keys}; do + # There is no point in adding a key that will be deleted right after + if [[ -z "${removed_ids[$key_id]}" ]]; then + ${GPG_NOKEYRING} --keyring "${DEPRECATED_KEYS}" --export "${key_id}" | ${GPG_PACMAN} --import + fi + done + fi + + # Remove the keys not marked to keep + if (( ${#removed_ids[@]} > 0 )); then + msg "$(gettext "Removing deleted keys from keyring...")" + for key_id in "${!removed_ids[@]}"; do + echo " removing key $key_id - ${removed_ids[$key_id]}" + ${GPG_PACMAN} --quiet --batch --yes --delete-key "${key_id}" + done + fi + + # Update trustdb, just to be sure + msg "$(gettext "Updating trust database...")" + ${GPG_PACMAN} --batch --check-trustdb +} + +# PROGRAM START +if ! type gettext &>/dev/null; then + gettext() { + echo "$@" + } +fi + +if [[ $1 != "--version" && $1 != "-V" && $1 != "--help" && $1 != "-h" && $1 != "" ]]; then + if type -p gpg >/dev/null 2>&1 = 1; then + error "$(gettext "gnupg does not seem to be installed.")" + msg2 "$(gettext "pacman-key requires gnupg for most operations.")" + exit 1 + elif (( EUID != 0 )); then + error "$(gettext "pacman-key needs to be run as root.")" + exit 1 + fi +fi + +# Parse global options +CONFIG="@sysconfdir@/pacman.conf" +PACMAN_KEYRING_DIR="@sysconfdir@/pacman.d/gnupg" +while [[ $1 =~ ^--(config|gpgdir)$ ]]; do + case "$1" in + --config) shift; CONFIG="$1" ;; + --gpgdir) shift; PACMAN_KEYRING_DIR="$1" ;; + esac + shift +done + +if [[ ! -r "${CONFIG}" ]]; then + error "$(gettext "%s not found.")" "$CONFIG" + exit 1 +fi + +# Read GPGDIR from $CONFIG. +if [[ GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then + PACMAN_KEYRING_DIR="${GPGDIR}" +fi +GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" + +# Try to create $PACMAN_KEYRING_DIR if non-existent +# Check for simple existence rather than for a directory as someone may want +# to use a symlink here +[[ -e ${PACMAN_KEYRING_DIR} ]] || mkdir -p -m 755 "${PACMAN_KEYRING_DIR}" + +# Parse and execute command +command="$1" +if [[ -z "${command}" ]]; then + usage + exit 1 +fi +shift + +case "${command}" in + -a|--add) + # If there is no extra parameter, gpg will read stdin + ${GPG_PACMAN} --quiet --batch --import "$@" + ;; + -d|--del) + if (( $# == 0 )); then + error "$(gettext "You need to specify at least one key identifier")" + exit 1 + fi + ${GPG_PACMAN} --quiet --batch --delete-key --yes "$@" + ;; + -u|--updatedb) + ${GPG_PACMAN} --batch --check-trustdb + ;; + --reload) + reload_keyring + ;; + -l|--list) + ${GPG_PACMAN} --batch --list-sigs "$@" + ;; + -f|--finger) + ${GPG_PACMAN} --batch --fingerprint "$@" + ;; + -e|--export) + ${GPG_PACMAN} --armor --export "$@" + ;; + -r|--receive) + if (( $# < 2 )); then + error "$(gettext "You need to specify the keyserver and at least one key identifier")" + exit 1 + fi + keyserver="$1" + shift + ${GPG_PACMAN} --keyserver "${keyserver}" --recv-keys "$@" + ;; + -t|--trust) + if (( $# == 0 )); then + error "$(gettext "You need to specify at least one key identifier")" + exit 1 + fi + while (( $# > 0 )); do + # Verify if the key exists in pacman's keyring + if ${GPG_PACMAN} --list-keys "$1" > /dev/null 2>&1; then + ${GPG_PACMAN} --edit-key "$1" + else + error "$(gettext "The key identified by %s doesn't exist")" "$1" + exit 1 + fi + shift + done + ;; + --adv) + msg "$(gettext "Executing: %s ")$*" "${GPG_PACMAN}" + ${GPG_PACMAN} "$@" || ret=$? + exit $ret + ;; + -h|--help) + usage; exit 0 ;; + -V|--version) + version; exit 0 ;; + *) + error "$(gettext "Unknown command:") $command" + usage; exit 1 ;; +esac diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index dfc93974..cb545f30 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -30,6 +30,8 @@ confdir='@sysconfdir@' QUIET=0 DELTA=0 WITHFILES=0 +SIGN=0 +VERIFY=0 REPO_DB_FILE= LOCKFILE= CLEAN_LOCK=0 @@ -61,31 +63,39 @@ error() { # print usage instructions usage() { - printf "repo-add, repo-remove (pacman) %s\n\n" "$myver" - printf "$(gettext "Usage: repo-add [-d] [-f] [-q] <path-to-db> <package|delta> ...\n")" - printf "$(gettext "Usage: repo-remove [-q] <path-to-db> <packagename|delta> ...\n\n")" - printf "$(gettext "\ + cmd="$(basename $0)" + printf "%s (pacman) %s\n\n" "$cmd" "$myver" + if [[ $cmd == "repo-add" ]] ; then + printf "$(gettext "Usage: repo-add [-d] [-f] [-q] [-s] [-v] <path-to-db> <package|delta> ...\n")" + 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 "\ + printf "$(gettext "Options:\n")" + printf "$(gettext " -d, --delta generate and add delta for package update\n")" + printf "$(gettext " -f, --files update database's file list\n")" + elif [[ $cmd == "repo-remove" ]] ; then + printf "$(gettext "Usage: repo-remove [-q] [-s] [-v] <path-to-db> <packagename|delta> ...\n\n")" + printf "$(gettext "\ repo-remove will update a package database by removing the package name\n\ specified on the command line from the given repo database. Multiple\n\ packages to remove can be specified on the command line.\n\n")" - printf "$(gettext "\ -Use the -q/--quiet flag to minimize output to basic messages, warnings,\n\ -and errors.\n\n")" - printf "$(gettext "\ -Use the -d/--delta flag to automatically generate and add a delta file\n\ -between the old entry and the new one, if the old package file is found\n\ -next to the new one.\n\n")" - printf "$(gettext "\ -Use the -f/--files flag to update a database including file entries.\n\n")" - echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")" - echo "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26")" + printf "$(gettext "Options:\n")" + fi + printf "$(gettext " -q, --quiet minimize output\n")" + printf "$(gettext " -s, --sign sign database with GnuPG after update\n")" + printf "$(gettext " -v, --verify verify database's signature before update\n")" + printf "$(gettext "\n\ +See %s(8) for more details and descriptions of the available options.\n\n")" $cmd + if [[ $cmd == "repo-add" ]] ; then + echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")" + elif [[ $cmd == "repo-remove" ]] ; then + echo "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26")" + fi } version() { - printf "repo-add, repo-remove (pacman) %s\n\n" "$myver" + cmd="$(basename $0)" + printf "%s (pacman) %s\n\n" "$cmd" "$myver" printf "$(gettext "\ Copyright (C) 2006-2008 Aaron Griffin <aaron@archlinux.org>.\n\ Copyright (c) 2007-2008 Dan McGee <dan@archlinux.org>.\n\n\ @@ -184,14 +194,56 @@ db_remove_delta() return 1 } # end db_remove_delta +# sign the package database once repackaged +create_signature() { + (( ! SIGN )) && return + local dbfile="$1" + local ret=0 + msg "$(gettext "Signing database...")" + if ! type -p gpg; then + error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")" + exit 1 # $E_MISSING_PROGRAM + fi + gpg --detach-sign --use-agent "$dbfile" || ret=$? + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" "$dbfile.sig" + else + warning "$(gettext "Failed to sign package database.")" + fi +} + +# verify the existing package database signature +verify_signature() { + (( ! VERIFY )) && return + local dbfile="$1" + local ret=0 + msg "$(gettext "Verifying database signature...")" + if ! type -p gpg; then + error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")" + exit 1 # $E_MISSING_PROGRAM + fi + if [[ ! -f $dbfile.sig ]]; then + warning "$(gettext "No existing signature found, skipping verification.")" + return + fi + gpg --verify "$dbfile.sig" || ret=$? + if (( ! ret )); then + msg2 "$(gettext "Database signature file verified.")" + else + error "$(gettext "Database signature was NOT valid!")" + exit 1 + fi +} + # write an entry to the pacman database # arg1 - path to package db_write_entry() { # blank out all variables local pkgfile="$1" - local pkgname pkgver pkgdesc csize size md5sum url arch builddate packager \ - _groups _licenses _replaces _depends _conflicts _provides _optdepends + local pkgname pkgver pkgdesc csize size url arch builddate packager \ + _groups _licenses _replaces _depends _conflicts _provides _optdepends \ + md5sum sha256sum pgpsig local OLDIFS="$IFS" # IFS (field separator) is only the newline character @@ -219,10 +271,19 @@ db_write_entry() IFS=$OLDIFS - # get md5sum and compressed size of package + csize=$(@SIZECMD@ "$pkgfile") + + # compute checksums + msg2 "$(gettext "Computing checksums...")" md5sum="$(openssl dgst -md5 "$pkgfile")" md5sum="${md5sum##* }" - csize=$(@SIZECMD@ "$pkgfile") + sha256sum="$(openssl dgst -sha256 "$pkgfile")" + sha256sum="${sha256sum##* }" + + # compute base64'd PGP signature + if [[ -f "$pkgfile.sig" ]]; then + pgpsig=$(openssl base64 -in "$pkgfile.sig" | tr -d '\n') + fi # ensure $pkgname and $pkgver variables were found if [[ -z $pkgname || -z $pkgver ]]; then @@ -264,9 +325,12 @@ db_write_entry() [[ -n $csize ]] && echo -e "%CSIZE%\n$csize\n" >>desc [[ -n $size ]] && echo -e "%ISIZE%\n$size\n" >>desc - # compute checksums - msg2 "$(gettext "Computing md5 checksums...")" + # add checksums echo -e "%MD5SUM%\n$md5sum\n" >>desc + echo -e "%SHA256SUM%\n$sha256sum\n" >>desc + + # add PGP sig + [[ -n $pgpsig ]] && echo -e "%PGPSIG%\n$pgpsig\n" >>desc [[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc write_list_entry "LICENSE" "$_licenses" "desc" @@ -352,6 +416,7 @@ check_repo_db() exit 1 fi fi + verify_signature "$REPO_DB_FILE" msg "$(gettext "Extracting database to a temporary location...")" bsdtar -xf "$REPO_DB_FILE" -C "$tmpdir" else @@ -482,6 +547,8 @@ for arg in "$@"; do -q|--quiet) QUIET=1;; -d|--delta) DELTA=1;; -f|--files) WITHFILES=1;; + -s|--sign) SIGN=1;; + -v|--verify) VERIFY=1;; *) if [[ -z $REPO_DB_FILE ]]; then REPO_DB_FILE="$arg" @@ -519,15 +586,24 @@ if (( success )); then warning "$(gettext "No packages remain, creating empty database.")" bsdtar -c${TAR_OPT}f "$filename" -T /dev/null fi + create_signature "$filename" + popd >/dev/null [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old" + [[ -f $REPO_DB_FILE.sig ]] && rm -f "$REPO_DB_FILE.sig" [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE" + [[ -f $tmpdir/$filename.sig ]] && mv "$tmpdir/$filename.sig" "$REPO_DB_FILE.sig" dblink="${REPO_DB_FILE%.tar.*}" target=${REPO_DB_FILE##*/} ln -sf "$target" "$dblink" 2>/dev/null || \ ln -f "$target" "$dblink" 2>/dev/null || \ cp "$REPO_DB_FILE" "$dblink" + if [[ -f "$target.sig" ]]; then + ln -sf "$target.sig" "$dblink.sig" 2>/dev/null || \ + ln -f "$target.sig" "$dblink.sig" 2>/dev/null || \ + cp "$REPO_DB_FILE.sig" "$dblink.sig" + fi else msg "$(gettext "No packages modified, nothing to do.")" exit 1 diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index 31e8b134..333b8193 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -1,6 +1,7 @@ # paths set at make time conffile = ${sysconfdir}/pacman.conf dbpath = ${localstatedir}/lib/pacman/ +gpgdir = ${sysconfdir}/pacman.d/gnupg/ cachedir = ${localstatedir}/cache/pacman/pkg/ logfile = ${localstatedir}/log/pacman.log @@ -10,6 +11,7 @@ DEFS = -DLOCALEDIR=\"@localedir@\" \ -DCONFFILE=\"$(conffile)\" \ -DROOTDIR=\"$(ROOTDIR)\" \ -DDBPATH=\"$(dbpath)\" \ + -DGPGDIR=\"$(gpgdir)\" \ -DCACHEDIR=\"$(cachedir)\" \ -DLOGFILE=\"$(logfile)\" \ @DEFS@ diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 5edcc966..d3dc7440 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -81,7 +81,7 @@ static double get_update_timediff(int first_call) } } - return(retval); + return retval; } /* refactored from cb_trans_progress */ @@ -224,10 +224,10 @@ void cb_trans_evt(pmtransevt_t event, void *data1, void *data2) printf(_("failed.\n")); break; case PM_TRANS_EVT_SCRIPTLET_INFO: - printf("%s", (char*)data1); + printf("%s", (char *)data1); break; case PM_TRANS_EVT_RETRIEVE_START: - printf(_(":: Retrieving packages from %s...\n"), (char*)data1); + printf(_(":: Retrieving packages from %s...\n"), (char *)data1); break; case PM_TRANS_EVT_DISKSPACE_START: if(config->noprogressbar) { @@ -398,7 +398,7 @@ void cb_trans_progress(pmtransprog_t event, const char *pkgname, int percent, } infolen = getcols() * 6 / 10; - if (infolen < 50) { + if(infolen < 50) { infolen = 50; } @@ -492,10 +492,11 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) int totaldownload = 0; off_t xfered, total; - double rate = 0.0, timediff = 0.0, f_xfered = 0.0; + double rate = 0.0, timediff = 0.0; unsigned int eta_h = 0, eta_m = 0, eta_s = 0; + double rate_human, xfered_human; + const char *rate_label, *xfered_label; int file_percent = 0, total_percent = 0; - char rate_size = 'K', xfered_size = 'K'; if(config->noprogressbar || file_total == -1) { if(file_xfered == 0) { @@ -506,7 +507,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) } infolen = getcols() * 6 / 10; - if (infolen < 50) { + if(infolen < 50) { infolen = 50; } /* explanation of magic 28 number at the end */ @@ -557,7 +558,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t 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 = xfered / timediff; /* round elapsed time to the nearest second */ eta_s = (int)(timediff + 0.5); @@ -569,10 +570,10 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) /* return if the calling interval was too short */ return; } - rate = (xfered - xfered_last) / (timediff * 1024.0); + rate = (xfered - xfered_last) / timediff; /* average rate to reduce jumpiness */ rate = (rate + 2 * rate_last) / 3; - eta_s = (total - xfered) / (rate * 1024.0); + eta_s = (total - xfered) / rate; rate_last = rate; xfered_last = xfered; } @@ -626,37 +627,13 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) } - /* Awesome formatting for progress bar. We need a mess of Kb->Mb->Gb stuff - * here. We'll use limit of 2048 for each until we get some empirical */ - /* rate_size = 'K'; was set above */ - if(rate > 2048.0) { - rate /= 1024.0; - rate_size = 'M'; - if(rate > 2048.0) { - rate /= 1024.0; - rate_size = 'G'; - /* we should not go higher than this for a few years (9999.9 Gb/s?)*/ - } - } - - f_xfered = xfered / 1024.0; /* convert to K by default */ - /* xfered_size = 'K'; was set above */ - if(f_xfered > 2048.0) { - f_xfered /= 1024.0; - xfered_size = 'M'; - if(f_xfered > 2048.0) { - f_xfered /= 1024.0; - xfered_size = 'G'; - /* I should seriously hope that archlinux packages never break - * the 9999.9GB mark... we'd have more serious problems than the progress - * bar in pacman */ - } - } + rate_human = humanize_size((off_t)rate, '\0', 0, &rate_label); + xfered_human = humanize_size(xfered, '\0', 0, &xfered_label); /* 1 space + filenamelen + 1 space + 7 for size + 1 + 7 for rate + 2 for /s + 1 space + 8 for eta */ - printf(" %ls%-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", wcfname, - padwid, "", f_xfered, xfered_size, - rate, rate_size, eta_h, eta_m, eta_s); + printf(" %ls%-*s %6.1f%s %#6.1f%s/s %02u:%02u:%02u", wcfname, + padwid, "", xfered_human, xfered_label, rate_human, rate_label, + eta_h, eta_m, eta_s); free(fname); free(wcfname); diff --git a/src/pacman/conf.c b/src/pacman/conf.c index e2a168ee..69110ab9 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -38,7 +38,7 @@ config_t *config_new(void) pm_fprintf(stderr, PM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(config_t)); - return(NULL); + return NULL; } /* defaults which may get overridden later */ newconfig->op = PM_OP_MAIN; @@ -46,13 +46,13 @@ config_t *config_new(void) /* CONFFILE is defined at compile-time */ newconfig->configfile = strdup(CONFFILE); - return(newconfig); + return newconfig; } int config_free(config_t *oldconfig) { if(oldconfig == NULL) { - return(-1); + return -1; } FREELIST(oldconfig->holdpkg); @@ -66,7 +66,7 @@ int config_free(config_t *oldconfig) free(oldconfig); oldconfig = NULL; - return(0); + return 0; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 92c379fc..4f96f4f9 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -40,6 +40,7 @@ typedef struct __config_t { char *rootdir; char *dbpath; char *logfile; + char *gpgdir; /* TODO how to handle cachedirs? */ unsigned short op_q_isfile; @@ -68,12 +69,15 @@ typedef struct __config_t { unsigned int ask; /* conf file options */ - unsigned short chomp; /* I Love Candy! */ - unsigned short showsize; /* show individual package sizes */ + /* I Love Candy! */ + unsigned short chomp; + /* format target pkg lists as table */ + unsigned short verbosepkglists; /* 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 */ + /* select -Sc behavior */ + unsigned short cleanmethod; alpm_list_t *holdpkg; alpm_list_t *syncfirst; char *xfercommand; @@ -106,7 +110,8 @@ enum { OP_NEEDED, OP_ASEXPLICIT, OP_ARCH, - OP_PRINTFORMAT + OP_PRINTFORMAT, + OP_GPGDIR }; /* clean method */ diff --git a/src/pacman/database.c b/src/pacman/database.c index 36433f33..123f72d2 100644 --- a/src/pacman/database.c +++ b/src/pacman/database.c @@ -20,7 +20,6 @@ #include "config.h" -#include <stdlib.h> #include <stdio.h> #include <alpm.h> @@ -47,7 +46,7 @@ int pacman_database(alpm_list_t *targets) if(targets == NULL) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); - return(1); + return 1; } if(config->flags & PM_TRANS_FLAG_ALLDEPS) { /* --asdeps */ @@ -56,12 +55,12 @@ int pacman_database(alpm_list_t *targets) reason = PM_PKG_REASON_EXPLICIT; } else { pm_printf(PM_LOG_ERROR, _("no install reason specified (use -h for help)\n")); - return(1); + return 1; } /* Lock database */ if(trans_init(0) == -1) { - return(1); + return 1; } db_local = alpm_option_get_localdb(); @@ -82,9 +81,9 @@ int pacman_database(alpm_list_t *targets) /* Unlock database */ if(trans_release() == -1) { - return(1); + return 1; } - return(retval); + return retval; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/deptest.c b/src/pacman/deptest.c index 8895b487..19e4da4a 100644 --- a/src/pacman/deptest.c +++ b/src/pacman/deptest.c @@ -20,17 +20,13 @@ #include "config.h" -#include <stdlib.h> #include <stdio.h> -#include <string.h> #include <alpm.h> #include <alpm_list.h> /* pacman */ #include "pacman.h" -#include "util.h" -#include "conf.h" int pacman_deptest(alpm_list_t *targets) { @@ -47,7 +43,7 @@ int pacman_deptest(alpm_list_t *targets) } if(deps == NULL) { - return(0); + return 0; } for(i = deps; i; i = alpm_list_next(i)) { @@ -56,7 +52,7 @@ int pacman_deptest(alpm_list_t *targets) printf("%s\n", dep); } alpm_list_free(deps); - return(127); + return 127; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/package.c b/src/pacman/package.c index 77a5ee72..346d3125 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -26,7 +26,6 @@ #include <unistd.h> #include <limits.h> #include <errno.h> -#include <wchar.h> #include <alpm.h> #include <alpm_list.h> @@ -51,6 +50,8 @@ void dump_pkg_full(pmpkg_t *pkg, int level) const char *reason; time_t bdate, idate; char bdatestr[50] = "", idatestr[50] = ""; + const char *label; + double size; const alpm_list_t *i; alpm_list_t *requiredby = NULL, *depstrings = NULL; @@ -82,7 +83,7 @@ void dump_pkg_full(pmpkg_t *pkg, int level) /* turn depends list into a text list */ for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) { - pmdepend_t *dep = (pmdepend_t*)alpm_list_getdata(i); + pmdepend_t *dep = (pmdepend_t *)alpm_list_getdata(i); depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(dep)); } @@ -105,17 +106,17 @@ void dump_pkg_full(pmpkg_t *pkg, int level) } list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg)); list_display(_("Replaces :"), alpm_pkg_get_replaces(pkg)); + + size = humanize_size(alpm_pkg_get_size(pkg), 'K', 1, &label); if(level < 0) { - printf(_("Download Size : %6.2f K\n"), - (double)alpm_pkg_get_size(pkg) / 1024.0); - } - if(level == 0) { - printf(_("Compressed Size: %6.2f K\n"), - (double)alpm_pkg_get_size(pkg) / 1024.0); + printf(_("Download Size : %6.2f %s\n"), size, label); + } else if(level == 0) { + printf(_("Compressed Size: %6.2f %s\n"), size, label); } - printf(_("Installed Size : %6.2f K\n"), - (double)alpm_pkg_get_isize(pkg) / 1024.0); + size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 1, &label); + printf(_("Installed Size : %6.2f %s\n"), size, label); + string_display(_("Packager :"), alpm_pkg_get_packager(pkg)); string_display(_("Architecture :"), alpm_pkg_get_arch(pkg)); string_display(_("Build Date :"), bdatestr); @@ -173,11 +174,11 @@ static const char *get_backup_file_status(const char *root, if(md5sum == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, _("could not calculate checksums for %s\n"), path); - return(NULL); + return NULL; } /* if checksums don't match, file has been modified */ - if (strcmp(md5sum, expected_md5) != 0) { + if(strcmp(md5sum, expected_md5) != 0) { ret = "MODIFIED"; } else { ret = "UNMODIFIED"; @@ -195,7 +196,7 @@ static const char *get_backup_file_status(const char *root, ret = "UNKNOWN"; } } - return(ret); + return ret; } /* Display list of backup files and their modification states diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 0ad03540..a4cfe75c 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -39,7 +39,6 @@ #include <sys/stat.h> #include <sys/utsname.h> /* uname */ #include <locale.h> /* setlocale */ -#include <time.h> /* time_t */ #include <errno.h> #include <glob.h> #if defined(PACMAN_DEBUG) && defined(HAVE_MCHECK_H) @@ -55,7 +54,6 @@ #include "util.h" #include "callback.h" #include "conf.h" -#include "package.h" /* list of targets specified on command line */ static alpm_list_t *pm_targets; @@ -66,9 +64,9 @@ static int options_cmp(const void *p1, const void *p2) const char *s1 = p1; const char *s2 = p2; - if(s1 == s2) return(0); - if(!s1) return(-1); - if(!s2) return(1); + if(s1 == s2) return 0; + if(!s1) return -1; + if(!s2) return 1; /* First skip all spaces in both strings */ while(isspace((unsigned char)*s1)) { s1++; @@ -87,15 +85,15 @@ static int options_cmp(const void *p1, const void *p2) s2++; } else if(*s2 == '-') { /* s1 short, s2 long */ - return(-1); + return -1; } else if(*s1 == '-') { /* s1 long, s2 short */ - return(1); + return 1; } /* two short -> strcmp */ } - return(strcmp(s1, s2)); + return strcmp(s1, s2); } /** Display usage/syntax for the specified operation. @@ -170,7 +168,7 @@ static void usage(int op, const char * const myname) addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n")); addlist(_(" -y, --refresh download fresh package databases from the server\n")); addlist(_(" --needed don't reinstall up to date packages\n")); - } else if (op == PM_OP_DATABASE) { + } else if(op == PM_OP_DATABASE) { printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" --asdeps mark packages as non-explicitly installed\n")); @@ -207,6 +205,7 @@ static void usage(int op, const char * const myname) addlist(_(" --cachedir <dir> set an alternate package cache location\n")); addlist(_(" --config <path> set an alternate configuration file\n")); addlist(_(" --debug display debug messages\n")); + addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n")); addlist(_(" --logfile <path> set an alternate log file\n")); addlist(_(" --noconfirm do not ask for any confirmation\n")); } @@ -239,7 +238,7 @@ static void version(void) static void localize(void) { static int init = 0; - if (!init) { + if(!init) { setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -263,7 +262,7 @@ static void setuseragent(void) static void setarch(const char *arch) { - if (strcmp(arch, "auto") == 0) { + if(strcmp(arch, "auto") == 0) { struct utsname un; uname(&un); pm_printf(PM_LOG_DEBUG, "config: Architecture: %s\n", un.machine); @@ -302,7 +301,7 @@ static ssize_t xwrite(int fd, const void *buf, size_t count) do { ret = write(fd, buf, count); } while(ret == -1 && errno == EINTR); - return(ret); + return ret; } /** Catches thrown signals. Performs necessary cleanup to ensure database is @@ -321,7 +320,7 @@ static void handler(int signum) xwrite(out, msg1, strlen(msg1)); xwrite(err, msg2, strlen(msg2)); exit(signum); - } else if((signum == SIGINT)) { + } else if(signum == SIGINT) { const char *msg = "\nInterrupt signal received\n"; xwrite(err, msg, strlen(msg)); if(alpm_trans_interrupt() == 0) { @@ -345,7 +344,7 @@ static void handler(int signum) static void setlibpaths(void) { static int init = 0; - if (!init) { + if(!init) { int ret = 0; pm_printf(PM_LOG_DEBUG, "setlibpaths() called\n"); @@ -390,6 +389,17 @@ static void setlibpaths(void) } } + /* Set GnuPG's home directory. This is not relative to rootdir, even if + * rootdir is defined. Reasoning: gpgdir contains configuration data. */ + if(config->gpgdir) { + ret = alpm_option_set_signaturedir(config->gpgdir); + if(ret != 0) { + pm_printf(PM_LOG_ERROR, _("problem setting gpgdir '%s' (%s)\n"), + config->gpgdir, alpm_strerrorlast()); + cleanup(ret); + } + } + /* add a default cachedir if one wasn't specified */ if(alpm_option_get_cachedirs() == NULL) { alpm_option_add_cachedir(CACHEDIR); @@ -398,9 +408,9 @@ static void setlibpaths(void) } } -#define check_optarg() if(!optarg) { return(1); } +#define check_optarg() if(!optarg) { return 1; } -typedef void (*fn_add) (const char *s); +typedef int (*fn_add) (const char *s); static int parsearg_util_addlist(fn_add fn) { @@ -412,7 +422,7 @@ static int parsearg_util_addlist(fn_add fn) fn((char *)alpm_list_getdata(item)); } FREELIST(list); - return(0); + return 0; } /** Helper function for parsing operation from command-line arguments. @@ -449,9 +459,9 @@ static int parsearg_op(int opt, int dryrun) if(dryrun) break; config->help = 1; break; default: - return(1); + return 1; } - return(0); + return 0; } /** Helper functions for parsing command-line arguments. @@ -472,7 +482,7 @@ static int parsearg_global(int opt) if(alpm_option_add_cachedir(optarg) != 0) { pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), optarg, alpm_strerrorlast()); - return(1); + return 1; } break; case OP_CONFIG: @@ -497,7 +507,7 @@ static int parsearg_global(int opt) default: pm_printf(PM_LOG_ERROR, _("'%s' is not a valid debug level\n"), optarg); - return(1); + return 1; } } else { config->logmask |= PM_LOG_DEBUG; @@ -505,6 +515,9 @@ static int parsearg_global(int opt) /* progress bars get wonky with debug on, shut them off */ config->noprogressbar = 1; break; + case OP_GPGDIR: + config->gpgdir = strdup(optarg); + break; case OP_LOGFILE: check_optarg(); config->logfile = strndup(optarg, PATH_MAX); @@ -516,9 +529,9 @@ static int parsearg_global(int opt) break; case 'r': check_optarg(); config->rootdir = strdup(optarg); break; case 'v': (config->verbose)++; break; - default: return(1); + default: return 1; } - return(0); + return 0; } static int parsearg_database(int opt) @@ -526,9 +539,9 @@ static int parsearg_database(int opt) switch(opt) { case OP_ASDEPS: config->flags |= PM_TRANS_FLAG_ALLDEPS; break; case OP_ASEXPLICIT: config->flags |= PM_TRANS_FLAG_ALLEXPLICIT; break; - default: return(1); + default: return 1; } - return(0); + return 0; } static int parsearg_query(int opt) @@ -548,9 +561,9 @@ static int parsearg_query(int opt) case 's': config->op_q_search = 1; break; case 't': config->op_q_unrequired = 1; break; case 'u': config->op_q_upgrade = 1; break; - default: return(1); + default: return 1; } - return(0); + return 0; } /* options common to -S -R -U */ @@ -572,15 +585,15 @@ static int parsearg_trans(int opt) check_optarg(); config->print_format = strdup(optarg); break; - default: return(1); + default: return 1; } - return(0); + return 0; } static int parsearg_remove(int opt) { - if (parsearg_trans(opt) == 0) - return(0); + if(parsearg_trans(opt) == 0) + return 0; switch(opt) { case 'c': config->flags |= PM_TRANS_FLAG_CASCADE; break; case 'n': config->flags |= PM_TRANS_FLAG_NOSAVE; break; @@ -592,16 +605,16 @@ static int parsearg_remove(int opt) } break; case 'u': config->flags |= PM_TRANS_FLAG_UNNEEDED; break; - default: return(1); + default: return 1; } - return(0); + return 0; } /* options common to -S -U */ static int parsearg_upgrade(int opt) { - if (parsearg_trans(opt) == 0) - return(0); + if(parsearg_trans(opt) == 0) + return 0; switch(opt) { case 'f': config->flags |= PM_TRANS_FLAG_FORCE; break; case OP_ASDEPS: config->flags |= PM_TRANS_FLAG_ALLDEPS; break; @@ -612,15 +625,15 @@ static int parsearg_upgrade(int opt) case OP_IGNOREGROUP: parsearg_util_addlist(alpm_option_add_ignoregrp); break; - default: return(1); + default: return 1; } - return(0); + return 0; } static int parsearg_sync(int opt) { - if (parsearg_upgrade(opt) == 0) - return(0); + if(parsearg_upgrade(opt) == 0) + return 0; switch(opt) { case OP_NEEDED: config->flags |= PM_TRANS_FLAG_NEEDED; break; case 'c': (config->op_s_clean)++; break; @@ -636,9 +649,9 @@ static int parsearg_sync(int opt) config->flags |= PM_TRANS_FLAG_NOCONFLICTS; break; case 'y': (config->op_s_sync)++; break; - default: return(1); + default: return 1; } - return(0); + return 0; } /** Parse command-line arguments for each operation. @@ -706,6 +719,7 @@ static int parseargs(int argc, char *argv[]) {"asexplicit", no_argument, 0, OP_ASEXPLICIT}, {"arch", required_argument, 0, OP_ARCH}, {"print-format", required_argument, 0, OP_PRINTFORMAT}, + {"gpgdir", required_argument, 0, OP_GPGDIR}, {0, 0, 0, 0} }; @@ -717,22 +731,22 @@ static int parseargs(int argc, char *argv[]) continue; } else if(opt == '?') { /* unknown option, getopt printed an error */ - return(1); + return 1; } parsearg_op(opt, 0); } if(config->op == 0) { pm_printf(PM_LOG_ERROR, _("only one operation may be used at a time\n")); - return(1); + return 1; } if(config->help) { usage(config->op, mbasename(argv[0])); - return(2); + return 2; } if(config->version) { version(); - return(2); + return 2; } /* parse all other options */ @@ -744,7 +758,7 @@ static int parseargs(int argc, char *argv[]) continue; } else if(opt == '?') { /* this should have failed during first pass already */ - return(1); + return 1; } else if(parsearg_op(opt, 1) == 0) { /* opt is an operation */ continue; @@ -771,7 +785,7 @@ static int parseargs(int argc, char *argv[]) result = 1; break; } - if (result == 0) { + if(result == 0) { continue; } @@ -780,7 +794,7 @@ static int parseargs(int argc, char *argv[]) if(result != 0) { /* global option parsing failed, abort */ pm_printf(PM_LOG_ERROR, _("invalid option\n")); - return(result); + return result; } } @@ -790,29 +804,32 @@ static int parseargs(int argc, char *argv[]) optind++; } - return(0); + return 0; } /* helper for being used with setrepeatingoption */ -static void option_add_holdpkg(const char *name) { +static int option_add_holdpkg(const char *name) { config->holdpkg = alpm_list_add(config->holdpkg, strdup(name)); + return 0; } /* helper for being used with setrepeatingoption */ -static void option_add_syncfirst(const char *name) { +static int option_add_syncfirst(const char *name) { config->syncfirst = alpm_list_add(config->syncfirst, strdup(name)); + return 0; } /* helper for being used with setrepeatingoption */ -static void option_add_cleanmethod(const char *value) { - if (strcmp(value, "KeepInstalled") == 0) { +static int option_add_cleanmethod(const char *value) { + if(strcmp(value, "KeepInstalled") == 0) { config->cleanmethod |= PM_CLEAN_KEEPINST; - } else if (strcmp(value, "KeepCurrent") == 0) { + } else if(strcmp(value, "KeepCurrent") == 0) { config->cleanmethod |= PM_CLEAN_KEEPCUR; } else { pm_printf(PM_LOG_ERROR, _("invalid value for 'CleanMethod' : '%s'\n"), value); } + return 0; } /** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm @@ -823,7 +840,7 @@ static void option_add_cleanmethod(const char *value) { * @param optionfunc a function pointer to an alpm_option_add_* function */ static void setrepeatingoption(char *ptr, const char *option, - void (*optionfunc)(const char*)) + int (*optionfunc)(const char *)) { char *q; @@ -843,7 +860,7 @@ static char *get_filename(const char *url) { if(filename != NULL) { filename++; } - return(filename); + return filename; } static char *get_destfile(const char *path, const char *filename) { @@ -853,7 +870,7 @@ static char *get_destfile(const char *path, const char *filename) { destfile = calloc(len, sizeof(char)); snprintf(destfile, len, "%s%s", path, filename); - return(destfile); + return destfile; } static char *get_tempfile(const char *path, const char *filename) { @@ -863,7 +880,7 @@ static char *get_tempfile(const char *path, const char *filename) { tempfile = calloc(len, sizeof(char)); snprintf(tempfile, len, "%s%s.part", path, filename); - return(tempfile); + return tempfile; } /** External fetch callback */ @@ -955,7 +972,7 @@ cleanup: free(tempfile); free(parsedcmd); - return(ret); + return ret; } static int _parse_options(const char *key, char *value, @@ -969,9 +986,9 @@ static int _parse_options(const char *key, char *value, } else if(strcmp(key, "ILoveCandy") == 0) { config->chomp = 1; pm_printf(PM_LOG_DEBUG, "config: chomp\n"); - } else if(strcmp(key, "ShowSize") == 0) { - config->showsize = 1; - pm_printf(PM_LOG_DEBUG, "config: showsize\n"); + } else if(strcmp(key, "VerbosePkgLists") == 0) { + config->verbosepkglists = 1; + pm_printf(PM_LOG_DEBUG, "config: verbosepkglists\n"); } else if(strcmp(key, "UseDelta") == 0) { alpm_option_set_usedelta(1); pm_printf(PM_LOG_DEBUG, "config: usedelta\n"); @@ -1013,7 +1030,7 @@ static int _parse_options(const char *key, char *value, if(alpm_option_add_cachedir(value) != 0) { pm_printf(PM_LOG_ERROR, _("problem adding cachedir '%s' (%s)\n"), value, alpm_strerrorlast()); - return(1); + return 1; } pm_printf(PM_LOG_DEBUG, "config: cachedir: %s\n", value); } else if(strcmp(key, "RootDir") == 0) { @@ -1022,17 +1039,34 @@ static int _parse_options(const char *key, char *value, config->rootdir = strdup(value); pm_printf(PM_LOG_DEBUG, "config: rootdir: %s\n", value); } - } else if (strcmp(key, "LogFile") == 0) { + } else if(strcmp(key, "GPGDir") == 0) { + if(!config->gpgdir) { + config->gpgdir = strdup(value); + pm_printf(PM_LOG_DEBUG, "config: gpgdir: %s\n", value); + } + } else if(strcmp(key, "LogFile") == 0) { if(!config->logfile) { config->logfile = strdup(value); pm_printf(PM_LOG_DEBUG, "config: logfile: %s\n", value); } - } else if (strcmp(key, "XferCommand") == 0) { + } else if(strcmp(key, "XferCommand") == 0) { config->xfercommand = strdup(value); alpm_option_set_fetchcb(download_with_xfercommand); pm_printf(PM_LOG_DEBUG, "config: xfercommand: %s\n", value); - } else if (strcmp(key, "CleanMethod") == 0) { + } else if(strcmp(key, "CleanMethod") == 0) { setrepeatingoption(value, "CleanMethod", option_add_cleanmethod); + } else if(strcmp(key, "VerifySig") == 0) { + if(strcmp(value, "Always") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_ALWAYS); + } else if(strcmp(value, "Optional") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_OPTIONAL); + } else if(strcmp(value, "Never") == 0) { + alpm_option_set_default_sigverify(PM_PGP_VERIFY_NEVER); + } else { + pm_printf(PM_LOG_ERROR, _("invalid value for 'VerifySig' : '%s'\n"), value); + return 1; + } + pm_printf(PM_LOG_DEBUG, "config: setting default VerifySig: %s\n", value); } else { pm_printf(PM_LOG_WARNING, @@ -1041,7 +1075,7 @@ static int _parse_options(const char *key, char *value, } } - return(0); + return 0; } static int _add_mirror(pmdb_t *db, char *value) @@ -1060,7 +1094,7 @@ static int _add_mirror(pmdb_t *db, char *value) free(temp); pm_printf(PM_LOG_ERROR, _("The mirror '%s' contains the $arch" " variable, but no Architecture is defined.\n"), value); - return(1); + return 1; } server = temp; } @@ -1070,11 +1104,11 @@ static int _add_mirror(pmdb_t *db, char *value) pm_printf(PM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"), dbname, server, alpm_strerrorlast()); free(server); - return(1); + return 1; } free(server); - return(0); + return 0; } /* The real parseconfig. Called with a null section argument by the publicly @@ -1093,7 +1127,7 @@ static int _parseconfig(const char *file, const char *givensection, fp = fopen(file, "r"); if(fp == NULL) { pm_printf(PM_LOG_ERROR, _("config file %s could not be read.\n"), file); - return(1); + return 1; } /* if we are passed a section, use it as our starting point */ @@ -1225,6 +1259,24 @@ static int _parseconfig(const char *file, const char *givensection, ret = 1; goto cleanup; } + } else if(strcmp(key, "VerifySig") == 0) { + if(strcmp(value, "Always") == 0) { + ret = alpm_db_set_pgp_verify(db, PM_PGP_VERIFY_ALWAYS); + } else if(strcmp(value, "Optional") == 0) { + ret = alpm_db_set_pgp_verify(db, PM_PGP_VERIFY_OPTIONAL); + } else if(strcmp(value, "Never") == 0) { + ret = alpm_db_set_pgp_verify(db, PM_PGP_VERIFY_NEVER); + } else { + pm_printf(PM_LOG_ERROR, _("invalid value for 'VerifySig' : '%s'\n"), value); + ret = 1; + goto cleanup; + } + if(ret != 0) { + pm_printf(PM_LOG_ERROR, _("could not add pgp verify option to database '%s': %s (%s)\n"), + alpm_db_get_name(db), value, alpm_strerrorlast()); + goto cleanup; + } + pm_printf(PM_LOG_DEBUG, "config: VerifySig for %s: %s\n",alpm_db_get_name(db), value); } else { pm_printf(PM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), @@ -1242,7 +1294,7 @@ cleanup: /* call setlibpaths here to ensure we have called it at least once */ setlibpaths(); pm_printf(PM_LOG_DEBUG, "config: finished parsing %s\n", file); - return(ret); + return ret; } /** Parse a configuration file. @@ -1252,7 +1304,7 @@ cleanup: static int parseconfig(const char *file) { /* call the real parseconfig function with a null section & db argument */ - return(_parseconfig(file, NULL, NULL)); + return _parseconfig(file, NULL, NULL); } /** print commandline to logfile @@ -1345,6 +1397,7 @@ int main(int argc, char *argv[]) /* define paths to reasonable defaults */ alpm_option_set_root(ROOTDIR); alpm_option_set_dbpath(DBPATH); + alpm_option_set_signaturedir(GPGDIR); alpm_option_set_logfile(LOGFILE); /* Priority of options: @@ -1383,7 +1436,7 @@ int main(int argc, char *argv[]) } } /* check for buffer overflow */ - if (i >= PATH_MAX) { + if(i >= PATH_MAX) { pm_printf(PM_LOG_ERROR, _("buffer overflow detected in arg parsing\n")); cleanup(EXIT_FAILURE); } @@ -1393,7 +1446,7 @@ int main(int argc, char *argv[]) line[i] = '\0'; pm_targets = alpm_list_add(pm_targets, strdup(line)); } - if (!freopen(ctermid(NULL), "r", stdin)) { + if(!freopen(ctermid(NULL), "r", stdin)) { pm_printf(PM_LOG_ERROR, _("failed to reopen stdin for reading: (%s)\n"), strerror(errno)); } @@ -1439,7 +1492,7 @@ int main(int argc, char *argv[]) printf("DB Path : %s\n", alpm_option_get_dbpath()); printf("Cache Dirs: "); for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { - printf("%s ", (char*)alpm_list_getdata(i)); + printf("%s ", (char *)alpm_list_getdata(i)); } printf("\n"); printf("Lock File : %s\n", alpm_option_get_lockfile()); @@ -1479,7 +1532,7 @@ int main(int argc, char *argv[]) cleanup(ret); /* not reached */ - return(EXIT_SUCCESS); + return EXIT_SUCCESS; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/query.c b/src/pacman/query.c index 5d036881..a3546bad 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -26,7 +26,6 @@ #include <string.h> #include <sys/stat.h> #include <errno.h> -#include <unistd.h> #include <alpm.h> #include <alpm_list.h> @@ -43,15 +42,15 @@ static char *resolve_path(const char *file) str = calloc(PATH_MAX + 1, sizeof(char)); if(!str) { - return(NULL); + return NULL; } if(!realpath(file, str)) { free(str); - return(NULL); + return NULL; } - return(str); + return str; } /* check if filename exists in PATH */ @@ -60,16 +59,16 @@ static int search_path(char **filename, struct stat *bufptr) char *envpath, *envpathsplit, *path, *fullname; size_t flen; - if ((envpath = getenv("PATH")) == NULL) { - return(-1); + if((envpath = getenv("PATH")) == NULL) { + return -1; } - if ((envpath = envpathsplit = strdup(envpath)) == NULL) { - return(-1); + if((envpath = envpathsplit = strdup(envpath)) == NULL) { + return -1; } flen = strlen(*filename); - while ((path = strsep(&envpathsplit, ":")) != NULL) { + while((path = strsep(&envpathsplit, ":")) != NULL) { size_t plen = strlen(path); /* strip the trailing slash if one exists */ @@ -84,17 +83,17 @@ static int search_path(char **filename, struct stat *bufptr) free(*filename); *filename = fullname; free(envpath); - return(0); + return 0; } free(fullname); } free(envpath); - return(-1); + return -1; } static void print_query_fileowner(const char *filename, pmpkg_t *info) { - if (!config->quiet) { + if(!config->quiet) { printf(_("%s is owned by %s %s\n"), filename, alpm_pkg_get_name(info), alpm_pkg_get_version(info)); } else { @@ -115,7 +114,7 @@ static int query_fileowner(alpm_list_t *targets) /* This code is here for safety only */ if(targets == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, _("no file was specified for --owns\n")); - return(1); + return 1; } /* Set up our root path buffer. We only need to copy the location of root in @@ -167,7 +166,7 @@ static int query_fileowner(alpm_list_t *targets) bname = mbasename(filename); dname = mdirname(filename); /* for files in '/', there is no directory name to match */ - if (strcmp(dname, "") == 0) { + if(strcmp(dname, "") == 0) { rpath = NULL; } else { rpath = resolve_path(dname); @@ -248,29 +247,21 @@ static int query_search(alpm_list_t *targets) freelist = 0; } if(searchlist == NULL) { - return(1); + return 1; } for(i = searchlist; i; i = alpm_list_next(i)) { alpm_list_t *grp; pmpkg_t *pkg = alpm_list_getdata(i); - if (!config->quiet) { + if(!config->quiet) { printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } else { printf("%s", alpm_pkg_get_name(pkg)); } - /* print the package size with the output if ShowSize option set */ - if(!config->quiet && config->showsize) { - /* Convert byte size to MB */ - double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0); - - printf(" [%.2f MB]", mbsize); - } - - if (!config->quiet) { + if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; printf(" ("); @@ -296,7 +287,7 @@ static int query_search(alpm_list_t *targets) if(freelist) { alpm_list_free(searchlist); } - return(0); + return 0; } static int query_group(alpm_list_t *targets) @@ -359,19 +350,19 @@ static int is_foreign(pmpkg_t *pkg) } } if(match == 0) { - return(1); + return 1; } - return(0); + return 0; } static int is_unrequired(pmpkg_t *pkg) { alpm_list_t *requiredby = alpm_pkg_compute_requiredby(pkg); if(requiredby == NULL) { - return(1); + return 1; } FREELIST(requiredby); - return(0); + return 0; } static int filter(pmpkg_t *pkg) @@ -379,26 +370,26 @@ static int filter(pmpkg_t *pkg) /* check if this package was explicitly installed */ if(config->op_q_explicit && alpm_pkg_get_reason(pkg) != PM_PKG_REASON_EXPLICIT) { - return(0); + return 0; } /* check if this package was installed as a dependency */ if(config->op_q_deps && alpm_pkg_get_reason(pkg) != PM_PKG_REASON_DEPEND) { - return(0); + return 0; } /* check if this pkg isn't in a sync DB */ if(config->op_q_foreign && !is_foreign(pkg)) { - return(0); + return 0; } /* check if this pkg is unrequired */ if(config->op_q_unrequired && !is_unrequired(pkg)) { - return(0); + return 0; } /* check if this pkg is outdated */ if(config->op_q_upgrade && (alpm_sync_newversion(pkg, alpm_option_get_syncdbs()) == NULL)) { - return(0); + return 0; } - return(1); + return 1; } /* Loop through the packages. For each package, @@ -416,7 +407,7 @@ static int check(pmpkg_t *pkg) if(rootlen + 1 > PATH_MAX) { /* we are in trouble here */ pm_fprintf(stderr, PM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); - return(1); + return 1; } strcpy(f, root); @@ -450,7 +441,7 @@ static int check(pmpkg_t *pkg) (unsigned long)errors), errors); } - return(errors != 0 ? 1 : 0); + return (errors != 0 ? 1 : 0); } static int display(pmpkg_t *pkg) @@ -476,13 +467,13 @@ static int display(pmpkg_t *pkg) } if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog && !config->op_q_check) { - if (!config->quiet) { + if(!config->quiet) { printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } else { printf("%s\n", alpm_pkg_get_name(pkg)); } } - return(ret); + return ret; } int pacman_query(alpm_list_t *targets) @@ -498,13 +489,13 @@ int pacman_query(alpm_list_t *targets) /* search for a package */ if(config->op_q_search) { ret = query_search(targets); - return(ret); + return ret; } /* looking for groups */ if(config->group) { ret = query_group(targets); - return(ret); + return ret; } if(config->op_q_foreign) { @@ -512,7 +503,7 @@ int pacman_query(alpm_list_t *targets) alpm_list_t *sync_dbs = alpm_option_get_syncdbs(); if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) { pm_printf(PM_LOG_ERROR, _("no usable package repositories configured.\n")); - return(1); + return 1; } } @@ -524,7 +515,7 @@ int pacman_query(alpm_list_t *targets) if(targets == NULL) { if(config->op_q_isfile || config->op_q_owns) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); - return(1); + return 1; } for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) { @@ -540,7 +531,7 @@ int pacman_query(alpm_list_t *targets) if(!match) { ret = 1; } - return(ret); + return ret; } /* Second: operations that require target(s) */ @@ -548,7 +539,7 @@ int pacman_query(alpm_list_t *targets) /* determine the owner of a file */ if(config->op_q_owns) { ret = query_fileowner(targets); - return(ret); + return ret; } /* operations on named packages in the local DB @@ -586,7 +577,7 @@ int pacman_query(alpm_list_t *targets) ret = 1; } - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/remove.c b/src/pacman/remove.c index fb02e242..58e6edd5 100644 --- a/src/pacman/remove.c +++ b/src/pacman/remove.c @@ -40,25 +40,25 @@ static int remove_target(char *target) if((info = alpm_db_get_pkg(db_local, target)) != NULL) { if(alpm_remove_pkg(info) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast()); - return(-1); + return -1; } - return(0); + return 0; } /* fallback to group */ pmgrp_t *grp = alpm_db_readgrp(db_local, target); if(grp == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': target not found\n", target); - return(-1); + return -1; } for(p = alpm_grp_get_pkgs(grp); p; p = alpm_list_next(p)) { pmpkg_t *pkg = alpm_list_getdata(p); if(alpm_remove_pkg(pkg) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", target, alpm_strerrorlast()); - return(-1); + return -1; } } - return(0); + return 0; } /** @@ -75,12 +75,12 @@ int pacman_remove(alpm_list_t *targets) if(targets == NULL) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); - return(1); + return 1; } /* Step 0: create a new transaction */ if(trans_init(config->flags) == -1) { - return(1); + return 1; } /* Step 1: add targets to the created transaction */ @@ -173,7 +173,7 @@ cleanup: if(trans_release() == -1) { retval = 1; } - return(retval); + return retval; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/sync.c b/src/pacman/sync.c index c56934b6..64d8cb08 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -47,7 +47,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) { dir = opendir(dbpath); if(dir == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, _("could not access database directory\n")); - return(1); + return 1; } syncdbs = alpm_option_get_syncdbs(); @@ -84,7 +84,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) { pm_fprintf(stderr, PM_LOG_ERROR, _("could not remove %s\n"), path); closedir(dir); - return(1); + return 1; } continue; } @@ -110,12 +110,12 @@ static int sync_cleandb(const char *dbpath, int keep_used) { pm_fprintf(stderr, PM_LOG_ERROR, _("could not remove %s\n"), path); closedir(dir); - return(1); + return 1; } } } closedir(dir); - return(0); + return 0; } static int sync_cleandb_all(void) { @@ -126,7 +126,7 @@ static int sync_cleandb_all(void) { dbpath = alpm_option_get_dbpath(); printf(_("Database directory: %s\n"), dbpath); if(!yesno(_("Do you want to remove unused repositories?"))) { - return(0); + return 0; } /* The sync dbs were previously put in dbpath/ but are now in dbpath/sync/. * We will clean everything in dbpath/ except local/, sync/ and db.lck, and @@ -137,7 +137,7 @@ static int sync_cleandb_all(void) { ret += sync_cleandb(newdbpath, 1); printf(_("Database directory cleaned up\n")); - return(ret); + return ret; } static int sync_cleancache(int level) @@ -148,7 +148,7 @@ static int sync_cleancache(int level) int ret = 0; for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) { - printf(_("Cache directory: %s\n"), (char*)alpm_list_getdata(i)); + printf(_("Cache directory: %s\n"), (char *)alpm_list_getdata(i)); } if(!config->cleanmethod) { @@ -165,12 +165,12 @@ static int sync_cleancache(int level) printf(_(" All current sync database packages\n")); } if(!yesno(_("Do you want to remove all other packages from cache?"))) { - return(0); + return 0; } printf(_("removing old packages from cache...\n")); } else { if(!noyes(_("Do you want to remove ALL files from cache?"))) { - return(0); + return 0; } printf(_("removing all files from cache...\n")); } @@ -258,7 +258,7 @@ static int sync_cleancache(int level) closedir(dir); } - return(ret); + return ret; } static int sync_synctree(int level, alpm_list_t *syncs) @@ -267,7 +267,7 @@ static int sync_synctree(int level, alpm_list_t *syncs) int success = 0, ret; if(trans_init(0) == -1) { - return(0); + return 0; } for(i = syncs; i; i = alpm_list_next(i)) { @@ -286,7 +286,7 @@ static int sync_synctree(int level, alpm_list_t *syncs) } if(trans_release() == -1) { - return(0); + 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 @@ -295,7 +295,7 @@ static int sync_synctree(int level, alpm_list_t *syncs) if(!success) { pm_fprintf(stderr, PM_LOG_ERROR, _("failed to synchronize any databases\n")); } - return(success > 0); + return (success > 0); } static void print_installed(pmdb_t *db_local, pmpkg_t *pkg) @@ -340,22 +340,14 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) alpm_list_t *grp; pmpkg_t *pkg = alpm_list_getdata(j); - if (!config->quiet) { + if(!config->quiet) { printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } else { printf("%s", alpm_pkg_get_name(pkg)); } - /* print the package size with the output if ShowSize option set */ - if(!config->quiet && config->showsize) { - /* Convert byte size to MB */ - double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0); - - printf(" [%.2f MB]", mbsize); - } - - if (!config->quiet) { + if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; printf(" ("); @@ -384,7 +376,7 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) } } - return(!found); + return !found; } static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets) @@ -432,7 +424,7 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets) } } - return(0); + return 0; } static int sync_info(alpm_list_t *syncs, alpm_list_t *targets) @@ -466,7 +458,7 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets) if(!db) { pm_fprintf(stderr, PM_LOG_ERROR, _("repository '%s' does not exist\n"), repo); - return(1); + return 1; } for(k = alpm_db_get_pkgcache(db); k; k = alpm_list_next(k)) { @@ -517,7 +509,7 @@ static int sync_info(alpm_list_t *syncs, alpm_list_t *targets) } } - return(ret); + return ret; } static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) @@ -543,7 +535,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) pm_fprintf(stderr, PM_LOG_ERROR, _("repository \"%s\" was not found.\n"),repo); alpm_list_free(ls); - return(1); + return 1; } ls = alpm_list_add(ls, db); @@ -558,7 +550,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) { pmpkg_t *pkg = alpm_list_getdata(j); - if (!config->quiet) { + if(!config->quiet) { printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); print_installed(db_local, pkg); @@ -573,7 +565,7 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) alpm_list_free(ls); } - return(0); + return 0; } static alpm_list_t *syncfirst(void) { @@ -592,7 +584,7 @@ static alpm_list_t *syncfirst(void) { } } - return(res); + return res; } static pmdb_t *get_db(const char *dbname) @@ -601,10 +593,10 @@ static pmdb_t *get_db(const char *dbname) for(i = alpm_option_get_syncdbs(); i; i = i->next) { pmdb_t *db = i->data; if(strcmp(alpm_db_get_name(db), dbname) == 0) { - return(db); + return db; } } - return(NULL); + return NULL; } static int process_pkg(pmpkg_t *pkg) @@ -616,14 +608,14 @@ static int process_pkg(pmpkg_t *pkg) || pm_errno == PM_ERR_PKG_IGNORED) { /* just skip duplicate or ignored targets */ pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), alpm_pkg_get_name(pkg)); - return(0); + return 0; } else { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", alpm_pkg_get_name(pkg), alpm_strerrorlast()); - return(1); + return 1; } } - return(0); + return 0; } static int process_group(alpm_list_t *dbs, char *group) @@ -635,7 +627,7 @@ static int process_group(alpm_list_t *dbs, char *group) if(!count) { pm_fprintf(stderr, PM_LOG_ERROR, _("target not found: %s\n"), group); - return(1); + return 1; } @@ -669,7 +661,7 @@ static int process_group(alpm_list_t *dbs, char *group) } cleanup: alpm_list_free(pkgs); - return(ret); + return ret; } static int process_targname(alpm_list_t *dblist, char *targname) @@ -680,14 +672,14 @@ static int process_targname(alpm_list_t *dblist, char *targname) if(pm_errno == PM_ERR_PKG_IGNORED) { pm_printf(PM_LOG_WARNING, _("skipping target: %s\n"), targname); pm_errno = 0; - return(0); + return 0; } if(pkg) { - return(process_pkg(pkg)); + return process_pkg(pkg); } /* fallback on group */ - return(process_group(dblist, targname)); + return process_group(dblist, targname); } static int process_target(char *target) @@ -722,7 +714,7 @@ static int process_target(char *target) } cleanup: free(targstring); - return(ret); + return ret; } static int sync_trans(alpm_list_t *targets) @@ -734,7 +726,7 @@ static int sync_trans(alpm_list_t *targets) /* Step 1: create a new transaction... */ if(trans_init(config->flags) == -1) { - return(1); + return 1; } /* process targets */ @@ -874,7 +866,7 @@ cleanup: retval = 1; } - return(retval); + return retval; } int pacman_sync(alpm_list_t *targets) @@ -886,7 +878,7 @@ int pacman_sync(alpm_list_t *targets) int ret = 0; if(trans_init(0) == -1) { - return(1); + return 1; } ret += sync_cleancache(config->op_s_clean); @@ -897,14 +889,14 @@ int pacman_sync(alpm_list_t *targets) ret++; } - return(ret); + return ret; } /* ensure we have at least one valid sync db set up */ sync_dbs = alpm_option_get_syncdbs(); if(sync_dbs == NULL || alpm_list_count(sync_dbs) == 0) { pm_printf(PM_LOG_ERROR, _("no usable package repositories configured.\n")); - return(1); + return 1; } if(config->op_s_sync) { @@ -912,40 +904,40 @@ int pacman_sync(alpm_list_t *targets) printf(_(":: Synchronizing package databases...\n")); alpm_logaction("synchronizing package lists\n"); if(!sync_synctree(config->op_s_sync, sync_dbs)) { - return(1); + return 1; } } /* search for a package */ if(config->op_s_search) { - return(sync_search(sync_dbs, targets)); + return sync_search(sync_dbs, targets); } /* look for groups */ if(config->group) { - return(sync_group(config->group, sync_dbs, targets)); + return sync_group(config->group, sync_dbs, targets); } /* get package info */ if(config->op_s_info) { - return(sync_info(sync_dbs, targets)); + return sync_info(sync_dbs, targets); } /* get a listing of files in sync DBs */ if(config->op_q_list) { - return(sync_list(sync_dbs, targets)); + return sync_list(sync_dbs, targets); } if(targets == NULL) { if(config->op_s_upgrade) { /* proceed */ } else if(config->op_s_sync) { - return(0); + return 0; } else { /* 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); + return 1; } } @@ -980,7 +972,7 @@ int pacman_sync(alpm_list_t *targets) int ret = sync_trans(targs); FREELIST(targs); - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/upgrade.c b/src/pacman/upgrade.c index 8cd29da0..5b894001 100644 --- a/src/pacman/upgrade.c +++ b/src/pacman/upgrade.c @@ -46,7 +46,7 @@ int pacman_upgrade(alpm_list_t *targets) if(targets == NULL) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); - return(1); + return 1; } /* Check for URL targets and process them @@ -57,7 +57,7 @@ int pacman_upgrade(alpm_list_t *targets) if(str == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", (char *)i->data, alpm_strerrorlast()); - return(1); + return 1; } else { free(i->data); i->data = str; @@ -67,7 +67,7 @@ int pacman_upgrade(alpm_list_t *targets) /* Step 1: create a new transaction */ if(trans_init(config->flags) == -1) { - return(1); + return 1; } /* add targets to the created transaction */ @@ -79,14 +79,14 @@ int pacman_upgrade(alpm_list_t *targets) pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerrorlast()); trans_release(); - return(1); + return 1; } if(alpm_add_pkg(pkg) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerrorlast()); alpm_pkg_free(pkg); trans_release(); - return(1); + return 1; } } @@ -135,7 +135,7 @@ int pacman_upgrade(alpm_list_t *targets) } trans_release(); FREELIST(data); - return(1); + return 1; } /* Step 3: perform the installation */ @@ -143,7 +143,7 @@ int pacman_upgrade(alpm_list_t *targets) if(config->print) { print_packages(alpm_trans_get_add()); trans_release(); - return(0); + return 0; } /* print targets and ask user confirmation */ @@ -151,7 +151,7 @@ int pacman_upgrade(alpm_list_t *targets) if(packages == NULL) { /* we are done */ printf(_(" there is nothing to do\n")); trans_release(); - return(retval); + return retval; } display_targets(alpm_trans_get_remove(), 0); display_targets(alpm_trans_get_add(), 1); @@ -159,7 +159,7 @@ int pacman_upgrade(alpm_list_t *targets) int confirm = yesno(_("Proceed with installation?")); if(!confirm) { trans_release(); - return(retval); + return retval; } if(alpm_trans_commit(&data) == -1) { @@ -197,13 +197,13 @@ int pacman_upgrade(alpm_list_t *targets) } FREELIST(data); trans_release(); - return(1); + return 1; } if(trans_release() == -1) { retval = 1; } - return(retval); + return retval; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/util.c b/src/pacman/util.c index 3d268031..8d7e8e98 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -31,12 +31,14 @@ #include <stdint.h> /* intmax_t */ #include <string.h> #include <errno.h> -#include <fcntl.h> #include <ctype.h> #include <dirent.h> #include <unistd.h> #include <limits.h> #include <wchar.h> +#ifdef HAVE_TERMIOS_H +#include <termios.h> /* tcflush */ +#endif #include <alpm.h> #include <alpm_list.h> @@ -68,9 +70,9 @@ int trans_init(pmtransflag_t flags) fprintf(stderr, _(" try running pacman-db-upgrade\n")); } - return(-1); + return -1; } - return(0); + return 0; } int trans_release(void) @@ -78,28 +80,40 @@ int trans_release(void) if(alpm_trans_release() == -1) { pm_fprintf(stderr, PM_LOG_ERROR, _("failed to release transaction (%s)\n"), alpm_strerrorlast()); - return(-1); + return -1; } - return(0); + return 0; } int needs_root(void) { switch(config->op) { case PM_OP_DATABASE: - return(1); + return 1; case PM_OP_UPGRADE: case PM_OP_REMOVE: - return(!config->print); + return !config->print; case PM_OP_SYNC: - return(config->op_s_clean || config->op_s_sync || + return (config->op_s_clean || config->op_s_sync || (!config->group && !config->op_s_info && !config->op_q_list && !config->op_s_search && !config->print)); default: - return(0); + return 0; } } +/* discard unhandled input on the terminal's input buffer */ +static int flush_term_input(void) { +#ifdef HAVE_TCFLUSH + if(isatty(fileno(stdin))) { + return(tcflush(fileno(stdin), TCIFLUSH)); + } +#endif + + /* fail silently */ + return 0; +} + /* gets the current screen column width */ int getcols(void) { @@ -125,24 +139,24 @@ int rmrf(const char *path) DIR *dirp; if(!unlink(path)) { - return(0); + return 0; } else { if(errno == ENOENT) { - return(0); + return 0; } else if(errno == EPERM) { /* fallthrough */ } else if(errno == EISDIR) { /* fallthrough */ } else if(errno == ENOTDIR) { - return(1); + return 1; } else { /* not a directory */ - return(1); + return 1; } dirp = opendir(path); if(!dirp) { - return(1); + return 1; } for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if(dp->d_ino) { @@ -157,7 +171,7 @@ int rmrf(const char *path) if(rmdir(path)) { errflag++; } - return(errflag); + return errflag; } } @@ -170,9 +184,9 @@ const char *mbasename(const char *path) { const char *last = strrchr(path, '/'); if(last) { - return(last + 1); + return last + 1; } - return(path); + return path; } /** Parse the dirname of a program from a path. @@ -187,7 +201,7 @@ char *mdirname(const char *path) /* null or empty path */ if(path == NULL || path == '\0') { - return(strdup(".")); + return strdup("."); } ret = strdup(path); @@ -196,11 +210,11 @@ char *mdirname(const char *path) if(last != NULL) { /* we found a '/', so terminate our string */ *last = '\0'; - return(ret); + return ret; } /* no slash found */ free(ret); - return(strdup(".")); + return strdup("."); } /* output a string, but wrap words properly with a specified indentation @@ -286,7 +300,7 @@ char *strtrim(char *str) if(str == NULL || *str == '\0') { /* string is empty, so we're done. */ - return(str); + return str; } while(isspace((unsigned char)*pch)) { @@ -298,7 +312,7 @@ char *strtrim(char *str) /* check if there wasn't anything but whitespace in the string. */ if(*str == '\0') { - return(str); + return str; } pch = (str + (strlen(str) - 1)); @@ -307,7 +321,7 @@ char *strtrim(char *str) } *++pch = '\0'; - return(str); + return str; } /* Replace all occurances of 'needle' with 'replace' in 'str', returning @@ -321,7 +335,7 @@ char *strreplace(const char *str, const char *needle, const char *replace) size_t newsz; if(!str) { - return(NULL); + return NULL; } p = str; @@ -334,7 +348,7 @@ char *strreplace(const char *str, const char *needle, const char *replace) /* no occurences of needle found */ if(!list) { - return(strdup(str)); + return strdup(str); } /* size of new string = size of old string + "number of occurences of needle" * x "size difference between replace and needle" */ @@ -342,7 +356,7 @@ char *strreplace(const char *str, const char *needle, const char *replace) alpm_list_count(list) * (replacesz - needlesz); newstr = malloc(newsz); if(!newstr) { - return(NULL); + return NULL; } *newstr = '\0'; @@ -368,7 +382,7 @@ char *strreplace(const char *str, const char *needle, const char *replace) } *newp = '\0'; - return(newstr); + return newstr; } /** Splits a string into a list of strings using the chosen character as @@ -388,7 +402,7 @@ alpm_list_t *strsplit(const char *str, const char splitchar) while((str = strchr(str, splitchar))) { dup = strndup(prev, (size_t)(str - prev)); if(dup == NULL) { - return(NULL); + return NULL; } list = alpm_list_add(list, dup); @@ -398,11 +412,11 @@ alpm_list_t *strsplit(const char *str, const char splitchar) dup = strdup(prev); if(dup == NULL) { - return(NULL); + return NULL; } list = alpm_list_add(list, dup); - return(list); + return list; } static int string_length(const char *s) @@ -411,7 +425,7 @@ static int string_length(const char *s) wchar_t *wcstr; if(!s) { - return(0); + return 0; } /* len goes from # bytes -> # chars -> # cols */ len = strlen(s) + 1; @@ -420,7 +434,7 @@ static int string_length(const char *s) len = wcswidth(wcstr, len); free(wcstr); - return(len); + return len; } void string_display(const char *title, const char *string) @@ -440,6 +454,116 @@ void string_display(const char *title, const char *string) printf("\n"); } +static void table_print_line(const alpm_list_t *line, + const alpm_list_t *formats) +{ + const alpm_list_t *curformat = formats; + const alpm_list_t *curcell = line; + + while(curcell && curformat) { + printf(alpm_list_getdata(curformat), alpm_list_getdata(curcell)); + curcell = alpm_list_next(curcell); + curformat = alpm_list_next(curformat); + } + + printf("\n"); +} + +/* creates format strings by checking max cell lengths in cols */ +static alpm_list_t *table_create_format(const alpm_list_t *header, + const alpm_list_t *rows) +{ + alpm_list_t *longest_str, *longest_strs = NULL; + alpm_list_t *formats = NULL; + const alpm_list_t *i, *row, *cell; + char *str, *formatstr; + const int padding = 2; + int colwidth, totalwidth = 0; + int curcol = 0; + + /* header determines column count and initial values of longest_strs */ + for(i = header; i; i = alpm_list_next(i)) { + longest_strs = alpm_list_add(longest_strs, alpm_list_getdata(i)); + } + + /* now find the longest string in each column */ + for(longest_str = longest_strs; longest_str; + longest_str = alpm_list_next(longest_str), curcol++) { + for(i = rows; i; i = alpm_list_next(i)) { + row = alpm_list_getdata(i); + cell = alpm_list_nth(row, curcol); + str = alpm_list_getdata(cell); + + if(strlen(str) > strlen(alpm_list_getdata(longest_str))) { + longest_str->data = str; + } + } + } + + /* now use the column width info to generate format strings */ + for(i = longest_strs; i; i = alpm_list_next(i)) { + colwidth = strlen(alpm_list_getdata(i)) + padding; + totalwidth += colwidth; + + /* right align the last column for a cleaner table display */ + str = (alpm_list_next(i) != NULL) ? "%%-%ds" : "%%%ds"; + pm_asprintf(&formatstr, str, colwidth); + + formats = alpm_list_add(formats, formatstr); + } + + alpm_list_free(longest_strs); + + /* return NULL if terminal is not wide enough */ + if(totalwidth > getcols()) { + fprintf(stderr, _("insufficient columns available for table display\n")); + FREELIST(formats); + return(NULL); + } + + return(formats); +} + +/** Displays the list in table format + * + * @param title the tables title + * @param header the column headers. column count is determined by the nr + * of headers + * @param rows the rows to display as a list of lists of strings. the outer + * list represents the rows, the inner list the cells (= columns) + * + * @return -1 if not enough terminal cols available, else 0 + */ +int table_display(const char *title, const alpm_list_t *header, + const alpm_list_t *rows) +{ + const alpm_list_t *i; + alpm_list_t *formats; + + if(rows == NULL || header == NULL) { + return(0); + } + + formats = table_create_format(header, rows); + if(formats == NULL) { + return(-1); + } + + if(title != NULL) { + printf("%s\n\n", title); + } + + table_print_line(header, formats); + printf("\n"); + + for(i = rows; i; i = alpm_list_next(i)) { + table_print_line(alpm_list_getdata(i), formats); + } + + FREELIST(formats); + return(0); +} + void list_display(const char *title, const alpm_list_t *list) { const alpm_list_t *i; @@ -464,7 +588,7 @@ void list_display(const char *title, const alpm_list_t *list) for (j = 1; j <= len; j++) { printf(" "); } - } else if (cols != len) { + } else if(cols != len) { /* 2 spaces are added if this is not the first element on a line. */ printf(" "); cols += 2; @@ -503,20 +627,74 @@ void list_display_linebreak(const char *title, const alpm_list_t *list) } } } + +/* creates a header row for use with table_display */ +static alpm_list_t *create_verbose_header(int install) +{ + alpm_list_t *res = NULL; + char *str; + + pm_asprintf(&str, "%s", _("Name")); + res = alpm_list_add(res, str); + pm_asprintf(&str, "%s", _("Old Version")); + res = alpm_list_add(res, str); + if(install) { + pm_asprintf(&str, "%s", _("New Version")); + res = alpm_list_add(res, str); + } + pm_asprintf(&str, "%s", _("Size")); + res = alpm_list_add(res, str); + + return(res); +} + +/* returns package info as list of strings */ +static alpm_list_t *create_verbose_row(pmpkg_t *pkg, int install) +{ + char *str; + double size; + const char *label; + alpm_list_t *ret = NULL; + pmdb_t *ldb = alpm_option_get_localdb(); + + /* a row consists of the package name, */ + pm_asprintf(&str, "%s", alpm_pkg_get_name(pkg)); + ret = alpm_list_add(ret, str); + + /* old and new versions */ + if(install) { + pmpkg_t *oldpkg = alpm_db_get_pkg(ldb, alpm_pkg_get_name(pkg)); + pm_asprintf(&str, "%s", + oldpkg != NULL ? alpm_pkg_get_version(oldpkg) : ""); + ret = alpm_list_add(ret, str); + } + + pm_asprintf(&str, "%s", alpm_pkg_get_version(pkg)); + ret = alpm_list_add(ret, str); + + /* and size */ + size = humanize_size(alpm_pkg_get_size(pkg), 'M', 1, &label); + pm_asprintf(&str, "%.2f %s", size, label); + ret = alpm_list_add(ret, str); + + return(ret); +} + /* prepare a list of pkgs to display */ void display_targets(const alpm_list_t *pkgs, int install) { char *str; + const char *title, *label; + double size; const alpm_list_t *i; off_t isize = 0, dlsize = 0; - double mbisize = 0.0, mbdlsize = 0.0; - alpm_list_t *targets = NULL; + alpm_list_t *j, *lp, *header = NULL, *targets = NULL; if(!pkgs) { return; } - printf("\n"); + /* gather pkg infos */ for(i = pkgs; i; i = alpm_list_next(i)) { pmpkg_t *pkg = alpm_list_getdata(i); @@ -525,54 +703,69 @@ void display_targets(const alpm_list_t *pkgs, int install) } isize += alpm_pkg_get_isize(pkg); - /* print the package size with the output if ShowSize option set */ - if(config->showsize) { - double mbsize = (double)alpm_pkg_get_size(pkg) / (1024.0 * 1024.0); - - pm_asprintf(&str, "%s-%s [%.2f MB]", alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg), mbsize); + if(config->verbosepkglists) { + targets = alpm_list_add(targets, create_verbose_row(pkg, install)); } else { pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + targets = alpm_list_add(targets, str); } - targets = alpm_list_add(targets, str); } - /* Convert byte sizes to MB */ - mbdlsize = (double)dlsize / (1024.0 * 1024.0); - mbisize = (double)isize / (1024.0 * 1024.0); + /* print to screen */ + title = install ? _("Targets (%d):") : _("Remove (%d):"); + pm_asprintf(&str, title, alpm_list_count(pkgs)); - if(install) { - pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets)); + printf("\n"); + if(config->verbosepkglists) { + header = create_verbose_header(install); + if(table_display(str, header, targets) != 0) { + config->verbosepkglists = 0; + display_targets(pkgs, install); + goto out; + } + } else { list_display(str, targets); - free(str); - printf("\n"); + } + printf("\n"); - printf(_("Total Download Size: %.2f MB\n"), mbdlsize); + if(install) { + size = humanize_size(dlsize, 'M', 1, &label); + printf(_("Total Download Size: %.2f %s\n"), size, label); if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY)) { - printf(_("Total Installed Size: %.2f MB\n"), mbisize); + size = humanize_size(isize, 'M', 1, &label); + printf(_("Total Installed Size: %.2f %s\n"), size, label); } } else { - pm_asprintf(&str, _("Remove (%d):"), alpm_list_count(targets)); - list_display(str, targets); - free(str); - printf("\n"); - - printf(_("Total Removed Size: %.2f MB\n"), mbisize); + size = humanize_size(isize, 'M', 1, &label); + printf(_("Total Removed Size: %.2f %s\n"), size, label); } - FREELIST(targets); +out: + /* cleanup */ + if(config->verbosepkglists) { + /* targets is a list of lists of strings, free inner lists here */ + for(j = alpm_list_first(targets); j; j = alpm_list_next(j)) { + lp = alpm_list_getdata(j); + FREELIST(lp); + } + alpm_list_free(targets); + FREELIST(header); + } else { + FREELIST(targets); + } + free(str); } static off_t pkg_get_size(pmpkg_t *pkg) { switch(config->op) { case PM_OP_SYNC: - return(alpm_pkg_download_size(pkg)); + return alpm_pkg_download_size(pkg); case PM_OP_UPGRADE: - return(alpm_pkg_get_size(pkg)); + return alpm_pkg_get_size(pkg); default: - return(alpm_pkg_get_isize(pkg)); + return alpm_pkg_get_isize(pkg); } } @@ -588,17 +781,55 @@ static char *pkg_get_location(pmpkg_t *pkg) if(dburl) { char *pkgurl = NULL; pm_asprintf(&pkgurl, "%s/%s", dburl, alpm_pkg_get_filename(pkg)); - return(pkgurl); + return pkgurl; } case PM_OP_UPGRADE: - return(strdup(alpm_pkg_get_filename(pkg))); + return strdup(alpm_pkg_get_filename(pkg)); default: string = NULL; pm_asprintf(&string, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); - return(string); + return string; } } +/** Converts sizes in bytes into human readable units. + * + * @param bytes the size in bytes + * @param target_unit '\0' or a short label. If equal to one of the short unit + * labels ('B', 'K', ...) bytes is converted to target_unit; if '\0', the first + * unit which will bring the value to below a threshold of 2048 will be chosen. + * @param long_labels whether to use short ("K") or long ("KiB") unit labels + * @param label will be set to the appropriate unit label + * + * @return the size in the appropriate unit + */ +double humanize_size(off_t bytes, const char target_unit, int long_labels, + const char **label) +{ + static const char *shortlabels[] = {"B", "K", "M", "G", "T", "P"}; + static const char *longlabels[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"}; + static const int unitcount = sizeof(shortlabels) / sizeof(shortlabels[0]); + + const char **labels = long_labels ? longlabels : shortlabels; + double val = (double)bytes; + int index; + + for(index = 0; index < unitcount - 1; index++) { + if(target_unit != '\0' && shortlabels[index][0] == target_unit) { + break; + } else if(target_unit == '\0' && val <= 2048.0) { + break; + } + val /= 1024.0; + } + + if(label) { + *label = labels[index]; + } + + return(val); +} + void print_packages(const alpm_list_t *packages) { const alpm_list_t *i; @@ -657,7 +888,7 @@ void print_packages(const alpm_list_t *packages) * alpm "compare func" signature */ int str_cmp(const void *s1, const void *s2) { - return(strcmp(s1, s2)); + return strcmp(s1, s2); } void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg) @@ -726,13 +957,13 @@ static int parseindex(char *s, int *val, int min, int max) if(n < min || n > max) { fprintf(stderr, _("Invalid value: %d is not between %d and %d\n"), n, min, max); - return(-1); + return -1; } *val = n; - return(0); + return 0; } else { fprintf(stderr, _("Invalid number: %s\n"), s); - return(-1); + return -1; } } @@ -746,7 +977,7 @@ static int multiselect_parse(char *array, int count, char *response) char *ends = NULL; char *starts = strtok_r(str, " ", &saveptr); - if (starts == NULL) { + if(starts == NULL) { break; } strtrim(starts); @@ -754,7 +985,7 @@ static int multiselect_parse(char *array, int count, char *response) if(len == 0) continue; - if (*starts == '^') { + if(*starts == '^') { starts++; len--; include = 0; @@ -773,14 +1004,14 @@ static int multiselect_parse(char *array, int count, char *response) } if(parseindex(starts, &start, 1, count) != 0) - return(-1); + return -1; if(!ends) { array[start-1] = include; } else { int d; if(parseindex(ends, &end, start, count) != 0) { - return(-1); + return -1; } for(d = start; d <= end; d++) { array[d-1] = include; @@ -788,7 +1019,7 @@ static int multiselect_parse(char *array, int count, char *response) } } - return(0); + return 0; } int multiselect_question(char *array, int count) @@ -815,6 +1046,8 @@ int multiselect_question(char *array, int count) break; } + flush_term_input(); + if(fgets(response, sizeof(response), stdin)) { strtrim(response); if(strlen(response) > 0) { @@ -826,7 +1059,7 @@ int multiselect_question(char *array, int count) } break; } - return(0); + return 0; } int select_question(int count) @@ -852,19 +1085,21 @@ int select_question(int count) break; } + flush_term_input(); + if(fgets(response, sizeof(response), stdin)) { strtrim(response); if(strlen(response) > 0) { int n; if(parseindex(response, &n, 1, count) != 0) continue; - return(n-1); + return (n - 1); } } break; } - return(preset-1); + return (preset - 1); } @@ -895,23 +1130,25 @@ static int question(short preset, char *fmt, va_list args) if(config->noconfirm) { fprintf(stream, "\n"); - return(preset); + return preset; } fflush(stream); + flush_term_input(); + if(fgets(response, sizeof(response), stdin)) { strtrim(response); if(strlen(response) == 0) { - return(preset); + return preset; } if(strcasecmp(response, _("Y")) == 0 || strcasecmp(response, _("YES")) == 0) { - return(1); - } else if (strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) { - return(0); + return 1; + } else if(strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) { + return 0; } } - return(0); + return 0; } int yesno(char *fmt, ...) @@ -923,7 +1160,7 @@ int yesno(char *fmt, ...) ret = question(1, fmt, args); va_end(args); - return(ret); + return ret; } int noyes(char *fmt, ...) @@ -935,7 +1172,7 @@ int noyes(char *fmt, ...) ret = question(0, fmt, args); va_end(args); - return(ret); + return ret; } int pm_printf(pmloglevel_t level, const char *format, ...) @@ -948,7 +1185,7 @@ int pm_printf(pmloglevel_t level, const char *format, ...) ret = pm_vfprintf(stdout, level, format, args); va_end(args); - return(ret); + return ret; } int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...) @@ -961,7 +1198,7 @@ int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...) ret = pm_vfprintf(stream, level, format, args); va_end(args); - return(ret); + return ret; } int pm_asprintf(char **string, const char *format, ...) @@ -977,7 +1214,7 @@ int pm_asprintf(char **string, const char *format, ...) } va_end(args); - return(ret); + return ret; } int pm_vasprintf(char **string, pmloglevel_t level, const char *format, va_list args) @@ -1013,7 +1250,7 @@ int pm_vasprintf(char **string, pmloglevel_t level, const char *format, va_list } free(msg); - return(ret); + return ret; } int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args) @@ -1061,7 +1298,7 @@ int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list ar /* print the message using va_arg list */ ret = vfprintf(stream, format, args); - return(ret); + return ret; } #ifndef HAVE_STRNDUP @@ -1070,7 +1307,7 @@ static size_t strnlen(const char *s, size_t max) { register const char *p; for(p = s; *p && max--; ++p); - return(p - s); + return (p - s); } char *strndup(const char *s, size_t n) @@ -1078,11 +1315,11 @@ char *strndup(const char *s, size_t n) size_t len = strnlen(s, n); char *new = (char *) malloc(len + 1); - if (new == NULL) + if(new == NULL) return NULL; new[len] = '\0'; - return (char *) memcpy(new, s, len); + return (char *)memcpy(new, s, len); } #endif diff --git a/src/pacman/util.h b/src/pacman/util.h index 234a631d..d8ae7d80 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -52,6 +52,8 @@ char *strtrim(char *str); char *strreplace(const char *str, const char *needle, const char *replace); alpm_list_t *strsplit(const char *str, const char splitchar); void string_display(const char *title, const char *string); +double humanize_size(off_t bytes, const char target_unit, int long_labels, const char **label); +int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows); void list_display(const char *title, const alpm_list_t *list); void list_display_linebreak(const char *title, const alpm_list_t *list); void display_targets(const alpm_list_t *pkgs, int install); diff --git a/src/util/cleanupdelta.c b/src/util/cleanupdelta.c index 71ba3a47..6388e840 100644 --- a/src/util/cleanupdelta.c +++ b/src/util/cleanupdelta.c @@ -119,7 +119,7 @@ int main(int argc, char *argv[]) if(alpm_initialize() == -1) { fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); - return(1); + return 1; } /* let us get log messages from libalpm */ diff --git a/src/util/pactree.c b/src/util/pactree.c index 6a10006f..1c6aebf2 100644 --- a/src/util/pactree.c +++ b/src/util/pactree.c @@ -60,12 +60,12 @@ static int alpm_local_init(void) ret = alpm_initialize(); if(ret != 0) { - return(ret); + return ret; } ret = alpm_option_set_root(ROOTDIR); if(ret != 0) { - return(ret); + return ret; } if(dbpath) { @@ -74,15 +74,15 @@ static int alpm_local_init(void) ret = alpm_option_set_dbpath(DBPATH); } if(ret != 0) { - return(ret); + return ret; } db_local = alpm_option_get_localdb(); if(!db_local) { - return(1); + return 1; } - return(0); + return 0; } static int parse_options(int argc, char *argv[]) @@ -137,12 +137,12 @@ static int parse_options(int argc, char *argv[]) case 'h': case '?': default: - return(1); + return 1; } } if(!argv[optind]) { - return(1); + return 1; } if(!color) { @@ -159,7 +159,7 @@ static int parse_options(int argc, char *argv[]) indent_size = 0; } - return(0); + return 0; } static void usage(void) @@ -267,7 +267,7 @@ static void walk_reverse_deps(pmpkg_t *pkg, int depth) return; } - walked = alpm_list_add(walked, (void*)alpm_pkg_get_name(pkg)); + walked = alpm_list_add(walked, (void *)alpm_pkg_get_name(pkg)); required_by = alpm_pkg_compute_requiredby(pkg); for(i = required_by; i; i = alpm_list_next(i)) { @@ -299,7 +299,7 @@ static void walk_deps(pmpkg_t *pkg, int depth) return; } - walked = alpm_list_add(walked, (void*)alpm_pkg_get_name(pkg)); + walked = alpm_list_add(walked, (void *)alpm_pkg_get_name(pkg)); for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) { pmdepend_t *depend = alpm_list_getdata(i); @@ -366,7 +366,7 @@ int main(int argc, char *argv[]) finish: cleanup(); - return(ret); + return ret; } /* vim: set ts=2 sw=2 noet: */ diff --git a/src/util/testdb.c b/src/util/testdb.c index 0436a23f..b29e49f4 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -63,10 +63,10 @@ static int check_localdb_files(void) snprintf(path, sizeof(path), "%slocal", dbpath); if(!(dir = opendir(path))) { fprintf(stderr, "error : %s : %s\n", path, strerror(errno)); - return(1); + return 1; } - while ((ent = readdir(dir)) != NULL) { + while((ent = readdir(dir)) != NULL) { if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 || ent->d_name[0] == '.') { continue; @@ -85,10 +85,10 @@ static int check_localdb_files(void) } if(closedir(dir)) { fprintf(stderr, "error closing dbpath : %s\n", strerror(errno)); - return(1); + return 1; } - return(ret); + return ret; } static int checkdeps(alpm_list_t *pkglist) @@ -107,7 +107,7 @@ static int checkdeps(alpm_list_t *pkglist) ret++; } FREELIST(data); - return(ret); + return ret; } static int checkconflicts(alpm_list_t *pkglist) @@ -123,7 +123,7 @@ static int checkconflicts(alpm_list_t *pkglist) ret++; } FREELIST(data); - return(ret); + return ret; } static int check_localdb(void) { @@ -133,7 +133,7 @@ static int check_localdb(void) { ret = check_localdb_files(); if(ret) { - return(ret); + return ret; } db = alpm_option_get_localdb(); @@ -145,7 +145,7 @@ static int check_localdb(void) { pkglist = alpm_db_get_pkgcache(db); ret += checkdeps(pkglist); ret += checkconflicts(pkglist); - return(ret); + return ret; } static int check_syncdbs(alpm_list_t *dbnames) { @@ -169,7 +169,7 @@ static int check_syncdbs(alpm_list_t *dbnames) { cleanup: alpm_list_free(syncpkglist); - return(ret); + return ret; } static void usage(void) { @@ -206,7 +206,7 @@ int main(int argc, char *argv[]) if(alpm_initialize() == -1) { fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); - return(EXIT_FAILURE); + return EXIT_FAILURE; } /* let us get log messages from libalpm */ @@ -214,7 +214,7 @@ int main(int argc, char *argv[]) if(alpm_option_set_dbpath(dbpath) != 0) { fprintf(stderr, "cannot set dbpath: %s\n", alpm_strerrorlast()); - return(EXIT_FAILURE); + return EXIT_FAILURE; } if(!dbnames) { diff --git a/src/util/testpkg.c b/src/util/testpkg.c index d0d9cac1..e562dde2 100644 --- a/src/util/testpkg.c +++ b/src/util/testpkg.c @@ -44,12 +44,12 @@ int main(int argc, char *argv[]) if(argc != 2) { fprintf(stderr, "usage: %s <package file>\n", BASENAME); - return(1); + return 1; } if(alpm_initialize() == -1) { fprintf(stderr, "cannot initialize alpm: %s\n", alpm_strerrorlast()); - return(1); + return 1; } /* let us get log messages from libalpm */ @@ -79,5 +79,5 @@ int main(int argc, char *argv[]) fprintf(stderr, "error releasing alpm: %s\n", alpm_strerrorlast()); } - return(retval); + return retval; } diff --git a/src/util/vercmp.c b/src/util/vercmp.c index adb5a42a..88cf49a6 100644 --- a/src/util/vercmp.c +++ b/src/util/vercmp.c @@ -45,13 +45,13 @@ int main(int argc, char *argv[]) if(argc == 1) { usage(); - return(2); + return 2; } if(argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "--usage") == 0)) { usage(); - return(0); + return 0; } if(argc > 2) { s2 = argv[2]; @@ -62,5 +62,5 @@ int main(int argc, char *argv[]) ret = alpm_pkg_vercmp(s1, s2); printf("%d\n", ret); - return(EXIT_SUCCESS); + return EXIT_SUCCESS; } diff --git a/test/pacman/pmdb.py b/test/pacman/pmdb.py index b31498a7..1af24ae9 100755 --- a/test/pacman/pmdb.py +++ b/test/pacman/pmdb.py @@ -89,6 +89,12 @@ class pmdb(object): def __str__(self): return "%s" % self.treename + def getverify(self): + for value in "Always","Never","Optional": + if value in self.treename: + return value + return "Never" + def getpkg(self, name): """ """ @@ -150,6 +156,8 @@ class pmdb(object): pkg.size = int(fd.readline().strip("\n")) elif line == "%MD5SUM%": pkg.md5sum = fd.readline().strip("\n") + elif line == "%PGPSIG%": + pkg.pgpsig = fd.readline().strip("\n") elif line == "%REPLACES%": pkg.replaces = _getsection(fd) elif line == "%DEPENDS%": @@ -241,6 +249,8 @@ class pmdb(object): data.append(_mksection("CSIZE", pkg.csize)) if pkg.md5sum: data.append(_mksection("MD5SUM", pkg.md5sum)) + if pkg.pgpsig: + data.append(_mksection("PGPSIG", pkg.pgpsig)) if data: data.append("") filename = os.path.join(path, "desc") diff --git a/test/pacman/pmpkg.py b/test/pacman/pmpkg.py index 73156ab2..59204265 100755 --- a/test/pacman/pmpkg.py +++ b/test/pacman/pmpkg.py @@ -27,7 +27,7 @@ import util class pmpkg(object): """Package object. - Object holding data from an ArchLinux package. + Object holding data from an Arch Linux package. """ def __init__(self, name, version = "1.0-1"): @@ -47,6 +47,7 @@ class pmpkg(object): self.csize = 0 self.reason = 0 self.md5sum = "" # sync only + self.pgpsig = "" # sync only self.replaces = [] self.depends = [] self.optdepends = [] @@ -88,7 +89,7 @@ class pmpkg(object): return "%s%s" % (self.fullname(), util.PM_EXT_PKG) def makepkg(self, path): - """Creates an ArchLinux package archive. + """Creates an Arch Linux package archive. A package archive is generated in the location 'path', based on the data from the object. diff --git a/test/pacman/tests/sign001.py b/test/pacman/tests/sign001.py new file mode 100644 index 00000000..0ae417b7 --- /dev/null +++ b/test/pacman/tests/sign001.py @@ -0,0 +1,9 @@ +self.description = "Add a signature to a package DB" + +sp = pmpkg("pkg1") +sp.pgpsig = "asdfasdfsdfasdfsdafasdfsdfasd" +self.addpkg2db("sync+Always", sp) + +self.args = "-Ss" + +self.addrule("PACMAN_RETCODE=0") diff --git a/test/pacman/tests/sign002.py b/test/pacman/tests/sign002.py new file mode 100644 index 00000000..b55f331e --- /dev/null +++ b/test/pacman/tests/sign002.py @@ -0,0 +1,10 @@ +self.description = "Verify a signature in a sync DB (failure)" + +sp = pmpkg("pkg1") +sp.pgpsig = "iEYEABECAAYFAkhMOggACgkQXC5GoPU6du2WVQCffVxF8GKXJIY4juJBIw/ljLrQxygAnj2QlvsUd7MdFekLX18+Ov/xzgZ1" +self.addpkg2db("sync+Always", sp) + +self.args = "-S %s" % sp.name + +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") diff --git a/test/pacman/tests/smoke004.py b/test/pacman/tests/smoke004.py new file mode 100644 index 00000000..1f9b883d --- /dev/null +++ b/test/pacman/tests/smoke004.py @@ -0,0 +1,11 @@ +self.description = "Read a package DB with several PGP signatures" + +for i in range(1000): + sp = pmpkg("pkg%03d" % i) + sp.desc = "test description for package %d" % i + sp.pgpsig = "asdfasdfsdfasdfsdafasdfsdfasd" + self.addpkg2db("sync", sp) + +self.args = "-Ss" + +self.addrule("PACMAN_RETCODE=0") diff --git a/test/pacman/util.py b/test/pacman/util.py index b771a345..47255923 100755 --- a/test/pacman/util.py +++ b/test/pacman/util.py @@ -132,8 +132,9 @@ def mkcfgfile(filename, root, option, db): if key != "local": value = db[key] data.append("[%s]\n" \ + "VerifySig = %s\n" \ "Server = file://%s" \ - % (value.treename, + % (value.treename, value.getverify(), \ os.path.join(root, SYNCREPO, value.treename))) for optkey, optval in value.option.iteritems(): data.extend(["%s = %s" % (optkey, j) for j in optval]) diff --git a/test/util/vercmptest.sh b/test/util/vercmptest.sh index 6b3869c5..7ebeba53 100755 --- a/test/util/vercmptest.sh +++ b/test/util/vercmptest.sh @@ -62,7 +62,7 @@ runtest() { # use first arg as our binary if specified [ -n "$1" ] && bin="$1" -if [ ! $(type -p "$bin") ]; then +if ! type -p "$bin"; then echo "vercmp binary ($bin) could not be located" exit 1 fi |