diff options
Diffstat (limited to '')
-rwxr-xr-x | src/password-store.sh | 694 |
1 files changed, 360 insertions, 334 deletions
diff --git a/src/password-store.sh b/src/password-store.sh index d9d458a..1a0e153 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -18,65 +18,10 @@ CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}" export GIT_DIR="${PASSWORD_STORE_GIT:-$PREFIX}/.git" export GIT_WORK_TREE="${PASSWORD_STORE_GIT:-$PREFIX}" +# +# BEGIN helper functions +# -version() { - cat <<-_EOF - ============================================ - = pass: the standard unix password manager = - = = - = v1.5 = - = = - = Jason A. Donenfeld = - = Jason@zx2c4.com = - = = - = http://zx2c4.com/projects/password-store = - ============================================ - _EOF -} -usage() { - version - echo - cat <<-_EOF - Usage: - $program init [--reencrypt,-e] [--path=subfolder,-p subfolder] gpg-id... - Initialize new password storage and use gpg-id for encryption. - Optionally reencrypt existing passwords using new gpg-id. - $program [ls] [subfolder] - List passwords. - $program find pass-names... - List passwords that match pass-names. - $program [show] [--clip,-c] pass-name - Show existing password and optionally put it on the clipboard. - If put on the clipboard, it will be cleared in $CLIP_TIME seconds. - $program insert [--echo,-e | --multiline,-m] [--force,-f] pass-name - Insert new password. Optionally, echo the password back to the console - during entry. Or, optionally, the entry may be multiline. Prompt before - overwriting existing password unless forced. - $program edit pass-name - Insert a new password or edit an existing password using ${EDITOR:-vi}. - $program generate [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length - Generate a new password of pass-length with optionally no symbols. - Optionally put it on the clipboard and clear board after 45 seconds. - Prompt before overwriting existing password unless forced. - $program rm [--recursive,-r] [--force,-f] pass-name - Remove existing password or directory, optionally forcefully. - $program git git-command-args... - If the password store is a git repository, execute a git command - specified by git-command-args. - $program help - Show this text. - $program version - Show version information. - - More information may be found in the pass(1) man page. - _EOF -} -is_command() { - case "$1" in - init|ls|list|find|search|show|insert|edit|generate|remove|rm|delete|git|help|--help|version|--version) return 0 ;; - *) return 1 ;; - esac -} git_add_file() { [[ -d $GIT_DIR ]] || return git add "$1" || return @@ -85,6 +30,7 @@ git_add_file() { git commit $sign -m "$2" } yesno() { + local response read -r -p "$1 [y/N] " response [[ $response == [yY] ]] || exit 1 } @@ -111,7 +57,7 @@ set_gpg_recipients() { before you may use the password store. _EOF - usage + cmd_usage exit 1 fi @@ -121,20 +67,25 @@ set_gpg_recipients() { } # -# BEGIN Platform definable +# END helper functions # + +# +# BEGIN platform definable +# + clip() { # This base64 business is a disgusting hack to deal with newline inconsistancies # in shell. There must be a better way to deal with this, but because I'm a dolt, # we're going with this for now. - sleep_argv0="password store sleep on display $DISPLAY" + local sleep_argv0="password store sleep on display $DISPLAY" pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5 - before="$(xclip -o -selection "$X_SELECTION" | base64)" + local before="$(xclip -o -selection "$X_SELECTION" | base64)" echo -n "$1" | xclip -selection "$X_SELECTION" ( ( exec -a "$sleep_argv0" sleep "$CLIP_TIME" ) - now="$(xclip -o -selection "$X_SELECTION" | base64)" + local now="$(xclip -o -selection "$X_SELECTION" | base64)" [[ $now != $(echo -n "$1" | base64) ]] && before="$now" # It might be nice to programatically check to see if klipper exists, @@ -166,301 +117,376 @@ GETOPT="getopt" SHRED="shred -f -z" # source /path/to/platform-defined-functions + # -# END Platform definable +# END platform definable # -program="${0##*/}" -command="$1" -if is_command "$command"; then - shift -else - command="show" -fi - -case "$command" in - init) - reencrypt=0 - id_path="" - - opts="$($GETOPT -o ep: -l reencrypt,path: -n "$program" -- "$@")" - err=$? - eval set -- "$opts" - while true; do case $1 in - -e|--reencrypt) reencrypt=1; shift ;; - -p|--path) id_path="$2"; shift 2 ;; - --) shift; break ;; - esac done - - if [[ $err -ne 0 || $# -lt 1 ]]; then - echo "Usage: $program $command [--reencrypt,-e] [--path=subfolder,-p subfolder] gpg-id..." - exit 1 - fi - if [[ -n $id_path && ! -d $PREFIX/$id_path ]]; then - if [[ -e $PREFIX/$id_path ]]; then - echo "Error: $PREFIX/$id_path exists but is not a directory." - exit 1; - fi - fi - mkdir -v -p "$PREFIX/$id_path" - gpg_id="$PREFIX/$id_path/.gpg-id" - printf "%s\n" "$@" > "$gpg_id" - id_print="$(printf "%s, " "$@")" - echo "Password store initialized for ${id_print%, }" - git_add_file "$gpg_id" "Set GPG id to ${id_print%, }." - - if [[ $reencrypt -eq 1 ]]; then - find "$PREFIX/$id_path" -iname '*.gpg' | while read -r passfile; do - fake_uniqueness_safety="$RANDOM" - passfile_dir=${passfile%/*} - passfile_dir=${passfile_dir#$PREFIX} - passfile_dir=${passfile_dir#/} - set_gpg_recipients "$passfile_dir" - $GPG -d $GPG_OPTS "$passfile" | $GPG -e "${gpg_recipient_args[@]}" -o "$passfile.new.$fake_uniqueness_safety" $GPG_OPTS && - mv -v "$passfile.new.$fake_uniqueness_safety" "$passfile" - done - git_add_file "$PREFIX/$id_path" "Reencrypted password store using new GPG id ${id_print}." - fi - exit 0 - ;; - help|--help) - usage - exit 0 - ;; - version|--version) - version - exit 0 - ;; - show|ls|list) - clip=0 - - opts="$($GETOPT -o c -l clip -n "$program" -- "$@")" - err=$? - eval set -- "$opts" - while true; do case $1 in - -c|--clip) clip=1; shift ;; - --) shift; break ;; - esac done - - if [[ $err -ne 0 ]]; then - echo "Usage: $program $command [--clip,-c] [pass-name]" - exit 1 - fi +# +# BEGIN subcommand functions +# - path="$1" - passfile="$PREFIX/$path.gpg" - if [[ -f $passfile ]]; then - if [[ $clip -eq 0 ]]; then - exec $GPG -d $GPG_OPTS "$passfile" - else - pass="$($GPG -d $GPG_OPTS "$passfile" | head -n 1)" - [[ -n $pass ]] || exit 1 - clip "$pass" "$path" - fi - elif [[ -d $PREFIX/$path ]]; then - if [[ -z $path ]]; then - echo "Password Store" - else - echo "${path%\/}" - fi - tree -l --noreport "$PREFIX/$path" | tail -n +2 | sed 's/\.gpg$//' - else - echo "$path is not in the password store." - exit 1 - fi - ;; - find|search) - if [[ -z "$@" ]]; then - echo "Usage: $program $command pass-names..." - exit 1 - fi - if ! tree --version | grep -q "Jason A. Donenfeld"; then - echo "ERROR: $program: incompatible tree command" - echo - echo "Your version of the tree command is missing the relevent patch to add the" - echo "--matchdirs and --caseinsensitive switches. Please ask your distribution" - echo "to patch your version of" - echo "tree with:" - echo " http://git.zx2c4.com/password-store/plain/contrib/tree-1.6.0-matchdirs.patch" - echo "Sorry for the inconvenience." - exit 1 - fi - terms="$@" - echo "Search Terms: $terms" - tree -l --noreport -P "*${terms// /*|*}*" --prune --matchdirs --caseinsensitive "$PREFIX" | tail -n +2 | sed 's/\.gpg$//' - ;; - insert) - multiline=0 - noecho=1 - force=0 - - opts="$($GETOPT -o mef -l multiline,echo,force -n "$program" -- "$@")" - err=$? - eval set -- "$opts" - while true; do case $1 in - -m|--multiline) multiline=1; shift ;; - -e|--echo) noecho=0; shift ;; - -f|--force) force=1; shift ;; - --) shift; break ;; - esac done - - if [[ $err -ne 0 || ( $multiline -eq 1 && $noecho -eq 0 ) || $# -ne 1 ]]; then - echo "Usage: $program $command [--echo,-e | --multiline,-m] [--force,-f] pass-name" - exit 1 - fi - path="$1" - passfile="$PREFIX/$path.gpg" +cmd_version() { + cat <<-_EOF + ============================================ + = pass: the standard unix password manager = + = = + = v1.5 = + = = + = Jason A. Donenfeld = + = Jason@zx2c4.com = + = = + = http://zx2c4.com/projects/password-store = + ============================================ + _EOF +} - [[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?" +cmd_usage() { + cmd_version + echo + cat <<-_EOF + Usage: + $program init [--reencrypt,-e] [--path=subfolder,-p subfolder] gpg-id... + Initialize new password storage and use gpg-id for encryption. + Optionally reencrypt existing passwords using new gpg-id. + $program [ls] [subfolder] + List passwords. + $program find pass-names... + List passwords that match pass-names. + $program [show] [--clip,-c] pass-name + Show existing password and optionally put it on the clipboard. + If put on the clipboard, it will be cleared in $CLIP_TIME seconds. + $program insert [--echo,-e | --multiline,-m] [--force,-f] pass-name + Insert new password. Optionally, echo the password back to the console + during entry. Or, optionally, the entry may be multiline. Prompt before + overwriting existing password unless forced. + $program edit pass-name + Insert a new password or edit an existing password using ${EDITOR:-vi}. + $program generate [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length + Generate a new password of pass-length with optionally no symbols. + Optionally put it on the clipboard and clear board after 45 seconds. + Prompt before overwriting existing password unless forced. + $program rm [--recursive,-r] [--force,-f] pass-name + Remove existing password or directory, optionally forcefully. + $program git git-command-args... + If the password store is a git repository, execute a git command + specified by git-command-args. + $program help + Show this text. + $program version + Show version information. - mkdir -p -v "$PREFIX/$(dirname "$path")" - set_gpg_recipients "$(dirname "$path")" + More information may be found in the pass(1) man page. + _EOF +} - if [[ $multiline -eq 1 ]]; then - echo "Enter contents of $path and press Ctrl+D when finished:" - echo - $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS - elif [[ $noecho -eq 1 ]]; then - while true; do - read -r -p "Enter password for $path: " -s password - echo - read -r -p "Retype password for $path: " -s password_again - echo - if [[ $password == "$password_again" ]]; then - $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$password" - break - else - echo "Error: the entered passwords do not match." - fi - done - else - read -r -p "Enter password for $path: " -e password - $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$password" - fi - git_add_file "$passfile" "Added given password for $path to store." - ;; - edit) - if [[ $# -ne 1 ]]; then - echo "Usage: $program $command pass-name" - exit 1 +cmd_init() { + local reencrypt=0 + local id_path="" + + local opts + opts="$($GETOPT -o ep: -l reencrypt,path: -n "$program" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -e|--reencrypt) reencrypt=1; shift ;; + -p|--path) id_path="$2"; shift 2 ;; + --) shift; break ;; + esac done + + if [[ $err -ne 0 || $# -lt 1 ]]; then + echo "Usage: $program $command [--reencrypt,-e] [--path=subfolder,-p subfolder] gpg-id..." + exit 1 + fi + if [[ -n $id_path && ! -d $PREFIX/$id_path ]]; then + if [[ -e $PREFIX/$id_path ]]; then + echo "Error: $PREFIX/$id_path exists but is not a directory." + exit 1; fi + fi - path="$1" - mkdir -p -v "$PREFIX/$(dirname "$path")" - set_gpg_recipients "$(dirname "$path")" - passfile="$PREFIX/$path.gpg" - template="$program.XXXXXXXXXXXXX" + mkdir -v -p "$PREFIX/$id_path" + local gpg_id="$PREFIX/$id_path/.gpg-id" + printf "%s\n" "$@" > "$gpg_id" + local id_print="$(printf "%s, " "$@")" + echo "Password store initialized for ${id_print%, }" + git_add_file "$gpg_id" "Set GPG id to ${id_print%, }." + + if [[ $reencrypt -eq 1 ]]; then + local passfile + find "$PREFIX/$id_path" -iname '*.gpg' | while read -r passfile; do + fake_uniqueness_safety="$RANDOM" + passfile_dir=${passfile%/*} + passfile_dir=${passfile_dir#$PREFIX} + passfile_dir=${passfile_dir#/} + set_gpg_recipients "$passfile_dir" + $GPG -d $GPG_OPTS "$passfile" | $GPG -e "${gpg_recipient_args[@]}" -o "$passfile.new.$fake_uniqueness_safety" $GPG_OPTS && + mv -v "$passfile.new.$fake_uniqueness_safety" "$passfile" + done + git_add_file "$PREFIX/$id_path" "Reencrypted password store using new GPG id ${id_print}." + fi +} - trap '$SHRED "$tmp_file"; rm -rf "$tmp_dir" "$tmp_file"' INT TERM EXIT +cmd_show() { + local clip=0 - tmpdir #Defines $tmp_dir - tmp_file="$(TMPDIR="$tmp_dir" mktemp -t "$template")" + local opts + opts="$($GETOPT -o c -l clip -n "$program" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -c|--clip) clip=1; shift ;; + --) shift; break ;; + esac done - action="Added" - if [[ -f $passfile ]]; then - $GPG -d -o "$tmp_file" $GPG_OPTS "$passfile" || exit 1 - action="Edited" - fi - ${EDITOR:-vi} "$tmp_file" - while ! $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS "$tmp_file"; do - echo "GPG encryption failed. Retrying." - sleep 1 - done - git_add_file "$passfile" "$action password for $path using ${EDITOR:-vi}." - ;; - generate) - clip=0 - force=0 - symbols="-y" - - opts="$($GETOPT -o ncf -l no-symbols,clip,force -n "$program" -- "$@")" - err=$? - eval set -- "$opts" - while true; do case $1 in - -n|--no-symbols) symbols=""; shift ;; - -c|--clip) clip=1; shift ;; - -f|--force) force=1; shift ;; - --) shift; break ;; - esac done - - if [[ $err -ne 0 || $# -ne 2 ]]; then - echo "Usage: $program $command [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length" - exit 1 - fi - path="$1" - length="$2" - if [[ ! $length =~ ^[0-9]+$ ]]; then - echo "pass-length \"$length\" must be a number." - exit 1 - fi - mkdir -p -v "$PREFIX/$(dirname "$path")" - set_gpg_recipients "$(dirname "$path")" - passfile="$PREFIX/$path.gpg" - - [[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?" + if [[ $err -ne 0 ]]; then + echo "Usage: $program $command [--clip,-c] [pass-name]" + exit 1 + fi - pass="$(pwgen -s $symbols $length 1)" - [[ -n $pass ]] || exit 1 - $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$pass" - git_add_file "$passfile" "Added generated password for $path to store." - + local path="$1" + local passfile="$PREFIX/$path.gpg" + if [[ -f $passfile ]]; then if [[ $clip -eq 0 ]]; then - echo "The generated password to $path is:" - echo "$pass" + exec $GPG -d $GPG_OPTS "$passfile" else + local pass="$($GPG -d $GPG_OPTS "$passfile" | head -n 1)" + [[ -n $pass ]] || exit 1 clip "$pass" "$path" fi - ;; - delete|rm|remove) - recursive="" - force=0 - - opts="$($GETOPT -o rf -l recursive,force -n "$program" -- "$@")" - err=$? - eval set -- "$opts" - while true; do case $1 in - -r|--recursive) recursive="-r"; shift ;; - -f|--force) force=1; shift ;; - --) shift; break ;; - esac done - if [[ $# -ne 1 ]]; then - echo "Usage: $program $command [--recursive,-r] [--force,-f] pass-name" - exit 1 + elif [[ -d $PREFIX/$path ]]; then + if [[ -z $path ]]; then + echo "Password Store" + else + echo "${path%\/}" fi - path="$1" - - passfile="$PREFIX/${path%/}" - if [[ ! -d $passfile ]]; then - passfile="$PREFIX/$path.gpg" - if [[ ! -f $passfile ]]; then - echo "$path is not in the password store." - exit 1 + tree -l --noreport "$PREFIX/$path" | tail -n +2 | sed 's/\.gpg$//' + else + echo "$path is not in the password store." + exit 1 + fi +} + +cmd_find() { + if [[ -z "$@" ]]; then + echo "Usage: $program $command pass-names..." + exit 1 + fi + if ! tree --version | grep -q "Jason A. Donenfeld"; then + echo "ERROR: $program: incompatible tree command" + echo + echo "Your version of the tree command is missing the relevent patch to add the" + echo "--matchdirs and --caseinsensitive switches. Please ask your distribution" + echo "to patch your version of" + echo "tree with:" + echo " http://git.zx2c4.com/password-store/plain/contrib/tree-1.6.0-matchdirs.patch" + echo "Sorry for the inconvenience." + exit 1 + fi + local terms="$@" + echo "Search Terms: $terms" + tree -l --noreport -P "*${terms// /*|*}*" --prune --matchdirs --caseinsensitive "$PREFIX" | tail -n +2 | sed 's/\.gpg$//' +} + +cmd_insert() { + local multiline=0 + local noecho=1 + local force=0 + + local opts + opts="$($GETOPT -o mef -l multiline,echo,force -n "$program" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -m|--multiline) multiline=1; shift ;; + -e|--echo) noecho=0; shift ;; + -f|--force) force=1; shift ;; + --) shift; break ;; + esac done + + if [[ $err -ne 0 || ( $multiline -eq 1 && $noecho -eq 0 ) || $# -ne 1 ]]; then + echo "Usage: $program $command [--echo,-e | --multiline,-m] [--force,-f] pass-name" + exit 1 + fi + local path="$1" + local passfile="$PREFIX/$path.gpg" + + [[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?" + + mkdir -p -v "$PREFIX/$(dirname "$path")" + set_gpg_recipients "$(dirname "$path")" + + if [[ $multiline -eq 1 ]]; then + echo "Enter contents of $path and press Ctrl+D when finished:" + echo + $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS + elif [[ $noecho -eq 1 ]]; then + local password + local password_again + while true; do + read -r -p "Enter password for $path: " -s password + echo + read -r -p "Retype password for $path: " -s password_again + echo + if [[ $password == "$password_again" ]]; then + $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$password" + break + else + echo "Error: the entered passwords do not match." fi - fi + done + else + local password + read -r -p "Enter password for $path: " -e password + $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$password" + fi + git_add_file "$passfile" "Added given password for $path to store." +} - [[ $force -eq 1 ]] || yesno "Are you sure you would like to delete $path?" +cmd_edit() { + if [[ $# -ne 1 ]]; then + echo "Usage: $program $command pass-name" + exit 1 + fi - rm $recursive -f -v "$passfile" - if [[ -d $GIT_DIR && ! -e $passfile ]]; then - git rm -qr "$passfile" - git commit -m "Removed $path from store." - fi - ;; - git) - if [[ $1 == "init" ]]; then - git "$@" || exit 1 - git_add_file "$PREFIX" "Added current contents of password store." - elif [[ -d $GIT_DIR ]]; then - exec git "$@" - else - echo "Error: the password store is not a git repository." + local path="$1" + mkdir -p -v "$PREFIX/$(dirname "$path")" + set_gpg_recipients "$(dirname "$path")" + local passfile="$PREFIX/$path.gpg" + local template="$program.XXXXXXXXXXXXX" + + trap '$SHRED "$tmp_file"; rm -rf "$tmp_dir" "$tmp_file"' INT TERM EXIT + + tmpdir #Defines $tmp_dir + local tmp_file="$(TMPDIR="$tmp_dir" mktemp -t "$template")" + + local action="Added" + if [[ -f $passfile ]]; then + $GPG -d -o "$tmp_file" $GPG_OPTS "$passfile" || exit 1 + action="Edited" + fi + ${EDITOR:-vi} "$tmp_file" + while ! $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS "$tmp_file"; do + echo "GPG encryption failed. Retrying." + sleep 1 + done + git_add_file "$passfile" "$action password for $path using ${EDITOR:-vi}." +} + +cmd_generate() { + local clip=0 + local force=0 + local symbols="-y" + + local opts + opts="$($GETOPT -o ncf -l no-symbols,clip,force -n "$program" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -n|--no-symbols) symbols=""; shift ;; + -c|--clip) clip=1; shift ;; + -f|--force) force=1; shift ;; + --) shift; break ;; + esac done + + if [[ $err -ne 0 || $# -ne 2 ]]; then + echo "Usage: $program $command [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length" + exit 1 + fi + local path="$1" + local length="$2" + if [[ ! $length =~ ^[0-9]+$ ]]; then + echo "pass-length \"$length\" must be a number." + exit 1 + fi + mkdir -p -v "$PREFIX/$(dirname "$path")" + set_gpg_recipients "$(dirname "$path")" + local passfile="$PREFIX/$path.gpg" + + [[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?" + + local pass="$(pwgen -s $symbols $length 1)" + [[ -n $pass ]] || exit 1 + $GPG -e "${gpg_recipient_args[@]}" -o "$passfile" $GPG_OPTS <<<"$pass" + git_add_file "$passfile" "Added generated password for $path to store." + + if [[ $clip -eq 0 ]]; then + echo "The generated password to $path is:" + echo "$pass" + else + clip "$pass" "$path" + fi +} + +cmd_delete() { + local recursive="" + local force=0 + + local opts + opts="$($GETOPT -o rf -l recursive,force -n "$program" -- "$@")" + local err=$? + eval set -- "$opts" + while true; do case $1 in + -r|--recursive) recursive="-r"; shift ;; + -f|--force) force=1; shift ;; + --) shift; break ;; + esac done + if [[ $# -ne 1 ]]; then + echo "Usage: $program $command [--recursive,-r] [--force,-f] pass-name" + exit 1 + fi + local path="$1" + + local passfile="$PREFIX/${path%/}" + if [[ ! -d $passfile ]]; then + passfile="$PREFIX/$path.gpg" + if [[ ! -f $passfile ]]; then + echo "$path is not in the password store." exit 1 fi - ;; - *) - usage + fi + + [[ $force -eq 1 ]] || yesno "Are you sure you would like to delete $path?" + + rm $recursive -f -v "$passfile" + if [[ -d $GIT_DIR && ! -e $passfile ]]; then + git rm -qr "$passfile" + git commit -m "Removed $path from store." + fi +} + +cmd_git() { + if [[ $1 == "init" ]]; then + git "$@" || exit 1 + git_add_file "$PREFIX" "Added current contents of password store." + elif [[ -d $GIT_DIR ]]; then + exec git "$@" + else + echo "Error: the password store is not a git repository." exit 1 - ;; + fi +} + +# +# END subcommand functions +# + +program="${0##*/}" +command="$1" + +case "$1" in + init) shift; cmd_init "$@"; ;; + help|--help) shift; cmd_usage "$@"; ;; + version|--version) shift; cmd_version "$@"; ;; + show|ls|list) shift; cmd_show "$@"; ;; + find|search) shift; cmd_find "$@"; ;; + insert) shift; cmd_insert "$@"; ;; + edit) shift; cmd_edit "$@"; ;; + generate) shift; cmd_generate "$@"; ;; + delete|rm|remove) shift; cmd_delete "$@"; ;; + git) shift; cmd_git "$@"; ;; + -*) shift; cmd_usage "$@"; exit 1; ;; + *) command="show"; cmd_show "$@"; ;; esac exit 0 |