FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > ArchLinux > ArchLinux Pacman Development

 
 
LinkBack Thread Tools
 
Old 07-08-2011, 11:59 AM
Allan McRae
 
Default pacman-key: use our option parser

The pacman-key script is complicated enough to warrent usage of the
parse_options script. This is especially helpful in dealing with
all the configuration file override flags as the no longer need to
be specified first. It also allows us to do the right thing early
with --help/--version and no option cases cleanly. This change also
makde the check for root privileges only occur on operations where
they are needed.

This patch is inspired by and supercedes some patches submitted by
Denis A. Altoé Falqueto and Ivan Kanakarakis who were altering the
previous option handling in an attempt to deal with the above issues.

Signed-off-by: Allan McRae <allan@archlinux.org>
---
scripts/pacman-key.sh.in | 191 +++++++++++++++++++++++----------------------
1 files changed, 98 insertions(+), 93 deletions(-)

diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 833943c..8e797f8 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -26,20 +26,30 @@ export TEXTDOMAINDIR='@localedir@'

myver="@PACKAGE_VERSION@"

+# Options
+ADD=0
+ADVANCED=0
+DELETE=0
+EXPORT=0
+FINGER=0
+LIST=0
+RECEIVE=0
+RELOAD=0
+TRUST=0
+UPDATEDB=0
+
m4_include(library/output_format.sh)

+m4_include(library/parse_options.sh)
+
usage() {
printf "pacman-key (pacman) %s
" ${myver}
echo
- printf "$(gettext "Usage: %s [options] <command> [arguments]")
" $(basename $0)
+ printf "$(gettext "Usage: %s [options]")
" $(basename $0)
echo
printf "$(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')")
" "$CONFIG"
- printf "$(gettext " --gpgdir Set an alternate directory for gnupg (instead of '%s')")
" "$PACMAN_KEYRING_DIR"
- echo
- echo "$(gettext "The available commands are:")"
+ echo "$(gettext "Options:")"
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")"
@@ -51,8 +61,11 @@ usage() {
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
+ echo "$(gettext " --config <file> Use an alternate config file")"
+ printf "$(gettext " (instead of '%s')")
" "@sysconfdir@/pacman.conf"
+ echo "$(gettext " --gpgdir <dir> Set an alternate directory for gnupg")"
+ printf "$(gettext " (instead of '%s')")
" "@sysconfdir@/pacman.d/gnupg"
+ echo "$(gettext " --reload Reload the default keys")"
}

version() {
@@ -198,116 +211,108 @@ 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
- 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
+OPT_SHORT="a::d:e:f::hlr:t:uV"
+OPT_LONG="add,adv:,config:,del:,export:,finger::, gpgdir:,help,list"
+OPT_LONG+=",receive:,reload,trust:,updatedb,versi on"
+if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
+ echo; usage; exit 1 # E_INVALID_OPTION;
+fi
+eval set -- "$OPT_TEMP"
+unset OPT_SHORT OPT_LONG OPT_TEMP
+
+if [[ $1 == "--" ]]; then
+ usage;
+ exit 0;
fi

-# Parse global options
-CONFIG="@sysconfdir@/pacman.conf"
-PACMAN_KEYRING_DIR="@sysconfdir@/pacman.d/gnupg"
-while [[ $1 =~ ^--(config|gpgdir)$ ]]; do
+while true; do
case "$1" in
- --config) shift; CONFIG="$1" ;;
- --gpgdir) shift; PACMAN_KEYRING_DIR="$1" ;;
+ -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;;
+ --adv) ADVANCED=1; shift; ARGUMENTS=($1) ;;
+ --config) shift; CONFIG=$1 ;;
+ -d|--del) DELETE=1; shift; KEYIDS=($1) ;;
+ -e|--export) EXPORT=1; shift; KEYIDS=($1) ;;
+ -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;;
+ --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;;
+ -l|--list) LIST=1 ;;
+ -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;;
+ --reload) RELOAD=1 ;;
+ -t|--trust) TRUST=1; shift; KEYIDS=($1) ;;
+ -u|--updatedb) UPDATEDB=1 ;;
+
+ -h|--help) usage; exit 0 ;;
+ -V|--version) version; exit 0 ;;
+
+ --) OPT_IND=0; shift; break;;
+ *) usage; exit 1 ;;
esac
shift
done

