Advertisement
devinteske

rput4 -- upload items scp(1)-style over Telnet

Jul 9th, 2015
507
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.27 KB | None | 0 0
  1. #!/bin/sh
  2. ############################################################ IDENT(1)
  3. #
  4. # $Title: Script to put file(s) on a remote cloud controller $
  5. #
  6. ############################################################ GLOBALS
  7.  
  8. #
  9. # Program name
  10. #
  11. pgm="${0##*/}"
  12.  
  13. #
  14. # Global exit status
  15. #
  16. SUCCESS=0
  17. FAILURE=1
  18.  
  19. #
  20. # Command-line options
  21. #
  22. DEBUG=
  23. DRYRUN=
  24. PRESERVE=
  25. QUIET=
  26. RECURSE=
  27. TELNET=
  28.  
  29. #
  30. # Miscellaneous
  31. #
  32. CONTROLLER=
  33. OUTPUT=
  34. PROMPT1="$( id -nu )@$( hostname ) expect> "
  35. PROMPT2="expect> "
  36.  
  37. ############################################################ FUNCTIONS
  38.  
  39. usage()
  40. {
  41.     local optfmt="\t%-4s %s\n"
  42.     exec >&2
  43.     printf "Usage: %s [-dnpTv] file1 ... host:[file2]\n" "$pgm"
  44.     printf "       %s [-dnpTv] -r dir1 ... host:[dir2]\n" "$pgm"
  45.     printf "\n"
  46.     printf "OPTIONS:\n"
  47.     printf "$optfmt" "-d" \
  48.         "Debug. Can be specified multiple times."
  49.     printf "$optfmt" "-n" \
  50.         "Dry run. Show what would be written but don't do anything."
  51.     printf "$optfmt" "-p" \
  52.         "Preserve permissions of source file(s) when writing."
  53.     printf "$optfmt" "-q" \
  54.         "Quiet. Suppress lines printed for each file written."
  55.     printf "$optfmt" "-r" \
  56.         "Recursively copy the contents of directories."
  57.     printf "$optfmt" "-T" \
  58.         "Telnet to localhost port \`host' instead of \`connect host'."
  59.     exit $FAILURE
  60. }
  61.  
  62. replace()
  63. {
  64.     local __string= __found=
  65.  
  66.     local OPTIND=1 OPTARG __flag __all=
  67.     while getopts a __flag; do
  68.         case "$__flag" in
  69.         a) __all=1 ;;
  70.         esac
  71.     done
  72.     shift $(( $OPTIND - 1 ))
  73.  
  74.     local __find="$1" __start="$2" __sub="$3" __var_to_set="$4"
  75.     while [ "$__start" ]; do
  76.         case "$__start" in *"$__find"*)
  77.             __found=1
  78.             __string="$__string${__start%%"$__find"*}$__sub"
  79.             __start="${__start#*"$__find"}"
  80.             [ "$__all" ] || break
  81.             continue
  82.         esac
  83.         break
  84.     done
  85.     __string="$__string$__start"
  86.  
  87.     if [ "$__var_to_set" ]; then
  88.         eval $__var_to_set=\"\$__string\"
  89.     else
  90.         echo "$__string"
  91.     fi
  92.  
  93.     [ "$__found" ] # return status
  94. }
  95.  
  96. shell_escape()
  97. {
  98.     eval replace -a \"\'\" \"\${$1}\" \"\'\\\\\'\'\" \"$1\"
  99. }
  100.  
  101. ############################################################ MAIN
  102.  
  103. #
  104. # Process command-line options
  105. #
  106. while getopts dnpqrT flag; do
  107.     case "$flag" in
  108.     d) DEBUG=$(( $DEBUG + 1 )) ;;
  109.     n) DRYRUN=1 ;;
  110.     p) PRESERVE=1 ;;
  111.     q) QUIET=1 ;;
  112.     r) RECURSE=1 ;;
  113.     T) TELNET=1 ;;
  114.     \?|*) usage
  115.     esac
  116. done
  117. shift $(( $OPTIND - 1 ))
  118.  
  119. #
  120. # Validate number of arguments
  121. #
  122. [ $# -lt 2 ] && usage
  123. eval OUTPUT=\"\${$#}\"
  124. [ "$OUTPUT" ] || usage
  125.  
  126. #
  127. # Validate arguments
  128. #
  129. case "$OUTPUT" in
  130. :*) echo "$pgm: Missing host: $OUTPUT" >&2
  131.     usage ;;
  132. *:*) CONTROLLER="${OUTPUT%%:*}" OUTPUT="${OUTPUT#*:}" ;;
  133. *) echo "$pgm: Missing host: $OUTPUT" >&2
  134.    usage
  135. esac
  136. [ "$CONTROLLER" ] || usage
  137.  
  138. #
  139. # Local shell command (executed via Tcl/expect) to send data to awk decoder
  140. #
  141. # NB: Arguments provided are different from parent script. The last argument
  142. # has been moved to the first argument (making it easier to remove prior to
  143. # operating on remaining source arguments given the destination first).
  144. #
  145. exec 9<<EOF_SH_ENCODER
  146.  
  147.     ################################################## PARENT GLOBALS
  148.  
  149.     pgm='${pgm%%\'*}'
  150.     SUCCESS=$SUCCESS
  151.     FAILURE=$FAILURE
  152.     DRYRUN=$DRYRUN
  153.     RECURSE=$RECURSE
  154.  
  155. EOF_SH_ENCODER
  156. exec 8<<'EOF_SH_ENCODER'
  157.     ################################################## GLOBALS
  158.  
  159.     DEST="$1"
  160.     local="$2"
  161.     prefix="${DEST#*:}"
  162.  
  163.     : ${UNAME_s:=$( uname -s )}
  164.  
  165.     ################################################## EXPORTED FUNCTIONS
  166.  
  167.     putsrc_function='
  168.     putsrc()
  169.     {
  170.         if [ "$DRYRUN" ]; then
  171.             echo "b64source" "$@"
  172.         else
  173.             echo "begin-source" "$@"
  174.         fi
  175.     }
  176.     ' # END-QUOTE
  177.     eval "$putsrc_function"
  178.  
  179.     perms_function='
  180.     perms()
  181.     {
  182.         local path="$1" fallback="$2"
  183.         case "$UNAME_s" in
  184.         FreeBSD) stat -f%Lp "$path" ;;
  185.               *) stat -c%a "$path"
  186.         esac
  187.         local retval=$?
  188.         [ $retval -eq $SUCCESS ] || echo "$fallback"
  189.         return $retval
  190.     }
  191.     ' # END-QUOTE
  192.     eval "$perms_function"
  193.  
  194.     encode_function='
  195.     encode()
  196.     {
  197.         local item="$1" src="$2" mode
  198.  
  199.         #
  200.         # Encode a directory
  201.         #
  202.         if [ -d "$item" ]; then
  203.             putsrc D "$ARGN,$src"
  204.             if [ "$DRYRUN" ]; then
  205.                 echo "b64dirent - $item"
  206.             else
  207.                 mode=$( perms "$item" 644 )
  208.                 echo "begin-dirent $mode $item"
  209.             fi
  210.             return $SUCCESS
  211.         fi
  212.  
  213.         #
  214.         # Encode a file
  215.         #
  216.         if [ "$DRYRUN" ]; then
  217.             echo "b64decode - $item"
  218.             return $SUCCESS
  219.         fi
  220.         local retval
  221.         if type b64encode > /dev/null 2>&1; then
  222.             b64encode "$item" "$item"
  223.             retval=$?
  224.         else
  225.             mode=$( perms "$item" 644 )
  226.             echo "begin-base64 $mode $item"
  227.             base64 "$item"
  228.             retval=$?
  229.             echo "===="
  230.         fi
  231.  
  232.         return $retval
  233.     }
  234.     ' # END-QUOTE
  235.     eval "$encode_function"
  236.  
  237.     ################################################## FUNCTIONS
  238.  
  239.     encode_file()
  240.     {
  241.         local file="$1" prefix="$2" src=
  242.         putsrc F "$ARGN,$file"
  243.         encode "$file" "$src"
  244.     }
  245.  
  246.     encode_dir()
  247.     {
  248.         local localdir="$1" prefix="$2"
  249.         if [ ! "$RECURSE" ]; then
  250.             echo "$pgm: $localdir: Not a regular file" >&2
  251.             return $FAILURE
  252.         fi
  253.         cd "$localdir" || return $?
  254.         local retval=$SUCCESS
  255.         find . \( -type f -or -type d \) -print0 | xargs -0r sh -c '
  256.             : ${UNAME_s:=$( uname -s )}
  257.             DRYRUN='"$DRYRUN"' ARGN='"$ARGN"'
  258.             '"$perms_function"'
  259.             '"$putsrc_function"'
  260.             '"$encode_function"'
  261.             localdir="$1" prefix="$2"
  262.             shift 2 # localdir prefix
  263.             while [ $# -gt 0 ]; do
  264.                 direntry="$1" src="$localdir"
  265.                 shift 1 # direntry
  266.                 [ -d "$direntry" ] || putsrc D "$ARGN,$src"
  267.                 encode "$direntry" "$src"
  268.             done
  269.         ' /bin/sh "$localdir" "$prefix" || retval=$?
  270.         cd - > /dev/null 2>&1
  271.         return $retval
  272.     }
  273.  
  274.     ################################################## MAIN
  275.  
  276.     exec 3<&1
  277.     shift 2 # DEST local
  278.  
  279.     ( ARGN=1
  280.       for p in "$@"; do
  281.         if [ -d "$p" ]; then
  282.             encode_dir "$p" "$prefix"
  283.         else
  284.             encode_file "$p" "$prefix"
  285.         fi
  286.         ARGN=$(( $ARGN + 1 ))
  287.       done
  288.     ) 2>&1 >&3 | awk 'sub(/^/, "SEND_ERROR: ")'
  289.  
  290.     echo # expect(1) chomps the last newline
  291.  
  292. EOF_SH_ENCODER
  293. SH_ENCODER_CMD=$( cat <&9; cat <&8 )
  294.  
  295. #
  296. # awk(1) code for processing the input of local command (SH_ENCODER_CMD)
  297. #
  298. # NB: Tabs replaced with 1 or 4 spaces (prevents shell interpretation of tab)
  299. # NB: Newlines are removed (so make sure semi-colons are used appropriately)
  300. #
  301. exec 9<<EOF_AWK_DECODER
  302.  
  303.     ################################################## GLOBALS
  304.     #
  305.     # Globals available from invocation line:
  306.     #
  307.     #  local    True if operating locally, false if remotely
  308.     #  prefix   Path prefix for file destination(s)
  309.     #  quiet    Maps to \$QUIET from parent script GLOBALS
  310.     #
  311.     # Globals available from BEGIN { ... }:
  312.     #
  313.     #  preserve True if permissions should be preserved
  314.     #  src_prefix   Array for source->prefix mapping
  315.     #
  316.     ################################################## BEGIN
  317.  
  318.     BEGIN {
  319.         preserve = ${PRESERVE:-0};
  320.         delete src_prefix;
  321.     }
  322.  
  323. EOF_AWK_DECODER
  324. exec 8<<'EOF_AWK_DECODER'
  325.  
  326.     ################################################## FUNCTIONS
  327.  
  328.     function escape(str) {
  329.         gsub(/'/, "&\\\\&&", str);
  330.         return str;
  331.     }
  332.  
  333.     function exists(path) {
  334.         return system(sprintf("[ -e '%s' ]", escape(path))) == 0;
  335.     }
  336.  
  337.     function isdir(path) {
  338.         return system(sprintf("[ -d '%s' ]", escape(path))) == 0;
  339.     }
  340.  
  341.     function chmod(mode, path) {
  342.         return system(sprintf("chmod %s '%s'", mode, escape(path)));
  343.     }
  344.  
  345.     function mkdir(path, mode, chdir)
  346.     {
  347.         cmd = "mkdir -p";
  348.         if (chdir = escape(chdir))
  349.             cmd = sprintf("cd '%s' 2>&- && %s", chdir, cmd);
  350.         if (mode = escape(mode))
  351.             cmd = sprintf("%s -m '%s'", cmd, mode);
  352.         cmd = sprintf("%s '%s'", cmd, escape(path));
  353.         return system(cmd);
  354.     }
  355.  
  356.     function reset_output() {
  357.         OUTPUT_CMD = OUTPUT_FILE = OUTPUT_MODE = "";
  358.         dump = 0;
  359.     }
  360.  
  361.     function target_perms(src_perms, isfile)
  362.     {
  363.         target_mode = "";
  364.  
  365.         # Validate quantity/quality of octal permissions
  366.         if (match(src_perms, /[0-7][0-7][0-7]+$/))
  367.             src_perms = substr(src_perms, RSTART);
  368.  
  369.         if (src_perms && preserve)
  370.             target_mode = src_perms;
  371.         else if (src_perms && isfile) {
  372.             # Carry over executable bits
  373.             n = split(src_perms, p, "");
  374.             if (p[n--] ~ /^[1357]$/) target_mode = target_mode "o";
  375.             if (p[n--] ~ /^[1357]$/) target_mode = target_mode "g";
  376.             if (p[n--] ~ /^[1357]$/) target_mode = target_mode "u";
  377.             if (target_mode) target_mode = target_mode "+x";
  378.         }
  379.  
  380.         return target_mode;
  381.     }
  382.  
  383.     function target_path(path)
  384.     {
  385.         target_prefix = INPUT_SRC ? src_prefix[INPUT_SRC] : "";
  386.         if (!target_prefix) {
  387.             target_prefix = prefix;
  388.             sub("/+$", "", target_prefix);
  389.             append = "";
  390.             if (isdir(target_prefix) || prefix ~ "/$") {
  391.                 if (INPUT_TYPE == "D") {
  392.                     src_name = INPUT_SRC;
  393.                     sub(/^[[:digit:]]+,/, "", src_name);
  394.                     gsub("^[^/]*/", "", src_name);
  395.                     append = "/" src_name;
  396.                 }
  397.             } else if (INPUT_TYPE == "F") {
  398.                 if (!exists(target_prefix)) {
  399.                     path = target_prefix;
  400.                     target_prefix = "";
  401.                 }
  402.             }
  403.             target_prefix = target_prefix append;
  404.             src_prefix[INPUT_SRC] = target_prefix;
  405.         }
  406.         sub("^\\./", "", path);
  407.         return target_prefix (target_prefix ? "/" : "") path;
  408.     }
  409.  
  410.     function prepare_directory(path, perms)
  411.     {
  412.         tpath = target_path(path);
  413.         sub("/\\.$", "", tpath);
  414.         sprefix = src_prefix[INPUT_SRC];
  415.         if (path == "." && !isdir(tpath)) {
  416.             gsub("^[^/]*/+", "", tpath);
  417.             sub("/+[^/]*$", "", sprefix);
  418.             chdir = "";
  419.             if (prefix ~ "/$" || isdir(sprefix))
  420.                 chdir = sprefix;
  421.             result = mkdir(tpath, perms, chdir);
  422.         } else if (isdir(tpath))
  423.             return (preserve ? chmod(perms, path) : 0);
  424.         else {
  425.             result = mkdir(path, perms, chdir = sprefix);
  426.         }
  427.         return result;
  428.     }
  429.  
  430.     function prepare_output(path, perms)
  431.     {
  432.         #
  433.         # This function reads the following globals:
  434.         #
  435.         #  INPUT_SRC    Part of base64 preamble for dest calculations
  436.         #
  437.         # and creates the following globals for referencing the output:
  438.         #
  439.         #  OUTPUT_FILE  Path to output file to be written
  440.         #  OUTPUT_MODE  chmod(1) mode to apply after writing file
  441.         #  OUTPUT_CMD   Command to write file (from base64 encoding)
  442.         #
  443.         reset_output();
  444.         OUTPUT_FILE = target_path(path);
  445.         OUTPUT_MODE = target_perms(perms, isfile = 1);
  446.         OUTPUT_CMD = sprintf("base64 -d - > '%s'",
  447.             escape(OUTPUT_FILE));
  448.     }
  449.  
  450.     function close_output()
  451.     {
  452.         success = (close(OUTPUT_CMD) == 0);
  453.         close(OUTPUT_FILE);
  454.         if (OUTPUT_FILE && success && !quiet) print OUTPUT_FILE;
  455.         if (OUTPUT_MODE && preserve) chmod(OUTPUT_MODE, OUTPUT_FILE);
  456.         reset_output();
  457.         INPUT_TYPE = INPUT_SRC = "";
  458.     }
  459.  
  460.     ################################################## MAIN
  461.  
  462.     # IPC/flow-control protocol
  463.     match($0, /^SEND_USER: /) {
  464.         print substr($0, local ? RSTART+RLENGTH : 0);
  465.     }
  466.     /^EOI: / { exit }
  467.  
  468.     # End of base64 encoded input
  469.     /^====/ { close_output() }
  470.  
  471.     # base64 encoded input
  472.     dump {
  473.         sub(/\r$/, "");
  474.         print | OUTPUT_CMD;
  475.     }
  476.  
  477.     # Preamble for base64 encoded input
  478.     match($0, /^(begin-|b64)source [A-Z] /) {
  479.         INPUT_TYPE = substr($0, RSTART + RLENGTH - 2, 1);
  480.         INPUT_SRC = substr($0, RSTART + RLENGTH);
  481.     }
  482.  
  483.     # Preamble for directory creation (with or without perms)
  484.     match($0, /^begin-dirent [0-7]+ /) {
  485.         # Capture permissions info ([0-7]+) and directory path
  486.         dir = substr($0, RSTART + RLENGTH);
  487.         perms = substr($0, 14);
  488.         sub(/\r$/, "", dir);
  489.         sub(/ .*/, "", perms);
  490.         prepare_directory(dir, perms);
  491.     }
  492.  
  493.     # Start of base64 encoded input
  494.     match($0, /^begin-base64 [0-7]+ /) {
  495.         # Capture permissions info ([0-7]+) and destination file path
  496.         file = substr($0, RSTART + RLENGTH);
  497.         perms = substr($0, 14);
  498.         sub(/\r$/, "", file);
  499.         sub(/ .*/, "", perms);
  500.         prepare_output(file, perms);
  501.         dump = 1;
  502.     }
  503.  
  504.     # DRYRUN processing (always on)
  505.     match($0, /^b64(en|de)code - /) {
  506.         file = substr($0, RSTART + RLENGTH);
  507.         sub(/\r$/, "", file);
  508.         prepare_output(file, perms = "");
  509.         print OUTPUT_FILE;
  510.         OUTPUT_FILE = "";
  511.     }
  512.  
  513.     END { close_output() }
  514.  
  515. EOF_AWK_DECODER
  516. AWK_DECODER_CMD=$(
  517.     program_text='
  518.         !/^[[:space:]]*(#|$)/ {
  519.             gsub(/\t/, d > 1 ? "    " : " ")
  520.             printf "%s" (d > 1 ? "\n" : ""), $0
  521.         } END { if (d < 2) printf "\n" }
  522.     ' # END-QUOTE
  523.     awk -v d="$DEBUG" "$program_text" <&9
  524.     awk -v d="$DEBUG" "$program_text" <&8
  525. )
  526.  
  527. #
  528. # Tcl/expect code for processing shell arguments ($@)
  529. #
  530. if [ "$TELNET" ]; then
  531.     spawn_cmd="telnet localhost"
  532. else
  533.     spawn_cmd="connect"
  534. fi
  535. exec 9<<EOF_EXPECT
  536.  
  537.     ################################################## PARENT GLOBALS
  538.  
  539.     set dryrun  ${DRYRUN:-0}
  540.     set quiet   ${QUIET:-0}
  541.     set recurse ${RECURSE:-0}
  542.     set spawn_cmd   "$spawn_cmd"
  543.     set prompt1 "${PROMPT1%%\"*}"
  544.     set prompt2 "${PROMPT2%%\"*}"
  545.  
  546. EOF_EXPECT
  547. exec 8<<'EOF_EXPECT'
  548.     ################################################## GLOBALS
  549.  
  550.     set timeout     300
  551.  
  552.     set sh_encoder_cmd  [lindex $argv 0]
  553.     set awk_decoder_cmd [lindex $argv 1]
  554.     set argv        [lreplace $argv 0 1]
  555.     set argc        [llength $argv]
  556.  
  557.     set argmax      [expr {$argc - 1}]
  558.     set lastarg     [lindex $argv $argmax]
  559.     set argv        [lreplace $argv $argmax $argmax]
  560.     set argc        [llength $argv]
  561.  
  562.     set cpos        [string first ":" $lastarg]
  563.     set cc          ""
  564.     set prefix      ""
  565.     if {$cpos >= 0} {
  566.         set cc      [string range $lastarg 0 [expr {$cpos-1}]]
  567.         set prefix  [string range $lastarg [expr {$cpos+1}] end]
  568.     }
  569.     if {$prefix == ""} {
  570.         set prefix  "."
  571.     }
  572.  
  573.     set awk_flags       {}
  574.     lappend awk_flags   " -v local=0"
  575.     lappend awk_flags   " -v prefix='$prefix'"
  576.     lappend awk_flags   " -v quiet='$quiet'"
  577.  
  578.     ################################################## MAIN
  579.  
  580.     # Validate arguments
  581.     if {$argc < 1} exit
  582.     if {$cc == ""} exit
  583.  
  584.     # Prepare decoder for remote injection
  585.     regsub -all {'} $awk_decoder_cmd {'\\''} awk_decoder_cmd
  586.     regsub {^\s*} $awk_decoder_cmd {} awk_decoder_cmd
  587.     regsub -all {\n} $awk_decoder_cmd {} awk_decoder_cmd
  588.  
  589.     fconfigure stdout -buffering none
  590.     spawn {*}$spawn_cmd $cc
  591.  
  592.     # Wait for available/dangling command prompt
  593.     expect -re {#\s+$} {
  594.         # Change to custom command/continuation prompts
  595.         send "PS1='$prompt1' PS2='$prompt2'\n"
  596.         send "\n"
  597.     }
  598.  
  599.     # Wait for customized command-prompt to inject awk(1) decoder
  600.     expect -re [subst -nocommands -nobackslashes {$prompt1$}] {
  601.         set awk_cmd "awk"
  602.         append awk_cmd [join $awk_flags " "]
  603.         append awk_cmd " '$awk_decoder_cmd'"
  604.  
  605.         #
  606.         # Run awk decoder in sub-shell that prefixes all
  607.         # + stdout messages with "SEND_USER: "
  608.         # + stderr messages with "SEND_ERROR: "
  609.         #
  610.         # NB: Allows remotely-running awk(1) code to get I/O
  611.         # past the AWK_TTY_CMD to user on appropriate fd
  612.         #
  613.         send "( exec 3<&1; $awk_cmd 2>&1 >&3 |"
  614.         send " awk 'sub(/^/, \"SEND_ERROR: \")' >&2"
  615.         send ") | awk 'sub(/^/, \"SEND_USER: \")'"
  616.  
  617.         # Send escaped newline to invoke continuation prompt
  618.         send " \\\n"
  619.     }
  620.  
  621.     # Wait for continuation prompt, start decoder, begin encoding
  622.     expect -re [subst -nocommands -nobackslashes {$prompt2$}] {
  623.         send "; exit\n" ; # exit shell after decoder completes
  624.         send [exec sh -c $sh_encoder_cmd /bin/sh $prefix 1 {*}$argv]
  625.         send "EOI: exiting.\n"
  626.     }
  627.  
  628.     expect eof
  629.  
  630. EOF_EXPECT
  631. EXPECT_CMD=$( cat <&9; cat <&8 )
  632.  
  633. #
  634. # Local awk for providing user feedback on attached terminal
  635. #
  636. AWK_TTY_CMD='
  637.     match($0, /^SEND_USER: /) { print substr($0, RSTART + RLENGTH) }
  638.     match($0, /^SEND_ERROR: /) {
  639.         print substr($0, RSTART + RLENGTH) > "/dev/stderr";
  640.     }
  641. ' # END-QUOTE
  642.  
  643. #
  644. # Interact with each path argument via expect(1)
  645. #
  646. debugfmt3="echo '\n%s\n\n' | expect -f- '\n%s\n' '\n%s\n' %s 2>&1"
  647. debugfmt2="$debugfmt3 | awk '\n%s\n'"
  648. if [ ${DEBUG:-0} -ge 3 ]; then
  649.     # Replace single-quotes (runnable via copy/paste or pipe to sh)
  650.     for var in EXPECT_CMD SH_ENCODER_CMD AWK_DECODER_CMD AWK_TTY_CMD; do
  651.         shell_escape $var
  652.     done
  653.     printf "$debugfmt3\n" "$EXPECT_CMD" \
  654.         "$SH_ENCODER_CMD" "$AWK_DECODER_CMD" "$*"
  655. elif [ ${DEBUG:-0} -ge 2 ]; then
  656.     # Replace single-quotes (runnable via copy/paste or pipe to sh)
  657.     for var in EXPECT_CMD SH_ENCODER_CMD AWK_DECODER_CMD AWK_TTY_CMD; do
  658.         shell_escape $var
  659.     done
  660.     printf "$debugfmt2\n" "$EXPECT_CMD" \
  661.         "$SH_ENCODER_CMD" "$AWK_DECODER_CMD" "$*" "$AWK_TTY_CMD"
  662. elif [ ${DEBUG:-0} -ge 1 ]; then
  663.     echo "$EXPECT_CMD" |
  664.         expect -f- "$SH_ENCODER_CMD" "$AWK_DECODER_CMD" "$@" 2>&1
  665. else
  666.     echo "$EXPECT_CMD" |
  667.         expect -f- "$SH_ENCODER_CMD" "$AWK_DECODER_CMD" "$@" 2>&1 |
  668.         awk "$AWK_TTY_CMD"
  669. fi
  670.  
  671. exit $SUCCESS
  672.  
  673. ################################################################################
  674. # END
  675. ################################################################################
  676. #
  677. # $Copyright: 2015 Devin Teske. All rights reserved. $
  678. #
  679. # $Header$
  680. #
  681. ################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement