diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 833943cb..4056451f 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\n" ${myver} echo - printf "$(gettext "Usage: %s [options] [arguments]")\n" $(basename $0) + printf "$(gettext "Usage: %s [options]")\n" $(basename $0) echo printf "$(gettext "Manage pacman\'s list of trusted keys")\n" echo - echo "$(gettext "Options must be placed before commands. The available options are:")" - printf "$(gettext " --config Use an alternate config file (instead of '%s')")\n" "$CONFIG" - printf "$(gettext " --gpgdir Set an alternate directory for gnupg (instead of '%s')")\n" "$PACMAN_KEYRING_DIR" - echo - echo "$(gettext "The available commands are:")" + echo "$(gettext "Options:")" echo "$(gettext " -a, --add [] Add the specified keys (empty for stdin)")" echo "$(gettext " -d, --del Remove the specified keyids")" echo "$(gettext " -e, --export 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 Use pacman's keyring with advanced gpg commands")" - printf "$(gettext " --reload Reload the default keys")" - echo + echo "$(gettext " --config Use an alternate config file")" + printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.conf" + echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" + printf "$(gettext " (instead of '%s')")\n" "@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,version" +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 [[ ! -r "${CONFIG}" ]]; then - error "$(gettext "%s not found.")" "$CONFIG" + +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 -# Read GPGDIR from $CONFIG. -if [[ GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then +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 configuation file '%s' not found.")" "pacman" "$CONFIG" + exit 1 +fi + +# 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 -fi -shift +GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" -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 + +(( 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 + +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: