diff options
Diffstat (limited to 'tessen')
-rwxr-xr-x | tessen | 442 |
1 files changed, 220 insertions, 222 deletions
@@ -11,23 +11,22 @@ set +x # GLOBAL VARIABLES -declare pass_backend dmenu_backend tsn_action tsn_config -declare -a dmenu_backend_opts tmp_tofi_opts tmp_rofi_opts tmp_wofi_opts -declare tsn_userkey tsn_urlkey tsn_autokey tsn_delay tsn_web_browser +declare _PASS_BACKEND _DMENU_BACKEND _TSN_ACTION _TSN_CONFIG +declare -a _DMENU_BACKEND_OPTS _TMP_TOFI_OPTS _TMP_ROFI_OPTS _TMP_WOFI_OPTS +declare _TSN_USERKEY _TSN_URLKEY _TSN_AUTOKEY _TSN_WEB_BROWSER +declare -i _TSN_DELAY # show both actions, 'autotype' and 'copy', to choose from by default -tsn_action="default" -tsn_otp=false -# initialize default values for keys -tsn_userkey="user" -tsn_urlkey="url" -tsn_autokey="autotype" -tsn_delay=100 -# initialize the default location of the config file -tsn_config="${XDG_CONFIG_HOME:-$HOME/.config}"/tessen/config +_TSN_ACTION="default" +_TSN_OTP=false +_TSN_USERKEY="user" +_TSN_URLKEY="url" +_TSN_AUTOKEY="autotype" +_TSN_DELAY=100 +_TSN_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}"/tessen/config # variables with sensitive data which will be manually unset using _clear -declare tsn_passfile tsn_username tsn_password tsn_url tsn_autotype chosen_key +declare _TSN_PASSFILE _TSN_USERNAME _TSN_PASSWORD _TSN_URL _TSN_AUTOTYPE _CHOSEN_KEY declare -i _EXIT_STATUS -declare -A tsn_passdata +declare -A _TSN_PASSDATA # FIRST MENU: generate a list of pass files, let the user select one get_pass_files() { @@ -45,11 +44,13 @@ get_pass_files() { tmp_pass_files=("${tmp_pass_files[@]%.gpg}") shopt -u nullglob globstar - tsn_passfile="$(printf "%s\n" "${tmp_pass_files[@]}" \ - | "$dmenu_backend" "${dmenu_backend_opts[@]}")" + _TSN_PASSFILE="$(printf "%s\n" "${tmp_pass_files[@]}" \ + | "$_DMENU_BACKEND" "${_DMENU_BACKEND_OPTS[@]}")" _EXIT_STATUS="$?" - if ! [[ -f "$tmp_prefix/$tsn_passfile".gpg ]]; then + # instead of searching through the tmp_pass_files array for valid selection, + # we check if the corresponding file is present + if ! [[ -f "$tmp_prefix/$_TSN_PASSFILE".gpg ]]; then _die fi @@ -103,29 +104,29 @@ get_gopass_files() { shopt -u nullglob globstar # the actual menu - tsn_passfile="$(printf "%s\n" "${!tmp_gopass_files[@]}" \ - | "$dmenu_backend" "${dmenu_backend_opts[@]}")" + _TSN_PASSFILE="$(printf "%s\n" "${!tmp_gopass_files[@]}" \ + | "$_DMENU_BACKEND" "${_DMENU_BACKEND_OPTS[@]}")" _EXIT_STATUS="$?" - if [[ -z $tsn_passfile ]]; then + if [[ -z $_TSN_PASSFILE ]]; then _die fi # remove the mount name for the path check to be successful - # initialize the temp variable with the value of tsn_passfile in case an + # initialize the temp variable with the value of _TSN_PASSFILE in case an # entry from the gopass path is chosen - tmp_tsn_passfile="$tsn_passfile" + tmp_tsn_passfile="$_TSN_PASSFILE" for idx in "${mount_name_arr[@]}"; do - if [[ ${tsn_passfile%%/*} == "$idx" ]]; then - tmp_tsn_passfile="${tsn_passfile#*/}" + if [[ ${_TSN_PASSFILE%%/*} == "$idx" ]]; then + tmp_tsn_passfile="${_TSN_PASSFILE#*/}" fi done # we had to use an associative array to keep track of the absolute path of # the selected file because it is possible to give invalid input to dmenu # while making a selection and tessen should exit in that case - if [[ -n ${tmp_gopass_files["$tsn_passfile"]} ]]; then - if ! [[ -f "${tmp_gopass_files["$tsn_passfile"]}"/"$tmp_tsn_passfile".gpg ]]; then + if [[ -n ${tmp_gopass_files["$_TSN_PASSFILE"]} ]]; then + if ! [[ -f "${tmp_gopass_files["$_TSN_PASSFILE"]}"/"$tmp_tsn_passfile".gpg ]]; then _die "the selected file was not found" fi fi @@ -139,19 +140,18 @@ get_pass_data() { local -a passdata local keyval_regex otp_regex idx key val - if [[ $pass_backend == "pass" ]]; then - mapfile -t passdata < <(pass show "$tsn_passfile" 2> /dev/null) + if [[ $_PASS_BACKEND == "pass" ]]; then + mapfile -t passdata < <(pass show "$_TSN_PASSFILE" 2> /dev/null) if [[ ${#passdata[@]} -eq 0 ]]; then - _die "$tsn_passfile is empty" + _die "$_TSN_PASSFILE is empty" fi - elif [[ $pass_backend == "gopass" ]]; then - # gopass show -n -f is weird because it emits a first line 'Secret: - # truncated-file-name' and that doesn't get assigned to a variable. but if - # I redirect stdout to /dev/null, that first line gets redirected as well. - # there doesn't seem to be any way to disable printing this first line. - mapfile -t passdata < <(gopass show -n -f "$tsn_passfile" 2> /dev/null) + elif [[ $_PASS_BACKEND == "gopass" ]]; then + # the output from gopass show -n -f that prints the first line and the + # newline before EOF doesn't use file descriptors but is printed only when + # the output is detected to be a terminal ... weird + mapfile -t passdata < <(gopass show -n -f "$_TSN_PASSFILE" 2> /dev/null) if [[ ${#passdata[@]} -eq 0 ]]; then - _die "$tsn_passfile is empty" + _die "$_TSN_PASSFILE is empty" fi fi @@ -159,44 +159,42 @@ get_pass_data() { # for parsing the 'otpauth://' URI # this regex is borrowed from pass-otp at commit 3ba564c otp_regex='^otpauth:\/\/(totp|hotp)(\/(([^:?]+)?(:([^:?]*))?)(:([0-9]+))?)?\?(.+)$' - - tsn_password="${passdata[0]}" + _TSN_PASSWORD="${passdata[0]}" for idx in "${passdata[@]:1}"; do key="${idx%%:*}" val="${idx#*: }" if [[ ${key,,} == "password" ]]; then continue - elif [[ ${key,,} =~ ^$tsn_userkey$ ]] && [[ -z ${tsn_username} ]]; then - tsn_userkey="${key,,}" - tsn_username="$val" - elif [[ ${key,,} =~ ^$tsn_autokey$ ]] && [[ -z ${tsn_autotype} ]]; then - tsn_autokey="${key,,}" - tsn_autotype="$val" - elif [[ ${key,,} =~ ^$tsn_urlkey$ ]] && [[ -z ${tsn_url} ]]; then - tsn_urlkey="${key,,}" - tsn_url="$val" - elif [[ $idx =~ $otp_regex ]] && [[ $tsn_otp == "false" ]]; then - tsn_otp=true - elif [[ $idx =~ $keyval_regex ]] && [[ -z ${tsn_passdata["$key"]} ]]; then - tsn_passdata["$key"]="$val" + elif [[ ${key,,} =~ ^$_TSN_USERKEY$ ]] && [[ -z ${_TSN_USERNAME} ]]; then + _TSN_USERKEY="${key,,}" + _TSN_USERNAME="$val" + elif [[ ${key,,} =~ ^$_TSN_AUTOKEY$ ]] && [[ -z ${_TSN_AUTOTYPE} ]]; then + _TSN_AUTOKEY="${key,,}" + _TSN_AUTOTYPE="$val" + elif [[ ${key,,} =~ ^$_TSN_URLKEY$ ]] && [[ -z ${_TSN_URL} ]]; then + _TSN_URLKEY="${key,,}" + _TSN_URL="$val" + elif [[ $idx =~ $otp_regex ]] && [[ $_TSN_OTP == "false" ]]; then + _TSN_OTP=true + elif [[ $idx =~ $keyval_regex ]] && [[ -z ${_TSN_PASSDATA["$key"]} ]]; then + _TSN_PASSDATA["$key"]="$val" fi done - # if $tsn_userkey isn't found, use the basename of file as username - # also set the value of the tsn_userkey to the default value + # set the value of the _TSN_USERKEY to the default value # this prevents the userkey from showing up as a regex in case a user has set # it in the config file # the same goes for other custom key variables - if [[ -z $tsn_username ]]; then - tsn_username="${tsn_passfile##*/}" - tsn_userkey="user" + if [[ -z $_TSN_USERNAME ]]; then + _TSN_USERNAME="${_TSN_PASSFILE##*/}" + _TSN_USERKEY="user" fi - if [[ -z $tsn_autotype ]]; then - tsn_autokey="autotype" + if [[ -z $_TSN_AUTOTYPE ]]; then + _TSN_AUTOKEY="autotype" fi - if [[ -z $tsn_url ]]; then - tsn_urlkey="url" + if [[ -z $_TSN_URL ]]; then + _TSN_URLKEY="url" fi unset -v passdata keyval_regex otp_regex idx key val @@ -206,69 +204,69 @@ get_pass_data() { custom_keyb_action() { case "$_EXIT_STATUS" in 10) auto_type_def ;; - 11) auto_type "$tsn_username" ;; - 12) auto_type "$tsn_password" ;; + 11) auto_type "$_TSN_USERNAME" ;; + 12) auto_type "$_TSN_PASSWORD" ;; 13) key_open_url ;; - 14) wld_copy "$tsn_username" ;; - 15) wld_copy "$tsn_password" ;; - 16) wld_copy "$tsn_url" ;; + 14) wld_copy "$_TSN_USERNAME" ;; + 15) wld_copy "$_TSN_PASSWORD" ;; + 16) wld_copy "$_TSN_URL" ;; *) _die "unmapped exit code detected" ;; esac } # SECOND MENU: show a list of possible keys to choose from for autotyping or -# copying, depending on the value of tsn_action -# THIRD MENU: optional, this will show up if tsn_action is blank +# copying, depending on the value of _TSN_ACTION +# THIRD MENU: optional, this will show up if _TSN_ACTION is blank get_key() { local -a key_arr local ch flag=false # the 2nd menu for autotype, both, and the default actions will be the same # and the autotype key will be present in these cases - # when tsn_action is set to copy, the autotype key shouldn't be shown in the 2nd menu - case "$tsn_action" in + # when _TSN_ACTION is set to copy, the autotype key shouldn't be shown in the 2nd menu + case "$_TSN_ACTION" in autotype | both | default) if [[ $1 == "key_list" ]]; then - if [[ $tsn_otp == "false" ]] && [[ -z $tsn_url ]]; then - key_arr=("$tsn_autokey" "$tsn_userkey" "password" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "false" ]] && [[ -n $tsn_url ]]; then - key_arr=("$tsn_autokey" "$tsn_userkey" "password" "$tsn_urlkey" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "true" ]] && [[ -z $tsn_url ]]; then - key_arr=("$tsn_autokey" "$tsn_userkey" "password" "otp" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "true" ]] && [[ -n $tsn_url ]]; then - key_arr=("$tsn_autokey" "$tsn_userkey" "password" "otp" "$tsn_urlkey" "${!tsn_passdata[@]}") + if [[ $_TSN_OTP == "false" ]] && [[ -z $_TSN_URL ]]; then + key_arr=("$_TSN_AUTOKEY" "$_TSN_USERKEY" "password" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "false" ]] && [[ -n $_TSN_URL ]]; then + key_arr=("$_TSN_AUTOKEY" "$_TSN_USERKEY" "password" "$_TSN_URLKEY" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "true" ]] && [[ -z $_TSN_URL ]]; then + key_arr=("$_TSN_AUTOKEY" "$_TSN_USERKEY" "password" "otp" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "true" ]] && [[ -n $_TSN_URL ]]; then + key_arr=("$_TSN_AUTOKEY" "$_TSN_USERKEY" "password" "otp" "$_TSN_URLKEY" "${!_TSN_PASSDATA[@]}") fi fi - # the (optional) third menu, its appearance depends on tsn_action being default - if [[ $tsn_action == "default" ]] && [[ $1 == "option" ]]; then - key_arr=("$tsn_autokey" "copy") - # the (optional) third menu if tsn_urlkey is chosen, it depends on - # tsn_action being default - elif [[ $tsn_action == "default" ]] && [[ $1 == "$tsn_urlkey" ]]; then + # the (optional) third menu, its appearance depends on _TSN_ACTION being default + if [[ $_TSN_ACTION == "default" ]] && [[ $1 == "option" ]]; then + key_arr=("$_TSN_AUTOKEY" "copy") + # the (optional) third menu if _TSN_URLKEY is chosen, it depends on + # _TSN_ACTION being default + elif [[ $_TSN_ACTION == "default" ]] && [[ $1 == "$_TSN_URLKEY" ]]; then key_arr=("open" "copy") fi ;; copy) if [[ $1 == "key_list" ]]; then - if [[ $tsn_otp == "false" ]] && [[ -z $tsn_url ]]; then - key_arr=("$tsn_userkey" "password" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "false" ]] && [[ -n $tsn_url ]]; then - key_arr=("$tsn_userkey" "password" "$tsn_urlkey" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "true" ]] && [[ -z $tsn_url ]]; then - key_arr=("$tsn_userkey" "password" "otp" "${!tsn_passdata[@]}") - elif [[ $tsn_otp == "true" ]] && [[ -n $tsn_url ]]; then - key_arr=("$tsn_userkey" "password" "otp" "$tsn_urlkey" "${!tsn_passdata[@]}") + if [[ $_TSN_OTP == "false" ]] && [[ -z $_TSN_URL ]]; then + key_arr=("$_TSN_USERKEY" "password" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "false" ]] && [[ -n $_TSN_URL ]]; then + key_arr=("$_TSN_USERKEY" "password" "$_TSN_URLKEY" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "true" ]] && [[ -z $_TSN_URL ]]; then + key_arr=("$_TSN_USERKEY" "password" "otp" "${!_TSN_PASSDATA[@]}") + elif [[ $_TSN_OTP == "true" ]] && [[ -n $_TSN_URL ]]; then + key_arr=("$_TSN_USERKEY" "password" "otp" "$_TSN_URLKEY" "${!_TSN_PASSDATA[@]}") fi fi ;; esac # a global variable to hold the selected key for key_menu - chosen_key="$(printf "%s\n" "${key_arr[@]}" | "$dmenu_backend" "${dmenu_backend_opts[@]}")" + _CHOSEN_KEY="$(printf "%s\n" "${key_arr[@]}" | "$_DMENU_BACKEND" "${_DMENU_BACKEND_OPTS[@]}")" # validate the chosen key, if it doesn't exist, exit for ch in "${key_arr[@]}"; do - if [[ $chosen_key == "$ch" ]]; then + if [[ $_CHOSEN_KEY == "$ch" ]]; then flag=true break fi @@ -284,59 +282,59 @@ get_key() { key_menu() { get_key key_list - case "$chosen_key" in - "$tsn_autokey") auto_type_def ;; - "$tsn_userkey") key_action "$tsn_username" ;; - password) key_action "$tsn_password" ;; + case "$_CHOSEN_KEY" in + "$_TSN_AUTOKEY") auto_type_def ;; + "$_TSN_USERKEY") key_action "$_TSN_USERNAME" ;; + password) key_action "$_TSN_PASSWORD" ;; otp) key_otp ;; - "$tsn_urlkey") key_action "$tsn_urlkey" ;; - *) key_action "${tsn_passdata["$chosen_key"]}" ;; + "$_TSN_URLKEY") key_action "$_TSN_URLKEY" ;; + *) key_action "${_TSN_PASSDATA["$_CHOSEN_KEY"]}" ;; esac } -# this function checks the value of tsn_action and decides if the third menu +# this function checks the value of _TSN_ACTION and decides if the third menu # should be presented or not # in case it receives "url", autotype becomes equivalent to opening the url in # a web browser key_action() { local arg="$1" - case "$tsn_action" in + case "$_TSN_ACTION" in autotype) - if [[ $arg == "$tsn_urlkey" ]]; then + if [[ $arg == "$_TSN_URLKEY" ]]; then key_open_url || _die return 0 fi auto_type "$arg" ;; copy) - if [[ $arg == "$tsn_urlkey" ]]; then - wld_copy "$tsn_url" || _die + if [[ $arg == "$_TSN_URLKEY" ]]; then + wld_copy "$_TSN_URL" || _die return 0 fi wld_copy "$arg" ;; both) - if [[ $arg == "$tsn_urlkey" ]]; then + if [[ $arg == "$_TSN_URLKEY" ]]; then key_open_url - wld_copy "$tsn_url" + wld_copy "$_TSN_URL" else - printf "%s" "$arg" | wtype -s "$tsn_delay" - + printf "%s" "$arg" | wtype -s "$_TSN_DELAY" - wld_copy "$arg" fi ;; default) - if [[ $arg == "$tsn_urlkey" ]]; then - get_key "$tsn_urlkey" - if [[ $chosen_key == "open" ]]; then + if [[ $arg == "$_TSN_URLKEY" ]]; then + get_key "$_TSN_URLKEY" + if [[ $_CHOSEN_KEY == "open" ]]; then key_open_url || _die return 0 else - wld_copy "$tsn_url" + wld_copy "$_TSN_URL" fi else get_key option - if [[ $chosen_key == "$tsn_autokey" ]]; then + if [[ $_CHOSEN_KEY == "$_TSN_AUTOKEY" ]]; then auto_type "$arg" else wld_copy "$arg" @@ -353,14 +351,14 @@ key_action() { key_otp() { local tmp_otp - if [[ $pass_backend == "pass" ]] && ! pass otp -h > /dev/null 2>&1; then + if [[ $_PASS_BACKEND == "pass" ]] && ! pass otp -h > /dev/null 2>&1; then _die "pass-otp is not installed" fi - if [[ $pass_backend == "pass" ]]; then - tmp_otp="$(pass otp "$tsn_passfile")" - elif [[ $pass_backend == "gopass" ]]; then - tmp_otp="$(gopass otp -o "$tsn_passfile")" + if [[ $_PASS_BACKEND == "pass" ]]; then + tmp_otp="$(pass otp "$_TSN_PASSFILE")" + elif [[ $_PASS_BACKEND == "gopass" ]]; then + tmp_otp="$(gopass otp -o "$_TSN_PASSFILE")" fi if ! [[ $tmp_otp =~ ^[[:digit:]]+$ ]]; then @@ -372,18 +370,18 @@ key_otp() { } key_open_url() { - if [[ -n $tsn_web_browser ]]; then - "$tsn_web_browser" "$tsn_url" > /dev/null 2>&1 || { - printf "%s\n" "$tsn_web_browser was unable to open '$tsn_url'" >&2 + if [[ -n $_TSN_WEB_BROWSER ]]; then + "$_TSN_WEB_BROWSER" "$_TSN_URL" > /dev/null 2>&1 || { + printf "%s\n" "$_TSN_WEB_BROWSER was unable to open '$_TSN_URL'" >&2 return 1 } elif is_installed xdg-open; then - xdg-open "$tsn_url" 2> /dev/null || { - printf "%s\n" "xdg-open was unable to open '$tsn_url'" >&2 + xdg-open "$_TSN_URL" 2> /dev/null || { + printf "%s\n" "xdg-open was unable to open '$_TSN_URL'" >&2 return 1 } else - _die "failed to open '$tsn_urlkey'" + _die "failed to open '$_TSN_URLKEY'" fi } @@ -392,26 +390,26 @@ key_open_url() { auto_type_def() { local word tmp_otp - if [[ -z $tsn_autotype ]]; then - printf "%s" "$tsn_username" | wtype -s "$tsn_delay" - - wtype -s "$tsn_delay" -k Tab -- - printf "%s" "$tsn_password" | wtype -s "$tsn_delay" - + if [[ -z $_TSN_AUTOTYPE ]]; then + auto_type "$_TSN_USERNAME" + wtype -s "$_TSN_DELAY" -k Tab -- + printf "%s" "$_TSN_PASSWORD" | wtype -s "$_TSN_DELAY" - else - for word in $tsn_autotype; do + for word in $_TSN_AUTOTYPE; do case "$word" in ":delay") sleep 1 ;; - ":tab") wtype -s "$tsn_delay" -k Tab -- ;; - ":space") wtype -s "$tsn_delay" -k space -- ;; - ":enter") wtype -s "$tsn_delay" -k Return -- ;; + ":tab") wtype -s "$_TSN_DELAY" -k Tab -- ;; + ":space") wtype -s "$_TSN_DELAY" -k space -- ;; + ":enter") wtype -s "$_TSN_DELAY" -k Return -- ;; ":otp") key_otp ;; - path | basename | filename) printf "%s" "${tsn_passfile##*/}" | wtype -s "$tsn_delay" - ;; - "$tsn_userkey") printf "%s" "$tsn_username" | wtype -s "$tsn_delay" - ;; - pass | password) printf "%s" "$tsn_password" | wtype -s "$tsn_delay" - ;; + path | basename | filename) printf "%s" "${_TSN_PASSFILE##*/}" | wtype -s "$_TSN_DELAY" - ;; + "$tsn_userkey") printf "%s" "$tsn_username" | wtype -s "$_TSN_DELAY" - ;; + pass | password) printf "%s" "$tsn_password" | wtype -s "$_TSN_DELAY" - ;; *) - if [[ -n ${tsn_passdata["$word"]} ]]; then - printf "%s" "${tsn_passdata["$word"]}" | wtype -s "$tsn_delay" - + if [[ -n ${_TSN_PASSDATA["$word"]} ]]; then + auto_type "${_TSN_PASSDATA["$word"]}" else - wtype -s "$tsn_delay" -k space -- + wtype -s "$_TSN_DELAY" -k space -- fi ;; esac @@ -420,19 +418,19 @@ auto_type_def() { } auto_type() { - printf "%s" "$1" | wtype -s "$tsn_delay" - + printf "%s" "$1" | wtype -s "$_TSN_DELAY" - } wld_copy() { local tsn_cliptime - if [[ $pass_backend == "pass" ]]; then + if [[ $_PASS_BACKEND == "pass" ]]; then tsn_cliptime="${PASSWORD_STORE_CLIP_TIME:-15}" if ! are_digits "$tsn_cliptime"; then printf "%s\n" "invalid clipboard timeout value in PASSWORD_STORE_CLIP_TIME" >&2 return 1 fi - elif [[ $pass_backend == "gopass" ]]; then + elif [[ $_PASS_BACKEND == "gopass" ]]; then tsn_cliptime="$(gopass config core.cliptimeout)" tsn_cliptime="${tsn_cliptime##*: }" if ! are_digits "$tsn_cliptime"; then @@ -455,7 +453,7 @@ wld_copy() { } > /dev/null 2>&1 & unset -v tsn_cliptime - unset -v tsn_passfile tsn_passdata tsn_username tsn_password chosen_key + unset -v _TSN_PASSFILE _TSN_PASSDATA _TSN_USERNAME _TSN_PASSWORD _CHOSEN_KEY } are_digits() { @@ -471,7 +469,7 @@ validate_pass_backend() { _die "please install a valid password store backend: pass | gopass" fi if [[ $1 == "pass" ]] || [[ $1 == "gopass" ]]; then - pass_backend="$1" + _PASS_BACKEND="$1" else _die "please specify a valid password store backend: pass | gopass" fi @@ -484,33 +482,33 @@ validate_dmenu_backend() { local -a bemenu_opts case "$1" in - rofi) - dmenu_backend="rofi" - dmenu_backend_opts=('-dmenu') - ;; fuzzel) - dmenu_backend="fuzzel" - dmenu_backend_opts=('-d' '--log-level=warning') - ;; - tofi) - dmenu_backend="tofi" - dmenu_backend_opts=() + _DMENU_BACKEND="fuzzel" + _DMENU_BACKEND_OPTS=('-d' '--log-level=warning') ;; bemenu) - dmenu_backend="bemenu" - dmenu_backend_opts=() + _DMENU_BACKEND="bemenu" + _DMENU_BACKEND_OPTS=() bemenu_opts=('-l' '10' '-n') if [[ -z ${BEMENU_OPTS[*]} ]]; then export BEMENU_OPTS="${bemenu_opts[*]}" fi ;; + tofi) + _DMENU_BACKEND="tofi" + _DMENU_BACKEND_OPTS=() + ;; wofi) - dmenu_backend="wofi" - dmenu_backend_opts=('-d' '-k' '/dev/null') + _DMENU_BACKEND="wofi" + _DMENU_BACKEND_OPTS=('-d' '-k' '/dev/null') + ;; + rofi) + _DMENU_BACKEND="rofi" + _DMENU_BACKEND_OPTS=('-dmenu') ;; dmenu) - dmenu_backend="dmenu" - dmenu_backend_opts=() + _DMENU_BACKEND="dmenu" + _DMENU_BACKEND_OPTS=() ;; *) _die "please install a valid dmenu backend: fuzzel | tofi | bemenu | wofi | rofi | dmenu" @@ -525,13 +523,13 @@ validate_action() { if ! is_installed "wtype"; then _die "wtype is not installed, unable to autotype pass data" fi - tsn_action="autotype" + _TSN_ACTION="autotype" ;; copy) if ! is_installed "wl-copy"; then _die "wl-clipboard is not installed, unable to copy-paste pass data" fi - tsn_action="copy" + _TSN_ACTION="copy" ;; both) if ! is_installed "wtype"; then @@ -539,17 +537,17 @@ validate_action() { elif ! is_installed "wl-copy"; then _die "wl-clipboard is not installed, unable to copy-paste pass data" fi - tsn_action="both" + _TSN_ACTION="both" ;; default) if is_installed "wtype" && is_installed "wl-copy"; then - tsn_action="default" + _TSN_ACTION="default" elif is_installed "wtype" && ! is_installed "wl-copy"; then printf "%s\n" "wl-clipboard is not installed, unable to copy-paste pass data" >&2 - tsn_action="autotype" + _TSN_ACTION="autotype" elif ! is_installed "wtype" && is_installed "wl-copy"; then printf "%s\n" "wtype is not installed, unable to autotype pass data" >&2 - tsn_action="copy" + _TSN_ACTION="copy" elif ! is_installed "wtype" && ! is_installed "wl-copy"; then _die "please install at least one the following backends to use tessen: wtype | wl-clipboard " fi @@ -564,11 +562,11 @@ find_pass_backend() { for idx in "${tmp_pass_arr[@]}"; do if is_installed "$idx"; then - pass_backend="$idx" + _PASS_BACKEND="$idx" break fi done - if [[ -z $pass_backend ]]; then + if [[ -z $_PASS_BACKEND ]]; then _die "please install a valid password store backend: pass | gopass" fi @@ -581,11 +579,11 @@ find_dmenu_backend() { for idx in "${tmp_dmenu_arr[@]}"; do if is_installed "$idx"; then - dmenu_backend="$idx" + _DMENU_BACKEND="$idx" break fi done - if [[ -z $dmenu_backend ]]; then + if [[ -z $_DMENU_BACKEND ]]; then _die "please install a valid dmenu backend: fuzzel | tofi | bemenu | wofi | rofi | dmenu" fi unset -v idx tmp_dmenu_arr @@ -600,8 +598,8 @@ is_installed() { } _clear() { - unset -v tsn_passfile tsn_passdata tsn_username tsn_password tsn_url - unset -v tsn_autotype chosen_key + unset -v _TSN_PASSFILE _TSN_PASSDATA _TSN_USERNAME _TSN_PASSWORD _TSN_URL + unset -v _TSN_AUTOTYPE _CHOSEN_KEY } _die() { @@ -657,14 +655,14 @@ parse_config() { local config_regex='^[[:alpha:]_]+="[[:alnum:]~_./^$|()-]+"$' # in case the user hasn't provided an explicit location, we'll have to check # if the default file exists before we parse it - if [[ -s $tsn_config ]]; then + if [[ -s $_TSN_CONFIG ]]; then while read -r line || [[ -n $line ]]; do if [[ $line == \#* ]]; then continue elif [[ $line =~ $config_regex ]]; then config_arr+=("$line") fi - done < "$tsn_config" + done < "$_TSN_CONFIG" for idx in "${config_arr[@]}"; do key="${idx%=*}" val="${idx#*\"}" @@ -672,35 +670,35 @@ parse_config() { # here comes the ladder # the -p, -d, and -a options will be parsed and set only if they're not # already set, i.e., from the argparse - if [[ $key == "pass_backend" ]] && [[ -z $pass_backend ]]; then + if [[ $key == "_PASS_BACKEND" ]] && [[ -z $_PASS_BACKEND ]]; then validate_pass_backend "$val" - readonly pass_backend - elif [[ $key == "dmenu_backend" ]] && [[ -z $dmenu_backend ]]; then + readonly _PASS_BACKEND + elif [[ $key == "dmenu_backend" ]] && [[ -z $_DMENU_BACKEND ]]; then validate_dmenu_backend "$val" - readonly dmenu_backend - elif [[ $key == "action" ]] && unset -v tsn_action 2> /dev/null; then + readonly _DMENU_BACKEND + elif [[ $key == "action" ]] && unset -v _TSN_ACTION 2> /dev/null; then validate_action "$val" - readonly tsn_action + readonly _TSN_ACTION elif [[ $key == "tofi_config_file" ]] && [[ -f ${val@P} ]]; then - tmp_tofi_opts+=("--config" "${val@P}") + _TMP_TOFI_OPTS+=("-c" "${val@P}") elif [[ $key == "rofi_config_file" ]] && [[ -f ${val@P} ]]; then - tmp_rofi_opts+=("-config" "${val@P}") + _TMP_ROFI_OPTS+=("-config" "${val@P}") elif [[ $key == "wofi_config_file" ]] && [[ -f ${val@P} ]]; then - tmp_wofi_opts+=("-c" "${val@P}") + _TMP_WOFI_OPTS+=("-c" "${val@P}") elif [[ $key == "wofi_style_file" ]] && [[ -f ${val@P} ]]; then - tmp_wofi_opts+=("-s" "${val@P}") + _TMP_WOFI_OPTS+=("-s" "${val@P}") elif [[ $key == "wofi_color_file" ]] && [[ -f ${val@P} ]]; then - tmp_wofi_opts+=("-C" "${val@P}") + _TMP_WOFI_OPTS+=("-C" "${val@P}") elif [[ $key == "userkey" ]]; then - tsn_userkey="$val" + _TSN_USERKEY="$val" elif [[ $key == "urlkey" ]]; then - tsn_urlkey="$val" + _TSN_URLKEY="$val" elif [[ $key == "autotype_key" ]]; then - tsn_autokey="$val" + _TSN_AUTOKEY="$val" elif [[ $key == "delay" ]]; then - tsn_delay="$val" + _TSN_DELAY="$val" elif [[ $key == "web_browser" ]] && is_installed "$val"; then - tsn_web_browser="$val" + _TSN_WEB_BROWSER="$val" fi done fi @@ -721,7 +719,7 @@ main() { _die "please specify a valid password store backend: pass | gopass" fi validate_pass_backend "$2" - readonly pass_backend + readonly _PASS_BACKEND shift ;; --pass=*) @@ -729,21 +727,21 @@ main() { _die "please specify a valid password store backend: pass | gopass" fi validate_pass_backend "${_opt##--pass=}" - readonly pass_backend + readonly _PASS_BACKEND ;; -d | --dmenu) if [[ $# -lt 2 ]]; then _die "please install a valid dmenu backend: fuzzel | tofi | bemenu | wofi | rofi | dmenu" fi validate_dmenu_backend "$2" - readonly dmenu_backend + readonly _DMENU_BACKEND # since there's a possibility that a user may mention config files for - # rofi and wofi, we will make dmenu_backend_opts readonly only if - # dmenu_backend is fuzzel and bemenu, the dmenu programs which don't + # rofi and wofi, we will make _DMENU_BACKEND_OPTS readonly only if + # _DMENU_BACKEND is fuzzel and bemenu, the dmenu programs which don't # support configuration files - if [[ $dmenu_backend == "fuzzel" ]] || [[ $dmenu_backend == "bemenu" ]] \ - || [[ $dmenu_backend == "dmenu" ]]; then - readonly dmenu_backend_opts + if [[ $_DMENU_BACKEND == "fuzzel" ]] || [[ $_DMENU_BACKEND == "bemenu" ]] \ + || [[ $_DMENU_BACKEND == "dmenu" ]]; then + readonly _DMENU_BACKEND_OPTS fi shift ;; @@ -752,10 +750,10 @@ main() { _die "please install a valid dmenu backend: fuzzel | tofi | bemenu | wofi | rofi | dmenu" fi validate_dmenu_backend "${_opt##--dmenu=}" - readonly dmenu_backend - if [[ $dmenu_backend == "fuzzel" ]] || [[ $dmenu_backend == "bemenu" ]] \ - || [[ $dmenu_backend == "dmenu" ]]; then - readonly dmenu_backend_opts + readonly _DMENU_BACKEND + if [[ $_DMENU_BACKEND == "fuzzel" ]] || [[ $_DMENU_BACKEND == "bemenu" ]] \ + || [[ $_DMENU_BACKEND == "dmenu" ]]; then + readonly _DMENU_BACKEND_OPTS fi ;; -a | --action) @@ -763,7 +761,7 @@ main() { _die "please specify a valid action: autotype | copy | both" fi validate_action "$2" - readonly tsn_action + readonly _TSN_ACTION shift ;; --action=*) @@ -771,20 +769,20 @@ main() { _die "please specify a valid action: autotype | copy | both" fi validate_action "${_opt##--action=}" - readonly tsn_action + readonly _TSN_ACTION ;; -c | --config) if [[ $# -lt 2 ]] || ! [[ -f $2 ]]; then _die "please specify a valid path for the configuration file of tessen" fi - tsn_config="$2" + _TSN_CONFIG="$2" shift ;; --config=*) if ! [[ -f ${_opt##--config=} ]]; then _die "please specify a valid path for the configuration file of tessen" fi - tsn_config="${_opt##--config=}" + _TSN_CONFIG="${_opt##--config=}" ;; -h | --help) print_help @@ -810,37 +808,37 @@ main() { # the options which are mutual between the argparse and the config file will # be considered in the config file only if those options aren't already set parse_config - if [[ $dmenu_backend == "tofi" ]]; then - dmenu_backend_opts+=("${tmp_tofi_opts[@]}") - readonly dmenu_backend_opts - elif [[ $dmenu_backend == "rofi" ]]; then - dmenu_backend_opts+=("${tmp_rofi_opts[@]}") - readonly dmenu_backend_opts - elif [[ $dmenu_backend == "wofi" ]]; then - dmenu_backend_opts+=("${tmp_wofi_opts[@]}") - readonly dmenu_backend_opts + if [[ $_DMENU_BACKEND == "tofi" ]]; then + _DMENU_BACKEND_OPTS+=("${_TMP_TOFI_OPTS[@]}") + readonly _DMENU_BACKEND_OPTS + elif [[ $_DMENU_BACKEND == "rofi" ]]; then + _DMENU_BACKEND_OPTS+=("${_TMP_ROFI_OPTS[@]}") + readonly _DMENU_BACKEND_OPTS + elif [[ $_DMENU_BACKEND == "wofi" ]]; then + _DMENU_BACKEND_OPTS+=("${_TMP_WOFI_OPTS[@]}") + readonly _DMENU_BACKEND_OPTS fi # initialize basic options for users who expect sane defaults and don't use # either the config file or args - if [[ -z $pass_backend ]]; then + if [[ -z $_PASS_BACKEND ]]; then find_pass_backend - readonly pass_backend + readonly _PASS_BACKEND fi - if [[ -z $dmenu_backend ]]; then + if [[ -z $_DMENU_BACKEND ]]; then find_dmenu_backend - validate_dmenu_backend "$dmenu_backend" - readonly dmenu_backend + validate_dmenu_backend "$_DMENU_BACKEND" + readonly _DMENU_BACKEND fi - if unset -v tsn_action 2> /dev/null; then + if unset -v _TSN_ACTION 2> /dev/null; then validate_action "default" - readonly tsn_action + readonly _TSN_ACTION fi trap '_clear' EXIT TERM INT - if [[ $pass_backend == "pass" ]]; then + if [[ $_PASS_BACKEND == "pass" ]]; then get_pass_files - elif [[ $pass_backend == "gopass" ]]; then + elif [[ $_PASS_BACKEND == "gopass" ]]; then get_gopass_files fi get_pass_data |