[pacman-dev] [PATCH 4/4] pacman-key.sh.in: fix options' handling

ivan.kanak at gmail.com ivan.kanak at gmail.com
Tue Apr 19 16:19:21 EDT 2011


From: Ivan Kanakarakis <ivan.kanak at gmail.com>

reverted most changes back to my previous patch
I also got rid of find_config() funciton and introduced get_from() function
it can actually be used with any configuration file of the format described 
in the comments

---
 scripts/pacman-key.sh.in |  168 ++++++++++++++++++++++------------------------
 1 files changed, 80 insertions(+), 88 deletions(-)

diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 7261c89..d64702e 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -82,11 +82,17 @@ This is free software; see the source for copying conditions.\n\
 There is NO WARRANTY, to the extent permitted by law.\n")"
 }
 
-find_config() {
-    # Prints on stdin the values of all the options from the configuration file that
-    # are associated with the first parameter of this function.
-    # The option names are stripped
-    grep -e "^[[:blank:]]*$1[[:blank:]]*=.*" "$CONFIG" | cut -d= -f 2-
+# Read file and search for values matching the given key
+# The file format expected is: 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
+get_from() {
+    while read key _ value; do
+        if [[ $key = $2 ]]; then
+            echo "$value"
+            break
+        fi
+    done < "$1"
 }
 
 reload_keyring() {
@@ -142,9 +148,9 @@ reload_keyring() {
             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%% *}
+                key_id="${key_values%% *}"
                 # the rest if the name of the owner
-                name=${key_values#* }
+                name="${key_values#* }"
                 if [[ -n ${key_id} ]]; then
                     # Mark this key to be deleted
                     removed_ids[$key_id]="$name"
@@ -154,12 +160,12 @@ reload_keyring() {
     fi
 
     # List of keys that must be kept installed, even if in the list of keys to be removed
-    local HOLD_KEYS=$(find_config "HoldKeys")
+    local HOLD_KEYS="$(get_from "$CONFIG" "HoldKeys" &>/dev/null)"
 
     # 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)
+            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
@@ -211,88 +217,75 @@ if ! type gettext &>/dev/null; then
     }
 fi
 
-if [[ $1 != "--version" && $1 != "-V" && $1 != "--help" && $1 != "-h" && $1 != "" ]]; then
-    if type -p gpg >/dev/null 2>&1 = 1; then
+# Set default values
+CONFIG="@sysconfdir@/pacman.conf"
+PACMAN_KEYRING_DIR="@sysconfdir@/pacman.d/gnupg"
+
+# Parse command line options
+# override default values
+while [[ $1 =~ ^--(config|gpgdir)$ ]]; do
+    case "$1" in
+        --config)
+            shift; cli_config="$1"
+            ;;
+        --gpgdir)
+            shift; PACMAN_KEYRING_DIR="$1"
+            ;;
+    esac
+    shift
+done
+
+# Parse the command
+command="$1"
+if [[ -z "${command}" ]]; then
+    usage
+    exit 1
+fi
+shift
+
+# If command is --help/-h or --version/-V then skip checks and execute those else
+# check for: dependencies , permissions and state of needed directories and files
+if [[ ! ${command} =~ ^(--help|-h|--version|-V)$ ]]; then
+    if ! type -p gpg &>/dev/null; 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
+    fi
+    if (( EUID != 0 )); then
         error "$(gettext "pacman-key needs to be run as root.")"
         exit 1
     fi
-fi
-
-# Iterate over the parameters to get --config and --gpgdir
-# The other parameters will be filtered to another array,
-# so --config and --gpgdir don't interfere with other options.
-CONFIG="@sysconfdir@/pacman.conf"
-declare -a PARAMS
-GPGDIR=""
-isconfig=0
-isgpgdir=0
-for arg in "$@"; do
-    if (( isconfig )); then
-        isconfig=0
-        CONFIG="$arg"
-        if [[ ! -f "$CONFIG" ]]; then
-            error "$(gettext "The configuration file is not a valid file.")"
-            usage
-            exit 1
-        fi
-        continue
+    # 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
+    if [[ ! -e ${PACMAN_KEYRING_DIR} ]]; then
+        mkdir -p -m 755 "${PACMAN_KEYRING_DIR}"
     fi
-    if (( isgpgdir )); then
-        isgpgdir=0
-        GPGDIR="$arg"
-        if [[ ! -d "$GPGDIR" ]]; then
-            error "$(gettext "The home directory for GnuPG is not valid.")"
-            usage
-            exit 1
+    # Check given configuration file. Failback to default configuration
+    # if the specified cannot be found or read.
+    if [[ ${cli_config} ]]; then
+        if [[ ! -r ${cli_config} ]]; then
+            error "$(gettext "Couldn't read configuration file: %s. Using default configuration.")" "$cli_config"
+        else
+            CONFIG="$cli_config"
         fi
-        continue
+        unset cli_config
+    fi
+    # Read GPGDIR from $CONFIG.
+    if [[ GPGDIR="$(get_from "${CONFIG}" "GPGDir" &>/dev/null)" ]]; then
+        PACMAN_KEYRING_DIR="${GPGDIR}"
     fi
-    case "$arg" in
-        --config) isconfig=1;;
-    --gpgdir) isgpgdir=1;;
-*) PARAMS[${#PARAMS[@]}]="$arg"
-    esac
-done
-
-if [[ ! -r "${CONFIG}" ]]; then
-    error "$(gettext "%s not found.")" "$CONFIG"
-    exit 1
 fi
 
-# Read GPGDIR from $CONFIG.
-# The precedence for GPGDIR is:
-# 1st: command line
-# 2nd: pacman.conf
-# 3rd: default value
-[[ -z "$GPGDIR" ]] && GPGDIR=$(find_config "GPGDir")
-[[ -z "$GPGDIR" ]] && GPGDIR="@sysconfdir@/pacman.d/gnupg"
-PACMAN_KEYRING_DIR="${GPGDIR}"
 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="${PARAMS[0]}"
-if [[ -z "${command}" ]]; then
-    usage
-    exit 1
-fi
-unset PARAMS[0]
-
 case "${command}" in
     -a|--add)
         # If there is no extra parameter, gpg will read stdin
-        ${GPG_PACMAN} --quiet --batch --import "${PARAMS[@]}"
+        ${GPG_PACMAN} --quiet --batch --import "$@"
         ;;
     -d|--del)
