Advertisement
devinteske

sudok

Oct 20th, 2019
981
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.82 KB | None | 0 0
  1. #!/bin/sh
  2. #-
  3. ############################################################ IDENT(1)
  4. #
  5. # $Title: Script to provide interactive shell that answers sudo prompts $
  6. # $Copyright: 2019 Devin Teske. All rights reserved. $
  7. # $FrauBSD$
  8. #
  9. ############################################################ ENVIRONMENT
  10.  
  11. : "${USER:=$( id -nu )}"
  12. : "${HOSTNAME:=$( hostname )}"
  13. export USER HOSTNAME
  14.  
  15. SUDO_PROMPT="[sudo] Password:"
  16. SUDO_PROMPT_RE="\\[sudo\\] [Pp]assword( for $USER)?: *"
  17. export SUDO_PROMPT SUDO_PROMPT_RE
  18.  
  19. ############################################################ GLOBALS
  20.  
  21. pgm="${0##*/}" # Program basename
  22. progdir="${0%/*}" # Program directory
  23.  
  24. #
  25. # Global exit status
  26. #
  27. SUCCESS=0
  28. FAILURE=1
  29.  
  30. ############################################################ FUNCTIONS
  31.  
  32. usage()
  33. {
  34.         local optfmt="\t%-5s %s\n"
  35.         exec >&2
  36.         printf "Usage: %s [-h]\n" "$pgm"
  37.         printf "Options:\n"
  38.         printf "$optfmt" "-h" "Print usage statement to stderr and exit."
  39.         die
  40. }
  41.  
  42. die()
  43. {
  44.         local fmt="$1"
  45.         if [ "$fmt" ]; then
  46.                 shift 1 # fmt
  47.                 printf "%s: $fmt\n" "$pgm" "$@"
  48.         fi
  49.         exit $FAILURE
  50. }
  51.  
  52. make_expect()
  53. {
  54.         local var=$1
  55.         shift 1 # var
  56.         exec 9<<-EOF
  57.         set okprompt    "$pgm> "
  58.         set timeout     -1
  59.         set user        $::env(USER)
  60.         set hostname    $::env(HOSTNAME)
  61.         set argv        $::env(COMMAND)
  62.  
  63.         $( n=1; for key_value in "$@"; do
  64.                 prompt="${key_value%%=*}"
  65.                 re="${key_value#*=}"
  66.                 printf '\nset prompt%u\t$::env(%s)' $n $prompt
  67.                 printf '\nset promptre%u\t$::env(%s)' $n $re
  68.                 n=$(( $n + 1 ))
  69.         done )
  70.  
  71.         regsub -all {\..*} \$hostname {} hostname
  72.  
  73.         set shell_prompts ""
  74.         foreach shell_prompt [list \
  75.                 [subst -nocommand -nobackslashes \
  76.                         {\$user@\$hostname[^\n\r]*$}] \
  77.                 [subst -nocommand -nobackslashes \
  78.                         {\$user@\$hostname[^\n\r]*[#%>]}] \
  79.         ] {
  80.                 set shell_prompts [subst -nocommand -nobackslashes \
  81.                         {\$shell_prompts|\$shell_prompt}]
  82.         }
  83.         set shell_prompts [string range \$shell_prompts 1 \
  84.                 [string length \$shell_prompts]]
  85.  
  86.         set prompts ""
  87.         foreach prompt [list \
  88.                 [subst -nocommand -nobackslashes {\$shell_prompts}] \
  89.                 $( n=0; for key_value in "$@"; do
  90.                         n=$(( $n + 1 ))
  91.                         printf '[subst %s {$%s}] \\\n' \
  92.                                 "-nocommand -nobackslashes" promptre$n
  93.                 done ) \
  94.         ] {
  95.                 set prompts [subst -nocommand -nobackslashes \
  96.                         {\$prompts|\$prompt}]
  97.         }
  98.         set prompts [string range \$prompts 1 [string length \$prompts]]
  99.  
  100.         fconfigure stdout -buffering none
  101.         spawn {*}\$argv
  102.  
  103.         # Get prompt answers
  104.         stty -echo
  105.         $( n=1; for key_value in "$@"; do
  106.                 printf 'send_user "$%s"\n' prompt$n
  107.                 printf 'expect_tty eof exit -re {([[:print:]]*)\\n}\n'
  108.                 printf 'send_user "\\n"\n'
  109.                 printf 'set %s $expect_out(1,string)\n' answer$n
  110.         done )
  111.         stty echo
  112.  
  113.         proc abort {} {
  114.                 log_user 0
  115.                 exit 0
  116.         }
  117.  
  118.         while (1) {
  119.                 expect eof abort -re [subst -nocommands -nobackslashes \
  120.                         {[^\n\r]*(\$prompts)\s*$}]
  121.                 set buffer \$expect_out(0,string)
  122.  
  123.                 # shell prompt(s)
  124.                 if {[regexp [subst -nocommands -nobackslashes \
  125.                         {^[^\n\r]*(\$shell_prompts)\s*$}] \$buffer]} \
  126.                 {
  127.                         send_tty \$okprompt
  128.                         interact eof abort \
  129.                                 -nobuffer -re {[\r\003\004]} {return} \
  130.                 }
  131.  
  132.                 # defined prompt(s)
  133.                 $( n=0; for key_value in "$@"; do
  134.                         n=$(( $n + 1 ))
  135.                         printf 'if {[regexp [subst %s {^$%s$}] $buffer]} ' \
  136.                                 "-nocommands -nobackslashes" promptre$n
  137.                         printf '{ send "$%s\\r" }\n' answer$n
  138.                 done )
  139.         }
  140.         EOF
  141.         eval $var='$( cat <&9 )'
  142. }
  143.  
  144. ############################################################ MAIN
  145.  
  146. #
  147. # Parse command-line options
  148. #
  149. while getopts h flag; do
  150.         case "$flag" in
  151.         *) usage # NOTREACHED
  152.         esac
  153. done
  154. shift $(( $OPTIND - 1 ))
  155.  
  156. #
  157. # Run command
  158. #
  159. make_expect EXPECT_SUDO SUDO_PROMPT=SUDO_PROMPT_RE
  160. export EXPECT_SUDO COMMAND="${*:-$( ps -o ucomm= -p $PPID )} -l"
  161. expect -c 'eval $::env(EXPECT_SUDO)'
  162.  
  163. ################################################################################
  164. # END
  165. ################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement