1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
# All these aliases take commands as arguments and have the property that
# they will not exand those commands prior to execution, making them safe.
#
# This may require some explanation:
#
# The ircii language has the concept of "expansion", whereby variable
# references are replaced with the variable values and escaped characters
# are unescaped. This is one of the side effects of an eval. In the
# following two commands, if entered from the command line, the first will
# whois the nick "\\`anderer", and the second will whois "\`anderer",
# because the eval will unescape it.
#
# /whois \\`anderer
# /eval whois \\`anderer
#
# This is from the command line. If these commands are executed from an
# alias, the first command will whois "\`anderer", and the second will
# whois "`anderer". This is because commands within an alias are always
# expanded prior to execution. There is no way to stop this, but you can
# control it by passing a variable to the whois command instead of the raw
# text. Since expansion only occurs once, the variables expansion will
# "shelter" the text from being expanded.
#
# If you wish to add more levels of expansion, you use more evals. If you
# wish to have _no_ expansion, you keep all your text in variables, and
# avoid using eval.
#
# It is easy to see that there may be occasions where you may want to whois
# someone from within a hook without having to worry about expansion. This
# is easy enough. /whois does not expand its arguments, however, hooks can
# generate floods, so you put the whois in a timer say. The problem with
# this is that /timer _does_ expand its arguments, so you end up with an
# extra level of expansion to deal with.
#
# These aliases solve these problems. Commands are given as arguments and
# are normally not expanded, just as if they had been given to a built in
# command. If you wish to have them expanded when they are run, precede
# them with /eval, or use a /timer or a /queue instead.
package qcmd
#
# Synonym for /timer, but which doesn't expand args.
#
# This is less than perfect and will break if numbers are used for commands.
#
alias timer.ue (args) {
while (word(0 $args) =~ [-*]) {
push :pre $shift(args)
if (isnumber(b10 $word(1 $args))) {
push :pre $shift(args)
}
}
timer $pre $shift(args) \$decode\($encode($args)\)
}
#
# Usage:
# scmd [server [command]]
#
# Execute command on server _without_ expanding command.
#
alias scmd (args) fe ($split(, $shift(args))) serv {xeval -s $serv {$args}}
#
# Usage:
# 1cmd [time [command]]
#
# command will not be executed if the same command has been executed in
# the last time seconds.
#
alias 1cmd {
@ :foo = encode($tolower($1-))
@ :eserv = 0 > servernum() ? [] : servernum()
if (time() - onecmd[$eserv][$foo] >= [$0]) {
@ onecmd[$eserv][$foo] = time()
$1-
}
if (time() != onecmd[$eserv] && (!rand(100))) {
@ onecmd[$eserv] = time()
foreach onecmd[$eserv] bar {
if (onecmd[$eserv][$bar] < time()) {
@ onecmd[$eserv][$bar] = []
}
}
}
}
#
# Usage:
# qcmd [queue [command]]
# fqcmd [queue [command]]
#
# Queue command, and schedule a timer for later execution. Prevents flooding.
# fqcmd adds the command to the beginning of the queue instead of the end.
#
# q1cmd [time [queue [command]]]
# fq1cmd [time [queue [command]]]
#
# The same as "1cmd {time} qcmd {queue} {command}", only, the command also
# won't be scheduled if the same command is already scheduled.
#
# Also, with [f]q1cmd, you can specify a coma separated list of queues for
# the second argument. All these queues will be searched for duplicates but
# the first will be the queue given to qcmd.
#
stack push alias alias.tt
alias alias.tt (cmd,op,args) {
@ sar(gr/\${cmd}/${cmd}/args)
@ sar(gr/\${op}/${op}/args)
alias $args
}
fe (q push fq unshift) cmd op {
alias.tt $cmd $op ${cmd}1cmd (qo,qc,args) {
@ :sn = servernum()
@ :sn = sn < 0 ? [_] : sn
@ :argz = args
@ sar(gr/\\/\\\\/argz)
@ sar(gr/\"/\\\"/argz)
@ :qc = split(, $qc)
fe ($qc) qqcc {
if (0 <= findw("$argz" $qcmd[$sn][$qqcc])) {
return
}
}
1cmd $qo ${cmd}cmd $shift(qc) $args
}
alias.tt $cmd $op ${cmd}cmd {
@ :sn = servernum()
@ :sn = sn < 0 ? [_] : sn
if (1 < #) {
@ :bar = [$1-]
@ ${op}(qcmd.${sn}.$0 \"$msar(gr/\\/\\\\/\"/\\\"/bar)\")
} else {
if (1 == #) {
@ :foo = [qcmd.${sn}.$0]
@ :foo = aliasctl(assign match $foo)
@ :foo = shift(foo)
@ :foo = after(2 . $foo)
} elsif (islagged()) {
@ :bar = [ ]
# Do nothing if we're lagged.
# This is meant to be a link to a
# fictitious lag measurement script.
} elsif (0 == #) {
foreach qcmd[$sn] bar {
@ :foo = bar
break
}
}
if (@foo) {
@ :bar = shift(qcmd[$sn][$foo])
$msar(gr/\\\\/\\/\\\"/\"/bar)
}
}
if (@bar) ^timer -ref qcmd.$sn 5 qcmd
return $bar
}
}
stack pop alias alias.tt
|