From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9428 invoked from network); 4 Jul 2003 16:22:54 -0000 Received: from sunsite.dk (130.225.247.90) by ns1.primenet.com.au with SMTP; 4 Jul 2003 16:22:54 -0000 Received: (qmail 11594 invoked by alias); 4 Jul 2003 16:22:47 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 18810 Received: (qmail 11587 invoked from network); 4 Jul 2003 16:22:47 -0000 Received: from localhost (HELO sunsite.dk) (127.0.0.1) by localhost with SMTP; 4 Jul 2003 16:22:47 -0000 X-MessageWall-Score: 0 (sunsite.dk) Received: from [62.189.183.235] by sunsite.dk (MessageWall 1.0.8) with SMTP; 4 Jul 2003 16:22:46 -0000 Received: from EXCHANGE02.csr.com (unverified) by MAILSWEEPER01.cambridgesiliconradio.com (Content Technologies SMTPRS 4.3.10) with ESMTP id for ; Thu, 3 Jul 2003 17:22:17 +0100 Received: from csr.com ([192.168.144.127]) by EXCHANGE02.csr.com with Microsoft SMTPSVC(5.0.2195.5329); Fri, 4 Jul 2003 17:21:58 +0100 To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: TCP function improvements Date: Fri, 04 Jul 2003 17:22:43 +0100 Message-ID: <29247.1057335763@csr.com> From: Peter Stephenson X-OriginalArrivalTime: 04 Jul 2003 16:21:58.0454 (UTC) FILETIME=[644FDD60:01C34248] Here's an assortment of improvements to the TCP functions which I've been playing with (as well as using regularly). There are also one or two minor fixes I noticed. New functions tcp_point and tcp_shoot provide one-shot file transfer without any session. tcp_spam can take option -e to evaluate a line. tcp_on_read associative array provides pattern triggers on data read. %c in TCP prompts provides way of output different text for current or uncurrent sessions by using the ternary expression enhancement to the zformat builtin. SECONDS is used as floating point for greater timing accuracy. Use TCP_SECONDS_START to provide workaround if this makes global SECONDS invisible. Variables were incorrectly put into the function index. Sanity check for existing session in tcp_send. Index: Doc/Zsh/tcpsys.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/tcpsys.yo,v retrieving revision 1.3 diff -u -r1.3 tcpsys.yo --- Doc/Zsh/tcpsys.yo 25 Apr 2003 11:19:09 -0000 1.3 +++ Doc/Zsh/tcpsys.yo 4 Jul 2003 16:13:47 -0000 @@ -353,7 +353,7 @@ connections. It continues to accept new connections until interrupted. ) findex(tcp_spam) -item(tt(tcp_spam [-rtv] [ -a | -s ) var(sess) tt(| -l) var(sess)tt(,... ]) var(cmd) tt(...))( +item(tt(tcp_spam [-ertv] [ -a | -s ) var(sess) tt(| -l) var(sess)tt(,... ]) var(cmd) tt(...))( Execute `var(cmd) tt(...)' for each session in turn. Note this executes the command and arguments; it does not send the command line as data unless the tt(-t) (transmit) option is given. @@ -374,6 +374,9 @@ session. This is output after any modification to TCP_SESS by the user-defined tt(tcp_on_spam) function described below. (Obviously that function is able to generate its own output.) + +If the option tt(-e) is present, the line given as var(cmd ...) is executed +using tt(eval), otherwise it is executed without any further processing. ) findex(tcp_talk) item(tt(tcp_talk))( @@ -403,7 +406,33 @@ ) enditem() -sect(TCP User-defined Function) +subsect(`One-shot' file transfer) +startitem() +xitem(tt(tcp_point) var(port)) +item(tt(tcp_shoot) var(host) var(port))( +This pair of functions provide a simple way to transfer a file between +two hosts within the shell. Note, however, that bulk data transfer is +currently done using tt(cat). tt(tcp_point) reads any data arriving at +var(port) and sends it to standard output; tt(tcp_shoot) connects to +var(port) on var(host) and sends its standard input. Any unused var(port) +may be used; the standard mechanism for picking a port is to think of a +random four-digit number above 1024 until one works. + +To transfer a file from host tt(woodcock) to host tt(springes), on +tt(springes): + +example(tcp_point 8091 >output_file) + +and on tt(woodcock): + +example(tcp_shoot springes 8091 &2 + return 1 +fi + +local REPLY lfd afd +if ! ztcp -l $1; then + print "Failed to listen on port $1" >&2 + return 1 +fi + +lfd=$REPLY + +if ! ztcp -a $lfd; then + print "Failed to accept on fd $lfd" >&2 + ztcp -c $lfd +fi + +afd=$REPLY + +cat <&$afd + +ztcp -c $lfd +ztcp -c $afd Index: Functions/TCP/tcp_read =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/TCP/tcp_read,v retrieving revision 1.2 diff -u -r1.2 tcp_read --- Functions/TCP/tcp_read 25 Apr 2003 11:19:10 -0000 1.2 +++ Functions/TCP/tcp_read 4 Jul 2003 16:13:47 -0000 @@ -60,7 +60,7 @@ zmodload -i zsh/mathfunc -local opt drain line quiet block read_fd all sess +local opt drain line quiet block read_fd all sess key val local -A read_fds read_fds=() float timeout timeout_all endtime @@ -139,8 +139,12 @@ local helper_stat=2 skip tpat reply REPLY float newtimeout -# Get extra accuracy by making SECONDS floating point locally -typeset -F SECONDS +if [[ ${(t)SECONDS} != float* ]]; then + # If called from another function, don't override + typeset -F TCP_SECONDS_START=$SECONDS + # Get extra accuracy by making SECONDS floating point locally + typeset -F SECONDS +fi if (( timeout_all )); then (( endtime = SECONDS + timeout_all )) @@ -194,11 +198,23 @@ helper_stat=0 sess=${tcp_by_fd[$read_fd]} - tcp_output -P "${TCP_PROMPT:=<-[%s] }" -S $sess -F $read_fd \ + tcp_output -P "${TCP_PROMPT=<-[%s] }" -S $sess -F $read_fd \ ${TCP_SILENT:+-q} "$line" # REPLY is now set to the line with an appropriate prompt. tcp_lines+=($REPLY) TCP_LINE=$REPLY TCP_LINE_FD=$read_fd + + # Handle user-defined triggers + if (( ${+tcp_on_read} )); then + # Call the function given in the key for each matching value. + # It is this way round because function names must be + # unique, while patterns do not need to be. Furthermore, + # this keeps the use of subscripting under control. + for key val in ${(kv)tcp_on_read}; do + [[ $line = ${~val} ]] && $key "$sess" "$line" + done + fi + # Only handle one line from one device at a time unless draining. [[ -z $drain ]] && return $stat done Index: Functions/TCP/tcp_send =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/TCP/tcp_send,v retrieving revision 1.1 diff -u -r1.1 tcp_send --- Functions/TCP/tcp_send 6 Feb 2003 12:21:51 -0000 1.1 +++ Functions/TCP/tcp_send 4 Jul 2003 16:13:47 -0000 @@ -3,6 +3,7 @@ local opt quiet all sess fd nonewline local -a sessions write_fds +integer mystat while getopts "al:nqs:" opt; do case $opt in @@ -56,6 +57,11 @@ for TCP_SESS in $sessions; do fd=${tcp_by_name[$TCP_SESS]} + if [[ -z $fd ]]; then + print "No such session: $TCP_SESS" >&2 + mystat=1 + continue + fi print $nonewline -r -- $* >&$fd if [[ $? -ne 0 || -n $TCP_FD_CLOSED ]]; then print "Session ${TCP_SESS}: fd $fd unusable." >&2 @@ -65,3 +71,5 @@ tcp_output -P "$TCP_OUTPUT" -S $TCP_SESS -F $fd -q "${(j. .)*}" fi done + +return $mystat Index: Functions/TCP/tcp_shoot =================================================================== RCS file: Functions/TCP/tcp_shoot diff -N Functions/TCP/tcp_shoot --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Functions/TCP/tcp_shoot 4 Jul 2003 16:13:47 -0000 @@ -0,0 +1,21 @@ +emulate -L zsh +setopt extendedglob + +local REPLY tfd + +if [[ $# -ne 2 ]]; then + print "Usage: tcp_dump host port +Connect to the given host and port; send standard input.">&2 + return 1 +fi + +if ! ztcp $1 $2; then + print "Failed to open connection to host $1 port $2" >&2 + return 1 +fi + +tfd=$REPLY + +cat >&$tfd + +ztcp -c $tfd Index: Functions/TCP/tcp_spam =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/TCP/tcp_spam,v retrieving revision 1.4 diff -u -r1.4 tcp_spam --- Functions/TCP/tcp_spam 2 May 2003 10:59:07 -0000 1.4 +++ Functions/TCP/tcp_spam 4 Jul 2003 16:13:47 -0000 @@ -4,6 +4,8 @@ # If not given and tcp_spam_list is set to a list of sessions, # only those will be spammed. If tcp_no_spam_list is set, those # will (also) be excluded from spamming. +# -e use `eval' to run the command list instead of executing as +# a normal command line. # -l sess1,sess2 give comma separated list of sessions to spam # -r reverse, spam in opposite order (default is alphabetic, -r means # omegapsiic). Note tcp_spam_list is not sorted (but may be reversed). @@ -19,14 +21,17 @@ emulate -L zsh setopt extendedglob -local TCP_SESS cmd opt verbose reverse sesslist transmit all +local cursess=$TCP_SESS sessstr +local TCP_SESS cmd opt verbose reverse sesslist transmit all eval local match mbegin mend REPLY local -a sessions -while getopts "al:rtv" opt; do +while getopts "ael:rtv" opt; do case $opt in (a) all=1 ;; + (e) eval=1 + ;; (l) sessions+=(${(s.,.)OPTARG}) ;; (r) reverse=1 @@ -82,7 +87,7 @@ if [[ -n $transmit ]]; then cmd=tcp_send -else +elif [[ -z $eval ]]; then cmd=$1 shift fi @@ -95,7 +100,18 @@ tcp_on_spam $TCP_SESS $cmd $* [[ $REPLY = done ]] && continue fi - [[ -n $verbose ]] && zformat -f REPLY $TCP_PROMPT "s:$TCP_SESS" \ - "f:${tcp_by_name[$TCP_SESS]}" && print -r $REPLY - eval $cmd '$*' + if [[ -n $verbose ]]; then + if [[ $TCP_SESS = $cursess ]]; then + sessstr="c:1" + else + sessstr="c:0" + fi + zformat -f REPLY $TCP_PROMPT "s:$TCP_SESS" \ + "f:${tcp_by_name[$TCP_SESS]}" $sessstr && print -r $REPLY + fi + if [[ -n $eval ]]; then + eval $* + else + eval $cmd '$*' + fi done Index: Functions/TCP/tcp_wait =================================================================== RCS file: /cvsroot/zsh/zsh/Functions/TCP/tcp_wait,v retrieving revision 1.1 diff -u -r1.1 tcp_wait --- Functions/TCP/tcp_wait 6 Feb 2003 12:21:51 -0000 1.1 +++ Functions/TCP/tcp_wait 4 Jul 2003 16:13:47 -0000 @@ -1,7 +1,14 @@ # Wait for given number of seconds, reading any data from # all TCP connections while doing so. -typeset -F SECONDS to end +if [[ ${(t)SECONDS} != float* ]]; then + # If called from tcp_expect, don't override + typeset -F TCP_SECONDS_START=$SECONDS + # Get extra accuracy by making SECONDS floating point locally + typeset -F SECONDS +fi + +typeset to end (( to = $1, end = SECONDS + to )) while (( SECONDS < end )); do -- Peter Stephenson Software Engineer CSR Ltd., Science Park, Milton Road, Cambridge, CB4 0WH, UK Tel: +44 (0)1223 692070 ********************************************************************** The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer. **********************************************************************