-        if (( ${#PARAMS[@]} == 0 )); then
+        if (( $# == 0 )); then
             error "$(gettext "You need to specify at least one key identifier")"
             usage
             exit 1
@@ -305,43 +298,42 @@ case "${command}" in
         reload_keyring
         ;;
     -l|--list)
-        ${GPG_PACMAN} --list-sigs "${PARAMS[@]}"
+        ${GPG_PACMAN} --list-sigs "$@"
         ;;
     -f|--finger)
-        ${GPG_PACMAN} --fingerprint "${PARAMS[@]}"
+        ${GPG_PACMAN} --fingerprint "$@"
         ;;
     -e|--export)
-        ${GPG_PACMAN} --armor --export "${PARAMS[@]}"
+        ${GPG_PACMAN} --armor --export "$@"
         ;;
     -r|--receive)
-        if (( ${#PARAMS[@]} < 2 )); then
+        if (( $# < 2 )); then
             error "$(gettext "You need to specify the keyserver and at least one key identifier")"
             exit 1
         fi
-        keyserver="${PARAMS[0]}"
-        unset PARAMS[0]
-        ${GPG_PACMAN} --keyserver "${keyserver}" --recv-keys "${PARAMS[@]}"
+        keyserver="$1"
+        shift
+        ${GPG_PACMAN} --keyserver "${keyserver}" --recv-keys "$@"
         ;;
     -t|--edit-key)
-        if (( ${#PARAMS[@]} == 0 )); then
+        if (( $# == 0 )); then
             error "$(gettext "You need to specify at least one key identifier")"
             exit 1
         fi
-        while (( ${#PARAMS[@]} > 0 )); do
+        while (( $# > 0 )); do
             # Verify if the key exists in pacman's keyring
-            if ${GPG_PACMAN} --list-keys "${PARAMS[0]}" &>/dev/null; then
-                ${GPG_PACMAN} --edit-key "${PARAMS[0]}"
+            if ${GPG_PACMAN} --list-keys "$1" &>/dev/null; then
+                ${GPG_PACMAN} --edit-key "$1"
             else
-                error "$(gettext "The key identified by %s doesn't exist")" "${PARAMS[0]}"
+                error "$(gettext "The key identified by %s doesn't exist")" "$1"
                 exit 1
             fi
-            unset PARAMS[0]
+            shift
         done
         ;;
     --adv)
         msg "$(gettext "Executing: %s ")$*" "${GPG_PACMAN}"
-        ${GPG_PACMAN} "$@" || ret=$?
-        exit $ret
+        ${GPG_PACMAN} "$@" || exit $?
         ;;
     -h|--help)
         usage
-- 
1.7.4.4



More information about the pacman-dev mailing list