.TH "ZSHTCPSYS" "1" "May 14, 2022" "zsh 5\&.9" .SH "NAME" zshtcpsys \- zsh tcp system .\" Yodl file: Zsh/tcpsys.yo .SH "DESCRIPTION" .PP A module \fBzsh/net/tcp\fP is provided to provide network I/O over TCP/IP from within the shell; see its description in \fIzshmodules\fP(1)\&. This manual page describes a function suite based on the module\&. If the module is installed, the functions are usually installed at the same time, in which case they will be available for autoloading in the default function search path\&. In addition to the \fBzsh/net/tcp\fP module, the \fBzsh/zselect\fP module is used to implement timeouts on read operations\&. For troubleshooting tips, consult the corresponding advice for the \fBzftp\fP functions described in \fIzshzftpsys\fP(1)\&. .PP There are functions corresponding to the basic I/O operations open, close, read and send, named \fBtcp_open\fP etc\&., as well as a function \fBtcp_expect\fP for pattern match analysis of data read as input\&. The system makes it easy to receive data from and send data to multiple named sessions at once\&. In addition, it can be linked with the shell\&'s line editor in such a way that input data is automatically shown at the terminal\&. Other facilities available including logging, filtering and configurable output prompts\&. .PP To use the system where it is available, it should be enough to `\fBautoload \-U tcp_open\fP\&' and run \fBtcp_open\fP as documented below to start a session\&. The \fBtcp_open\fP function will autoload the remaining functions\&. .PP .PP .SH "TCP USER FUNCTIONS" .PP .SS "Basic I/O" .PP .PD 0 .TP .PD 0 \fBtcp_open\fP [ \fB\-qz\fP ] \fIhost port\fP [ \fIsess\fP ] .TP .PD 0 \fBtcp_open\fP [ \fB\-qz\fP ] [ \fB\-s\fP \fIsess\fP | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] ] \&.\&.\&. .TP .PD \fBtcp_open\fP [ \fB\-qz\fP ] [ \fB\-a\fP \fIfd\fP | \fB\-f\fP \fIfd\fP ] [ \fIsess\fP ] Open a new session\&. In the first and simplest form, open a TCP connection to host \fIhost\fP at port \fIport\fP; numeric and symbolic forms are understood for both\&. .RS .PP If \fIsess\fP is given, this becomes the name of the session which can be used to refer to multiple different TCP connections\&. If \fIsess\fP is not given, the function will invent a numeric name value (note this is \fInot\fP the same as the file descriptor to which the session is attached)\&. It is recommended that session names not include `funny\&' characters, where funny characters are not well\-defined but certainly do not include alphanumerics or underscores, and certainly do include whitespace\&. .PP In the second case, one or more sessions to be opened are given by name\&. A single session name is given after \fB\-s\fP and a comma\-separated list after \fB\-l\fP; both options may be repeated as many times as necessary\&. A failure to open any session causes \fBtcp_open\fP to abort\&. The host and port are read from the file \fB\&.ztcp_sessions\fP in the same directory as the user\&'s zsh initialisation files, i\&.e\&. usually the home directory, but \fB$ZDOTDIR\fP if that is set\&. The file consists of lines each giving a session name and the corresponding host and port, in that order (note the session name comes first, not last), separated by whitespace\&. .PP The third form allows passive and fake TCP connections\&. If the option \fB\-a\fP is used, its argument is a file descriptor open for listening for connections\&. No function front\-end is provided to open such a file descriptor, but a call to `\fBztcp \-l\fP \fIport\fP\&' will create one with the file descriptor stored in the parameter \fB$REPLY\fP\&. The listening port can be closed with `\fBztcp \-c\fP \fIfd\fP\&'\&. A call to `\fBtcp_open \-a\fP \fIfd\fP' will block until a remote TCP connection is made to \fIport\fP on the local machine\&. At this point, a session is created in the usual way and is largely indistinguishable from an active connection created with one of the first two forms\&. .PP If the option \fB\-f\fP is used, its argument is a file descriptor which is used directly as if it were a TCP session\&. How well the remainder of the TCP function system copes with this depends on what actually underlies this file descriptor\&. A regular file is likely to be unusable; a FIFO (pipe) of some sort will work better, but note that it is not a good idea for two different sessions to attempt to read from the same FIFO at once\&. .PP If the option \fB\-q\fP is given with any of the three forms, \fBtcp_open\fP will not print informational messages, although it will in any case exit with an appropriate status\&. .PP If the line editor (zle) is in use, which is typically the case if the shell is interactive, \fBtcp_open\fP installs a handler inside zle which will check for new data at the same time as it checks for keyboard input\&. This is convenient as the shell consumes no CPU time while waiting; the test is performed by the operating system\&. Giving the option \fB\-z\fP to any of the forms of \fBtcp_open\fP prevents the handler from being installed, so data must be read explicitly\&. Note, however, this is not necessary for executing complete sets of send and read commands from a function, as zle is not active at this point\&. Generally speaking, the handler is only active when the shell is waiting for input at a command prompt or in the \fBvared\fP builtin\&. The option has no effect if zle is not active; `\fB[[ \-o zle]]\fP\&' will test for this\&. .PP The first session to be opened becomes the current session and subsequent calls to \fBtcp_open\fP do not change it\&. The current session is stored in the parameter \fB$TCP_SESS\fP; see below for more detail about the parameters used by the system\&. .PP The function \fBtcp_on_open\fP, if defined, is called when a session is opened\&. See the description below\&. .RE .TP \fBtcp_close\fP [ \fB\-qn\fP ] [ \fB\-a\fP | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] | \fIsess\fP \&.\&.\&. ] Close the named sessions, or the current session if none is given, or all open sessions if \fB\-a\fP is given\&. The options \fB\-l\fP and \fB\-s\fP are both handled for consistency with \fBtcp_open\fP, although the latter is redundant\&. .RS .PP If the session being closed is the current one, \fB$TCP_SESS\fP is unset, leaving no current session, even if there are other sessions still open\&. .PP If the session was opened with \fBtcp_open \-f\fP, the file descriptor is closed so long as it is in the range 0 to 9 accessible directly from the command line\&. If the option \fB\-n\fP is given, no attempt will be made to close file descriptors in this case\&. The \fB\-n\fP option is not used for genuine \fBztcp\fP session; the file descriptors are always closed with the session\&. .PP If the option \fB\-q\fP is given, no informational messages will be printed\&. .RE .TP .PD 0 \fBtcp_read \fP[ \fB\-bdq\fP ] [ \fB\-t\fP \fITO\fP ] [ \fB\-T\fP \fITO\fP ] .TP .PD \fB \fP[ \fB\-a\fP | \fB\-u\fP \fIfd\fP[\fB,\fP\&.\&.\&.] | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] | \fB\-s\fP \fIsess\fP \&.\&.\&. ] Perform a read operation on the current session, or on a list of sessions if any are given with \fB\-u\fP, \fB\-l\fP or \fB\-s\fP, or all open sessions if the option \fB\-a\fP is given\&. Any of the \fB\-u\fP, \fB\-l\fP or \fB\-s\fP options may be repeated or mixed together\&. The \fB\-u\fP option specifies a file descriptor directly (only those managed by this system are useful), the other two specify sessions as described for \fBtcp_open\fP above\&. .RS .PP The function checks for new data available on all the sessions listed\&. Unless the \fB\-b\fP option is given, it will not block waiting for new data\&. Any one line of data from any of the available sessions will be read, stored in the parameter \fB$TCP_LINE\fP, and displayed to standard output unless \fB$TCP_SILENT\fP contains a non\-empty string\&. When printed to standard output the string \fB$TCP_PROMPT\fP will be shown at the start of the line; the default form for this includes the name of the session being read\&. See below for more information on these parameters\&. In this mode, \fBtcp_read\fP can be called repeatedly until it returns status 2 which indicates all pending input from all specified sessions has been handled\&. .PP With the option \fB\-b\fP, equivalent to an infinite timeout, the function will block until a line is available to read from one of the specified sessions\&. However, only a single line is returned\&. .PP The option \fB\-d\fP indicates that all pending input should be drained\&. In this case \fBtcp_read\fP may process multiple lines in the manner given above; only the last is stored in \fB$TCP_LINE\fP, but the complete set is stored in the array \fB$tcp_lines\fP\&. This is cleared at the start of each call to \fBtcp_read\fP\&. .PP The options \fB\-t\fP and \fB\-T\fP specify a timeout in seconds, which may be a floating point number for increased accuracy\&. With \fB\-t\fP the timeout is applied before each line read\&. With \fB\-T\fP, the timeout applies to the overall operation, possibly including multiple read operations if the option \fB\-d\fP is present; without this option, there is no distinction between \fB\-t\fP and \fB\-T\fP\&. .PP The function does not print informational messages, but if the option \fB\-q\fP is given, no error message is printed for a non\-existent session\&. .PP A return status of 2 indicates a timeout or no data to read\&. Any other non\-zero return status indicates some error condition\&. .PP See \fBtcp_log\fP for how to control where data is sent by \fBtcp_read\fP\&. .RE .TP .PD 0 \fBtcp_send\fP [ \fB\-cnq\fP ] [ \fB\-s\fP \fIsess\fP | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] ] \fIdata\fP \&.\&.\&. .TP .PD \fBtcp_send\fP [ \fB\-cnq\fP ] \fB\-a\fP \fIdata\fP \&.\&.\&. Send the supplied data strings to all the specified sessions in turn\&. The underlying operation differs little from a `\fBprint \-r\fP\&' to the session's file descriptor, although it attempts to prevent the shell from dying owing to a \fBSIGPIPE\fP caused by an attempt to write to a defunct session\&. .RS .PP The option \fB\-c\fP causes \fBtcp_send\fP to behave like \fBcat\fP\&. It reads lines from standard input until end of input and sends them in turn to the specified session(s) exactly as if they were given as \fIdata\fP arguments to individual \fBtcp_send\fP commands\&. .PP The option \fB\-n\fP prevents \fBtcp_send\fP from putting a newline at the end of the data strings\&. .PP The remaining options all behave as for \fBtcp_read\fP\&. .PP The data arguments are not further processed once they have been passed to \fBtcp_send\fP; they are simply passed down to \fBprint \-r\fP\&. .PP If the parameter \fB$TCP_OUTPUT\fP is a non\-empty string and logging is enabled then the data sent to each session will be echoed to the log file(s) with \fB$TCP_OUTPUT\fP in front where appropriate, much in the manner of \fB$TCP_PROMPT\fP\&. .RE .PP .SS "Session Management" .PP .PD 0 .TP .PD 0 \fBtcp_alias\fP [ \fB\-q\fP ] \fIalias\fP\fB=\fP\fIsess\fP \&.\&.\&. .TP .PD 0 \fBtcp_alias\fP [ \fB\-q\fP ] [ \fIalias\fP \&.\&.\&. ] .TP .PD \fBtcp_alias\fP \fB\-d\fP [ \fB\-q\fP ] \fIalias\fP \&.\&.\&. This function is not particularly well tested\&. .RS .PP The first form creates an alias for a session name; \fIalias\fP can then be used to refer to the existing session \fIsess\fP\&. As many aliases may be listed as required\&. .PP The second form lists any aliases specified, or all aliases if none\&. .PP The third form deletes all the aliases listed\&. The underlying sessions are not affected\&. .PP The option \fB\-q\fP suppresses an inconsistently chosen subset of error messages\&. .RE .TP \fBtcp_log\fP [ \fB\-asc\fP ] [ \fB\-n\fP | \fB\-N\fP ] [ \fIlogfile\fP ] With an argument \fIlogfile\fP, all future input from \fBtcp_read\fP will be logged to the named file\&. Unless \fB\-a\fP (append) is given, this file will first be truncated or created empty\&. With no arguments, show the current status of logging\&. .RS .PP With the option \fB\-s\fP, per\-session logging is enabled\&. Input from \fBtcp_read\fP is output to the file \fIlogfile\fP\fB\&.\fP\fIsess\fP\&. As the session is automatically discriminated by the filename, the contents are raw (no \fB$TCP_PROMPT\fP)\&. The option \fB\-a\fP applies as above\&. Per\-session logging and logging of all data in one file are not mutually exclusive\&. .PP The option \fB\-c\fP closes all logging, both complete and per\-session logs\&. .PP The options \fB\-n\fP and \fB\-N\fP respectively turn off or restore output of data read by \fBtcp_read\fP to standard output; hence `\fBtcp_log \-cn\fP\&' turns off all output by \fBtcp_read\fP\&. .PP The function is purely a convenient front end to setting the parameters \fB$TCP_LOG\fP, \fB$TCP_LOG_SESS\fP, \fB$TCP_SILENT\fP, which are described below\&. .RE .TP \fBtcp_rename\fP \fIold\fP \fInew\fP Rename session \fIold\fP to session \fInew\fP\&. The old name becomes invalid\&. .TP \fBtcp_sess\fP [ \fIsess\fP [ \fIcommand\fP [ \fIarg\fP \&.\&.\&. ] ] ] With no arguments, list all the open sessions and associated file descriptors\&. The current session is marked with a star\&. For use in functions, direct access to the parameters \fB$tcp_by_name\fP, \fB$tcp_by_fd\fP and \fB$TCP_SESS\fP is probably more convenient; see below\&. .RS .PP With a \fIsess\fP argument, set the current session to \fIsess\fP\&. This is equivalent to changing \fB$TCP_SESS\fP directly\&. .PP With additional arguments, temporarily set the current session while executing `\fIcommand\fP \fIarg\fP \&.\&.\&.\&'\&. \fIcommand\fP is re\-evaluated so as to expand aliases etc\&., but the remaining \fIarg\fPs are passed through as that appear to \fBtcp_sess\fP\&. The original session is restored when \fBtcp_sess\fP exits\&. .RE .PP .SS "Advanced I/O" .PP .PD 0 .TP .PD \fBtcp_command\fP \fIsend\-option\fP \&.\&.\&. \fIsend\-argument\fP \&.\&.\&. This is a convenient front\-end to \fBtcp_send\fP\&. All arguments are passed to \fBtcp_send\fP, then the function pauses waiting for data\&. While data is arriving at least every \fB$TCP_TIMEOUT\fP (default 0\&.3) seconds, data is handled and printed out according to the current settings\&. Status 0 is always returned\&. .RS .PP This is generally only useful for interactive use, to prevent the display becoming fragmented by output returned from the connection\&. Within a programme or function it is generally better to handle reading data by a more explicit method\&. .RE .TP .PD 0 \fBtcp_expect \fP[ \fB\-q\fP ] [ \fB\-p\fP \fIvar\fP | \fB\-P\fP \fIvar\fP ] [ \fB\-t\fP \fITO\fP | \fB\-T\fP \fITO\fP ] .TP .PD \fB \fP[ \fB\-a\fP | \fB\-s\fP \fIsess\fP | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] ] \fIpattern\fP \&.\&.\&. Wait for input matching any of the given \fIpattern\fPs from any of the specified sessions\&. Input is ignored until an input line matches one of the given patterns; at this point status zero is returned, the matching line is stored in \fB$TCP_LINE\fP, and the full set of lines read during the call to \fBtcp_expect\fP is stored in the array \fB$tcp_expect_lines\fP\&. .RS .PP Sessions are specified in the same way as \fBtcp_read\fP: the default is to use the current session, otherwise the sessions specified by \fB\-a\fP, \fB\-s\fP, or \fB\-l\fP are used\&. .PP Each \fIpattern\fP is a standard zsh extended\-globbing pattern; note that it needs to be quoted to avoid it being expanded immediately by filename generation\&. It must match the full line, so to match a substring there must be a `\fB*\fP\&' at the start and end\&. The line matched against includes the \fB$TCP_PROMPT\fP added by \fBtcp_read\fP\&. It is possible to include the globbing flags `\fB#b\fP\&' or `\fB#m\fP' in the patterns to make backreferences available in the parameters \fB$MATCH\fP, \fB$match\fP, etc\&., as described in the base zsh documentation on pattern matching\&. .PP Unlike \fBtcp_read\fP, the default behaviour of \fBtcp_expect\fP is to block indefinitely until the required input is found\&. This can be modified by specifying a timeout with \fB\-t\fP or \fB\-T\fP; these function as in \fBtcp_read\fP, specifying a per\-read or overall timeout, respectively, in seconds, as an integer or floating\-point number\&. As \fBtcp_read\fP, the function returns status 2 if a timeout occurs\&. .PP The function returns as soon as any one of the patterns given match\&. If the caller needs to know which of the patterns matched, the option \fB\-p\fP \fIvar\fP can be used; on return, \fB$var\fP is set to the number of the pattern using ordinary zsh indexing, i\&.e\&. the first is 1, and so on\&. Note the absence of a `\fB$\fP\&' in front of \fIvar\fP\&. To avoid clashes, the parameter cannot begin with `\fB_expect\fP\&'\&. The index \-1 is used if there is a timeout and 0 if there is no match\&. .PP The option \fB\-P\fP \fIvar\fP works similarly to \fB\-p\fP, but instead of numerical indexes the regular arguments must begin with a prefix followed by a colon: that prefix is then used as a tag to which \fIvar\fP is set when the argument matches\&. The tag \fBtimeout\fP is used if there is a timeout and the empty string if there is no match\&. Note it is acceptable for different arguments to start with the same prefix if the matches do not need to be distinguished\&. .PP The option \fB\-q\fP is passed directly down to \fBtcp_read\fP\&. .PP As all input is done via \fBtcp_read\fP, all the usual rules about output of lines read apply\&. One exception is that the parameter \fB$tcp_lines\fP will only reflect the line actually matched by \fBtcp_expect\fP; use \fB$tcp_expect_lines\fP for the full set of lines read during the function call\&. .RE .TP \fBtcp_proxy\fP This is a simple\-minded function to accept a TCP connection and execute a command with I/O redirected to the connection\&. Extreme caution should be taken as there is no security whatsoever and this can leave your computer open to the world\&. Ideally, it should only be used behind a firewall\&. .RS .PP The first argument is a TCP port on which the function will listen\&. .PP The remaining arguments give a command and its arguments to execute with standard input, standard output and standard error redirected to the file descriptor on which the TCP session has been accepted\&. If no command is given, a new zsh is started\&. This gives everyone on your network direct access to your account, which in many cases will be a bad thing\&. .PP The command is run in the background, so \fBtcp_proxy\fP can then accept new connections\&. It continues to accept new connections until interrupted\&. .RE .TP \fBtcp_spam\fP [ \fB\-ertv\fP ] [ \fB\-a\fP | \fB\-s\fP \fIsess\fP | \fB\-l\fP \fIsess\fP[\fB,\fP\&.\&.\&.] ] \fIcmd\fP [ \fIarg\fP \&.\&.\&. ] Execute `\fIcmd\fP [ \fIarg\fP \&.\&.\&. ]\&' for each session in turn\&. Note this executes the command and arguments; it does not send the command line as data unless the \fB\-t\fP (transmit) option is given\&. .RS .PP The sessions may be selected explicitly with the standard \fB\-a\fP, \fB\-s\fP or \fB\-l\fP options, or may be chosen implicitly\&. If none of the three options is given the rules are: first, if the array \fB$tcp_spam_list\fP is set, this is taken as the list of sessions, otherwise all sessions are taken\&. Second, any sessions given in the array \fB$tcp_no_spam_list\fP are removed from the list of sessions\&. .PP Normally, any sessions added by the `\fB\-a\fP\&' flag or when all sessions are chosen implicitly are spammed in alphabetic order; sessions given by the \fB$tcp_spam_list\fP array or on the command line are spammed in the order given\&. The \fB\-r\fP flag reverses the order however it was arrived it\&. .PP The \fB\-v\fP flag specifies that a \fB$TCP_PROMPT\fP will be output before each session\&. This is output after any modification to \fBTCP_SESS\fP by the user\-defined \fBtcp_on_spam\fP function described below\&. (Obviously that function is able to generate its own output\&.) .PP If the option \fB\-e\fP is present, the line given as `\fIcmd\fP [ \fIarg\fP \&.\&.\&. ]\&' is executed using \fBeval\fP, otherwise it is executed without any further processing\&. .RE .TP \fBtcp_talk\fP This is a fairly simple\-minded attempt to force input to the line editor to go straight to the default \fBTCP_SESS\fP\&. .RS .PP An escape string, \fB$TCP_TALK_ESCAPE\fP, default `\fB:\fP\&', is used to allow access to normal shell operation\&. If it is on its own at the start of the line, or followed only by whitespace, the line editor returns to normal operation\&. Otherwise, the string and any following whitespace are skipped and the remainder of the line executed as shell input without any change of the line editor\&'s operating mode\&. .PP The current implementation is somewhat deficient in terms of use of the command history\&. For this reason, many users will prefer to use some form of alternative approach for sending data easily to the current session\&. One simple approach is to alias some special character (such as `\fB%\fP\&') to `\fBtcp_command \-\fP\fB\-\fP\&'\&. .RE .TP \fBtcp_wait\fP The sole argument is an integer or floating point number which gives the seconds to delay\&. The shell will do nothing for that period except wait for input on all TCP sessions by calling \fBtcp_read \-a\fP\&. This is similar to the interactive behaviour at the command prompt when zle handlers are installed\&. .PP .SS "`One\-shot\&' file transfer" .PD 0 .TP .PD 0 \fBtcp_point\fP \fIport\fP .TP .PD \fBtcp_shoot\fP \fIhost\fP \fIport\fP 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 \fBcat\fP\&. \fBtcp_point\fP reads any data arriving at \fIport\fP and sends it to standard output; \fBtcp_shoot\fP connects to \fIport\fP on \fIhost\fP and sends its standard input\&. Any unused \fIport\fP may be used; the standard mechanism for picking a port is to think of a random four\-digit number above 1024 until one works\&. .RS .PP To transfer a file from host \fBwoodcock\fP to host \fBspringes\fP, on \fBspringes\fP: .PP .RS .nf \fBtcp_point 8091 >output_file\fP .fi .RE .PP and on \fBwoodcock\fP: .PP .RS .nf \fBtcp_shoot springes 8091