From 5c1f3b65a6f5abeae8459f41adb8fd2316971515 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 6 Feb 2003 12:21:49 +0000 Subject: 18202: New TCP function system plus small error message change in ztcp. --- Functions/TCP/tcp_expect | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Functions/TCP/tcp_expect (limited to 'Functions/TCP/tcp_expect') diff --git a/Functions/TCP/tcp_expect b/Functions/TCP/tcp_expect new file mode 100644 index 000000000..14963a3e6 --- /dev/null +++ b/Functions/TCP/tcp_expect @@ -0,0 +1,115 @@ +# Expect one of a series of regular expressions from $TCP_SESS. +# Can make backreferences to be handled by $match. Returns 0 for +# successful match, 1 for error, 2 for timeout. +# +# This function has no facility for conditionally calling code based +# the regular expression found. This should be done in the calling code +# by testing $TCP_LINE, which contains the line which matched the +# regular expression. The complete set of lines read while waiting for +# this line is available in the array $tcp_expect_lines (including $TCP_LINE +# itself which will be the final element). Alternatively, use -p pind +# which sets $pind to the index of the pattern which matched. It +# will be set to 0 otherwise. +# +# Many of the options are passed straight down to tcp_read. +# +# Options: +# -a Run tcp_expect across all sessions; the first pattern matched +# from any session is used. The TCP output prompt can be +# used to decide which session matched. +# -l list +# Comma-separated list of sessions as for tcp_read. +# -p pv If the Nth of a series of patterns matches, set the parameter +# whose name is given by $pv to N; in the case of a timeout, +# set it to -1; otherwise (unless the function exited prematurely), +# set it to 0. +# To avoid namespace clashes, the parameter's name must +# not begin with `_expect'. +# -q Quiet, passed down to tcp_read. Bad option and argument +# usage is always reported. +# -s sess +# Expect from session sess. May be repeated for multiple sessions. +# -t to Timeout in seconds (may be floating point) per read operation. +# tcp_expect will only time out if every read operation takes longer +# than to +# -T TO Overall timeout; tcp_expect will time out if the overall operation +# takes longer than this many seconds. +emulate -L zsh +setopt extendedglob + +# Get extra accuracy by making SECONDS floating point locally +typeset -F SECONDS + +# Variables are all named _expect_* to avoid problems with the -p param. +local _expect_opt _expect_pvar +local -a _expect_read_args +float _expect_to1 _expect_to_all _expect_to _expect_new_to +integer _expect_i _expect_stat + +while getopts "al:p:qs:t:T:" _expect_opt; do + case $_expect_opt in + (a) _expect_read_args+=(-a) + ;; + (l) _expect_read_args+=(-l $OPTARG) + ;; + (p) _expect_pvar=$OPTARG + if [[ $_expect_pvar != [a-zA-Z_][a-zA-Z_0-9]# ]]; then + print "invalid parameter name: $_expect_pvar" >&2 + return 1 + fi + if [[ $_expect_pvar = _expect* ]]; then + print "$0: parameter names staring \`_expect' are reserved." + return 1 + fi + eval "$_expect_pvar=0" + ;; + (q) _expect_read_args+=(-q) + ;; + (s) _expect_read_args+=(-s $OPTARG) + ;; + (t) _expect_to1=$OPTARG + ;; + (T) _expect_to_all=$(( SECONDS + $OPTARG )) + ;; + (\?) return 1 + ;; + (*) print Unhandled option $_expect_opt, complain >&2 + return 1 + ;; + esac +done +(( OPTIND > 1 )) && shift $(( OPTIND - 1 )) + +tcp_expect_lines=() +while true; do + if (( _expect_to_all || _expect_to1 )); then + _expect_to=0 + (( _expect_to1 )) && (( _expect_to = _expect_to1 )) + if (( _expect_to_all )); then + # overall timeout, see if it has already triggered + if (( (_expect_new_to = (_expect_to_all - SECONDS)) <= 0 )); then + [[ -n $_expect_pvar ]] && eval "$_expect_pvar=-1" + return 2 + fi + if (( _expect_to <= 0 || _expect_new_to < _expect_to )); then + _expect_to=$_expect_new_to + fi + fi + tcp_read $_expect_read_args -t $_expect_to + _expect_stat=$? + else + tcp_read $_expect_read_args -b + _expect_stat=$? + fi + if (( _expect_stat )); then + [[ -n $_expect_pvar ]] && eval "$_expect_pvar=-1" + return $_expect_stat + fi + tcp_expect_lines+=($TCP_LINE) + for (( _expect_i = 1; _expect_i <= $#; _expect_i++ )); do + if [[ "$TCP_LINE" = ${~argv[_expect_i]} ]]; then + [[ -n $_expect_pvar ]] && eval "$_expect_pvar=\$_expect_i" + return 0 + fi + done +done -- cgit 1.4.1