1# SPAM is a registered trademark of Hormel Foods Corporation.
2#
3# -a all connections, override $tcp_spam_list and $tcp_no_spam_list.
4#    If not given and tcp_spam_list is set to a list of sessions,
5#    only those will be spammed.  If tcp_no_spam_list is set, those
6#    will (also) be excluded from spamming.
7# -e use `eval' to run the command list instead of executing as
8#    a normal command line.
9# -l sess1,sess2    give comma separated list of sessions to spam
10# -r reverse, spam in opposite order (default is alphabetic, -r means
11#    omegapsiic).  Note tcp_spam_list is not sorted (but may be reversed).
12# -t transmit, send data to slave rather than executing command for eac
13#    session.
14# -v verbose, list session being spammed in turn
15#
16# If the function tcp_on_spam is defined, it is called for each link
17# with the first argument set to the session name, and the remainder the
18# command line to be executed.  If it sets the parameter REPLY to `done',
19# the command line will not then be executed by tcp_spam, else it will.
20
21emulate -L zsh
22setopt extendedglob
23
24local cursess=$TCP_SESS sessstr
25local TCP_SESS cmd opt verbose reverse sesslist transmit all eval
26local match mbegin mend REPLY
27local -a sessions
28
29while getopts "ael:rtv" opt; do
30    case $opt in
31	(a) all=1
32	    ;;
33	(e) eval=1
34	    ;;
35	(l) sessions+=(${(s.,.)OPTARG})
36	    ;;
37	(r) reverse=1
38	    ;;
39	(s) sessions+=($OPTARG)
40	    ;;
41	(t) transmit=-t
42	    ;;
43	(v) verbose=1
44	    ;;
45	(*) [[ $opt != '?' ]] && print "Option $opt not handled." >&2
46	    print "Sorry, spam's off." >&2
47	    return 1
48	    ;;
49    esac
50done
51(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
52
53local name
54if [[ -n $all ]]; then
55    sessions=(${(ko)tcp_by_name})
56elif (( ! ${#sessions} )); then
57  if (( ${#tcp_spam_list} )); then
58    sessions=($tcp_spam_list)
59  else
60    sessions=(${(ko)tcp_by_name})
61  fi
62  if (( ${#tcp_no_spam_list} )); then
63    for name in ${tcp_no_spam_list}; do
64      sessions=(${sessions:#$name})
65    done
66  fi
67fi
68
69if [[ -n $reverse ]]; then
70  local tmp
71  integer i
72  for (( i = 1; i <= ${#sessions}/2; i++ )); do
73    tmp=${sessions[i]}
74    sessions[i]=${sessions[-i]}
75    sessions[-i]=$tmp
76  done
77fi
78
79if (( ! ${#sessions} )); then
80  print "No connections to spam." >&2
81  return 1
82fi
83if (( ! $# )); then
84  print "No commands given." >&2
85  return 1
86fi
87
88if [[ -n $transmit ]]; then
89  cmd=tcp_send
90elif [[ -z $eval ]]; then
91  cmd=$1
92  shift
93fi
94
95: ${TCP_PROMPT:=T[%s]:}
96
97for TCP_SESS in $sessions; do
98  REPLY=
99  if (( ${+functions[tcp_on_spam]} )); then
100    tcp_on_spam $TCP_SESS $cmd $*
101    [[ $REPLY = done ]] && continue
102  fi
103  if [[ -n $verbose ]]; then
104      if [[ $TCP_SESS = $cursess ]]; then
105	  sessstr="c:1"
106      else
107	  sessstr="c:0"
108      fi
109      zformat -f REPLY $TCP_PROMPT "s:$TCP_SESS" \
110	  "f:${tcp_by_name[$TCP_SESS]}" $sessstr && print -r $REPLY
111  fi
112  if [[ -n $eval ]]; then
113      eval $*
114  else
115      eval $cmd '$*'
116  fi
117done
118