From: Ivan Kanakarakis <ivan.kanak@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