Hi, This is my third patch to passmenu; the last was on May 14th, 2016.
If you install this patch, passmenu lock will have a '.lock' extension. My first email on May 8th, 2016 better explains why I'm using a file lock and adding a multiclip feature in the first place. This file lock business is just an empty folder which holds the pid of passmenu in the filename. It's a safe (cross platform) way to prevent two passmenu sessions from running at the same time. I'm aiming for a more consistent user experience. I hope you find this update to be as stable as I found the last patch. I'm testing on Linux. I would particularly welcome feedback from others. For those who like github: https://github.com/ampling/pass/blob/passmenu_multi-clip/contrib/dmenu/passmenu From dacf9f38ba38b86b79420d2cc3b25ff0191ed9b2 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Tue, 19 Jul 2016 16:11:10 -0400 Subject: [PATCH] Renamed filelock for clarity. --- contrib/dmenu/passmenu | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 40dfe97..e1835d2 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -26,8 +26,8 @@ _finish () { [[ True == $cleanup ]] && printf "$before" | base64 -d | xclip -sel "$X_SELECTION" -i [[ True = "$cleanup" ]] && - if compgen -G "/tmp/passmenulock.1000*" >/dev/null 2>&1 ;then - rmdir /tmp/passmenulock.*.*."$$" >/dev/null 2>&1 + if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenu.*.*."$$".lock >/dev/null 2>&1 fi exit } @@ -47,22 +47,23 @@ trap _finish EXIT ## Clearing old filelock(s). umask 077 stalelock=( "${stalelock:-''}" ) -stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && +stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenu."$userID".*" -user $(whoami) -print0 -quit -type d)" ) && if test -n "$stalelock" ;then + stalename=${stalelock%.*} report=( "$(ps -u $(id -u $(whoami)) aux | grep "bash" | grep "passmenu" | grep -v "$$")" ) - stalePID=( "$(printf $stalelock | - sed -e "s/\/tmp\/passmenulock\.[0-9]\{1,6\}\?\..*\.//g")" ) + stalePID=( "$(printf $stalename | + sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" ) if [[ "$report" == *"$stalePID"* ]] ;then kill "$stalePID" || exit 1 else - rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 || + rmdir /tmp/passmenu."$userID".* >/dev/null 2>&1 || { echo ":: Unable to clear old filelock"; exit 1; } fi fi ## Adding a new filelock -( mktemp -d "/tmp/passmenulock."$userID".XXXXXXXXXX"."$$" >/dev/null 2>&1 && cleanup=True || +( mktemp -d "/tmp/passmenu."$userID".XXXXXXXXXX"."$$".lock >/dev/null 2>&1 && cleanup=True || { echo >&2 ":: Unable to make a filelock."; exit 1; } ) cleanup=True -- 2.9.0 -- At your service, mitfree https://ampling.com
From 1d2e5d9d0b3e46e1ce72e4151193eb648d668176 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 8 Apr 2016 23:38:57 -0400 Subject: [PATCH 01/11] Adding xclip loop to select multiple pass entries. --- contrib/dmenu/passmenu | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 7a9c517..b80399c 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -4,22 +4,27 @@ shopt -s nullglob globstar typeit=0 if [[ $1 == "--type" ]]; then - typeit=1 - shift + typeit=1 + shift fi +X_SELECTION="$PASSWORD_STORE_X_SELECTION" prefix=${PASSWORD_STORE_DIR-~/.password-store} + password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -password=$(printf '%s\n' "${password_files[@]}" | dmenu "$@") +if [[ $typeit -eq 0 ]]; then + for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do + pass show $password | + xclip -l 1 -quiet -sel $X_SELECTION + done [[ -n $password ]] || exit -if [[ $typeit -eq 0 ]]; then - pass show -c "$password" 2>/dev/null else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - + pass show "$password" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - fi -- 2.8.0 From 4b003d9bbd9b79d71250aeee029468806bf16e09 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 9 Apr 2016 00:46:26 -0400 Subject: [PATCH 02/11] Add condition to skip xclip loop on 1 selection. --- contrib/dmenu/passmenu | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index b80399c..ddfb07f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -17,13 +17,20 @@ password_files=( "${password_files[@]%.gpg}" ) if [[ $typeit -eq 0 ]]; then for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do - pass show $password | - xclip -l 1 -quiet -sel $X_SELECTION + dmenu -f "$@"); do + lot+=($password) done -[[ -n $password ]] || exit + [[ -n $password ]] || exit + if [ ${#lot[@]} -gt "0" ]; then + for entry in "${lot[@]}"; do + pass show $entry | awk 'NR==1' | + xclip -l 1 -quiet -sel $X_SELECTION + done + else + pass show -c "$password" 2>/dev/null + fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | xdotool type --clearmodifiers --file - -- 2.8.0 From 1e52e9fc165961a94bc834d5fd58ee2669eaae1d Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Thu, 14 Apr 2016 02:03:17 -0400 Subject: [PATCH 03/11] Restores clipboard to previous state. --- contrib/dmenu/passmenu | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index ddfb07f..789d0de 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -15,22 +15,24 @@ password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -if [[ $typeit -eq 0 ]]; then - for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do +for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do lot+=($password) - done +done - [[ -n $password ]] || exit +[[ -n $password ]] || exit - if [ ${#lot[@]} -gt "0" ]; then - for entry in "${lot[@]}"; do - pass show $entry | awk 'NR==1' | - xclip -l 1 -quiet -sel $X_SELECTION +if [[ $typeit -eq 0 ]]; then + xclip -sel clip -o | xclip -sel sec -i + if [ ${#lot[@]} -gt "1" ]; then + for entry in "${lot[@]}"; do + pass show $entry | awk 'NR==1' | + xclip -l 1 -quiet -sel $X_SELECTION &>/dev/null done + xclip -sel sec -o | xclip -sel clip -i else - pass show -c "$password" 2>/dev/null - fi + pass show -c "$password" &>/dev/null + fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | xdotool type --clearmodifiers --file - -- 2.8.0 From 24d3194a119c4503d471d09159d11f3d4c12eda3 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 22 Apr 2016 14:44:51 -0400 Subject: [PATCH 04/11] Clears secondary clipboard after use. --- contrib/dmenu/passmenu | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 789d0de..84b4ae4 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -8,13 +8,14 @@ if [[ $1 == "--type" ]]; then shift fi -X_SELECTION="$PASSWORD_STORE_X_SELECTION" -prefix=${PASSWORD_STORE_DIR-~/.password-store} +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) +## Press Ctrl-Return to continue selecting entries. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do lot+=($password) @@ -23,15 +24,19 @@ done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - xclip -sel clip -o | xclip -sel sec -i + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i if [ ${#lot[@]} -gt "1" ]; then + x=0 for entry in "${lot[@]}"; do - pass show $entry | awk 'NR==1' | - xclip -l 1 -quiet -sel $X_SELECTION &>/dev/null + printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" + pass show $entry | head -n 1 | tr -d '\n' | + xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null + x=`expr $x + 1` done - xclip -sel sec -o | xclip -sel clip -i + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i else - pass show -c "$password" &>/dev/null + pass -c "$password" 2>/dev/null fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | -- 2.8.0 From 8e25eeeab68810ec295fb5d8cb2b4412bcd529f2 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 02:36:55 -0400 Subject: [PATCH 05/11] Limits use of secondary clip to multi selections. --- contrib/dmenu/passmenu | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 84b4ae4..a784481 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -24,17 +24,17 @@ done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i if [ ${#lot[@]} -gt "1" ]; then x=0 + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i for entry in "${lot[@]}"; do printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" pass show $entry | head -n 1 | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null x=`expr $x + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i else pass -c "$password" 2>/dev/null fi -- 2.8.0 From 20d3a8a8c55dfb31fa9cdc191b156f7d98ac3a53 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 17:12:29 -0400 Subject: [PATCH 06/11] Changes variables and comments for readability. --- contrib/dmenu/passmenu | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index a784481..45eb66f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -8,30 +8,31 @@ if [[ $1 == "--type" ]]; then shift fi -X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-primary}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## Press Ctrl-Return to continue selecting entries. +## dmenu exits on KeyPress. +## We should send KeyRelease event to some dummy window. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do - lot+=($password) + passel+=($password) done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - if [ ${#lot[@]} -gt "1" ]; then - x=0 + if [ ${#passel[@]} -gt "1" ]; then + round=0 xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${lot[@]}"; do - printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" pass show $entry | head -n 1 | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - x=`expr $x + 1` + round=`expr $round + 1` done xclip -sel sec -o | xclip -sel "$X_SELECTION" -i printf "" | xclip -sel sec -i -- 2.8.0 From 499a2b10739514860744c0179f00a551bd34cd12 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 20:22:08 -0400 Subject: [PATCH 07/11] Adding multi password selection to option --type. --- contrib/dmenu/passmenu | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 45eb66f..1b0339f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -40,6 +40,20 @@ if [[ $typeit -eq 0 ]]; then pass -c "$password" 2>/dev/null fi else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - + if [ ${#passel[@]} -gt "1" ]; then + round=0 + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null + pass show "$entry" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i + else + pass show "$password" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - + fi fi -- 2.8.0 From 67dacee2237bf12dfa0f6e14806971ad2daab7ea Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Wed, 27 Apr 2016 20:29:07 -0400 Subject: [PATCH 08/11] Locks script and attemps to clear old loop. --- contrib/dmenu/passmenu | 91 ++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 1b0339f..e842f13 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -4,56 +4,69 @@ shopt -s nullglob globstar typeit=0 if [[ $1 == "--type" ]]; then - typeit=1 - shift + typeit=1 + shift fi -X_SELECTION="${PASSWORD_STORE_X_SELECTION:-primary}" +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## dmenu exits on KeyPress. -## We should send KeyRelease event to some dummy window. -for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do - passel+=($password) +## Preexisting xclip loops can cause unanticipated behavior. +exec {lock_fd}>/tmp/passmenulock || exit 1 +flock -n "$lock_fd" || + { xclip -sel "$X_SELECTION" -o >/dev/null 2>&1 + flock -n "$lock_fd" || + printf '%s\n' 'Already running' >&2 + exit 1 + } + +## dmenu exits on KeyPress not KeyRelease. +## It would be nice to send KeyRelease event to some dummy window. +for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do + passel+=($password) done [[ -n $password ]] || exit - + if [[ $typeit -eq 0 ]]; then - if [ ${#passel[@]} -gt "1" ]; then - round=0 - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${passel[@]}"; do - printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - pass show $entry | head -n 1 | tr -d '\n' | - xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - round=`expr $round + 1` - done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i - else - pass -c "$password" 2>/dev/null - fi + if [ ${#passel[@]} -gt "1" ]; then + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + round=0 + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + pass show $entry | sed '1!d' | tr -d '\n' | + xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 + ~/bin/beeponce + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + else + pass -c "$password" 2>/dev/null + fi else - if [ ${#passel[@]} -gt "1" ]; then - round=0 - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${passel[@]}"; do - printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - pass show "$entry" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - - round=`expr $round + 1` - done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i - else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - - fi + command -v xdotool >/dev/null 2>&1 || + { echo >&2 "e: cannot find xdotool."; exit 1; } + if [ ${#passel[@]} -gt "1" ]; then + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + round=0 + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 + ~/bin/beeponce + pass show "$entry" | sed '1!d' | tr -d '\n' | + xdotool type --clearmodifiers --file - + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + else + pass show "$password" | sed '1!d' | tr -d '\n' | + xdotool type --clearmodifiers --file - + fi fi +printf "" | xclip -sel sec -i +flock -u "$lock_fd" -- 2.8.0 From 5cee86eb671b0db6229bcb490ca1762ae2eb8d76 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sun, 1 May 2016 17:49:36 -0400 Subject: [PATCH 09/11] A portable process lock avoids unanticipated behavior. --- contrib/dmenu/passmenu | 68 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index e842f13..021c48f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -1,6 +1,7 @@ #!/usr/bin/env bash shopt -s nullglob globstar +set -o errexit typeit=0 if [[ $1 == "--type" ]]; then @@ -9,64 +10,93 @@ if [[ $1 == "--type" ]]; then fi X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## Preexisting xclip loops can cause unanticipated behavior. -exec {lock_fd}>/tmp/passmenulock || exit 1 -flock -n "$lock_fd" || - { xclip -sel "$X_SELECTION" -o >/dev/null 2>&1 - flock -n "$lock_fd" || - printf '%s\n' 'Already running' >&2 - exit 1 +_finish () { + [[ 1 = "$remove" ]] + rmdir /tmp/passmenu."$uid".* 2>/dev/null + ## kill more child processes here. + # echo $(ps -o pgid=$$ | grep -o [0-9]*) + printf "$buffer" | xclip -sel "$X_SELECTION" -i + exit } +trap _finish EXIT + +_fire () { + stale="$(find /tmp/passmenu."$uid".* -print -quit | + sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" + report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | + grep "passmenu" | grep -v "$$")" + if [[ "$report" == *"passmenu"* ]] ;then + kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + else + rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + fi +} + +## Clearing stale Xclip loops avoids a posible race condition. +uid="$(id -u $(whoami))" +remove=0 +if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + question=$(printf 'yes\nno'| + dmenu -nf red -f -p "The clipboard is locked by another process. Kill it with fire?") + if [ "$question" = 'yes' ] ;then + _fire + else + exit 0 + fi +fi ## dmenu exits on KeyPress not KeyRelease. ## It would be nice to send KeyRelease event to some dummy window. +## psydocode: xdotool getwindowfocus; create dummy window; +## exec dmenu; close dummy window; restore focus. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do - passel+=($password) + passel+=("$password") done [[ -n $password ]] || exit - + +umask 077 +mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || exit 1 +remove=1 + +buffer="$(xclip -sel "$X_SELECTION" -o)" if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i round=0 for entry in "${passel[@]}"; do printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - pass show $entry | sed '1!d' | tr -d '\n' | + pass show "$entry" | sed '1!d' | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 - ~/bin/beeponce round=`expr $round + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i else - pass -c "$password" 2>/dev/null + pass show "$password" | sed '1!d' | tr -d '\n' | + xclip -sel "$X_SELECTION" -i + sleep "$CLIP_TIME" fi else command -v xdotool >/dev/null 2>&1 || { echo >&2 "e: cannot find xdotool."; exit 1; } if [ ${#passel[@]} -gt "1" ]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i round=0 for entry in "${passel[@]}"; do printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 - ~/bin/beeponce pass show "$entry" | sed '1!d' | tr -d '\n' | xdotool type --clearmodifiers --file - round=`expr $round + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i else pass show "$password" | sed '1!d' | tr -d '\n' | xdotool type --clearmodifiers --file - fi fi -printf "" | xclip -sel sec -i -flock -u "$lock_fd" +exit -- 2.8.0 From f8b10ed59edbb293e3728f29fc087ddcf316cc3c Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 6 May 2016 11:58:34 -0400 Subject: [PATCH 10/11] Adding strict mode. --- contrib/dmenu/passmenu | 58 ++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 021c48f..e6e2cfc 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -1,10 +1,11 @@ #!/usr/bin/env bash -shopt -s nullglob globstar -set -o errexit +shopt -s nullglob globstar failglob +set -euo pipefail +tool=${1:-} typeit=0 -if [[ $1 == "--type" ]]; then +if [[ $tool == "--type" ]]; then typeit=1 shift fi @@ -18,56 +19,49 @@ password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) _finish () { - [[ 1 = "$remove" ]] - rmdir /tmp/passmenu."$uid".* 2>/dev/null - ## kill more child processes here. - # echo $(ps -o pgid=$$ | grep -o [0-9]*) - printf "$buffer" | xclip -sel "$X_SELECTION" -i + [[ -n $before ]] && + printf "$before" | xclip -sel "$X_SELECTION" -i + [[ True = "$remove" ]] && + if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenu."$uid".* >/dev/null 2>&1 + fi exit - } +} trap _finish EXIT -_fire () { +## Clearing stale Xclip loops avoids a posible race condition. +uid="$(id -u $(whoami))" +remove=False +if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then stale="$(find /tmp/passmenu."$uid".* -print -quit | sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | grep "passmenu" | grep -v "$$")" - if [[ "$report" == *"passmenu"* ]] ;then + if [[ "$report" == *"$stale"* ]] ;then kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 else rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 fi -} - -## Clearing stale Xclip loops avoids a posible race condition. -uid="$(id -u $(whoami))" -remove=0 -if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - question=$(printf 'yes\nno'| - dmenu -nf red -f -p "The clipboard is locked by another process. Kill it with fire?") - if [ "$question" = 'yes' ] ;then - _fire - else - exit 0 - fi fi ## dmenu exits on KeyPress not KeyRelease. ## It would be nice to send KeyRelease event to some dummy window. ## psydocode: xdotool getwindowfocus; create dummy window; ## exec dmenu; close dummy window; restore focus. -for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do +password=${password:-} +for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do passel+=("$password") done +before=${before:-} [[ -n $password ]] || exit +before="$(xclip -sel "$X_SELECTION" -o >/dev/null 2>&1)" || true umask 077 -mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || exit 1 -remove=1 +mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || +{ echo >&2 ":: Unable to make a filelock."; exit 1; } +remove=True -buffer="$(xclip -sel "$X_SELECTION" -o)" if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then round=0 @@ -78,12 +72,12 @@ if [[ $typeit -eq 0 ]]; then round=`expr $round + 1` done else + printf '%s\n' "Sending "$password" via "$X_SELECTION"" pass show "$password" | sed '1!d' | tr -d '\n' | - xclip -sel "$X_SELECTION" -i - sleep "$CLIP_TIME" + xclip -sel "$X_SELECTION" -i && sleep "$CLIP_TIME" fi else - command -v xdotool >/dev/null 2>&1 || + command -v xdotool >/dev/null 2>&1 || { echo >&2 "e: cannot find xdotool."; exit 1; } if [ ${#passel[@]} -gt "1" ]; then round=0 -- 2.8.0 From 90a3613d854085e1fe1416714729aa24e2013cf3 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 7 May 2016 06:14:50 -0400 Subject: [PATCH 11/11] Improved filelock, and more appropriate variable names. --- contrib/dmenu/passmenu | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index e6e2cfc..68b4150 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -17,50 +17,52 @@ prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) +password=( ${password:-""} ) +before=( "${before:-}" ) +userID="$(id -u $(whoami))" +stalelock=( "${stalelock:-""}" ) +stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && +cleanup=True || { true; cleanup=False; } _finish () { [[ -n $before ]] && - printf "$before" | xclip -sel "$X_SELECTION" -i - [[ True = "$remove" ]] && - if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - rmdir /tmp/passmenu."$uid".* >/dev/null 2>&1 + printf "$before" | base64 -d | xclip -sel "$X_SELECTION" -i + [[ True = "$cleanup" ]] && + if compgen -G "/tmp/passmenulock.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 fi exit } trap _finish EXIT ## Clearing stale Xclip loops avoids a posible race condition. -uid="$(id -u $(whoami))" -remove=False -if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - stale="$(find /tmp/passmenu."$uid".* -print -quit | - sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" - report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | - grep "passmenu" | grep -v "$$")" - if [[ "$report" == *"$stale"* ]] ;then - kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 +if test -n "$stalelock" ;then + report=( "$(ps -u $(id -u $(whoami)) aux | grep "bash" | + grep "passmenu" | grep -v "$$")" ) + stalePID=( "$(printf $stalelock | + sed -e "s/\/tmp\/passmenulock\.[0-9]\{1,6\}\?\..*\.//g")" ) + if [[ "$report" == *"$stalePID"* ]] ;then + kill "$stalePID" || exit 1 else - rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + rmdir /tmp/passmenulock.$userID.* >/dev/null 2>&1 || exit 1 fi fi ## dmenu exits on KeyPress not KeyRelease. -## It would be nice to send KeyRelease event to some dummy window. -## psydocode: xdotool getwindowfocus; create dummy window; -## exec dmenu; close dummy window; restore focus. -password=${password:-} +# It would be nice to send KeyRelease event to some dummy window. +# psydocode: xdotool getwindowfocus; create dummy window; +# exec dmenu; close dummy window; restore focus. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do passel+=("$password") done -before=${before:-} [[ -n $password ]] || exit -before="$(xclip -sel "$X_SELECTION" -o >/dev/null 2>&1)" || true +# It would be nice to first somehow test if string exists. +before="$(xclip -sel "$X_SELECTION" -o 2>/dev/null | base64)" || true umask 077 -mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || -{ echo >&2 ":: Unable to make a filelock."; exit 1; } -remove=True +( mktemp -d "/tmp/passmenulock."$userID".XXXXXXXXXX"."$$" >/dev/null 2>&1 && cleanup=True || + { echo >&2 ":: Unable to make a filelock."; exit 1; } ) if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then -- 2.8.0
From dacf9f38ba38b86b79420d2cc3b25ff0191ed9b2 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Tue, 19 Jul 2016 16:11:10 -0400 Subject: [PATCH] Renamed filelock for clarity. --- contrib/dmenu/passmenu | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 40dfe97..e1835d2 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -26,8 +26,8 @@ _finish () { [[ True == $cleanup ]] && printf "$before" | base64 -d | xclip -sel "$X_SELECTION" -i [[ True = "$cleanup" ]] && - if compgen -G "/tmp/passmenulock.1000*" >/dev/null 2>&1 ;then - rmdir /tmp/passmenulock.*.*."$$" >/dev/null 2>&1 + if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenu.*.*."$$".lock >/dev/null 2>&1 fi exit } @@ -47,22 +47,23 @@ trap _finish EXIT ## Clearing old filelock(s). umask 077 stalelock=( "${stalelock:-''}" ) -stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && +stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenu."$userID".*" -user $(whoami) -print0 -quit -type d)" ) && if test -n "$stalelock" ;then + stalename=${stalelock%.*} report=( "$(ps -u $(id -u $(whoami)) aux | grep "bash" | grep "passmenu" | grep -v "$$")" ) - stalePID=( "$(printf $stalelock | - sed -e "s/\/tmp\/passmenulock\.[0-9]\{1,6\}\?\..*\.//g")" ) + stalePID=( "$(printf $stalename | + sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" ) if [[ "$report" == *"$stalePID"* ]] ;then kill "$stalePID" || exit 1 else - rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 || + rmdir /tmp/passmenu."$userID".* >/dev/null 2>&1 || { echo ":: Unable to clear old filelock"; exit 1; } fi fi ## Adding a new filelock -( mktemp -d "/tmp/passmenulock."$userID".XXXXXXXXXX"."$$" >/dev/null 2>&1 && cleanup=True || +( mktemp -d "/tmp/passmenu."$userID".XXXXXXXXXX"."$$".lock >/dev/null 2>&1 && cleanup=True || { echo >&2 ":: Unable to make a filelock."; exit 1; } ) cleanup=True -- 2.9.0
From 1d2e5d9d0b3e46e1ce72e4151193eb648d668176 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 8 Apr 2016 23:38:57 -0400 Subject: [PATCH 01/12] Adding xclip loop to select multiple pass entries. --- contrib/dmenu/passmenu | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 7a9c517..b80399c 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -4,22 +4,27 @@ shopt -s nullglob globstar typeit=0 if [[ $1 == "--type" ]]; then - typeit=1 - shift + typeit=1 + shift fi +X_SELECTION="$PASSWORD_STORE_X_SELECTION" prefix=${PASSWORD_STORE_DIR-~/.password-store} + password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -password=$(printf '%s\n' "${password_files[@]}" | dmenu "$@") +if [[ $typeit -eq 0 ]]; then + for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do + pass show $password | + xclip -l 1 -quiet -sel $X_SELECTION + done [[ -n $password ]] || exit -if [[ $typeit -eq 0 ]]; then - pass show -c "$password" 2>/dev/null else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - + pass show "$password" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - fi -- 2.8.0 From 4b003d9bbd9b79d71250aeee029468806bf16e09 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 9 Apr 2016 00:46:26 -0400 Subject: [PATCH 02/12] Add condition to skip xclip loop on 1 selection. --- contrib/dmenu/passmenu | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index b80399c..ddfb07f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -17,13 +17,20 @@ password_files=( "${password_files[@]%.gpg}" ) if [[ $typeit -eq 0 ]]; then for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do - pass show $password | - xclip -l 1 -quiet -sel $X_SELECTION + dmenu -f "$@"); do + lot+=($password) done -[[ -n $password ]] || exit + [[ -n $password ]] || exit + if [ ${#lot[@]} -gt "0" ]; then + for entry in "${lot[@]}"; do + pass show $entry | awk 'NR==1' | + xclip -l 1 -quiet -sel $X_SELECTION + done + else + pass show -c "$password" 2>/dev/null + fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | xdotool type --clearmodifiers --file - -- 2.8.0 From 1e52e9fc165961a94bc834d5fd58ee2669eaae1d Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Thu, 14 Apr 2016 02:03:17 -0400 Subject: [PATCH 03/12] Restores clipboard to previous state. --- contrib/dmenu/passmenu | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index ddfb07f..789d0de 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -15,22 +15,24 @@ password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -if [[ $typeit -eq 0 ]]; then - for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do +for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do lot+=($password) - done +done - [[ -n $password ]] || exit +[[ -n $password ]] || exit - if [ ${#lot[@]} -gt "0" ]; then - for entry in "${lot[@]}"; do - pass show $entry | awk 'NR==1' | - xclip -l 1 -quiet -sel $X_SELECTION +if [[ $typeit -eq 0 ]]; then + xclip -sel clip -o | xclip -sel sec -i + if [ ${#lot[@]} -gt "1" ]; then + for entry in "${lot[@]}"; do + pass show $entry | awk 'NR==1' | + xclip -l 1 -quiet -sel $X_SELECTION &>/dev/null done + xclip -sel sec -o | xclip -sel clip -i else - pass show -c "$password" 2>/dev/null - fi + pass show -c "$password" &>/dev/null + fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | xdotool type --clearmodifiers --file - -- 2.8.0 From 24d3194a119c4503d471d09159d11f3d4c12eda3 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 22 Apr 2016 14:44:51 -0400 Subject: [PATCH 04/12] Clears secondary clipboard after use. --- contrib/dmenu/passmenu | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 789d0de..84b4ae4 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -8,13 +8,14 @@ if [[ $1 == "--type" ]]; then shift fi -X_SELECTION="$PASSWORD_STORE_X_SELECTION" -prefix=${PASSWORD_STORE_DIR-~/.password-store} +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) +## Press Ctrl-Return to continue selecting entries. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do lot+=($password) @@ -23,15 +24,19 @@ done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - xclip -sel clip -o | xclip -sel sec -i + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i if [ ${#lot[@]} -gt "1" ]; then + x=0 for entry in "${lot[@]}"; do - pass show $entry | awk 'NR==1' | - xclip -l 1 -quiet -sel $X_SELECTION &>/dev/null + printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" + pass show $entry | head -n 1 | tr -d '\n' | + xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null + x=`expr $x + 1` done - xclip -sel sec -o | xclip -sel clip -i + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i else - pass show -c "$password" &>/dev/null + pass -c "$password" 2>/dev/null fi else pass show "$password" | { read -r pass; printf %s "$pass"; } | -- 2.8.0 From 8e25eeeab68810ec295fb5d8cb2b4412bcd529f2 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 02:36:55 -0400 Subject: [PATCH 05/12] Limits use of secondary clip to multi selections. --- contrib/dmenu/passmenu | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 84b4ae4..a784481 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -24,17 +24,17 @@ done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i if [ ${#lot[@]} -gt "1" ]; then x=0 + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i for entry in "${lot[@]}"; do printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" pass show $entry | head -n 1 | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null x=`expr $x + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i else pass -c "$password" 2>/dev/null fi -- 2.8.0 From 20d3a8a8c55dfb31fa9cdc191b156f7d98ac3a53 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 17:12:29 -0400 Subject: [PATCH 06/12] Changes variables and comments for readability. --- contrib/dmenu/passmenu | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index a784481..45eb66f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -8,30 +8,31 @@ if [[ $1 == "--type" ]]; then shift fi -X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-primary}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## Press Ctrl-Return to continue selecting entries. +## dmenu exits on KeyPress. +## We should send KeyRelease event to some dummy window. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do - lot+=($password) + passel+=($password) done [[ -n $password ]] || exit if [[ $typeit -eq 0 ]]; then - if [ ${#lot[@]} -gt "1" ]; then - x=0 + if [ ${#passel[@]} -gt "1" ]; then + round=0 xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${lot[@]}"; do - printf '%s\n' "Sending "${lot[$x]}" via "$X_SELECTION"" + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" pass show $entry | head -n 1 | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - x=`expr $x + 1` + round=`expr $round + 1` done xclip -sel sec -o | xclip -sel "$X_SELECTION" -i printf "" | xclip -sel sec -i -- 2.8.0 From 499a2b10739514860744c0179f00a551bd34cd12 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 23 Apr 2016 20:22:08 -0400 Subject: [PATCH 07/12] Adding multi password selection to option --type. --- contrib/dmenu/passmenu | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 45eb66f..1b0339f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -40,6 +40,20 @@ if [[ $typeit -eq 0 ]]; then pass -c "$password" 2>/dev/null fi else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - + if [ ${#passel[@]} -gt "1" ]; then + round=0 + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null + pass show "$entry" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + printf "" | xclip -sel sec -i + else + pass show "$password" | { read -r pass; printf %s "$pass"; } | + xdotool type --clearmodifiers --file - + fi fi -- 2.8.0 From 67dacee2237bf12dfa0f6e14806971ad2daab7ea Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Wed, 27 Apr 2016 20:29:07 -0400 Subject: [PATCH 08/12] Locks script and attemps to clear old loop. --- contrib/dmenu/passmenu | 91 ++++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 1b0339f..e842f13 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -4,56 +4,69 @@ shopt -s nullglob globstar typeit=0 if [[ $1 == "--type" ]]; then - typeit=1 - shift + typeit=1 + shift fi -X_SELECTION="${PASSWORD_STORE_X_SELECTION:-primary}" +X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## dmenu exits on KeyPress. -## We should send KeyRelease event to some dummy window. -for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do - passel+=($password) +## Preexisting xclip loops can cause unanticipated behavior. +exec {lock_fd}>/tmp/passmenulock || exit 1 +flock -n "$lock_fd" || + { xclip -sel "$X_SELECTION" -o >/dev/null 2>&1 + flock -n "$lock_fd" || + printf '%s\n' 'Already running' >&2 + exit 1 + } + +## dmenu exits on KeyPress not KeyRelease. +## It would be nice to send KeyRelease event to some dummy window. +for password in $(printf '%s\n' "${password_files[@]}" | + dmenu -f "$@"); do + passel+=($password) done [[ -n $password ]] || exit - + if [[ $typeit -eq 0 ]]; then - if [ ${#passel[@]} -gt "1" ]; then - round=0 - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${passel[@]}"; do - printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - pass show $entry | head -n 1 | tr -d '\n' | - xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - round=`expr $round + 1` - done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i - else - pass -c "$password" 2>/dev/null - fi + if [ ${#passel[@]} -gt "1" ]; then + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + round=0 + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + pass show $entry | sed '1!d' | tr -d '\n' | + xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 + ~/bin/beeponce + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + else + pass -c "$password" 2>/dev/null + fi else - if [ ${#passel[@]} -gt "1" ]; then - round=0 - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i - for entry in "${passel[@]}"; do - printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" &>/dev/null - pass show "$entry" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - - round=`expr $round + 1` - done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i - printf "" | xclip -sel sec -i - else - pass show "$password" | { read -r pass; printf %s "$pass"; } | - xdotool type --clearmodifiers --file - - fi + command -v xdotool >/dev/null 2>&1 || + { echo >&2 "e: cannot find xdotool."; exit 1; } + if [ ${#passel[@]} -gt "1" ]; then + xclip -sel "$X_SELECTION" -o | xclip -sel sec -i + round=0 + for entry in "${passel[@]}"; do + printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" + printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 + ~/bin/beeponce + pass show "$entry" | sed '1!d' | tr -d '\n' | + xdotool type --clearmodifiers --file - + round=`expr $round + 1` + done + xclip -sel sec -o | xclip -sel "$X_SELECTION" -i + else + pass show "$password" | sed '1!d' | tr -d '\n' | + xdotool type --clearmodifiers --file - + fi fi +printf "" | xclip -sel sec -i +flock -u "$lock_fd" -- 2.8.0 From 5cee86eb671b0db6229bcb490ca1762ae2eb8d76 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sun, 1 May 2016 17:49:36 -0400 Subject: [PATCH 09/12] A portable process lock avoids unanticipated behavior. --- contrib/dmenu/passmenu | 68 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index e842f13..021c48f 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -1,6 +1,7 @@ #!/usr/bin/env bash shopt -s nullglob globstar +set -o errexit typeit=0 if [[ $1 == "--type" ]]; then @@ -9,64 +10,93 @@ if [[ $1 == "--type" ]]; then fi X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}" +CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}" prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -## Preexisting xclip loops can cause unanticipated behavior. -exec {lock_fd}>/tmp/passmenulock || exit 1 -flock -n "$lock_fd" || - { xclip -sel "$X_SELECTION" -o >/dev/null 2>&1 - flock -n "$lock_fd" || - printf '%s\n' 'Already running' >&2 - exit 1 +_finish () { + [[ 1 = "$remove" ]] + rmdir /tmp/passmenu."$uid".* 2>/dev/null + ## kill more child processes here. + # echo $(ps -o pgid=$$ | grep -o [0-9]*) + printf "$buffer" | xclip -sel "$X_SELECTION" -i + exit } +trap _finish EXIT + +_fire () { + stale="$(find /tmp/passmenu."$uid".* -print -quit | + sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" + report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | + grep "passmenu" | grep -v "$$")" + if [[ "$report" == *"passmenu"* ]] ;then + kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + else + rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + fi +} + +## Clearing stale Xclip loops avoids a posible race condition. +uid="$(id -u $(whoami))" +remove=0 +if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + question=$(printf 'yes\nno'| + dmenu -nf red -f -p "The clipboard is locked by another process. Kill it with fire?") + if [ "$question" = 'yes' ] ;then + _fire + else + exit 0 + fi +fi ## dmenu exits on KeyPress not KeyRelease. ## It would be nice to send KeyRelease event to some dummy window. +## psydocode: xdotool getwindowfocus; create dummy window; +## exec dmenu; close dummy window; restore focus. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do - passel+=($password) + passel+=("$password") done [[ -n $password ]] || exit - + +umask 077 +mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || exit 1 +remove=1 + +buffer="$(xclip -sel "$X_SELECTION" -o)" if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i round=0 for entry in "${passel[@]}"; do printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" - pass show $entry | sed '1!d' | tr -d '\n' | + pass show "$entry" | sed '1!d' | tr -d '\n' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 - ~/bin/beeponce round=`expr $round + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i else - pass -c "$password" 2>/dev/null + pass show "$password" | sed '1!d' | tr -d '\n' | + xclip -sel "$X_SELECTION" -i + sleep "$CLIP_TIME" fi else command -v xdotool >/dev/null 2>&1 || { echo >&2 "e: cannot find xdotool."; exit 1; } if [ ${#passel[@]} -gt "1" ]; then - xclip -sel "$X_SELECTION" -o | xclip -sel sec -i round=0 for entry in "${passel[@]}"; do printf '%s\n' "Sending "${passel[$round]}" via "$X_SELECTION"" printf '' | xclip -l 1 -quiet -sel "$X_SELECTION" >/dev/null 2>&1 - ~/bin/beeponce pass show "$entry" | sed '1!d' | tr -d '\n' | xdotool type --clearmodifiers --file - round=`expr $round + 1` done - xclip -sel sec -o | xclip -sel "$X_SELECTION" -i else pass show "$password" | sed '1!d' | tr -d '\n' | xdotool type --clearmodifiers --file - fi fi -printf "" | xclip -sel sec -i -flock -u "$lock_fd" +exit -- 2.8.0 From f8b10ed59edbb293e3728f29fc087ddcf316cc3c Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 6 May 2016 11:58:34 -0400 Subject: [PATCH 10/12] Adding strict mode. --- contrib/dmenu/passmenu | 58 ++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 021c48f..e6e2cfc 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -1,10 +1,11 @@ #!/usr/bin/env bash -shopt -s nullglob globstar -set -o errexit +shopt -s nullglob globstar failglob +set -euo pipefail +tool=${1:-} typeit=0 -if [[ $1 == "--type" ]]; then +if [[ $tool == "--type" ]]; then typeit=1 shift fi @@ -18,56 +19,49 @@ password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) _finish () { - [[ 1 = "$remove" ]] - rmdir /tmp/passmenu."$uid".* 2>/dev/null - ## kill more child processes here. - # echo $(ps -o pgid=$$ | grep -o [0-9]*) - printf "$buffer" | xclip -sel "$X_SELECTION" -i + [[ -n $before ]] && + printf "$before" | xclip -sel "$X_SELECTION" -i + [[ True = "$remove" ]] && + if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenu."$uid".* >/dev/null 2>&1 + fi exit - } +} trap _finish EXIT -_fire () { +## Clearing stale Xclip loops avoids a posible race condition. +uid="$(id -u $(whoami))" +remove=False +if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then stale="$(find /tmp/passmenu."$uid".* -print -quit | sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | grep "passmenu" | grep -v "$$")" - if [[ "$report" == *"passmenu"* ]] ;then + if [[ "$report" == *"$stale"* ]] ;then kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 else rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 fi -} - -## Clearing stale Xclip loops avoids a posible race condition. -uid="$(id -u $(whoami))" -remove=0 -if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - question=$(printf 'yes\nno'| - dmenu -nf red -f -p "The clipboard is locked by another process. Kill it with fire?") - if [ "$question" = 'yes' ] ;then - _fire - else - exit 0 - fi fi ## dmenu exits on KeyPress not KeyRelease. ## It would be nice to send KeyRelease event to some dummy window. ## psydocode: xdotool getwindowfocus; create dummy window; ## exec dmenu; close dummy window; restore focus. -for password in $(printf '%s\n' "${password_files[@]}" | - dmenu -f "$@"); do +password=${password:-} +for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do passel+=("$password") done +before=${before:-} [[ -n $password ]] || exit +before="$(xclip -sel "$X_SELECTION" -o >/dev/null 2>&1)" || true umask 077 -mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || exit 1 -remove=1 +mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || +{ echo >&2 ":: Unable to make a filelock."; exit 1; } +remove=True -buffer="$(xclip -sel "$X_SELECTION" -o)" if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then round=0 @@ -78,12 +72,12 @@ if [[ $typeit -eq 0 ]]; then round=`expr $round + 1` done else + printf '%s\n' "Sending "$password" via "$X_SELECTION"" pass show "$password" | sed '1!d' | tr -d '\n' | - xclip -sel "$X_SELECTION" -i - sleep "$CLIP_TIME" + xclip -sel "$X_SELECTION" -i && sleep "$CLIP_TIME" fi else - command -v xdotool >/dev/null 2>&1 || + command -v xdotool >/dev/null 2>&1 || { echo >&2 "e: cannot find xdotool."; exit 1; } if [ ${#passel[@]} -gt "1" ]; then round=0 -- 2.8.0 From 90a3613d854085e1fe1416714729aa24e2013cf3 Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Sat, 7 May 2016 06:14:50 -0400 Subject: [PATCH 11/12] Improved filelock, and more appropriate variable names. --- contrib/dmenu/passmenu | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index e6e2cfc..68b4150 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -17,50 +17,52 @@ prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) +password=( ${password:-""} ) +before=( "${before:-}" ) +userID="$(id -u $(whoami))" +stalelock=( "${stalelock:-""}" ) +stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && +cleanup=True || { true; cleanup=False; } _finish () { [[ -n $before ]] && - printf "$before" | xclip -sel "$X_SELECTION" -i - [[ True = "$remove" ]] && - if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - rmdir /tmp/passmenu."$uid".* >/dev/null 2>&1 + printf "$before" | base64 -d | xclip -sel "$X_SELECTION" -i + [[ True = "$cleanup" ]] && + if compgen -G "/tmp/passmenulock.1000*" >/dev/null 2>&1 ;then + rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 fi exit } trap _finish EXIT ## Clearing stale Xclip loops avoids a posible race condition. -uid="$(id -u $(whoami))" -remove=False -if compgen -G "/tmp/passmenu.1000*" >/dev/null 2>&1 ;then - stale="$(find /tmp/passmenu."$uid".* -print -quit | - sed -e "s/\/tmp\/passmenu\.[0-9]\{1,6\}\?\..*\.//g")" - report="$(ps -u $(id -u $(whoami)) aux | grep "bash" | - grep "passmenu" | grep -v "$$")" - if [[ "$report" == *"$stale"* ]] ;then - kill "$stale" && rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 +if test -n "$stalelock" ;then + report=( "$(ps -u $(id -u $(whoami)) aux | grep "bash" | + grep "passmenu" | grep -v "$$")" ) + stalePID=( "$(printf $stalelock | + sed -e "s/\/tmp\/passmenulock\.[0-9]\{1,6\}\?\..*\.//g")" ) + if [[ "$report" == *"$stalePID"* ]] ;then + kill "$stalePID" || exit 1 else - rmdir /tmp/passmenu.$uid.* >/dev/null 2>&1 || exit 1 + rmdir /tmp/passmenulock.$userID.* >/dev/null 2>&1 || exit 1 fi fi ## dmenu exits on KeyPress not KeyRelease. -## It would be nice to send KeyRelease event to some dummy window. -## psydocode: xdotool getwindowfocus; create dummy window; -## exec dmenu; close dummy window; restore focus. -password=${password:-} +# It would be nice to send KeyRelease event to some dummy window. +# psydocode: xdotool getwindowfocus; create dummy window; +# exec dmenu; close dummy window; restore focus. for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do passel+=("$password") done -before=${before:-} [[ -n $password ]] || exit -before="$(xclip -sel "$X_SELECTION" -o >/dev/null 2>&1)" || true +# It would be nice to first somehow test if string exists. +before="$(xclip -sel "$X_SELECTION" -o 2>/dev/null | base64)" || true umask 077 -mktemp -d "/tmp/passmenu."$uid".XXXXXXXXXX"."$$" >/dev/null 2>&1 || -{ echo >&2 ":: Unable to make a filelock."; exit 1; } -remove=True +( mktemp -d "/tmp/passmenulock."$userID".XXXXXXXXXX"."$$" >/dev/null 2>&1 && cleanup=True || + { echo >&2 ":: Unable to make a filelock."; exit 1; } ) if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then -- 2.8.0 From e6f32f4d33fe022c4b13def31c401890298e5b1e Mon Sep 17 00:00:00 2001 From: ampling <[email protected]> Date: Fri, 13 May 2016 16:40:32 -0400 Subject: [PATCH 12/12] Delayed file-lock improves corner-case. --- contrib/dmenu/passmenu | 51 +++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/contrib/dmenu/passmenu b/contrib/dmenu/passmenu index 68b4150..40dfe97 100755 --- a/contrib/dmenu/passmenu +++ b/contrib/dmenu/passmenu @@ -17,25 +17,37 @@ prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" password_files=( "$prefix"/**/*.gpg ) password_files=( "${password_files[@]#"$prefix"/}" ) password_files=( "${password_files[@]%.gpg}" ) -password=( ${password:-""} ) -before=( "${before:-}" ) -userID="$(id -u $(whoami))" -stalelock=( "${stalelock:-""}" ) -stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && -cleanup=True || { true; cleanup=False; } +password=( '' ) +cleanup=( '' ) +before=( '' ) +userID=( "$(id -u $(whoami))" ) _finish () { - [[ -n $before ]] && + [[ True == $cleanup ]] && printf "$before" | base64 -d | xclip -sel "$X_SELECTION" -i [[ True = "$cleanup" ]] && if compgen -G "/tmp/passmenulock.1000*" >/dev/null 2>&1 ;then - rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 + rmdir /tmp/passmenulock.*.*."$$" >/dev/null 2>&1 fi exit } + +## dmenu exits on KeyPress not KeyRelease. +# It might be nice to send KeyRelease event to some dummy window. +# psydocode: xdotool getwindowfocus; create dummy window; +# exec dmenu; close dummy window; restore focus. +for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do + passel+=("$password") +done + +[[ -n $password ]] || exit + trap _finish EXIT -## Clearing stale Xclip loops avoids a posible race condition. +## Clearing old filelock(s). +umask 077 +stalelock=( "${stalelock:-''}" ) +stalelock=( "$(find '/tmp' -maxdepth 1 -name "passmenulock."$userID".*" -user $(whoami) -print0 -quit)" ) && if test -n "$stalelock" ;then report=( "$(ps -u $(id -u $(whoami)) aux | grep "bash" | grep "passmenu" | grep -v "$$")" ) @@ -44,26 +56,19 @@ if test -n "$stalelock" ;then if [[ "$report" == *"$stalePID"* ]] ;then kill "$stalePID" || exit 1 else - rmdir /tmp/passmenulock.$userID.* >/dev/null 2>&1 || exit 1 + rmdir /tmp/passmenulock."$userID".* >/dev/null 2>&1 || + { echo ":: Unable to clear old filelock"; exit 1; } fi fi -## dmenu exits on KeyPress not KeyRelease. -# It would be nice to send KeyRelease event to some dummy window. -# psydocode: xdotool getwindowfocus; create dummy window; -# exec dmenu; close dummy window; restore focus. -for password in $(printf '%s\n' "${password_files[@]}" | dmenu -f "$@"); do - passel+=("$password") -done - -[[ -n $password ]] || exit -# It would be nice to first somehow test if string exists. -before="$(xclip -sel "$X_SELECTION" -o 2>/dev/null | base64)" || true - -umask 077 +## Adding a new filelock ( mktemp -d "/tmp/passmenulock."$userID".XXXXXXXXXX"."$$" >/dev/null 2>&1 && cleanup=True || { echo >&2 ":: Unable to make a filelock."; exit 1; } ) +cleanup=True +# It would be nice to first first test if string exists. +before="$(xclip -sel "$X_SELECTION" -o 2>/dev/null | base64)" || true + if [[ $typeit -eq 0 ]]; then if [ ${#passel[@]} -gt "1" ]; then round=0 -- 2.8.0
signature.asc
Description: signature
_______________________________________________ Password-Store mailing list [email protected] http://lists.zx2c4.com/mailman/listinfo/password-store