+
+if ! type -p gpg >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for all %s operations.")" "gpg" "pacman-key"
+ exit 1
+fi
+
+if (( (ADD || ADVANCED || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then
+ error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key"
+ exit 1
+fi
+
+CONFIG=${CONFIG:-@sysconfdir@/pacman.conf}
if [[ ! -r "${CONFIG}" ]]; then
- error "$(gettext "%s not found.")" "$CONFIG"
+ error "$(gettext "%s configuation file '%s' not found.")" "pacman" "$CONFIG"
exit 1
fi

-# Read GPGDIR from $CONFIG.
-if [[ GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then
+# Get GPGDIR from pacman.conf iff not specified on command line
+if [[ -z PACMAN_KEYRING_DIR && GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then
PACMAN_KEYRING_DIR="${GPGDIR}"
fi
-GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning"
+PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg}

# 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
+GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning"
+
+
+(( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}"
+(( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}"
+(( EXPORT )) && ${GPG_PACMAN} --armor --export "${KEYIDS[@]}"
+(( FINGER )) && ${GPG_PACMAN} --batch --fingerprint "${KEYIDS[@]}"
+(( LIST )) && ${GPG_PACMAN} --batch --list-sigs "${KEYIDS[@]}"
+(( RELOAD )) && reload_keyring
+(( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb
+
+if (( ADVANCED )); then
+ msg "$(gettext "Executing: %s %s")" "${GPG_PACMAN}" "${ARGUMENTS[@]}"
+ ${GPG_PACMAN} "${ARGUMENTS[@]}" || ret=$?
+ exit $ret
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
+
+if (( RECEIVE )); then
+ if [[ -z ${KEYIDS[@]} ]]; then
+ error "$(gettext "You need to specify the keyserver and at least one key identifier")"
+ exit 1
+ fi
+ ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}"
+fi
+
+if (( TRUST )); then
+ for key in ${KEYIDS[@]}; 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"
+ if ${GPG_PACMAN} --list-keys "$key" > /dev/null 2>&1; then
+ ${GPG_PACMAN} --edit-key "$key"
else
- error "$(gettext "The key identified by %s doesn't exist")" "$1"
+ error "$(gettext "The key identified by %s does not exist")" "$key"
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
+fi

# vim: set ts=2 sw=2 noet:
--
1.7.6
 
Old 07-08-2011, 11:59 AM
Allan McRae
 
Default pacman-key: use our option parser

The pacman-key script is complicated enough to warrent usage of the
parse_options script. This is especially helpful in dealing with
all the configuration file override flags as the no longer need to
be specified first. It also allows us to do the right thing early
with --help/--version and no option cases cleanly. This change also
makde the check for root privileges only occur on operations where
they are needed.

This patch is inspired by and supercedes some patches submitted by
Denis A. Altoé Falqueto and Ivan Kanakarakis who were altering the
previous option handling in an attempt to deal with the above issues.

Signed-off-by: Allan McRae <allan@archlinux.org>
---
scripts/pacman-key.sh.in | 191 +++++++++++++++++++++++----------------------
1 files changed, 98 insertions(+), 93 deletions(-)

diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 833943c..8e797f8 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -26,20 +26,30 @@ export TEXTDOMAINDIR='@localedir@'

myver="@PACKAGE_VERSION@"

+# Options
+ADD=0
+ADVANCED=0
+DELETE=0
+EXPORT=0
+FINGER=0
+LIST=0
+RECEIVE=0
+RELOAD=0
+TRUST=0
+UPDATEDB=0
+
m4_include(library/output_format.sh)

+m4_include(library/parse_options.sh)
+
usage() {
printf "pacman-key (pacman) %s
" ${myver}
echo
- printf "$(gettext "Usage: %s [options] <command> [arguments]")
" $(basename $0)
+ printf "$(gettext "Usage: %s [options]")
" $(basename $0)
echo
printf "$(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')")
" "$CONFIG"
- printf "$(gettext " --gpgdir Set an alternate directory for gnupg (instead of '%s')")
" "$PACMAN_KEYRING_DIR"
- echo
- echo "$(gettext "The available commands are:")"
+ echo "$(gettext "Options:")"
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")"
@@ -51,8 +61,11 @@ usage() {
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
+ echo "$(gettext " --config <file> Use an alternate config file")"
+ printf "$(gettext " (instead of '%s')")
" "@sysconfdir@/pacman.conf"
+ echo "$(gettext " --gpgdir <dir> Set an alternate directory for gnupg")"
+ printf "$(gettext " (instead of '%s')")
" "@sysconfdir@/pacman.d/gnupg"
+ echo "$(gettext " --reload Reload the default keys")"
}

version() {
@@ -198,116 +211,108 @@ 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
- 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
+OPT_SHORT="a::d:e:f::hlr:t:uV"
+OPT_LONG="add,adv:,config:,del:,export:,finger::, gpgdir:,help,list"
+OPT_LONG+=",receive:,reload,trust:,updatedb,versi on"
+if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then
+ echo; usage; exit 1 # E_INVALID_OPTION;
+fi
+eval set -- "$OPT_TEMP"
+unset OPT_SHORT OPT_LONG OPT_TEMP
+
+if [[ $1 == "--" ]]; then
+ usage;
+ exit 0;
fi

-# Parse global options
-CONFIG="@sysconfdir@/pacman.conf"
-PACMAN_KEYRING_DIR="@sysconfdir@/pacman.d/gnupg"
-while [[ $1 =~ ^--(config|gpgdir)$ ]]; do
+while true; do
case "$1" in
- --config) shift; CONFIG="$1" ;;
- --gpgdir) shift; PACMAN_KEYRING_DIR="$1" ;;
+ -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;;
+ --adv) ADVANCED=1; shift; ARGUMENTS=($1) ;;
+ --config) shift; CONFIG=$1 ;;
+ -d|--del) DELETE=1; shift; KEYIDS=($1) ;;
+ -e|--export) EXPORT=1; shift; KEYIDS=($1) ;;
+ -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;;
+ --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;;
+ -l|--list) LIST=1 ;;
+ -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;;
+ --reload) RELOAD=1 ;;
+ -t|--trust) TRUST=1; shift; KEYIDS=($1) ;;
+ -u|--updatedb) UPDATEDB=1 ;;
+
+ -h|--help) usage; exit 0 ;;
+ -V|--version) version; exit 0 ;;
+
+ --) OPT_IND=0; shift; break;;
+ *) usage; exit 1 ;;
esac
shift
done

