diff --git a/bin/read-up b/bin/read-up new file mode 120000 index 0000000..b815a2d --- /dev/null +++ b/bin/read-up @@ -0,0 +1 @@ +../shell/read-up \ No newline at end of file diff --git a/bin/scotty b/bin/scotty deleted file mode 120000 index 64bfd58..0000000 --- a/bin/scotty +++ /dev/null @@ -1 +0,0 @@ -../web/scotty \ No newline at end of file diff --git a/bin/select-option b/bin/select-option new file mode 120000 index 0000000..07c1051 --- /dev/null +++ b/bin/select-option @@ -0,0 +1 @@ +../shell/select-option.sh \ No newline at end of file diff --git a/shell/read-up b/shell/read-up new file mode 100755 index 0000000..e11a92f --- /dev/null +++ b/shell/read-up @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + + +_help() { + SELF=$( basename "$0" ) + echo "Read arrows keys up/down + + Usage: $SELF [-c Char] + -c Char Print Char character at the start of line + + Returns + 100 - number of rows above start point + 0 if ctrl-c or ESC pressed + +" + exit +} + +CHAR="" +for (( i=1; i<=$#; i++ )); do + value=${!i} + j=$(( i + 1 )) + [[ "$value" = "-h" ]] && _help + [[ "$value" = "--help" ]] && _help + [[ "$value" = "-c" ]] && { CHAR="${!j}"; ((i++)); continue; } +done +printf -v EMPTYCHAR "%-${#CHAR}s" " " + + +ESC=$( printf "\033") +cursor_blink_on() { printf "$ESC[?25h"; } +cursor_blink_off() { printf "$ESC[?25l"; } +cursor_to() { printf "$ESC[$1;${2:-1}H"; } +get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } +get_screen_rows() { tput lines; } +key_input() { read -s -n1 key1 2>/dev/null >&2 + read -s -n2 -t 0.1 key2 2>/dev/null >&2 + if [[ $key1 = "" ]]; then echo enter; return; fi + if [[ $key1$key2 = $ESC[A ]]; then echo up; return; fi + if [[ $key1$key2 = $ESC[B ]]; then echo down; return; fi + if [[ -z "$key2" ]]; then + if [[ $key1 = $'\e' ]]; then echo esc; return; fi + fi + } +reset_display() { + cursor_blink_on; stty echo; +} +print_char() { printf -- "$CHAR\r"; } +print_empty() { if [[ -n "$CHAR" ]]; then printf "$EMPTYCHAR\r"; fi; } + +startrow=`get_cursor_row` +trap "cursor_blink_on; stty echo; cursor_to $startrow; exit 1" 2 +#trap "cursor_blink_on; stty echo; printf '\n'; exit 1" 2 +if [[ -n "$CHAR" ]]; then + cursor_blink_off +fi +selected=0 +while true; do + cursor_to $(( $startrow - $selected)) + print_char + # user key control + case `key_input` in + enter) break;; + esc) reset_display; exit 1;; + up) + cursor_to $(( $startrow - $selected)) + print_empty + ((selected++)); + # limit going top + ;; + down) + cursor_to $(( $startrow - $selected)) + print_empty + ((selected--)); + # limit going down + ;; + esac + lastrow=`get_cursor_row` + if [ $(( $startrow - $selected )) -lt 1 ]; then + ((selected--)) + fi + if [ $(( startrow - $selected )) -gt `get_screen_rows` ]; then + ((selected++)) + fi +done + +cursor_blink_on +cursor_to $startrow + +exit $(( 100 - $selected )) diff --git a/shell/select-option.sh b/shell/select-option.sh new file mode 100755 index 0000000..0cd524b --- /dev/null +++ b/shell/select-option.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash + +# Renders a text based list of options that can be selected by the +# user using up, down and enter keys and returns the chosen option. +# +# Arguments : list of options, maximum of 256 +# "opt1" "opt2" ... +# Return value: selected index (0 for opt1, 1 for opt2 ...) + + +function select_option { + local nformat + local optcount=$# + printf -v nformat "%%%dd. " ${#optcount} + local max_opt=0 + for opt; do + if [[ "${#opt}" -gt $max_opt ]]; then + max_opt=${#opt} + fi + done + + # little helpers for terminal print control and key input + ESC=$( printf "\033") + cursor_blink_on() { printf "$ESC[?25h"; } + cursor_blink_off() { printf "$ESC[?25l"; } + cursor_to() { printf "$ESC[$1;${2:-1}H"; } + if [[ $COLORS -eq 1 ]]; then + print_option() { printf " $ESC[33m $1 $ESC[0m "; } + print_selected() { printf " [$ESC[37;1m$1$ESC[0m] "; } + else + print_option() { printf " $1 "; } + print_selected() { printf " [$ESC[1m$1$ESC[0m] "; } + fi + get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; } + key_input() { read -s -n1 key1 2>/dev/null >&2 + read -s -n2 -t 0.1 key2 2>/dev/null >&2 + + if [[ $key1$key2 = $ESC[A ]]; then echo up; return; fi + if [[ $key1$key2 = $ESC[B ]]; then echo down; return; fi + if [[ $key1 = $'\e' ]]; then echo esc; return; fi + if [[ $key1 = "" ]]; then echo enter; return; fi + } + reset_display() { + cursor_blink_on; stty echo; printf '\n'; + } + # initially print empty new lines (scroll down if at bottom of screen) + for opt; do printf "\n"; done + + # determine current screen position for overwriting the options + local lastrow=`get_cursor_row` + local startrow=$(($lastrow - $#)) + + # ensure cursor and input echoing back on upon a ctrl+c during read -s + trap "cursor_blink_on; stty echo; printf '\n'; exit 1" 2 + cursor_blink_off + + local selected=0 + while true; do + # print options by overwriting the last lines + local idx=0 + local nidx + + for opt; do + if [[ $SELECT_UNDERSCORES -eq 1 ]]; then + opt=${opt//_/ } + fi + if [[ $SELECT_NUMBERS -eq 1 ]]; then + printf -v nidx "$nformat" $(( idx + 1 )) + fi + printf -v padopt "%-${max_opt}s" "$opt" + cursor_to $(($startrow + $idx)) + if [ $idx -eq $selected ]; then + print_selected "$nidx$padopt" + else + print_option "$nidx$padopt" + fi + ((idx++)) + done + + # user key control + case `key_input` in + enter) break;; + esc) reset_display; exit 1;; + up) ((selected--)); + if [ $selected -lt 0 ]; then selected=$(($# - 1)); fi;; + down) ((selected++)); + if [ $selected -ge $# ]; then selected=0; fi;; + esac + done + + # cursor position back to normal + cursor_to $lastrow + printf "\n" + cursor_blink_on + if [[ -n "$SELECT_TOFILE" ]]; then + local idx=0 + for opt; do + if [ $idx -eq $selected ]; then + echo "$opt" > "$SELECT_TOFILE" + fi + ((idx++)) + done + fi + return $(( 10 + $selected )) +} + +[[ $_ == $0 ]] && { +_help() { + SELF=$( basename "$0" ) + echo "Select Option + + Usage: $SELF [-n] [--nc] [-o File] [-_] list of options + -n Number list + --nc No colors + -o File Save the choice in a file + -_ Print spaces instead of underscores + + Returns + (10 + index) of selection (first option = 10) + 1 if ctrl-c or ESC pressed + + Example: + $SELF -n one two three + EC=\$? + [[ \$EC -lt 10 ]] && { echo Exited..; } || { echo You selected \$(( \$EC - 9 )); } +" + exit +} + +SELECT_COLORS=1 +SELECT_NUMBERS=0 +SELECT_UNDERSCORES=0 +SELECT_TOFILE="" +for (( i=1; i<=$#; i++ )); do + value=${!i} + j=$(( i + 1 )) + [[ "$value" = "-h" ]] && _help + [[ "$value" = "--help" ]] && _help + [[ "$value" = "--nc" ]] && { SELECT_COLORS=0; continue; } + [[ "$value" = "-n" ]] && { SELECT_NUMBERS=1; continue; } + [[ "$value" = "-_" ]] && { SELECT_UNDERSCORES=1; continue; } + [[ "$value" = "-o" ]] && { SELECT_TOFILE="${!j}"; ((i++)); continue; } + opts+=( "$value" ) +done + +select_option "${opts[@]}" +exit $? +} diff --git a/web/ssh-tunnelier b/web/ssh-tunnelier index 6dea256..52c8b6d 100755 --- a/web/ssh-tunnelier +++ b/web/ssh-tunnelier @@ -7,7 +7,7 @@ MAGIC_TIME=525601 BASE="base64 -w 0" UNBASE="base64 -d" -if [[ "$OSTYPE" = "darwin"* ]]; then +if [[ "$OSTYPE" = "darwin"* ]]; then BASE="base64" UNBASE="base64 -D" fi @@ -22,13 +22,13 @@ Configuration stored in: $CONF If run with arguments, runs an ssh tunnel with arguments: ssh-tunnelier hostname [local-port] remote-port - + If local port missing, the same port assumed in local " exit 0 } -for (( i=1; i<=$#; i++ )); do +for (( i=1; i<=$#; i++ )); do [[ ${!i} = "-h" ]] && _helpexit [[ ${!i} = "--help" ]] && _helpexit done @@ -50,7 +50,7 @@ colRow=$( _qCol z S ) colMenu=$( _qCol z y ) colWarn=$( _qCol z R ) -function fpgrep() { +function fpgrep() { [[ -z $( pgrep -x -u $UID "$@" ) ]] && { echo '----'; return; } pgrep -x -u $UID "$@" | xargs ps -o pid,start,args } @@ -75,10 +75,10 @@ function list_all_ssh() { printf "${colTitle}Enter PID to kill, empty to return $colZ\n" printf "${colTitle}Outgoing SSH processes\n" printf "${colTitle}=============================================\n${colRow}" - fpgrep ssh + fpgrep ssh printf "${colTitle}Incoming SSH processes\n" printf "${colTitle}=============================================\n${colRow}" - fpgrep sshd + fpgrep sshd read -t 600 inputpid [[ "$inputpid" =~ $number_re ]] && { @@ -111,16 +111,16 @@ function run_command() { } function ask_to_kill() { - printf "${colRow}" - ps -o pid,bsdstart,args "$1" - printf "\n k kill\n t terminate${colZ}\n" + printf "${colRow}" + ps -o pid,bsdstart,args "$1" + printf "\n k kill\n t terminate${colZ}\n" read -t 600 input2 [[ "$input2" = "k" ]] && kill $1 [[ "$input2" = "t" ]] && kill -9 $1 } -[[ -n "$2" ]] && { +[[ -n "$2" ]] && { run_args "$@" } @@ -128,7 +128,7 @@ while true; do ids=() i=1 printf "\n${colTitle}=============================================\n" - printf "${colTitle} List of tunnels:${colZ}\n" + printf "${colTitle} List of tunnels:${colZ}\n" printf "${colTitle} (q)uit (e)dit (l)ist ssh [%s]${colZ}\n" $( date +%H:%M ) printf "${colTitle}=============================================\n" printf "${colRow}ID PID command\n" @@ -142,12 +142,12 @@ while true; do [[ "$input" = "0" ]] && continue [[ "$input" =~ $number_re ]] && { j=$(( $input - 1 )) - [[ $j -gt $(( $i - 1 )) ]] && { + [[ $j -gt $(( $i - 1 )) ]] && { printf "${colWarn}No such tunnel number${colZ}\n" continue } - - printf "\n${colTitle}Tunnel command: %s${colZ}\n" "$( echo "${ids[$j]}" | $UNBASE )" + + printf "\n${colTitle}Tunnel command: %s${colZ}\n" "$( echo "${ids[$j]}" | $UNBASE )" this_pid="$( get_pid "${ids[$j]}" )" [[ -n "$this_pid" ]] && { # PID exists, ask to kill