summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2012-01-23 19:19:51 +0100
committerDan McGee <dan@archlinux.org>2012-01-23 19:20:52 +0100
commite50c4a8837cedf47c2fe1a2c6064b4dc03dc5b03 (patch)
treedf2e33d95d02b17e5d720320c19e267893d68bdf
parentb3612e9cc198f198b3806efa461bf6fc04dd4502 (diff)
parent825b4ff35aa676b139dc24bc651724b092f2fded (diff)
downloadpacman-e50c4a8837cedf47c2fe1a2c6064b4dc03dc5b03.tar.gz
pacman-e50c4a8837cedf47c2fe1a2c6064b4dc03dc5b03.tar.xz
Merge branch 'maint'
Conflicts: lib/libalpm/diskspace.c src/pacman/util.h
-rw-r--r--configure.ac4
-rw-r--r--contrib/bash_completion.in4
-rw-r--r--contrib/zsh_completion.in2
-rw-r--r--doc/pacman.8.txt2
-rw-r--r--doc/vercmp.8.txt9
-rw-r--r--lib/libalpm/diskspace.c56
-rw-r--r--lib/libalpm/dload.c155
-rw-r--r--lib/libalpm/remove.c2
-rw-r--r--lib/libalpm/signing.c2
-rw-r--r--lib/libalpm/util.c10
-rw-r--r--scripts/makepkg.sh.in17
-rw-r--r--scripts/pacman-key.sh.in174
-rw-r--r--scripts/repo-add.sh.in24
-rw-r--r--src/pacman/pacman.c4
-rw-r--r--src/pacman/sync.c34
-rw-r--r--src/pacman/util.c33
-rw-r--r--src/pacman/util.h3
17 files changed, 390 insertions, 145 deletions
diff --git a/configure.ac b/configure.ac
index 6941054f..45e0111a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -174,7 +174,9 @@ AM_CONDITIONAL([HAVE_LIBGPGME], [test "x$with_gpgme" = "xyes"])
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h float.h glob.h libintl.h limits.h locale.h \
- mntent.h stddef.h string.h sys/ioctl.h sys/mount.h \
+ mntent.h netinet/in.h netinet/tcp.h \
+ stddef.h string.h sys/ioctl.h \
+ sys/mnttab.h sys/mount.h \
sys/param.h sys/statvfs.h sys/time.h sys/types.h \
sys/ucred.h syslog.h termios.h wchar.h])
diff --git a/contrib/bash_completion.in b/contrib/bash_completion.in
index d9f8d826..529734c3 100644
--- a/contrib/bash_completion.in
+++ b/contrib/bash_completion.in
@@ -59,9 +59,9 @@ _makepkg() {
_pacman_pkg() {
_arch_compgen "$(
if [[ $2 ]]; then
- \pacman -$1 | \cut -d' ' -f1 | \sort -u
+ \pacman -$1 2>/dev/null | \cut -d' ' -f1 | \sort -u
else
- \pacman -$1
+ \pacman -$1 2>/dev/null
fi
)"
}
diff --git a/contrib/zsh_completion.in b/contrib/zsh_completion.in
index f3130867..b30e9600 100644
--- a/contrib/zsh_completion.in
+++ b/contrib/zsh_completion.in
@@ -276,7 +276,7 @@ _pacman_completions_repositories() {
# $cmd must be declared by calling function
_pacman_get_command() {
# this is mostly nicked from _perforce
- cmd=( "pacman" )
+ cmd=( "pacman" "2>/dev/null")
integer i
for (( i = 2; i < CURRENT - 1; i++ )); do
if [[ ${words[i]} = "--config" || ${words[i]} = "--root" ]]; then
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 39551e15..0813b887 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -349,7 +349,7 @@ Sync Options[[SO]]
databases are saved for every sync DB you download from, and are not
deleted even if they are removed from the configuration file
linkman:pacman.conf[5]. Use one '\--clean' switch to only remove
- packages that are no longer installed; use two to remove all packages
+ packages that are no longer installed; use two to remove all files
from the cache. In both cases, you will have a yes or no option to
remove packages and/or unused downloaded databases.
+
diff --git a/doc/vercmp.8.txt b/doc/vercmp.8.txt
index 4b0490fa..6b94f3e4 100644
--- a/doc/vercmp.8.txt
+++ b/doc/vercmp.8.txt
@@ -6,7 +6,7 @@ vercmp(8)
Name
----
-vercmp - version comparsion utility
+vercmp - version comparison utility
Synopsis
@@ -23,7 +23,7 @@ numbers. It outputs values as follows:
* = 0 : if ver1 == ver2
* > 0 : if ver1 > ver2
-Version comparsion operates as follows:
+Version comparison operates as follows:
Alphanumeric:
1.0a < 1.0b < 1.0beta < 1.0p < 1.0pre < 1.0rc < 1.0 < 1.0.a < 1.0.1
@@ -35,6 +35,11 @@ overrule any version comparison (unless the epoch values are equal). This is
specified in an `epoch:version-rel` format. For example, `2:1.0-1` is always
greater than `1:3.6-1`.
+Keep in mind that the 'pkgrel' is only compared if it is available on both
+versions given to this tool. For example, comparing `1.5-1` and `1.5` will
+yield 0; comparing `1.5-1` and `1.5-2` will yield < 0 as expected. This is
+mainly for supporting versioned dependencies that do not include the 'pkgrel'.
+
Options
-------
diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 274aa676..91b655e5 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -1,7 +1,7 @@
/*
* diskspace.c
*
- * Copyright (c) 2010-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2010-2012 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,10 +17,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
+#include <stdio.h>
#include <errno.h>
+
#if defined(HAVE_MNTENT_H)
#include <mntent.h>
#endif
+#if defined(HAVE_SYS_MNTTAB_H)
+#include <sys/mnttab.h>
+#endif
#if defined(HAVE_SYS_STATVFS_H)
#include <sys/statvfs.h>
#endif
@@ -69,10 +76,10 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
alpm_list_t *mount_points = NULL, *ptr;
alpm_mountpoint_t *mp;
-#if defined HAVE_GETMNTENT
+#if defined(HAVE_GETMNTENT) && defined(HAVE_MNTENT_H)
+ /* Linux */
struct mntent *mnt;
FILE *fp;
- struct statvfs fsp;
fp = setmntent(MOUNTED, "r");
@@ -81,8 +88,10 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
while((mnt = getmntent(fp))) {
+ struct statvfs fsp;
if(!mnt) {
- _alpm_log(handle, ALPM_LOG_WARNING, _("could not get filesystem information\n"));
+ _alpm_log(handle, ALPM_LOG_WARNING,
+ _("could not get filesystem information\n"));
continue;
}
if(statvfs(mnt->mnt_dir, &fsp) != 0) {
@@ -102,7 +111,44 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle)
}
endmntent(fp);
-#elif defined HAVE_GETMNTINFO
+#elif defined(HAVE_GETMNTENT) && defined(HAVE_MNTTAB_H)
+ /* Solaris, Illumos */
+ struct mnttab mnt;
+ FILE *fp;
+ int ret;
+
+ fp = fopen("/etc/mnttab", "r");
+
+ if(fp == NULL) {
+ return NULL;
+ }
+
+ while((ret = getmntent(fp, &mnt)) == 0) {
+ struct statvfs fsp;
+ if(statvfs(mnt->mnt_mountp, &fsp) != 0) {
+ _alpm_log(handle, ALPM_LOG_WARNING,
+ _("could not get filesystem information for %s: %s\n"),
+ mnt->mnt_mountp, strerror(errno));
+ continue;
+ }
+
+ CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
+ mp->mount_dir = strdup(mnt->mnt_mountp);
+ mp->mount_dir_len = strlen(mp->mount_dir);
+ memcpy(&(mp->fsp), &fsp, sizeof(struct statvfs));
+ mp->read_only = fsp.f_flag & ST_RDONLY;
+
+ mount_points = alpm_list_add(mount_points, mp);
+ }
+ /* -1 == EOF */
+ if(ret != -1) {
+ _alpm_log(handle, ALPM_LOG_WARNING,
+ _("could not get filesystem information\n"));
+ }
+
+ fclose(fp);
+#elif defined(HAVE_GETMNTINFO)
+ /* FreeBSD (statfs), NetBSD (statvfs), OpenBSD (statfs), OS X (statfs) */
int entries;
FSSTATSTYPE *fsp;
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index a3980d65..97778c27 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -1,7 +1,7 @@
/*
* download.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -23,11 +23,19 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
+#include <sys/socket.h> /* setsockopt, SO_KEEPALIVE */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* IPPROTO_TCP */
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h> /* TCP_KEEPINTVL, TCP_KEEPIDLE */
+#endif
+
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif
@@ -82,7 +90,7 @@ static void inthandler(int UNUSED signum)
dload_interrupted = ABORT_SIGINT;
}
-static int curl_progress(void *file, double dltotal, double dlnow,
+static int dload_progress_cb(void *file, double dltotal, double dlnow,
double UNUSED ultotal, double UNUSED ulnow)
{
struct dload_payload *payload = (struct dload_payload *)file;
@@ -184,7 +192,7 @@ static mode_t _getumask(void)
return mask;
}
-static size_t parse_headers(void *ptr, size_t size, size_t nmemb, void *user)
+static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *user)
{
size_t realsize = size * nmemb;
const char *fptr, *endptr = NULL;
@@ -215,6 +223,47 @@ static size_t parse_headers(void *ptr, size_t size, size_t nmemb, void *user)
return realsize;
}
+static int dload_sockopt_cb(void *userdata, curl_socket_t curlfd,
+ curlsocktype purpose)
+{
+ alpm_handle_t *handle = userdata;
+ int optval = 1;
+
+ /* this whole method is to prevent FTP control connections from going sour
+ * during a long data transfer; crappy firewalls love to drop otherwise idle
+ * connections if there is no traffic. */
+ if(purpose != CURLSOCKTYPE_IPCXN) {
+ return 0;
+ }
+
+ /* don't abort operation if any setsockopt fails, just log to debug */
+ if(setsockopt(curlfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval,
+ sizeof(optval)) < 0) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ "Failed to set SO_KEEPALIVE on fd %d\n", curlfd);
+ }
+ else {
+#ifdef TCP_KEEPIDLE
+ optval = 60;
+ if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval,
+ sizeof(optval)) < 0) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ "Failed to set TCP_KEEPIDLE on fd %d\n", curlfd);
+ }
+#endif
+#ifdef TCP_KEEPINTVL
+ optval = 60;
+ if(setsockopt(curlfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval,
+ sizeof(optval)) < 0) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ "Failed to set TCP_KEEPINTVL on fd %d\n", curlfd);
+ }
+#endif
+ }
+
+ return 0;
+}
+
static void curl_set_handle_opts(struct dload_payload *payload,
CURL *curl, char *error_buffer)
{
@@ -232,13 +281,15 @@ static void curl_set_handle_opts(struct dload_payload *payload,
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
- curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, curl_progress);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, dload_progress_cb);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void *)payload);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1024L);
curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10L);
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parse_headers);
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, dload_parseheader_cb);
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)payload);
curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
+ curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, dload_sockopt_cb);
+ curl_easy_setopt(curl, CURLOPT_SOCKOPTDATA, (void *)handle);
_alpm_log(handle, ALPM_LOG_DEBUG, "url: %s\n", payload->fileurl);
@@ -388,6 +439,8 @@ static int curl_download_internal(struct dload_payload *payload,
/* perform transfer */
payload->curlerr = curl_easy_perform(curl);
+ _alpm_log(handle, ALPM_LOG_DEBUG, "curl returned error %d from transfer\n",
+ payload->curlerr);
/* disconnect relationships from the curl handle for things that might go out
* of scope, but could still be touched on connection teardown. This really
@@ -558,6 +611,22 @@ int _alpm_download(struct dload_payload *payload, const char *localpath,
}
}
+static char *filecache_find_url(alpm_handle_t *handle, const char *url)
+{
+ const char *basename = strrchr(url, '/');
+
+ if(basename == NULL) {
+ return NULL;
+ }
+
+ basename++;
+ if(basename == '\0') {
+ return NULL;
+ }
+
+ return _alpm_filecache_find(handle, basename);
+}
+
/** Fetch a remote pkg. */
char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
{
@@ -565,7 +634,7 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
const char *cachedir;
char *final_file = NULL;
struct dload_payload payload;
- int ret;
+ int ret = 0;
CHECK_HANDLE(handle, return NULL);
ASSERT(url, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, NULL));
@@ -574,51 +643,63 @@ char SYMEXPORT *alpm_fetch_pkgurl(alpm_handle_t *handle, const char *url)
cachedir = _alpm_filecache_setup(handle);
memset(&payload, 0, sizeof(struct dload_payload));
- payload.handle = handle;
- STRDUP(payload.fileurl, url, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
- payload.allow_resume = 1;
-
- /* download the file */
- ret = _alpm_download(&payload, cachedir, &final_file);
- _alpm_dload_payload_reset(&payload);
- if(ret == -1) {
- _alpm_log(handle, ALPM_LOG_WARNING, _("failed to download %s\n"), url);
- free(final_file);
- return NULL;
+
+ /* attempt to find the file in our pkgcache */
+ filepath = filecache_find_url(handle, url);
+ if(filepath == NULL) {
+ STRDUP(payload.fileurl, url, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
+ payload.allow_resume = 1;
+ payload.handle = handle;
+
+ /* download the file */
+ ret = _alpm_download(&payload, cachedir, &final_file);
+ _alpm_dload_payload_reset(&payload);
+ if(ret == -1) {
+ _alpm_log(handle, ALPM_LOG_WARNING, _("failed to download %s\n"), url);
+ free(final_file);
+ return NULL;
+ }
+ _alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", url);
}
- _alpm_log(handle, ALPM_LOG_DEBUG, "successfully downloaded %s\n", url);
/* attempt to download the signature */
if(ret == 0 && (handle->siglevel & ALPM_SIG_PACKAGE)) {
- char *sig_final_file = NULL;
+ char *sig_filepath, *sig_final_file = NULL;
size_t len;
len = strlen(url) + 5;
MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
snprintf(payload.fileurl, len, "%s.sig", url);
- payload.handle = handle;
- payload.force = 1;
- payload.errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
-
- /* set hard upper limit of 16KiB */
- payload.max_size = 16 * 1024;
-
- ret = _alpm_download(&payload, cachedir, &sig_final_file);
- if(ret == -1 && !payload.errors_ok) {
- _alpm_log(handle, ALPM_LOG_WARNING,
- _("failed to download %s\n"), payload.fileurl);
- /* Warn now, but don't return NULL. We will fail later during package
- * load time. */
- } else if(ret == 0) {
- _alpm_log(handle, ALPM_LOG_DEBUG,
- "successfully downloaded %s\n", payload.fileurl);
+
+ sig_filepath = filecache_find_url(handle, payload.fileurl);
+ if(sig_filepath == NULL) {
+ payload.handle = handle;
+ payload.force = 1;
+ payload.errors_ok = (handle->siglevel & ALPM_SIG_PACKAGE_OPTIONAL);
+
+ /* set hard upper limit of 16KiB */
+ payload.max_size = 16 * 1024;
+
+ ret = _alpm_download(&payload, cachedir, &sig_final_file);
+ if(ret == -1 && !payload.errors_ok) {
+ _alpm_log(handle, ALPM_LOG_WARNING,
+ _("failed to download %s\n"), payload.fileurl);
+ /* Warn now, but don't return NULL. We will fail later during package
+ * load time. */
+ } else if(ret == 0) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ "successfully downloaded %s\n", payload.fileurl);
+ }
+ FREE(sig_final_file);
}
- FREE(sig_final_file);
+ free(sig_filepath);
_alpm_dload_payload_reset(&payload);
}
/* we should be able to find the file the second time around */
- filepath = _alpm_filecache_find(handle, final_file);
+ if(filepath == NULL) {
+ filepath = _alpm_filecache_find(handle, final_file);
+ }
free(final_file);
return filepath;
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index bc196510..469ce9bb 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -1,7 +1,7 @@
/*
* remove.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c
index 3ff83ba0..cfe0f5e8 100644
--- a/lib/libalpm/signing.c
+++ b/lib/libalpm/signing.c
@@ -1,7 +1,7 @@
/*
* signing.c
*
- * Copyright (c) 2008-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2008-2012 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
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index e2cbd8c5..3cc4bbf7 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -1,7 +1,7 @@
/*
* util.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu>
@@ -406,7 +406,6 @@ int _alpm_rmrf(const char *path)
int errflag = 0;
struct dirent *dp;
DIR *dirp;
- char name[PATH_MAX];
struct stat st;
if(_alpm_lstat(path, &st) == 0) {
@@ -426,9 +425,10 @@ int _alpm_rmrf(const char *path)
return 1;
}
for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- if(dp->d_ino) {
- sprintf(name, "%s/%s", path, dp->d_name);
+ if(dp->d_name) {
if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) {
+ char name[PATH_MAX];
+ sprintf(name, "%s/%s", path, dp->d_name);
errflag += _alpm_rmrf(name);
}
}
@@ -1168,7 +1168,7 @@ off_t _alpm_strtoofft(const char *line)
errno = 0;
/* we are trying to parse bare numbers only, no leading anything */
- if(line[0] < '0' || line[0] > '9') {
+ if(!isdigit((unsigned char)line[0])) {
return (off_t)-1;
}
result = strtoull(line, &end, 10);
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 20440265..c761a098 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -3,7 +3,7 @@
# makepkg - make packages compatible for use with pacman
# @configure_input@
#
-# Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
# Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
# Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
@@ -412,7 +412,11 @@ download_file() {
run_pacman() {
local cmd
- printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
+ if [[ ! $1 = -@(T|Qq) ]]; then
+ printf -v cmd "%q " "$PACMAN" $PACMAN_OPTS "$@"
+ else
+ printf -v cmd "%q " "$PACMAN" "$@"
+ fi
if (( ! ASROOT )) && [[ ! $1 = -@(T|Qq) ]]; then
if type -p sudo >/dev/null; then
cmd="sudo $cmd"
@@ -507,14 +511,15 @@ remove_deps() {
# check for packages removed during dependency install (e.g. due to conflicts)
# removing all installed packages is risky in this case
if [[ -n $(grep -xvFf <(printf '%s\n' "${current_packagelist[@]}") \
- <(printf '%s\n' "${original_packagelist[@]}") ) ]]; then
+ <(printf '%s\n' "${original_packagelist[@]}") || true) ]]; then
warning "$(gettext "Failed to remove installed dependencies.")"
return 0
fi
local deplist
- if ! deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
- <(printf "%s\n" "${current_pkglist[@]}"))); then
+ deplist=($(grep -xvFf <(printf "%s\n" "${original_pkglist[@]}") \
+ <(printf "%s\n" "${current_pkglist[@]}") || true))
+ if [[ -n deplist ]]; then
return
fi
@@ -1869,7 +1874,7 @@ usage() {
version() {
printf "makepkg (pacman) %s\n" "$myver"
printf "$(gettext "\
-Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
+Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>.\n\
Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>.\n\n\
This is free software; see the source for copying conditions.\n\
There is NO WARRANTY, to the extent permitted by law.\n")"
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 689dc564..4e321e63 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -4,7 +4,7 @@
# Based on apt-key, from Debian
# @configure_input@
#
-# Copyright (c) 2010-2011 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (c) 2010-2012 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
@@ -88,7 +88,7 @@ usage() {
version() {
printf "pacman-key (pacman) %s\n" "${myver}"
printf "$(gettext "\
-Copyright (c) 2010-2011 Pacman Development Team <pacman-dev@archlinux.org>.\n\
+Copyright (c) 2010-2012 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")"
}
@@ -144,6 +144,20 @@ add_gpg_conf_option() {
fi
}
+check_keyids_exist() {
+ local ret=0
+ for key in "${KEYIDS[@]}"; do
+ # Verify if the key exists in pacman's keyring
+ if ! "${GPG_PACMAN[@]}" --list-keys "$key" &>/dev/null ; then
+ error "$(gettext "The key identified by %s could not be found locally.")" "$key"
+ ret=1
+ fi
+ done
+ if (( ret )); then
+ exit 1
+ fi
+}
+
initialize() {
local conffile keyserv
# Check for simple existence rather than for a directory as someone
@@ -338,41 +352,144 @@ populate_keyring() {
fi
}
+add_keys() {
+ if ! "${GPG_PACMAN[@]}" --quiet --batch --import "${KEYFILES[@]}" ; then
+ error "$(gettext "A specified keyfile could not be added to the gpg keychain.")"
+ exit 1
+ fi
+}
+
+delete_keys() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --quiet --batch --delete-key --yes "${KEYIDS[@]}" ; then
+ error "$(gettext "A specified key could not be removed from the gpg keychain.")"
+ exit 1
+ fi
+}
+
edit_keys() {
- local errors=0;
+ check_keyids_exist
+ local ret=0
for key in "${KEYIDS[@]}"; do
- # Verify if the key exists in pacman's keyring
- if ! "${GPG_PACMAN[@]}" --list-keys "$key" &>/dev/null; then
- error "$(gettext "The key identified by %s does not exist.")" "$key"
- errors=1;
+ if ! "${GPG_PACMAN[@]}" --edit-key "$key" ; then
+ error "$(gettext "The key identified by %s could not be edited.")" "$key"
+ ret=1
fi
done
- (( errors )) && exit 1;
+ if (( ret )); then
+ exit 1
+ fi
+}
- for key in "${KEYIDS[@]}"; do
- "${GPG_PACMAN[@]}" --edit-key "$key"
- done
+export_keys() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --armor --export "${KEYIDS[@]}" ; then
+ error "$(gettext "A specified key could not be exported from the gpg keychain.")"
+ exit 1
+ fi
+}
+
+finger_keys() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --batch --fingerprint "${KEYIDS[@]}" ; then
+ error "$(gettext "The fingerprint of a specified key could not be determined.")"
+ exit 1
+ fi
}
import_trustdb() {
local importdir
-
+ local ret=0
for importdir in "${IMPORT_DIRS[@]}"; do
if [[ -f "${importdir}/trustdb.gpg" ]]; then
gpg --homedir "${importdir}" --export-ownertrust | \
"${GPG_PACMAN[@]}" --import-ownertrust -
+ if (( PIPESTATUS )); then
+ error "$(gettext "%s could not be imported.")" "${importdir}/trustdb.gpg"
+ ret=1
+ fi
+ else
+ error "$(gettext "File %s does not exist and could not be imported.")" "${importdir}/trustdb.gpg"
+ ret=1
fi
done
+ if (( ret )); then
+ exit 1
+ fi
}
import() {
local importdir
-
+ local ret=0
for importdir in "${IMPORT_DIRS[@]}"; do
if [[ -f "${importdir}/pubring.gpg" ]]; then
- "${GPG_PACMAN[@]}" --quiet --batch --import "${importdir}/pubring.gpg"
+ if ! "${GPG_PACMAN[@]}" --quiet --batch --import "${importdir}/pubring.gpg" ; then
+ error "$(gettext "%s could not be imported.")" "${importdir}/pubring.gpg"
+ ret=1
+ fi
+ else
+ error "$(gettext "File %s does not exist and could not be imported.")" "${importdir}/pubring.gpg"
+ ret=1
fi
done
+ if (( ret )); then
+ exit 1
+ fi
+}
+
+list_keys() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --batch --list-keys "${KEYIDS[@]}" ; then
+ error "$(gettext "A specified key could not be listed.")"
+ exit 1
+ fi
+}
+
+list_sigs() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --batch --list-sigs "${KEYIDS[@]}" ; then
+ error "$(gettext "A specified signature could not be listed.")"
+ exit 1
+ fi
+}
+
+lsign_keys() {
+ check_keyids_exist
+ printf 'y\ny\n' | LANG=C "${GPG_PACMAN[@]}" --command-fd 0 --quiet --batch --lsign-key "${KEYIDS[@]}" 2>/dev/null
+ if (( PIPESTATUS[1] )); then
+ error "$(gettext "A specified key could not be locally signed.")"
+ exit 1
+ fi
+}
+
+receive_keys() {
+ if ! "${GPG_PACMAN[@]}" --recv-keys "${KEYIDS[@]}" ; then
+ error "$(gettext "Remote key not fetched correctly from keyserver.")"
+ exit 1
+ fi
+}
+
+refresh_keys() {
+ check_keyids_exist
+ if ! "${GPG_PACMAN[@]}" --refresh-keys "${KEYIDS[@]}" ; then
+ error "$(gettext "A specified local key could not be updated from a keyserver.")"
+ exit 1
+ fi
+}
+
+verify_sig() {
+ if ! "${GPG_PACMAN[@]}" --verify $SIGNATURE ; then
+ error "$(gettext "The signature identified by %s could not be verified.")" "$SIGNATURE"
+ exit 1
+ fi
+}
+
+updatedb() {
+ msg "$(gettext "Updating trust database...")"
+ if ! "${GPG_PACMAN[@]}" --batch --check-trustdb ; then
+ error "$(gettext "Trust database could not be updated.")"
+ exit 1
+ fi
}
# PROGRAM START
@@ -476,27 +593,24 @@ esac
(( ! INIT )) && check_keyring
-(( ADD )) && "${GPG_PACMAN[@]}" --quiet --batch --import "${KEYFILES[@]}"
-(( DELETE )) && "${GPG_PACMAN[@]}" --quiet --batch --delete-key --yes "${KEYIDS[@]}"
+(( ADD )) && add_keys
+(( DELETE )) && delete_keys
(( EDITKEY )) && edit_keys
-(( EXPORT )) && "${GPG_PACMAN[@]}" --armor --export "${KEYIDS[@]}"
-(( FINGER )) && "${GPG_PACMAN[@]}" --batch --fingerprint "${KEYIDS[@]}"
+(( EXPORT )) && export_keys
+(( FINGER )) && finger_keys
(( IMPORT )) && import
(( IMPORT_TRUSTDB)) && import_trustdb
(( INIT )) && initialize
-(( LISTKEYS )) && "${GPG_PACMAN[@]}" --batch --list-keys "${KEYIDS[@]}"
-(( LISTSIGS )) && "${GPG_PACMAN[@]}" --batch --list-sigs "${KEYIDS[@]}"
-if (( LSIGNKEY )); then
- printf 'y\ny\n' | LANG=C "${GPG_PACMAN[@]}" --command-fd 0 --quiet --batch --lsign-key "${KEYIDS[@]}" 2>/dev/null
-fi
+(( LISTKEYS )) && list_keys
+(( LISTSIGS )) && list_sigs
+(( LSIGNKEY )) && lsign_keys
(( POPULATE )) && populate_keyring
-(( RECEIVE )) && "${GPG_PACMAN[@]}" --recv-keys "${KEYIDS[@]}"
-(( REFRESH )) && "${GPG_PACMAN[@]}" --refresh-keys "${KEYIDS[@]}"
-(( VERIFY )) && "${GPG_PACMAN[@]}" --verify "$SIGNATURE"
+(( RECEIVE )) && receive_keys
+(( REFRESH )) && refresh_keys
+(( VERIFY )) && verify_sig
-if (( UPDATEDB )); then
- msg "$(gettext "Updating trust database...")"
- "${GPG_PACMAN[@]}" --batch --check-trustdb
-fi
+(( UPDATEDB )) && updatedb
+
+exit 0
# vim: set ts=2 sw=2 noet:
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index 28339e64..48eee7ac 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -4,7 +4,7 @@
# repo-remove - remove a package entry from a given repo database file
# @configure_input@
#
-# Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (c) 2006-2012 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
@@ -48,30 +48,38 @@ usage() {
printf "%s (pacman) %s\n\n" "$cmd" "$myver"
if [[ $cmd == "repo-add" ]] ; then
printf "$(gettext "Usage: repo-add [options] <path-to-db> <package|delta> ...\n")"
+ printf "\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")"
+Multiple packages to add can be specified on the command line.\n")"
+ printf "\n"
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 [options] <path-to-db> <packagename|delta> ...\n\n")"
+ printf "$(gettext "Usage: repo-remove [options] <path-to-db> <packagename|delta> ...\n")"
+ printf "\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")"
+packages to remove can be specified on the command line.\n")"
+ printf "\n"
printf "$(gettext "Options:\n")"
+ else
+ printf "$(gettext "Please move along, there is nothing to see here.\n")"
+ return
fi
printf "$(gettext " -q, --quiet minimize output\n")"
printf "$(gettext " -s, --sign sign database with GnuPG after update\n")"
printf "$(gettext " -k, --key <key> use the specified key to sign the database\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
+See %s(8) for more details and descriptions of the available options.\n")" $cmd
+ printf "\n"
if [[ $cmd == "repo-add" ]] ; then
- echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0-1-i686.pkg.tar.gz")"
+ printf "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0-1-i686.pkg.tar.gz\n")"
elif [[ $cmd == "repo-remove" ]] ; then
- echo "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26")"
+ printf "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26\n")"
fi
}
@@ -79,7 +87,7 @@ version() {
cmd=${0##*/}
printf "%s (pacman) %s\n\n" "$cmd" "$myver"
printf "$(gettext "\
-Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>\n\n\
+Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>\n\n\
This is free software; see the source for copying conditions.\n\
There is NO WARRANTY, to the extent permitted by law.\n")"
}
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 3e17d905..014520e8 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -218,7 +218,7 @@ static void version(void)
{
printf("\n");
printf(" .--. Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version());
- printf("/ _.-' .-. .-. .-. Copyright (C) 2006-2011 Pacman Development Team\n");
+ printf("/ _.-' .-. .-. .-. Copyright (C) 2006-2012 Pacman Development Team\n");
printf("\\ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet\n");
printf(" '--'\n");
printf(_(" This program may be freely redistributed under\n"
@@ -791,7 +791,7 @@ int main(int argc, char *argv[])
config = config_new();
/* disable progressbar if the output is redirected */
- if(!isatty(1)) {
+ if(!isatty(fileno(stdout))) {
config->noprogressbar = 1;
}
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index a13b6c7f..e22f94f7 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -1,7 +1,7 @@
/*
* sync.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -196,7 +196,6 @@ static int sync_cleancache(int level)
/* step through the directory one file at a time */
while((ent = readdir(dir)) != NULL) {
char path[PATH_MAX];
- size_t pathlen;
int delete = 1;
alpm_pkg_t *localpkg = NULL, *pkg = NULL;
const char *local_name, *local_version;
@@ -207,30 +206,18 @@ static int sync_cleancache(int level)
/* build the full filepath */
snprintf(path, PATH_MAX, "%s%s", cachedir, ent->d_name);
- /* short circuit for removing all packages from cache */
+ /* short circuit for removing all files from cache */
if(level > 1) {
unlink(path);
continue;
}
- /* we handle .sig files with packages, not separately */
- pathlen = strlen(path);
- if(strcmp(path + pathlen - 4, ".sig") == 0) {
- continue;
- }
-
- /* attempt to load the package, prompt removal on failures as we may have
- * files here that aren't valid packages. we also don't need a full
- * load of the package, just the metadata. */
- if(alpm_pkg_load(config->handle, path, 0, 0, &localpkg) != 0
- || localpkg == NULL) {
- if(yesno(_("File %s does not seem to be a valid package, remove it?"),
- path)) {
- if(localpkg) {
- alpm_pkg_free(localpkg);
- }
- unlink(path);
- }
+ /* attempt to load the file as a package. if we cannot load the file,
+ * simply skip it and move on. we don't need a full load of the package,
+ * just the metadata. */
+ if(alpm_pkg_load(config->handle, path, 0, 0, &localpkg) != 0) {
+ pm_printf(ALPM_LOG_DEBUG, "skipping %s, could not load as package\n",
+ path);
continue;
}
local_name = alpm_pkg_get_name(localpkg);
@@ -242,7 +229,7 @@ static int sync_cleancache(int level)
if(pkg != NULL && alpm_pkg_vercmp(local_version,
alpm_pkg_get_version(pkg)) == 0) {
/* package was found in local DB and version matches, keep it */
- pm_printf(ALPM_LOG_DEBUG, "pkg %s-%s found in local db\n",
+ pm_printf(ALPM_LOG_DEBUG, "package %s-%s found in local db\n",
local_name, local_version);
delete = 0;
}
@@ -256,7 +243,7 @@ static int sync_cleancache(int level)
if(pkg != NULL && alpm_pkg_vercmp(local_version,
alpm_pkg_get_version(pkg)) == 0) {
/* package was found in a sync DB and version matches, keep it */
- pm_printf(ALPM_LOG_DEBUG, "pkg %s-%s found in sync db\n",
+ pm_printf(ALPM_LOG_DEBUG, "package %s-%s found in sync db\n",
local_name, local_version);
delete = 0;
}
@@ -266,6 +253,7 @@ static int sync_cleancache(int level)
alpm_pkg_free(localpkg);
if(delete) {
+ size_t pathlen = strlen(path);
unlink(path);
/* unlink a signature file if present too */
if(PATH_MAX - 5 >= pathlen) {
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 467bedfe..27efdb0a 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -1,7 +1,7 @@
/*
* util.c
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -190,10 +190,10 @@ int rmrf(const char *path)
return 1;
}
for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- if(dp->d_ino) {
- char name[PATH_MAX];
- sprintf(name, "%s/%s", path, dp->d_name);
+ if(dp->d_name) {
if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) {
+ char name[PATH_MAX];
+ snprintf(name, PATH_MAX, "%s/%s", path, dp->d_name);
errflag += rmrf(name);
}
}
@@ -310,19 +310,6 @@ void indentprint(const char *str, size_t indent)
free(wcstr);
}
-/* Convert a string to uppercase
- */
-char *strtoupper(char *str)
-{
- char *ptr = str;
-
- while(*ptr) {
- (*ptr) = (char)toupper((unsigned char)*ptr);
- ptr++;
- }
- return str;
-}
-
/* Trim whitespace and newlines from a string
*/
size_t strtrim(char *str)
@@ -898,8 +885,12 @@ static void _display_targets(alpm_list_t *targets, int verbose)
/* add up size of all removed packages */
rsize += alpm_pkg_get_isize(target->remove);
}
+ }
+
+ /* form data for both verbose and non-verbose display */
+ for(i = targets; i; i = alpm_list_next(i)) {
+ pm_target_t *target = i->data;
- /* form data for both verbose and non-verbose display */
rows = alpm_list_add(rows, create_verbose_row(target, show_dl_size));
if(target->install) {
pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
@@ -1430,6 +1421,12 @@ static int question(short preset, char *fmt, va_list args)
return preset;
}
+ /* if stdin is piped, response does not get printed out, and as a result
+ * a \n is missing, resulting in broken output (FS#27909) */
+ if(!isatty(fileno(stdin))) {
+ fprintf(stream, "%s\n", response);
+ }
+
if(strcasecmp(response, _("Y")) == 0 || strcasecmp(response, _("YES")) == 0) {
return 1;
} else if(strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) {
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 5d3ea2f1..18048de9 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -1,7 +1,7 @@
/*
* util.h
*
- * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
+ * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,6 @@ int rmrf(const char *path);
const char *mbasename(const char *path);
char *mdirname(const char *path);
void indentprint(const char *str, size_t indent);
-char *strtoupper(char *str);
size_t strtrim(char *str);
char *strreplace(const char *str, const char *needle, const char *replace);
alpm_list_t *strsplit(const char *str, const char splitchar);