+
+if ! type -p gpg >/dev/null; then
+ error "$(gettext "Cannot find the %s binary required for all %s operations.")" "gpg" "pacman-key"
+ exit 1
+fi
+
+if (( (ADD || ADVANCED || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then
+ error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key"
+ exit 1
+fi
+
+CONFIG=${CONFIG:-@sysconfdir@/pacman.conf}
if [[ ! -r "${CONFIG}" ]]; then
- error "$(gettext "%s not found.")" "$CONFIG"
+ error "$(gettext "%s configuation file '%s' not found.")" "pacman" "$CONFIG"
exit 1
fi

-# Read GPGDIR from $CONFIG.
-if [[ GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then
+# Get GPGDIR from pacman.conf iff not specified on command line
+if [[ -z PACMAN_KEYRING_DIR && GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then
PACMAN_KEYRING_DIR="${GPGDIR}"
fi
-GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning"
+PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg}

# 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
+GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning"
+
+
+(( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}"
+(( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}"
+(( EXPORT )) && ${GPG_PACMAN} --armor --export "${KEYIDS[@]}"
+(( FINGER )) && ${GPG_PACMAN} --batch --fingerprint "${KEYIDS[@]}"
+(( LIST )) && ${GPG_PACMAN} --batch --list-sigs "${KEYIDS[@]}"
+(( RELOAD )) && reload_keyring
+(( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb
+
+if (( ADVANCED )); then
+ msg "$(gettext "Executing: %s %s")" "${GPG_PACMAN}" "${ARGUMENTS[@]}"
+ ${GPG_PACMAN} "${ARGUMENTS[@]}" || ret=$?
+ exit $ret
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
+
+if (( RECEIVE )); then
+ if [[ -z ${KEYIDS[@]} ]]; then
+ error "$(gettext "You need to specify the keyserver and at least one key identifier")"
+ exit 1
+ fi
+ ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}"
+fi
+
+if (( TRUST )); then
+ for key in ${KEYIDS[@]}; 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"
+ if ${GPG_PACMAN} --list-keys "$key" > /dev/null 2>&1; then
+ ${GPG_PACMAN} --edit-key "$key"
else
- error "$(gettext "The key identified by %s doesn't exist")" "$1"
+ error "$(gettext "The key identified by %s does not exist")" "$key"
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
+fi

# vim: set ts=2 sw=2 noet:
--
1.7.6
 

Thread Tools




All times are GMT. The time now is 08:45 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright ©2007 - 2008, www.linux-archive.org