epic4-2.10.2.orig/0000755000000000000000000000000012171117171010424 5ustar epic4-2.10.2.orig/BUG_FORM0000644000000000000000000000651607706336213011627 0ustar If you should see what you think to be a bug, please visit http://prbh.org/bugs/ Please remember when reporting a bug that information counts. Since we have not yet mastered the skill of mind-reading, you should not assume that we know anything about your situation. We have seen some things that look absolutely strange to us, but are perfectly normal to the user. It is best for you to take the stance that we dont know that much about your operating system, so you should try to start at the beginning and clue us in. Thanks a bunch. |8^) Please include as much as possible of the following information in your bug report. Bug reports with insufficient information are frustrating for everybody involved. This list was compiled to help you help us the most effectively: Describe your computer: Hardware type? Operating System? (try uname -a) Your compiler (if gcc, include version) What scripts/script packs you run (lice, darkstar, obv, etc) Anything else you think might be helpful. When did the problem occur? * Configure time (dies while running configure) If it is configure time, please include a cut and paste of everything that appears on your screen from the line when you type "./configure" until you see your prompt again. Please do not leave out any lines, for any line may contain very important information! * Compiler time (dies when you type 'make') If it is at compile time, please include a cut and paste of everything that appears on your screen from the line when you type 'make' until you see your prompt again. Please do not leave out any lines, for any line may contain very important information! * Run time (You got a "CRITICAL PROTECTION ERROR") * Run time (You got a "PANIC" message) * Run time (non-fatal logic bug) If it is at run time, please try to describe as best you can what you were doing when the client malfunctioned. Had you just run a command? Can you duplicate the error? What seems to cause the error in your best judgement? Have you found anything else that independantly causes this same problem? Bugs that can be reproduced are the easiest bugs to fix. Can you get a stack trace? If EPIC crashed, and you can recreate the crash, run EPIC under a debugger (such as gdb) and get a stack trace and include that in your bug report. Under normal circumstances, EPIC will not create a corefile, so you must run EPIC under a debugger in order to get a stack trace. When a "PANIC" or "CRITICAL PROTECTION ERROR" occurs, sometimes EPIC will be able to tell you what ircII commands were executing at the time of the crash. If you see any message that says "INCLUDE THE ABOVE IMPORTANT INFORMATION" or "stack trace", please include that in your bug report. Is there anything else you think would be helpful? ----------------------------------------------------------------------------- About the software: EPIC is a fork of ircII-2.8.2. ircII was originally written by Michael Sandroff, and then later developed by Troy Rollo and Matthew Green. This distribution came from EPIC Software Labs (epicsol.org) who maintains it in stewardship of The EPIC Project. "EPIC" is an unregistered trademark of The EPIC Project "ESL" and "EPICSOL" are unregistered trademarks of EPIC Software Labs This product is (ircII) EPIC4-1.1.* epic4-2.10.2.orig/bsdinstall0000755000000000000000000000220707213031314012505 0ustar #! /bin/sh # # @(#)install.sh 4.5 (Berkeley) 10/12/83 # cmd=/bin/mv strip="" chmod="/bin/chmod 755" chown="" chgrp="" while true ; do case $1 in -s ) strip="/bin/strip" shift ;; -c ) cmd="/bin/cp -p" shift ;; -m ) chmod="/bin/chmod $2" shift shift ;; -o ) chown="/etc/chown -f $2" shift shift ;; -g ) chgrp="/bin/chgrp -f $2" shift shift ;; -d ) cmd="/bin/mkdir" shift ;; * ) break ;; esac done if test ! ${2-""}; then echo "install: no destination specified" exit 1 fi if test ${3-""}; then echo "install: too many files specified -> $*" exit 1 fi if test $1 = $2 -o $2 = .; then echo "install: can't move $1 onto itself" exit 1 fi case $cmd in /bin/mkdir ) file=$2/$1 ;; * ) if test '!' -f $1; then echo "install: can't open $1" exit 1 fi if test -d $2; then file=$2/$1 else file=$2 fi /bin/rm -f $file ;; esac case $cmd in /bin/mkdir ) if test ! -d "$file"; then $cmd $file fi ;; * ) $cmd $1 $file if test -n "$strip"; then $strip $file fi ;; esac if test -n "$chown"; then $chown $file fi if test -n "$chgrp"; then $chgrp $file fi $chmod $file exit 0 epic4-2.10.2.orig/script/0000755000000000000000000000000012171117135011730 5ustar epic4-2.10.2.orig/script/stat0000644000000000000000000000337407213031315012631 0ustar # STAT version 1.0 03 November 1993 # # Shows additional statistics on server's current role on the net. # # Concept, original version: Twilight1 # This version: Jeremy Nelson (jnelson@acronet.net) # # Usage: /stat [server] # # Action: /stat by itself will query the statistics from the local server. # /stat with an optional server name will query the remote server for # the statistics. alias stat {if ([$0]) {rstat $0} {lstat}} alias lstat { start_stat ^on ^255 * { @ lstat.tmp = FLOATING_POINT_MATH set floating_point_math ON @ remote_users = [$3] @ percent = (remote_users / total_users) * 100 @ average = total_users / total_servers set floating_point_math $lstat.tmp echo *** User statistics for server $0 echo *** I have $remote_users of $total_users users on $total_servers servers. end_stat } lusers } alias rstat { start_stat lusers wait ^on ^251 * { @remote_users = [$3]+[$6] } ^on ^255 * { @ lstat.tmp = FLOATING_POINT_MATH set floating_point_math ON @ percent = (remote_users / total_users) * 100 @ average = total_users / total_servers set floating_point_math $lstat.tmp echo *** User statistics for server $0 echo *** I have $local_users of $total_users users on $total_servers servers. end_stat } lusers $remote_server } alias start_stat { stack push on 251 stack push on 252 stack push on 254 stack push on 255 ^on ^251 * {@total_users = [$3]+[$6];@total_servers = [$9]} ^on ^252 * # ^on ^254 * # ^on ^255 * # } alias end_stat { stack pop on 251 stack pop on 252 stack pop on 254 stack pop on 255 echo *** That is $percent% of the total number of users on IRC. echo *** The average serverload is $average user[s] per server. } # Set phasers to stun. epic4-2.10.2.orig/script/tabkey.ce0000644000000000000000000001660707750415413013541 0ustar # # OK, here's the plan: # # Tabkey cuts the input line up into edible chunks, and selects a function # to do the actual completion. The function will receive a single word as # its argument, and return a list of potential matches. The word is whatever # is under the cursor, up to the insertion point at the current time. The # word may be empty or contain spaces and the function should be able to # cope with this. # # The exact function chosen works like this: # * If the current _word_ is a command (first word, begins with $cmdchars), # call command_completion by way of parsekey (don't call any aliases). # * Or, if the current line is a command, it gets handed to $tabkey.cmd(). # * Otherwise, call tabkey.default, which is a stub that can be changed # to suit your preferences. The default tabkey.default calls # tabkey.nickchan which matches against all channels you're currently on # and either the nicks in your current channel, or failing that, the # nicks in all channels. # * tabkey.default is also called if tabkey.cmd() returns nothing. If # necessary, the function can prevent this behaviour by returning a single # space, but this is discouraged. # * tabkey.default is also called by $tabkey.cmd() if it cannot find an # appropriate command handler. # * $tabkey.cmd() will search for an appropriate function by joining the # command and all its arguments together with dots and progressively # removing those arguments until a function is found. # # tabkey "exports" a number of local variables that the functions may use # or alter after using "bless": # * $curword is what tabkey believes the current word is. The function # may make use of this for context sensitivity. I say believes because # this may be open to different interpretations. # * $wordind is the character index of the _beginning_ of the word that is # being completed. If it is equal to $curpos(), then the first argument # will be empty and the user has hit tab at the beginning of the word or # in between words and the function should return all possible matches. # The reason you may need to use it is if the function is designed to # complete something that is not a single word. It, and the current # cursor position may be altered to cause tabkey to replace the chosen # part of the string instead of just the word. # # The organisation of the supporting functions goes like this: # * "Context sensitive" functions are to be named with "tabkey.cmd." as a # prefix followed by the name of the command that they are used to # complete. This is where tabkey.cmd will look for them. # * Generally, completion "methods" should be placed under tabkey.method # Context sensitive functions should be as simple as possible and the bulk # of the work should be done by the methods. # # NOTE: The "first argument" description above is no longer true. The # functions argument list is to be treated as a single argument. # # Remaining known issues: # Doesn't work (very well) with commands with dots in them. package tabkey.ce bind ^i parse_command tabkey.main alias tabkey.default tabkey.method.nickchan alias tabkey.main { @ :oxd = xdebug(extractw) xdebug extractw @ :curpos = curpos() @ :curword = indextoword($curpos $L ) @ :wordind = wordtoindex($curword $L) @ :cmdind = 0 if (32 >= (127 & ascii($mid(${curpos-1} 1 $L )))) { @ curword++ @ wordind = curpos } @ :word = mid($wordind ${curpos-wordind} $L) if (word=~["*"]) { @ :word = shift(word) } elsif (word=~["*]) { @ :word#=["] @ :word = shift(word) } if (!index($cmdchars $L)) { wait for @ :matches = tabkey.cmd($word) } else { wait for @ :matches = tabkey.default($word) } @ :prefix = prefix($matches) if (1 < numwords($matches) && word == prefix) { echo Completions for \"$word\": $matches } elsif (#matches && strlen($word) <= strlen($prefix)) { @ :prefix = 0 > index("$chr($jot(32 1))" $prefix) ? prefix : ["$prefix"] @ :line = mid(0 $wordind $L) parsekey erase_to_beg_of_line xtype -l $line$prefix${1<#matches?[]:[ ]} } xdebug $oxd } alias tabkey.cmd { bless @ :ret = :cmd = [] @ :pass = chr($jot($ascii(AZ))) @ :pass#= chr($jot($ascii(az))) @ :pass#= chr($jot($ascii(09))) @ :args = wordtoindex($cmdind $L) @ :args = mid($args $curpos $L) @ :args = unsplit(. $args) @ :args = pass(._$pass $args) if (!curword) { @ ret = tabkey.method.commands($args) repeat $#ret {push ret /$shift(ret)} return $ret } while (args) { @ :matches = aliasctl(alias pmatch tabkey.cmd.$args*) @ :matches = prefix($matches) if (curword == count(. $args)) { } elsif (matches != [tabkey.cmd.$args]) { } elsif (aliasctl(alias exists $matches)) { @ args = matches break } @ args = before(-1 . $args) } if (args) { wait for @ ret = ${args}($*) } unless (strlen($ret)) { wait for @ ret = tabkey.default($*) } return $ret } # Used for things like /eval and /repeat where what you are completing # is another command. depth is the arg number where the command begins. # This is not well cpu optimised. See examples below. alias tabkey.recurse (depth,...) { bless @ :curpos += wordtoindex($cmdind $L ) @ :curpos -= wordtoindex(${cmdind+depth} $L ) @ :cmdind += depth @ :curword -= depth @ function_return = 0 > curword ? [] : tabkey.cmd($*) @ :curword += depth @ :cmdind -= depth @ :curpos += wordtoindex(${cmdind+depth} $L ) @ :curpos -= wordtoindex($cmdind $L ) } # Context sensitive completion goes here. alias tabkey.cmd.eval tabkey.recurse 1 alias tabkey.cmd.repeat tabkey.recurse 2 alias tabkey.cmd.dcc (args) { bless switch ($curword) { (1) {return $pattern("$args*" CHAT CLOSE CLOSEALL GET LIST RAW RENAME RESUME SEND)} } } alias tabkey.cmd.dcc.resume tabkey.cmd.dcc.send alias tabkey.cmd.dcc.send { bless switch ($curword) { (0) (1) {echo This should never happen.;call;local} (2) {return $tabkey.method.nick($*)} (*) {return $tabkey.method.filei($*)} } } alias tabkey.cmd.help { bless @ :matches = [] @ :path = restw(1 $left($curpos $L)) if (wordind == curpos) {@ push(path *)} repeat $#path @ push(path $shift(path)*) @ matches = globi($unsplit(/ $getset(HELP_PATH) $path)) repeat $#matches @ push(matches $rightw(1 $remws(/ $split(/ $shift(matches))))) return $matches } # Methods. alias tabkey.method.commands { @ :ret = sort($uniq($getcommands($**) $aliasctl(alias match $*) $aliasctl(alias match $**))) return $ret } alias tabkey.method.chan (args) { return $pattern("$args*" $mychannels()); } alias tabkey.method.notify (args) { return $pattern("$args*" $notify(on)); } stack push alias alias.foo alias alias.foo alias $*;alias $sar(g/globi/glob/$sar(g/filei/file/$*)) alias.foo tabkey.method.filei (f0) { @ :f0 = sar(gr/\\/\\\\/f0) @ :f0 = sar(gr/*/\\*/f0) @ :f0 = sar(gr/?/\\?/f0) @ :f0 = sar(gr/[/\\[/f0) @ :f0 = sar(gr/]/\\]/f0) @ :f0 = :f1 = globi("" $f0*) while (numwords($f0) == 1 && f0 =~ [*/]) { @ f0 = globi("" $f0*) } return ${f0 ? f0 : f1} } stack pop alias alias.foo alias tabkey.method.nick (args) { if (match("$args*" $chanusers())) { return $pattern("$args*" $chanusers()); } else { @ :chanusers = mychannels() repeat $#chanusers @ push(chanusers $chanusers($shift(chanusers))) return $pattern("$args*" $sort($uniq($chanusers))); } } alias tabkey.method.nickchan { return $remws(/ $tabkey.method.chan($*) $tabkey.method.nick($*)) } alias tabkey.method.nickchannotify { return $remws(/ $tabkey.method.chan($*) $sort($uniq($tabkey.method.nick($*) $tabkey.method.notify($*)))) } epic4-2.10.2.orig/script/dcc_timeout0000644000000000000000000000072107213031315014146 0ustar @ dcc.inbound.threshhold = 0 @ dcc.outbound.threshhold = 0 on #-timer -333 * { ^stack push on dcc_list ^on dcc_list * # if (dcc.inbound.threshold) { ^on -dcc_list "* * * Offered *" { if (time() - [$4] > dcc.inbound.threshhold) { dcc close $0 $2 } } } if (dcc.outbound.threshold) { ^on -dcc_list "* * * Waiting *" { if (time() - [$4] > dcc.outbound.threshhold) { dcc close $0 $2 } } } ^//dcc list ^stack pop on dcc_list } #hop'98 epic4-2.10.2.orig/script/tc0000644000000000000000000000476407253747052012310 0ustar /* * ``TC'' - Tabscript Clone For EPIC * Copyright 1995 Jeremy Nelson * Copyright 1998 The EPIC Project * Originally written for Daveman's Toolbox * Please use and distribute this script like crazy! */ # # (note from jfn) The original allowed you to save up to 10 nicks to # by cycled through by pressing or . I totaly rewrote the file # and added the ability to set the number of nicks to save, and also made # it a full tabkey clone. This file is a lot easier to figure out, too. # # What it does: # save an arbitrary number of nicks in a list (settable by you) # cycle through the list by pressing # cycle backwards through the list by pressing <^R> # remove last bed nick from the list (^X^X) # # Because this script uses a queue instead of a list and index counter, # you may find this script has a different set of idiosyncrasies then # the original tabscript. # package tc bind ^I parse_command ^tc.get_nick bind ^R parse_command ^tc.get_nick_backward bind ^X^X parse_command { xecho -b Nickname $word($tc.position $tc.msglist) removed @ tc.msglist = notw($tc.position $tc.msglist) @ tc.num_nicks = #tc.msglist @ tc.position-- tc.get_nick } # maximum number of nicks you want to keep track of... @ tc.max_nicks = 6 # # add a word to a list -- makes sure the list doesnt get longer then # the number allowed in max_nicks. # alias tc.add_to_list { # This was suggested by David Luyer (david_luyver@pacfici.net.au) (tc.msglist = [$0 $leftw(${tc.max_nicks-1} $remw($0 $tc.msglist))]) (tc.num_nicks = #tc.msglist) (tc.position = 0) } alias tc.get_nick { parsekey erase_line xtype -l /msg $word($tc.position $tc.msglist) ((++tc.position >= tc.num_nicks) && (tc.position -= tc.num_nicks)) } alias tc.get_nick_backward { parsekey erase_line xtype -l /msg $word($tc.position $tc.msglist) ((--tc.position < 0) && (tc.position += tc.num_nicks)) } alias addnick for x in ($*) {tc.add_to_list $x} alias nicklist xecho -b Nickname list: $tc.msglist on #-msg -12782 * tc.add_to_list $0 on #-send_msg -12782 * tc.add_to_list $0 on #-dcc_chat -12782 * tc.add_to_list =$0 on #-send_dcc_chat -12782 * tc.add_to_list =$0 /* * This alias doesnt work if you try to do something like: * /m x .... * because $x expands to your userhost, and that gets confusing. * * No, the lack of brackets around $0 is not a bug, thats how it works. * Try it. If $0 is 'bc' and $bc is "bigcheese" then * if ($0) -> if (bc) -> if ([bigcheese]) */ ALIAS M if \($0\) {msg $($0) $1-} {msg $0 $1-} epic4-2.10.2.orig/script/list0000644000000000000000000000074107415131614012633 0ustar # showlist # # Comments: # This is apparently an intellectual exercise, as this is most certainly # not the "best" way to do this, by any modern measure. However, it does # demonstrate that it is possible to use a counter to iterate through the # argument list in a useful manner without using recursion of any kind. # alias showlist { @ sl.cnt = 0 while (sl.wrd = [$($sl.cnt)]) { echo $sl.wrd @sl.cnt++ } ^assign -sl.cnt ^assign -sl.wrd } #Ian Frechett epic4-2.10.2.orig/script/paste0000644000000000000000000000364407700453642013006 0ustar # # Here's the plan... # # We want a scripted /set paste, when we turn it on, it sends whatever we type # to the current target. We also need to be able to turn it off automatically # because we won't be able to type any commands while it's active. We need # to be able to configure the timeout, and we also want to be able to strip # any leading whitespace on the lines we paste. (AnguzHawk asked for this # feature particularly.) # @ paste.on = 0 @ paste.strip = 0 @ paste.delay = 30 # Uncomment this if you want a key binding. bind ^P parse_command { set paste toggle } # # # on ^set "paste %" { xecho -b PASTE is ${paste.on ? [ON] : [OFF]} xecho -b PASTE_STRIP is ${paste.strip ? [ON] : [OFF]} xecho -b PASTE_DELAY is $paste.delay } on ^set "paste toggle" { set paste ${paste.on ? [off] : [on]} } on ^set "paste on" { @ paste.on = 1 setup_paste xecho -b PASTE mode ON -- automatically turns off in $paste.delay seconds. } on ^set "paste off" { @ paste.on = 0 remove_paste xecho -b PASTE mode OFF } # # # on ^set "paste_strip %" { xecho -b Usage: /SET PASTE_STRIP [ON|OFF] } on ^set "paste_strip toggle" { set paste_strip ${paste.on ? [off] : [on]} } on ^set "paste_strip on" { @ paste.strip = 1 xecho -b PASTE stripping set to ON } on ^set "paste_strip off" { @ paste.strip = 0 xecho -b PASTE stripping set to OFF } # # # on ^set "paste_delay %" { if (!isnumber($1) || [$1] <= 0) { xecho -b Usage: /SET PASTE_DELAY seconds } { @ paste.delay = [$1] xecho -b PASTE_DELAY set to $paste.delay seconds. } } # # # alias setup_paste { stack push bind ^I bind ^I self_insert stack push on input on input - on ^input * { if (paste.strip) { //send $0 $1- } else { //send $* } } timer -refnum PASTEOFF $paste.delay set paste off } # The 'defer' is for epic clients before epic4-1.1.8 alias remove_paste { on input -* stack pop on input stack pop bind ^I defer ^timer -delete PASTEOFF } #hop'y2k3 epic4-2.10.2.orig/script/window0000644000000000000000000000066107526111621013167 0ustar # Emacs-like window handling # bind ^Xo next_window bind ^X0 parse_command window kill bind ^X1 parse_command window kill_others bind ^X2 parse_command window new bind ^X= parse_command window balance bind ^X+ parse_command window grow 1 bind ^X- parse_command window shrink 1 bind ^Xz parse_command window grow 1 bind ^X^z parse_command window shrink 1 # bind ^X^ parse_command window grow 1 # bind ^X^^ parse_command window grow 1 epic4-2.10.2.orig/script/scandir0000644000000000000000000000043107253747052013310 0ustar /* * scandir -- an interesting way to use $glob() to get all the files * in a [sub]directory. */ alias scandir { ^local retval ^local last for x in ($glob($*/*)) { if (!(last = after(-1 / $x))) \ @ last = x push retval $last } @ function_return = retval } #hop'97 epic4-2.10.2.orig/script/newformat0000644000000000000000000001153607525764605013704 0ustar # $EPIC: newformat,v 1.2 2002/08/12 16:59:49 jnelson Exp $ # This script is intended for use with 2.8 servers on all sites. # It's an extension of the 2.8script but with much much nicer # formatting. # Written by Ian Frechette (daemon) @ RCS.newformat = [$$Header: /home/cvs/repository/epic4/script/newformat,v 1.2 2002/08/12 16:59:49 jnelson Exp $$] # An operator command. ESC-t turns this option on and off. # It allows one to see users or not see them in a TRACE. # It also effects the output of STAT l ^bind ^[t parse_command tt ^alias tt if (trace) { assign -trace } { assign trace x } # Stores the output of a trace for use with conall ^alias trace ^cleantr;//trace $* ^alias storetrace { if (index([ $0)>-1) { assign trace.$strip([].-0123456789*/ $0) $left($index([ $0) $0) } { assign trace.$strip([].-0123456789*/ $0) $0 } } ^alias cleantr foreach trace ii { assign -trace[$ii] } # connect to all the servers listed in the last trace # food for when you restart the server. ^alias conall foreach trace ii { connect $trace[$ii] } ^alias invite if ([$1]) { //invite $0 $1 } { //invite $0 $C } # Don't EVER screw with the format() or lformat() commands # as many other things may use them. ^alias format { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([-$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } ^alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } # Trace information # ----------------- # define RPL_TRACELINK 200 ^on ^200 * echo $[7]0 $1 $lformat(23 [$2]) ==> $3- # define RPL_TRACECONNECTING 201 ^on ^201 * echo $[7]0 $1 Class$format(7 [$2]) trying... ==> $3- # define RPL_TRACEHANDSHAKE 202 ^on ^202 * echo $[7]0 $1 Class$format(7 [$2]) handshake ==> $3- # define RPL_TRACEUNKNOWN 203 ^on ^203 * echo $[7]0 $1 Class$format(7 [$2]) *unknown* ==> $3- # define RPL_TRACEOPERATOR 204 ^on ^204 * echo $[7]0 $1 Class$format(7 [$2]) $format(9 1C) ==> $left(35 $3) # define RPL_TRACEUSER 205 ^on ^205 * if (trace) { echo $[7]0 $1 Class$format(7 [$2]) $format(9 1C) ==> $left(35 $3) } # define RPL_TRACESERVER 206 ^on ^206 * storetrace $5;echo $[7]0 $1 Class$format(7 [$2]) $format(4 $3) $format(5 $4) ==> $left(35 $5) # define RPL_TRACESERVICE 207 ^on ^207 * echo $[7]0 $1 Class[$format(7 $2)] service ==> $3- # define RPL_TRACENEWTYPE 208 ^on ^208 * echo $[7]0 $1 Class[$format(7 $2)] newtype ==> $3- # define RPL_TRACECLASS 209 ^on ^209 * echo $[7]0 -==- $1$format(7 [$2]) Entries linked: $3 # numeric 261 A debug file type in a trace ^on ^261 * echo $[7]0 $1 Level$format(7 [$3]) $[9]xbogus ==> $2 # Stats information # ----------------- alias statsltime { if ([$1] != []) {@function_return = left(19 $*)} {@function_return = left(16 $shorttime($tdiff($0)))} } # takes time as returned from $tdiff() e.g. 23 days 1 hour 32 minutes 10 seconds # and puts it in the format 23d 1h 32m 10s alias shorttime { @ function_return = [$0] ## left(1 $1) ## [ $2] ## left(1 $3) ## [ $4] ## left(1 $5) ## [ $6] ## left(1 $7) } alias stats { if ([$0] == [l]) { echo $lformat(17 Server) $lformat(40 Link) $lformat(16 Connect Time) echo $lformat(10 SendQ) $lformat(10 SendM) $lformat(10 SendBytes) $lformat(10 RcveM) $lformat(7 RcveByte) } //stats $* } # define RPL_STATSLINKINFO 211 ^on ^211 * ^echo $[17]0 $[40]1 $statsltime($7-);echo $[10]2 $[10]3 $[10]4 $[10]5 $[7]6 ^on ^211 "% *.*[*.*] *" ^echo $[17]0 $[40]1 $statsltime($7-);echo $[10]2 $[10]3 $[10]4 $[10]5 $[7]6 ^on ^211 "% *[*" if (trace) {^echo $[17]0 $[40]1 $statsltime($7-);echo $[10]2 $[10]3 $[10]4 $[10]5 $[7]6} # ^on ^211 * ^echo $[7]0 $[20]1 $[10]3 $[10]5 $7- # define RPL_STATSCOMMANDS 212 ^on ^212 * ^echo $[7]0 $[10]1 : $[-10]2 $[-10]3 # define RPL_STATSCLINE 213 # ^on ^213 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSNLINE 214 # ^on ^214 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSILINE 215 ^on ^215 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSKLINE 216 ^on ^216 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSQLINE 217 ^on ^217 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSYLINE 218 # ^on ^218 * ^echo $[7]0 $1:$[5]2:$[5]3:$[5]4:$[5]5:$6- # # 220 is used by .troy versions to return information on # host masks being enforced locally. # ^on ^220 * ^echo $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # User Mode (2.1.5 actually knows about this. This is for 2.1.4e) # define RPL_UMODEIS 221 ^on ^221 * ^echo $[7]0 Your user mode is $1 ^comment Service list: ^on ^231 * ^echo $[7]0 Service $1 ($0) ^comment Ban list: ^on ^367 * ^echo $[7]0 ban in [ $[15]1 ] for [ $[30]2- ] ^on ^369 * if (SHOW_END_OF_MSGS==[ON]) { if (SHOW_NUMERICS==[ON]) {echo 369 $1-} {echo *** $1-} } #Ian Frechette epic4-2.10.2.orig/script/status_lag0000644000000000000000000000276207213031315014024 0ustar # Adds a STATUS_LAG set, following the regular STATUS_* conventions. # By default, this will be assigned to %2. # To change the format of the lag indicator, use /set status_lag. # To change how often the lag figure is updated, use /set status_lag_update. @ status_lag = [\[Lag: %2\]] @ status_lag_update = 30 # isnumber() is wc's code. # epic4pre1.047 and up has a built in $isnumber(). #alias isnumber { # ^local isnum 1 # if (![$0]) # { @ isnum = 0 } # # fec ($0) ii { # if (!isdigit($ii) && ii != [-]) # { @ isnum = 0 } # } # @ function_return = isnum #} ^on ^set "status_lag *" { if ([$1]) { @ status_lag = [$1-] echo $banner Value of STATUS_LAG set to $1- } else { echo $banner Current value of STATUS_LAG is $(status_lag) } } ^on ^set "status_lag_update *" { if ([$1]) { if (isnumber($1)) { @ status_lag_update = [$1] echo $banner Value of STATUS_LAG_UPDATE set to $1 } else { echo $banner Value of STATUS_LAG_UPDATE must be a number } } else { echo $banner Current value of STATUS_LAG_UPDATE is $(status_lag_update) } } alias checklag { setstatuslag ?? ^on ^raw_irc "$S PONG $S :$N" { ^on ^raw_irc -"$S PONG $S :$N" setstatuslag ${time()-checktime} timer -refnum lag $(status_lag_update) checklag } @ checktime = time() ^quote ping $S } alias setstatuslag { ^set status_user2 $sar(/%2/$[-2]*/$status_lag) } ^timer -delete lag checklag #psykotyk- nov 23/97 epic4-2.10.2.orig/script/grep0000644000000000000000000000323107751341072012616 0ustar # # grep 1.0 -- adds [e]grep support to the client, neat # Author -- wd@anduril.org White_Dragon Chip Norkus # Any deviation from the original is Jeremy Nelson's fault. # # Contributed to the EPIC project by Phoengold, on Fri, 14 Apr 2000. # # Usage: /grep [-w #] # /egrep [-w #] # Performs a text search on the lastlog of the current/specified window # # At the most basic level, /grep searches the lastlog of your current window # for the specified text. with the -w option you can specify the window # whose lastlog you want to use. A regular expression of any sort can be # used, as well. # alias grep { ^local win,exp,re,i,x,l,s.,l. if (![$0]) { echo Usage: /grep [-w #] return } @ win = 1 if ([$0] == [-w]) { if (![$2]) { return } @ win = [$1] @ exp = [$2-] }{ @ exp = [$*] } if (!winlevel($win)) { assign -win } @ re = regcomp($exp) ### grep here, and save the lines @ i = getset(LASTLOG) @ x = 0 while (i) { @ l = line($i $win) if (!regexec($re $l)) { @ s[$x] = l @ l[$x] = i @ x++ } @ i-- } @ regfree($re) echo ------------------ Results of grep: ---------------------- @ i = 0 while (i < x) { xecho -nolog $[4]l[$i]: $s[$i] @ i++ } echo ------------------------ End ----------------------------- } #WhiteDragon'Y2K epic4-2.10.2.orig/script/old-dcc0000644000000000000000000000032707213031315013156 0ustar # Older implementations of dcc will need this script to handle the # new DCC REJECT syntax of EPIC3pre1 and upwards # on ctcp_reply "% DCC REJECT % *" { dcc close $3 $0 echo Closing DCC $3 to $0 at $0's request } epic4-2.10.2.orig/script/fe.pf0000644000000000000000000000177407704572313012673 0ustar if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo());return } : { This is a "preformatted" version of the FE script. You can load this script with /LOAD -PF fe. This demonstrates how to pre-format a script for use with the P(re)F(ormatted) loader. } alias opalot {fe ($2-) xx yy zz {mode $0 $1ooo $xx $yy $zz}}; alias banalot {fe ($2-) xx yy zz {mode $0 $1bbb $xx $yy $zz}}; #alias kickalot fe ($1-) xx {kick $0 $xx} alias kickalot {for xx in ($1-) {kick $0 $xx}}; alias masskick {kickalot ${[$0]?[$0]:C} $remw($N $onchannel($0))}; alias massdeop {opalot ${[$0]?[$0]:C} - $remw($N $chops($0))}; alias opall {opalot ${[$0]?[$0]:C} + $nochops($0)}; alias cuh { ^local foobar; # fe ($onchannel($0)) ix { push foobar $userhost($ix) } for ix in ($onchannel($0)) { push foobar $userhost($ix) }; @ function_return = foobar }; alias botsweep (target, chan default "$C") { @ :nicks = onchannel($chan); @ :uhs = cuh($nicks); kickalot $chan $copattern($uh($target) uhs nicks) }; load guh; #hop'94 epic4-2.10.2.orig/script/pipe0000644000000000000000000000060107213031315012601 0ustar /* * Ok. Here's the plan. * * $pipe(commands) will return the output from 'commands'. */ alias pipe { @ pipe.intval++ ^local mypipeval $pipe.intval ^local mypipedesc pipe$mypipeval ^local mypiperetval ^on ^exec "$mypipedesc *" { bless push mypiperetval $1- } ^exec -name $mypipedesc $* ^wait %$mypipedesc ^on exec -"$mypipedesc *" return $mypiperetval } #hop'97 epic4-2.10.2.orig/script/nopaste0000644000000000000000000000136107213031315013321 0ustar load utime on ^set "nopaste on" { @ nopaste.on = 1 setup_nopaste xecho -b NOPASTE set to on } on ^set "nopaste off" { @ nopaste.on = 0 remove_nopaste xecho -b NOPASTE set to off } alias setup_nopaste { @ nopaste.last = utime() @ nopaste.counter = 0 on ?input * { if ([$[1]*] == [/]) { return 0 } if ((:nc = strlen($*)) == 0) { return 0 } @ :td = utime_sub($utime() $nopaste.last) @ :sec = word(0 $td) @ :usec = (sec * 1000000) + word(1 $td) @ nopaste.last = utime() @ :us = ((100000 - usec) / nc) @ nopaste.counter += us if (nopaste.counter < 0) { @ nopaste.counter = 0 } if (nopaste.counter > 2500) { parsekey erase_line return 1 } { return 0 } } } alias remove_nopaste { on input -* } epic4-2.10.2.orig/script/columns0000644000000000000000000000112207213031315013323 0ustar # columnate some output alias format { assign IRCII.word $1 if ( @IRCII.word < [$0] ) { assign function_return $([-$0]1) } { assign function_return $1 } } on ^public * echo $format(11 <$0>) $2- on ^send_public * { if ( C == [$0] ) { echo $format(11 <$N>) $1- } { echo $format(10 <$N):$0> $1- } } on ^public_other * echo $format(10 <$0):$1> $2- on ^msg * echo $format(11 *$0*) $1- on ^send_msg * echo -> $format(8 *$0*) $1- on ^notice * echo $format(11 -$(0)-) $1- on ^send_notice * echo -> $format(8 -$(0)-) $1- on ^wall * echo $format(11 #$0#) $1- set continued_line epic4-2.10.2.orig/script/tabkey0000644000000000000000000000644507213031315013137 0ustar #------------------------------------------------------------------------------# # updated for 2.2.2 # This keeps track of the nicks of people you MSG. You can then # just hit the tab key ^I to flip through the list of people # you sent MSGs to. # Assign tk.msgmax to the number of nicknames you wish to store # Modified by Chetnik (s902211@yallara.cs.rmit.oz.au) # and Daemon (frechett@spot.colorado.edu) # It will now keep unique nicknames in the list ordered from the most recent # message received or sent to the oldest message received or sent. # Ctrl R will flip thru the list backwards (Reverse). # Crtl-X Ctrl-X deletes the currently displayed or current nick from the list. # /addnick will add the nicknames to the list. # /nicklist will show the current list of names # If a nickname which has 'never' existed is messaged, it will not be added to # the list. #echo *** #echo *** Just try ''TC''! #echo *** # searches thru list forwards (tab) or backwards (ctrl R) bind ^I parse_command ^tk.getmsg 1 $tk.msglist bind ^R parse_command ^tk.getmsg -1 $tk.msglist # Delete current nickname or currently displayed nickname from list bind ^X^X parse_command tk.delnick # shows all the current nicknames in the list. alias nicklist echo *** Nickname List: $tk.msglist # Adds nicknames to the list.. alias addnick if ([$1]) { addnick $1- };tk.addmsg $0 $tk.msglist # Set this to the max number of nickname you want on the list at a time @ tk.msgmax = 10 # From here down are internal aliases and 'ON's. # This script uses SERIAL NUMBER #55 # keeps list of unique nicks from newest message to oldest message. alias tk.addmsg { @ tk.matched = rmatch($0 $^\1-) if (tk.matched) { @ tk.msglist = [$(0-${tk.matched-1}) $(${tk.matched+1}-)] } #else { @ tk.msglist = [$(0-${tk.msgmax-1})] } @ tk.msgcnt = 0 ^assign -tk.matched } # searches thru list forwards or backwards. ($0==1==forward),($0==-1==back) alias tk.getmsg { @ tk.msgcnt = tk.msgcnt + [$0] if ( #tk.msglist < tk.msgcnt ) {@ tk.msgcnt = 1} if (tk.msgcnt <= 0) {@ tk.msgcnt = #tk.msglist} @ tk.junk = K ## [msg] parsekey erase_line xtype -l $tk.junk $($tk.msgcnt) } # some initialisation. You can comment these out if you want to. # ^on #-401 55 * if ([$AUTO_WHOWAS] != [ON]) { ^whowas $1 } # ^on ^406 * { # ^assign tk.msglist $notword($rmatch($1 $tk.msglist) $tk.msglist) # if ([$AUTO_WHOWAS] == [ON]) { echo *** $1- } #} # Adds nick to list when message is sent or received. Doesn't effect output. on #-send_msg 55 * ^tk.addmsg $0 $tk.msglist on #-msg 55 * ^tk.addmsg $0 $tk.msglist on #-send_dcc_chat 55 * ^tk.addmsg \=$0 $tk.msglist on #-dcc_chat 55 * ^tk.addmsg \=$0 $tk.msglist # deletes current nick from list alias tk.delnick { if (tk.msgcnt == 0) { echo *** Nickname: $word(0 $tk.msglist) removed. @ tk.msglist = [$notword(1 $tk.msglist)] } { echo *** Nickname: $word(${tk.msgcnt-1} $tk.msglist) removed. @ tk.msglist = [$notword($tk.msgcnt $tk.msglist)] } parsekey erase_line } # The $notword() function. alias notword { if ([$0] > 0) { if (([$0] > 1) && ([$0] < #)) { @ nw.sep = [ ] } { @ nw.sep = [] } @ function_return = [$(1-${[$0]-1})] ## [$nw.sep] ## [$(${[$0]+1}-)] } { @ function_return = [$1-] } } #------------------------------------------------------------------------------# epic4-2.10.2.orig/script/edit_topic0000644000000000000000000000054507260474517014017 0ustar # # Felony asked me for this, so here you go! =) # alias edit_topic { ^local thetopic ^stack push on 333 ^stack push on 332 ^stack push on 331 ^on ^333 * # ^on ^332 * { bless @ thetopic = [$2-] } ^on ^331 * # ^topic ^wait ^parsekey erase_line ^xtype -literal /topic $thetopic stack pop on 331 stack pop on 332 stack pop on 333 } #hop'y2k epic4-2.10.2.orig/script/notify0000644000000000000000000003152007770212634013175 0ustar # notify.irc: a module to detect the presence of nicknames # # written by nsx # # /set variables this script uses: # # NOTIFY -- turns notify system on or off # # NOTIFY_INTERVAL -- how often (in seconds) to check for signons and signoffs # # NOTIFY_USERHOST_AUTOMATIC -- if set on, userhosts will be displayed in # the signon messages (this can lag you if you # have a very large notify list) # # # note: this script uses the serial number 100 for its serial hooks # package notify # global config vars @ison_req_size = 500 @notify = [ON] @notify_interval = 30 @notify_userhost_automatic = [ON] # turn off epic's built-in notify system on ^set -"NOTIFY *" set notify off alias change_notify_status (refnum, newstatus, nicklist) { if (newstatus == [online]) { push online_list[$refnum] $nicklist if (np_in_progress[$refnum] == 1) { push ob_signons[$refnum] $nicklist } if (notify_userhost_automatic == [on]) { xeval -server $refnum { fe ($nicklist) n1 n2 n3 n4 n5 { userhost $n1 $n2 $n3 $n4 $n5 -cmd { shook notify_signon $0 $3@$4 } } } } else { fe ($nicklist) nickname { shook notify_signon $nickname } } } elsif (newstatus == [offline]) { @online_list[$refnum] = remws($nicklist / $online_list[$refnum])) if (np_in_progress[$refnum] == 1) { push ob_signoffs[$refnum] $nicklist } fe ($nicklist) nickname { shook notify_signoff $nickname } } } alias clear_notify_list { @notify_list = [] fe ($myservers(*)) refnum { @notify_list[$refnum] = [] } } alias clear_notify_records { fe ($myservers(*)) refnum { @ison_hist[$refnum] = [] @np_in_progress[$refnum] = [] @online_list[$refnum] = [] } } alias detect_signons { if (notify == [OFF]) { return } fe ($myservers(*)) refnum { if (np_in_progress[$refnum] == 1) { continue } @ob_signoffs[$refnum] = [] @ob_signons[$refnum] = [] @ison[$refnum] = [] @:ison_send_list = notify_list push ison_send_list $notify_list[$refnum] if (ison_send_list == []) { continue } xeval -server $refnum { //ison $ison_send_list$() } repeat ${(@ison_send_list / (ison_req_size + 1)) + 1} push ison_hist[$refnum] n @np_in_progress[$refnum] = 1 } } alias establish_notify_hooks { ^on #^channel_nick 100 "*" { @:refnum = servernum() @:online_list = online_list[$refnum] @:offline_list = remws($online_list / $notify_list $notify_list[$refnum]) if (findw($1 $online_list) > -1) { @change_notify_status($refnum offline $1) } if (findw($2 $offline_list) > -1) { @change_notify_status($refnum online $2) } } ^on #^channel_signoff 100 "*" { @:refnum = servernum() if (findw($1 $online_list[$refnum]) > -1) { @change_notify_status($refnum offline $1) } } ^on #^join 100 "*" { @:refnum = servernum() @:offline_list = remws($online_list[$refnum] / $notify_list $notify_list[$refnum]) if (findw($0 $offline_list) > -1) { @change_notify_status($refnum online $0) } } ^on #^msg 100 "*" { @:refnum = servernum() @:offline_list = remws($online_list[$refnum] / $notify_list $notify_list[$refnum]) if (findw($0 $offline_list) > -1) { @change_notify_status($refnum online $0) } } ^on #^notice 100 "*" { @:refnum = servernum() @:offline_list = remws($online_list[$refnum] / $notify_list $notify_list[$refnum]) if (findw($0 $offline_list) > -1) { @change_notify_status($refnum online $0) } } ^on #^server_lost 100 "*" { @:refnum = [$0] @ison_hist[$refnum] = [] @np_in_progress[$refnum] = 0 @online_list[$refnum] = [] } ^on #^003 100 "*" { @:refnum = servernum() @ison_hist[$refnum] = [] @np_in_progress[$refnum] = 0 @online_list[$refnum] = [] } ^on ^303 "*" { @:refnum = servernum() @:ison_type = left(1 $ison_hist[$refnum]) @ison_hist[$refnum] = restw($ison_hist[$refnum]) if (ison_type == [n]) { push ison[$refnum] $* if (index(n $ison_hist[$refnum]) == -1) { @process_ison_reply($refnum $ison_list[$refnum]) } } else { xecho -b -w $serv_win() -- online: $* } } ^on #^311 100 "*" { @:refnum = servernum() @:offline_list = remws($online_list[$refnum] / $notify_list $notify_list[$refnum]) if (findw($1 $offline_list) > -1) { @change_notify_status($refnum online $1) } } ^on #^401 100 "*" { @:refnum = servernum() if (findw($1 $online_list[$refnum]) > -1) { @change_notify_status($refnum offline $1) } } } alias find_local_notify_entry (nickname) { fe ($myservers(*)) refnum { if (findw($nickname $notify_list[$refnum]) > -1) { return $refnum } } return -1 } alias ison (nicklist) { repeat ${(@nicklist / (ison_req_size + 1)) + 1} push ison_hist[$servernum()] m //ison $nicklist } alias lookup_server (server) { if (findw($server $myservers()) == -1) { if (isnumber($server)) { if (index($server $myservers(*)) == -1) { xecho -b -c -- $server is an invalid reference number return -1 } else { return $server } } else { xecho -b -c -- $server is an invalid server name return -1 } } else { return $servernum($server) } } alias nlist { xecho -b -- global notify list: $notify_list fe ($myservers(*)) refnum { xecho -c -b -- local notify list for server $refnum: $notify_list[$refnum] } } alias notify (nicklist) { @:snum = servernum() @:online_list = online_list[$snum] @:offline_list = remws($online_list / $notify_list $notify_list[$snum]) if (nicklist == []) { xecho -b -c -- Currently online: $online_list xecho -b -c -- Currently offline: $offline_list return } if (nicklist == [-]) { fe ($notify_list) nickname { @remove_notify_entry($nickname) } xecho -b -c -- the global notify list has been cleared return } if (nicklist == [--]) { @clear_notify_list() @clear_notify_records() xecho -b -c -- the global and local notify lists have been cleared return } fe ($nicklist) nickname { @:separators = count(: $nickname) if (left(1 $nickname) == [-]) { @:nickname = rest($nickname) if (separators == 1) { @:serv = after(: $nickname) @:refnum = lookup_server($serv) @:nickname = before(: $nickname) if (refnum == -1) { continue } if (nickname == []) { fe ($notify_list[$refnum]) nickname { @remove_notify_entry($nickname $refnum) } xecho -b -c -- the local notify list for server $refnum has been cleared continue } if (findw($nickname $notify_list[$refnum]) == -1) { xecho -b -c -- $nickname is not in the local notify list for server ${refnum}! continue } @remove_notify_entry($nickname $refnum) xecho -b -c -- $nickname has been removed from the local notify list for server $serv } elsif (separators == 2) { @:groupname = after(-1 : $nickname) @:nickname = before(: $nickname) @:grouprefs = serverctl(GMATCH $groupname) if (grouprefs == []) { xecho -b -c -- $groupname is an invalid server group name continue } if (nickname == []) { fe ($grouprefs) refnum { fe ($notify_list[$refnum]) nickname { @remove_notify_entry($nickname $refnum) } } xecho -b -c -- the local notify lists for servers in group $groupname have been cleared continue } fe ($grouprefs) refnum { @remove_notify_entry($nickname $refnum) } xecho -b -c -- $nickname has been removed from the local notify lists for servers in group $groupname } else { if (nickname == []) { continue } if (findw($nickname $notify_list) == -1) { xecho -b -c -- $nickname is not in the global notify list! continue } @remove_notify_entry($nickname -1) xecho -b -c -- $nickname has been removed from the global notify list } } else { if (left(1 $nickname) == [+]) { @:nickname = rest($nickname) } if (separators == 1) { @:serv = after(: $nickname) @:refnum = lookup_server($serv) @:nickname = before(: $nickname) if (nickname == []) { continue } if (refnum == -1) { continue } if (findw($nickname $notify_list[$refnum]) > -1) { xecho -b -c -- $nickname is already in the local notify list for server ${serv}! continue } if (findw($nickname $notify_list) > -1) { xecho -b -c -- $nickname is already in the global notify list! continue } push notify_list[$refnum] $nickname xecho -b -c -- $nickname has been added to the local notify list for server $serv } elsif (separators == 2) { @:groupname = after(-1 : $nickname) @:nickname = before(: $nickname) @:grouprefs = serverctl(GMATCH $groupname) if (nickname == []) { continue } if (grouprefs == []) { xecho -b -c -- $groupname is an invalid server group name continue } fe ($grouprefs) refnum { push notify_list[$refnum] $nickname } xecho -b -c -- $nickname has been added to the local notify lists for servers in group $groupname } else { @:refnum = find_local_notify_entry($nickname) if (nickname == []) { continue } if (refnum > -1) { xecho -b -c -- $nickname is already in the local notify list for server ${refnum}! continue } if (findw($nickname $notify_list) > -1) { xecho -b -c -- $nickname is already in the global notify list! continue } push notify_list $nickname xecho -b -c -- $nickname has been added to the global notify list } } } @detect_signons() } alias process_ison_reply (refnum, ison_list) { @:new_offline_nicks = [] @:new_online_nicks = [] @:current_nick = servernick($refnum) @:ison_list = remws($ob_signoffs[$refnum] / $ison[$refnum]) @:online_list = online_list[$refnum] @:offline_list = remws($online_list / $notify_list $notify_list[$refnum]) push ison_list $ob_signons[$refnum] fe ($offline_list) nickname { if (findw($nickname $ison_list) > -1) { push new_online_nicks $nickname } } fe ($online_list) nickname { if (findw($nickname $ison_list) == -1) { push new_offline_nicks $nickname } } if (new_offline_nicks != []) { @change_notify_status($refnum offline $new_offline_nicks) } if (new_online_nicks != []) { @change_notify_status($refnum online $new_online_nicks) } @np_in_progress[$refnum] = 0 } alias remove_notify_entry (nickname, refnum) { if (refnum < 0) { @notify_list = remw($nickname $notify_list) fe ($myservers(*)) refnum { @online_list[$refnum] = remw($nickname $online_list[$refnum]) } } else { @online_list[$refnum] = remw($nickname $online_list[$refnum]) @notify_list[$refnum] = remw($nickname $notify_list[$refnum]) } } alias remove_notify_hooks { ^on #^channel_nick 100 -"*" ^on #^channel_signoff 100 -"*" ^on #^join 100 -"*" ^on #^msg 100 -"*" ^on #^notice 100 -"*" ^on #^server_lost 100 -"*" ^on #^003 100 -"*" ^on ^303 -"*" ^on #^311 100 -"*" ^on #^401 100 -"*" } alias serv_win (refnum) { @:win_max = [255] @:i = [1] if (refnum == []) { @:refnum = servernum() } while (i < win_max) { if (winserv($i) == refnum) { return $i } @:i++ } } on ^notify_signoff "*" { xecho -b -w $serv_win() -- Signoff by $0 detected } on ^notify_signon "*" { if ([$1] == [@]) { xecho -b -w $serv_win() -- Signon by $0 \(\) detected } elsif ([$1] == []) { xecho -b -w $serv_win() -- Signon by $0 detected } else { xecho -b -w $serv_win() -- Signon by $0 \($1\) detected } } on ^set "NOTIFY *" { if ([$1] == []) { xecho -b Current value of NOTIFY is $notify } elsif ([$1] == [off]) { @notify = [off] ^timer -del notcheck @remove_notify_hooks() xecho -b Value of NOTIFY set to OFF } elsif ([$1] == [on]) { @notify = [on] @clear_notify_records() @establish_notify_hooks() ^timer -refnum notcheck -rep -1 $notify_interval @detect_signons() xecho -b Value of NOTIFY set to ON } else { xecho -b Value of NOTIFY must be ON or OFF } } on ^set "NOTIFY_INTERVAL *" { if ([$1] == []) { xecho -b Current value of NOTIFY_INTERVAL is $notify_interval } elsif (!isnumber($1)) { xecho -b Value of NOTIFY_INTERVAL must be numeric! } elsif ([$1] < 1) { xecho -b Value of NOTIFY_INTERVAL must be greater than or equal to 1 } else { @notify_interval = [$1] ^timer -del notcheck ^timer -refnum notcheck -rep -1 $notify_interval @detect_signons() xecho -b Value of NOTIFY_INTERVAL set to $notify_interval } } on ^set "NOTIFY_USERHOST_AUTOMATIC *" { if ([$1] == []) { xecho -b Current value of NOTIFY_USERHOST_AUTOMATIC is $notify_userhost_automatic } elsif ([$1] == [off]) { @notify_userhost_automatic = [OFF] xecho -b Value of NOTIFY_USERHOST_AUTOMATIC set to OFF } elsif ([$1] == [on]) { @notify_userhost_automatic = [ON] xecho -b Value of NOTIFY_USERHOST_AUTOMATIC set to ON } else { xecho -b Value of NOTIFY_USERHOST_AUTOMATIC must be ON or OFF } } @clear_notify_list() @clear_notify_records() @establish_notify_hooks() @detect_signons() ^eval timer -refnum notcheck -rep -1 $notify_interval @detect_signons() epic4-2.10.2.orig/script/away0000644000000000000000000000156507415131614012626 0ustar /* * AWAY script -- a minimalist faking of the /AWAY command for when they * take /AWAY away from us. Only sends the message once per nick per time * you change it. * Requires ircII2.6 or later (Written for EPIC3.001) */ /* * This variable determines how often you send the away message to a * person, even if they've already seen it. */ @ away.recycle_time = 10000 on #-msg -633 * { if (away.msg && (sentaway[$encode($0)] < away.time) || \ (sentaway[$encode($0)] + away.recycle_time < time())) { ctcp $0 AWAY $away.msg $away.gonefor() @ sentaway[$encode($0)] = time() } } alias away { if (away.msg = [$*]) { echo *** You are now away [$*] } { echo *** You are now back $away.gonefor() } @ away.time = time() } alias away.idle @ function_return = time() - away.time alias away.gonefor @ function_return = [\(Away for $tdiff($away.idle())\)] #hop'96 epic4-2.10.2.orig/script/2.8script0000644000000000000000000000630307535552711013424 0ustar : { This script is intended for use with 2.8 servers on all sites. It handles some formatting options and join options for novice users This script references some aliases that are in 'basical'. Both of these scripts should be loaded from 'global', so that should not be a problem. This script will _not_ work correctly if 'basical' is not loaded from 'global'. This script is a dependency for other scripts. THIS SCRIPT MUST ALWAYS BE LOADED, OR OTHER SCRIPTS MIGHT NOT WORK! THIS VERSION IS FOR EPIC CLIENTS ONLY (EPIC3.001 or up) } # I dont know why the client cant do this... alias join { switch ($*) { (*,*) { join $before(, $*) join $after(, $*) } (#*) (&*) (0) (-*) (!*) (+*) { //join $* } () { //join -i } (*) { //join #$* } } } alias leave { switch ($0) { (*,*) { leave $before(, $0) $1- leave $after(, $0) $1- } (#*) (&*) (0) (-*) (!*) (+*) { //leave $* } () (\\*) { //leave * $1- } (*) { //leave #$* } } } alias invite { if ([$1]) {//invite $0 $1} {//invite $0 $C} } alias off { on $0 -$1- } : { I broke this, more or less on purpose on epic3.001. This makes it look like it did before. } on ^send_public * {if (iscurchan($0)) {echo > $1-} {echo $0> $1-}} on ^ctcp ^"% % ERRMSG *no such function*" on ^dcc_raw ^"% % D %" # Trace information on ^200 * { unless (tracepath) (tracepath = [$0]) xecho -b S:[$[15]0] V:[$[10]2] U:[$[20]4] @ tracepath #= [!$4] } on ^201 * xecho -b $1 Class[$2] ==> $3- on ^202 * xecho -b $1 Class[$2] ==> $3- on ^203 * xecho -b S:[$[15]0] UNKNOWN $3 on ^204 * xecho -b S:[$[15]0] OPER [$[30]tr(/[/!/$3) on ^205 * xecho -b $1 Class[$2] ==> $3- on ^206 * { if (tracepath) echo TRACE PATH: $tracepath xecho -b S:[$[15]0] SERV [$[25]5] [$[-4]3] [$[-5]4] (tracepath = []) } on ^207 * xecho -b $1 Class[$2] ==> $3- on ^208 * xecho -b $1 Class[$2] ==> $3- on ^209 * xecho -b $1 $2 Entries linked: $3 # Stats information ON ^211 * { XECHO -b $1: Sent: ${[$4]/1024}mB Received: ${[$6]/1024}mB SendQ: $2 Connected for: $tdiff2($7) Idle: $8 [$9-] } on ^211 * xecho -b $[40]1 $[10]2 $[10]3 $[10]4 $[10]5 $[12]6 $7- on ^212 * xecho -b $[10]1 $2 on ^213 * xecho -b $1:$2:$3:$4:$5:$6 on ^214 * xecho -b $1:$2:$3:$4:$5:$6 on ^215 * xecho -b $1:$2:$3:$4:$5:$6 # K lines # efnet version : { on ^216 * { (astuff = [$*]) pop astuff pop astuff (k.user = pop(astuff)) shift astuff shift astuff (k.host = shift(astuff)) xecho -b K $lformat(30 [$k.user@$k.host]) [$astuff] } } # a2.9 version on ^216 * xecho -b $1:$2:$3:$4:$5- on ^217 * xecho -b $1:$2:$3:$4:$5:$6 on ^218 * xecho -b $1:$2:$3:$4:$5:$6 on ^241 * xecho -b $1:$2:$3:$4:$5:$6 # ef2.9 version #on ^218 * xecho -b $1:$2:$3:$4:$5:$6:$7:$8 # Get da5id's script for handling 278 and 279 numerics. : { 220 is used by .troy versions to return information on host masks being enforced locally. } on ^220 * xecho -b $1 $[10]2 $3 # Service list: on ^231 * xecho -b Service $1 \($0\) # Ban list: on ^367 * xecho -b $[$CHANNEL_NAME_WIDTH]1 $2- # Compatibility with BX alias evalserver xeval -server $* # Compatibility with EPIC4pre1.013 through EPIC4pre1.047 on ^set "CONTROL_C_COLOR ON" set color on on ^set "CONTROL_C_COLOR OFF" set color off epic4-2.10.2.orig/script/commandqueues0000644000000000000000000001143110015324457014523 0ustar # 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 epic4-2.10.2.orig/script/mkpdir0000644000000000000000000000022207522602043013136 0ustar #Simulate /exec mkdir -p alias mkpdir (dirname, void) { while (mkdir($dirname) != 0) { mkpdir($before(-1 / $dirname)) } } #hop'01 epic4-2.10.2.orig/script/genalias0000644000000000000000000000215007535120120013430 0ustar # GENERAL ALIASES, 1993 # Yea -- i do really use these every day /******************** Commands *************************************/ alias + mode $C +vvv $0 $1 $2;mode $C +ooo $0 $1 $2 alias - mode $C -ooo $0 $1 $2 alias n nick $0 alias ! kick $C $* alias !! autokick $0 alias !!! kick * $0 $3-;kick * $1 $3-;kick * $2 $3- alias a+ set input_aliases on alias a- set input_aliases off alias M mode * $* alias I invite $* $C alias send dcc send $0 $1 alias get dcc get $0 $1 alias close dcc close send $0 alias ban mode * +b $0 alias umode mode $N $* alias ws umode +ws alias nws umode -ws alias client ctcp $0 version alias finger ctcp $0 finger #alias log window log $0 alias cycle {@ :temp = C;leave *;wait;join $temp} alias script send $0 $which($1) alias chops who * -chop alias recho eval echo $* alias boot eval / damn! i wish i had a fancy kick alias! *pout*;kick * $0 alias brb eval away *click* Hello. You have reached the answering machine of $N: $* alias bbl eval away Time departed: $stime($time()) Est. Time of return: $0 Times in CDT alias when assign function_return $tdiff(${time() - [$0]}) #hop'93 epic4-2.10.2.orig/script/dcc_spacefix0000644000000000000000000000142410002456151014262 0ustar # # The DCC protocol specifies no way to include spaces in the # filename of a request. Some clients attempt to fix this by # enclosing spaced filenames in double quotes, but epic doesn't # decode these requests correctly. # # What this script does is convert these requests to a form # that epic normally can handle. # on #^ctcp_request 0 "% % DCC \[SEND ACCEPT\] *\"* *\"*" { @ :ll = before(\\" $2-) @ :mm = after(\\" $2-) @ :mm = before(-1 \\" $mm) @ :mm = urlencode($mm) @ :rr = after(-1 \\" $2-) pretend :$0!$userhost() PRIVMSG $1 :$chr(1)$ll$mm$rr$chr(1) } # # This is a new feature in epic which conflicts with this script. You may want # to not load this script and leave this feature on instead. # set dcc_dequote_filenames off epic4-2.10.2.orig/script/vi-binds0000644000000000000000000000332707525764605013414 0ustar # # This script makes an attempt to simulate vi keybindings using the # ^E sticky keybinding. Who knows how successful I will be... # This is very much a work in progress. Not every vi keybinding maps # nicely to an ircII keybinding. Some of these new keybindings can just # as well be added to epic, some of them may never be. Suggestions for # improvements are always welcome. # bind ^E ^E bind ^E0 BEGINNING_OF_LINE bind ^E$$ END_OF_LINE bind ^Ew FORWARD_WORD bind ^EW FORWARD_WORD bind ^Eb BACKWARD_WORD bind ^EB BACKWARD_WORD #bind ^Ee #bind ^EE bind ^Ea parse_command { parsekey FORWARD_CHARACTER # Insert mode? } bind ^EA parse_command { parsekey END_OF_LINE # Insert mode? } #bind ^Er #bind ^ER bind ^Ep YANK_FROM_CUTBUFFER bind ^Ex DELETE_CHARACTER bind ^EX BACKSPACE #bind ^Ey #bind ^EY #bind ^Ei #bind ^EI bind ^Eh BACKWARD_CHARACTER bind ^El FORWARD_CHARACTER bind ^Ek BACKWARD_HISTORY bind ^Ej FORWARD_HISTORY #bind ^Eu #bind ^EU #bind ^Ecw #bind ^EcW #bind ^Ecb #bind ^EcB #bind ^Ec$$ #bind ^EC #bind ^Ec0 #bind ^EdW #bind ^Edb #bind ^EdB #bind ^Ed$$ #bind ^Ed0 #hop'y2k epic4-2.10.2.orig/script/efnext0000644000000000000000000000171607260474517013166 0ustar /* requires EPIC4 or better to run properly. if someone would like * to backport this to be friendly to ircII that would be spiffy. * * Written because EPIC4 doesn't change your "current channel" to * the OJOINed channel when you use OJOIN to join a channel. * * November 14, 2000 - William Rockwood */ alias ojoin { if (![$1]) { echo $G Error: Not enough arguments echo $G Usage: /ojoin <[#]channel> <[@][-][+]> } { ^stack push on 329 ^on -329 "*" { @ :jchan = [$1] ^channel $jchan ^stack pop on 329 } switch ($*) { (#*) { quote ojoin $* } (*) { quote ojoin #$* } } } } # wjr'y2k epic4-2.10.2.orig/script/functions0000644000000000000000000002520107775617245013710 0ustar # # Some misc functions.. for 2.2 and beyond. # by: Ian Frechette (frechett@spot.colorado.edu) # Wed Aug 18 00:26:53 MDT 1993 # # ircII scripting note. @ var = is used a lot. One case # where it is not feasible to use the @ var = othervar or @ var = funct() # format is when the $(stuff) construct is needed. In that case you # must surround it with []. e.g. @ blah = [$($0)] will assign # to 'blah' the contents of the variable named in arg 0. # # # These have been updated to handle multiple words. # format and lformat differ from $[-num]var and $[num]var in that # They don't chop off the string if it is too long. # These are obsoleted by the built in $pad() function. # alias format { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([-$0]IRCII.word)] } { @ function_return = IRCII.word } } alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = IRCII.word } } # pluck a word from a list. # eg. $blah == "one two three four five" # $pluck(blah three) returns "one two four five" # alias pluck @ function_return = $0 = $remw($1 $($0)) /* These map some of the original functions to their EPIC names. */ alias notword @ function_return = notw($*) alias remove @ function_return = remw($*) /* * All of these functions have been obsoleted by built in functions * in ircII-EPIC. Some of them were obsoleted by comparable functions, * and several of them were re-implemented as built-in functions for no * reason other than to provide a faster alternative to these functions. */ /* # # reverse a string fed to it. The first argument is the width of the # field in which to right justify the reversed text # $reverse(65 one two three) returns.. # eerht owt eno # if 0 is given as the width it's reversed and output left justified # # Obsoleted by the built-in $reverse(). You can get the effect of the # 'width' argument by specifying the width operator: # $[-65]reverse(one two three) # alias reverse { ^assign -rev.result @ rev.ind = 0 @ rev.str = [$1-] while (mid($rev.ind 1 $rev.str)!=[]) { @ rev.result = mid($rev.ind 1 $rev.str) ## rev.result @ rev.ind = rev.ind + 1 } # This right justifies to a field with of $0. # strip out the format() function if you don't want it formatted. @ function_return = format($0 $rev.result) } # # Center text within a given width. center(width text) # "$center(10 one)" returns " one" # this might not make sense at first, but it saves a lot of cursor travel # not writing all the spaces on the right side. # # Obsoleted by the built-in $center(). # alias center { @ IRCII.word = [$1-] @ IRCII.wordl = @IRCII.word @ IRCII.width = [$0] if (IRCII.wordl > IRCII.width) { @ function_return = ircII.word } { @ function_return = [$([${(IRCII.width - ircII.wordl)/2}])] ## IRCII.word } } # # This is the huge beastly CPU expensive search and replace function # written entirely in ircII script language. # $sandr(search pat/replace pat/words) # the search and replace patterns can contain spaces or any other chars # with the exception of '/'. # # Obsoleted by the built-in $sar(), which has more features, allows # more flexibility, and is orders of magnitude faster. # alias sandr { @ sr.src = left($index(/ $*) $*) @ sr.rep = mid(${index(/ $*) +1} ${rindex(/ $*) - index(/ $*) +1} $*) @ sr.word = mid(${rindex(/ $*) + 1} 512 $*) @ sr.srcl = @sr.src @ sr.wordl = @sr.word @ sr.cnt1 = 0 @ sr.cnt2 = 0 @ sr.lmark = 0 @ sr.gotit = 0 ^assign -sr.fstring while (sr.cnt1 < sr.wordl) { @ sr.scnt1 = sr.cnt1 while ((mid($sr.cnt1 1 $sr.word) == mid($sr.cnt2 1 $sr.src)) && (sr.cnt2 < sr.srcl)) { if (sr.cnt2 == sr.srcl - 1) { @ sr.gotit = 1 } @ sr.cnt1 = sr.cnt1 + 1 @ sr.cnt2 = sr.cnt2 + 1 } @ sr.cnt2 = 0 if (sr.gotit) { @ sr.fstring = sr.fstring ## mid($sr.lmark ${sr.scnt1 - sr.lmark} $sr.word) ## sr.rep @ sr.gotit = 0 @ sr.lmark = sr.cnt1 } { @ sr.cnt1 = sr.cnt1 +1 } } @ sr.fstring = sr.fstring ## mid($sr.lmark 512 $sr.word) @ function_return = sr.fstring } # # The perfect complement to the $word() function. # $notword(index words) returns words minus the indexed word. # the special handling of nw.sep is to deal with the cases when # the index points to the first or last word. # # Obsoleted by the built-in $notw() function, which actually works reliably # if $~ appears more than once in the arguments (this breaks in that case) # alias notword { if ([$0] > 0) { if (([$0] > 1) && ([$0] < #)) { @ nw.sep = [ ] } { @ nw.sep = [] } @ function_return = [$(1-${[$0]-1})] ## nw.sep ## [$(${[$0]+1}-)] } { @ function_return = [$1-] } ^assign -nw.sep } # If you want to look an array.. Type /show # Lists keys and contents ^alias show { if ( [$($0)] ) echo $0 $($0) foreach $0 ii { show $0.$ii } ^assign -ii } # push an item onto the head of a list # this only takes the name of the list instead of the variable itself. # examples. # /push list Item # or if (push(list Item)) { echo push successful } { echo push failed } # echo $list returns 'Item' # # Obsoleted by the built-in $push() function, and built-in PUSH command. # alias push { if (![$1]) { @function_return = 0 } { eval @ $0 = [$1- $($0)];@function_return = 1} } # pop an item off a list. Specified with $pop(listname) # note there is no $ in front of listname. # examples. # /eval echo $pop(list) returns 'Item' and the list is shortened # push List2 $pop(List1) moves first item from List1 to List2 # # Obsoleted by the built-in $pop() function, and built-in POP command. # alias pop { @function_return = word(0 $($0)) eval @ $0 = notword(1 $($0)) } # # Obsoleted by the built-in $remw() function # alias remove { @ rem.tmp = [$($0)] while (rmatch($1 ${rem.tmp = pluck(rem.tmp $1)})) {#} @ function_return = rem.tmp } # This alias sorts flat lists case insensitive # IT can be easily changed to sort case sensitive by removing the # $toupper() call. # operation.. $sort(list or words here) will return a string with # the list of words sorted in ascending order. # to sort in reverse order # # Obsoleted by the built-in $sort() function. # alias sort { @ sort.tmp = [$*] while (sort.word = pop(sort.tmp)) { eval @ sort.str.$encode($toupper($sort.word)) = sort.word } @ sort.sep = [] foreach sort.str ii { # sort ascending @ sort.tmp = sort.tmp ## sort.sep ## sort.str[$ii] # sort descending # push sort.tmp sort.str[$ii] ^assign -sort.str[$ii] @ sort.sep = [ ] } @ function_return = sort.tmp ^assign -sort.sep ^assign -sort.tmp } */ # $min() $max(). fe (min leftw max rightw) foo bar { alias $foo return \$$bar\(1 \$numsort($*)\) } # $regpattern() and $regfilter() work exactly like $pattern() # and $filter except that they use regexes rather than wildcards. stack push alias alias alias alias (args) fe (filter ! pattern "") func cond { //alias $msar(gr/\${func}/$func/\${cond}/$cond/args) } alias reg${func} (ret) { @:reg=regcomp($shift(ret)) fe ret foo { @ foo = ${cond}regexec($reg $foo) ? [] : foo=~[* *] ? ["\$foo"] : foo } @regfree($reg) return $ret } stack pop alias alias # A version of $indextoword() that ignores double quoting. alias indextowword return $indextoword($tr(/"/_/$*)) alias wwordtoindex return $wordtoindex($tr(/"/_/$*)) # Character jot. # $jotc(afWZ) returns abcdefWXYZ. alias jotc return $chr($jotm($ascii($*))) alias jotm (ret) { fe ret foo bar { @ foo = jot($foo $bar) @ bar = [] } return $ret } # A version of $mask() that operates with multiple args. alias maskm (mask,args) { fe args arg { @ arg = mask($mask $arg) } return $args } # $randn( rep val ) returns rep random numbers up to val. alias randn (args) { @ :rep = isnumber(b10 $args) ? shift(args) : 1 @ :val = isnumber(b10 $args) ? shift(args) : 0 eval return$repeat($rep \$rand\($val\)) } # $replace(#x# x $jot(0 3)) returns #0# #1# #2# #3#. alias replace (args) { @ :in = shift(args) @ :rep = shift(args) fe args arg { @ arg = sar(g/$rep/$arg/$in) } return $args } # Shuffle functions shuffle their args. # The s in shuffles stands for "slow". # The f in shufflef stands for "fast". # The c in shufflec stands for "char". # The slow version is actually faster than the fast for smaller arg lists. alias shufflec return $chr($shufflef($ascii($*))) alias shufflef (args) { @ :foo = randn($#args 2) if (#args < 1000) { return $shuffles($copattern(0 foo args)) $shuffles($copattern(1 foo args)) } else { return $shufflef($copattern(0 foo args)) $shufflef($copattern(1 foo args)) } } alias shuffles { @ :w = 0 @ :ret = [] if (xdebug(extractw) =~ [-*]) { fe ($*) foo { @ splice(ret $rand(${++w}) 0 $foo) } } else { @ :space = chr($jot(1 32)) fe ($*) foo { @ splice(ret $rand(${++w}) 0 ${0>index("$space" $foo)?foo:["$foo"]}) } } return $ret } # A lot more like the shell version of "uniq -d" than $uniq(). # $uniqd() removes unique items in a list. alias uniqd (ret) { fe ret foo { if (last!=foo) { @ :last = foo @ :foo = [] } } return $ret } # $wordn(0.9.2,9.0.2 $jot(0 9)) returns "0 2 4 6 8 9 7 5 3 1". alias wordn (num,args) { @ :num = split(, $num) fe num foo { @ :foo = foo =~ [*.*] ? jot($split(. $foo)) : foo } fe num foo { @ foo = word($foo $args) } return $num } # $cut(0.9.2,9.0.2 : $unsplit(: $jot(0 9))) returns "0:2:4:6:8:9:7:5:3:1". alias cut (num,sep,args) { switch ($num) { (*,*) { @ :mid = (count(, $num) + 1) / 2 return $cut($before($mid , $num) $sep $args)$sep$cut($after($mid , $num) $sep $args) } (*.*) { return $cut($unsplit(, $jot($split(. $num))) $sep $args) } (*) { return $before(1 $sep ${num ? after($num $sep $args) : args}$sep) } } } # Splice characters. The bless is so it can be called on local vars. alias splicec (var,start,count,replace) { bless ^assign $var $ascii($($var)) @ function_return = chr($splice($var $start $count $ascii($replace))) ^assign $var $chr($($var)) } # Bit of a hack here. Return all args with spacing removed. alias words return $unsplit(" " $*) # $chvoices() returns the voiced users on a channel. # $chnovoices() is the compliment. stack push alias alias alias alias (args) { fe (chhops 1 ishalfop nochhops 0 ishalfop chvoices 1 ischanvoice chnovoices 0 ischanvoice) cmd val fn { //alias $msar(gr/\$cmd/$cmd/\$val/$val/\$fn/$fn/args) } } alias $cmd (args) { @ :chan = shift(args) @ :ret = chanusers($chan) fe ret user { @ user = $val == $fn($user $chan) ? user : [] } return $ret } stack pop alias alias alias mychats (args) { @ :function_return = dccctl(typematch chat) fe function_return dcc {@ :dcc = [=]##dccctl(get $dcc user)} } epic4-2.10.2.orig/script/country0000644000000000000000000001721507415131614013367 0ustar /* * This script is used with permission. * * Copyright 1993, 1994 Daniel Cedras * Copyright 1995, 1996 Daniel Cedras and Jeremy Nelson */ /* Country code lookup Country information compiled by Daniel Cedras (cedras@texas.net) Software written by Jeremy Nelson Requires ircII-EPIC4pre. Last modified (01/31/97) by Jeremy Nelson How to use: /country Brief Usage Instructions. /country With no flags, the alias attempts to look up the userhost of the argument "as-if" it were a nickname. If the userhost lookup is successful, it then figures out the name of that nick's domain. If the lookup is not successful, then it will try to do a lookup on the name itself. /country Supported for backwards compatibility are the ability to specify flags. All flags (except for -n, which is strictly ignored) have the same effect, and that is to circumvent the userhost lookup and do a direct lookup on the argument. The previous meanings of the flags are no longer supported as they make no sense now. /lcountry /lcode Do a forced lookup NOTE: You can (and should) use wildcards anywhere you want. */ alias country.help { echo *** USE: /country or /country echo *** Will tell you what country nickname is from or echo *** What the country corresponding to the Isometric code is echo *** /country echo *** Will tell you what the Isometric code is for that country echo *** Using any flag besides -n will bypass the nick lookup. echo *** This is required for arguments with asterisks in them. } alias country { switch ($0) { () {country.help} (-n) {country $1-} (-*) {country.lookup $1-} (*\\**) ("* *") {country.lookup $*} (*) { local args $* userhost $0 -cmd { bless if ([$3] == []) { country.lookup $args } { country.lookup $after(-1 . $4) } } wait } } } /* This is an internal alias -- not intended for direct call */ alias country.lookup { echo *** Looking for  $TOUPPER($*)  ... Be patient ! fe ($country.info) aa ab { if (match("$*" "$aa") || match("$*" "$ab")) { echo +++ $toupper($aa) is $toupper($ab) } } echo *** DONE ! } alias lcountry country -c alias lcode country -i ############ THE ACTUAL DATABASE: push country.info Afghanistan AF Albania AL Algeria DZ "American Samoa" AS push country.info Andorra AD Angola AO Anguilla AI Antarctica AQ push country.info "Antigua and Barbuda" AG Argentina AR Armenia AM Aruba AW push country.info Australia AU Austria AT Azerbaijan AZ Bahamas BS push country.info Bahrain BH Bangladesh BD Barbados BB Belarus BY push country.info Belguim BE Belize BZ Benin BJ Bermuda BM push country.info Bhutan BT Bolivia BO Bosnia BA Botswana BW push country.info "Bouvet Island" BV Brazil BR "British Indian Ocean Territory" IO push country.info "Brunei Darussalam" BN Brunei BN Bulgaria BG "Burkina Faso" BF push country.info Burundi BI "Byelorussian SSR" BY Cambodia KH Cameroon CM push country.info Canada CA "Cap Verde" CV "Cayman Islands" KY "Central African Republic" CF push country.info Chad TD Chile CL China CN "Christmas Island" CX push country.info "Cocos (Keeling) Islands" CC Columbia CO Comoros KM Congo CG push country.info "Cook Islands" CK "Costa Rica" CR "Cote D'Ivoire" CI Croatia HR push country.info Hrvatska HR Cuba CU Cybrus CY Czechoslovakia CS push country.info Denmark DK Djibouti DJ Dominica DM "Dominican Republic" DO push country.info "East Timor" TP Ecuador EC Eqypt EG "El Salvador" SV push country.info "Equatorial Guinea" GQ Estonia EE Ethiopia ET "Falkland Islands" FK push country.info Malvinas FK "Faroe Islands" FO Fiji FJ Finland FI push country.info France FR "French Guiana" GF "French Polynesia" PF push country.info "French Southern Territories" TF Gabon GA Gambia GM Georgia GE push country.info Germany DE Deutschland DE Ghana GH Gibraltar GI Greece GR push country.info Greenland GL Grenada GD Guadeloupe GP Guam GU push country.info Guatemala GT Guinea GN "Guinea Bissau" GW push country.info Gyana GY Haiti HT "Heard and Mc Donald Islands" HM push country.info Honduras HN "Hong Kong" HK Hungary HU Iceland IS India IN push country.info Indonesia ID Iran IR Iraq IQ Ireland IE Israel IL Italy IT push country.info Jamaica JM Japan JP Jordan JO Kazakhstan KZ Kenya KE push country.info Kiribati KI "North Korea" KP "South Korea" KR Kuwait KW push country.info Kyrgyzstan KG Lao LA Laos LA Latvia LV Lebanon LB Lesotho LS push country.info Liberia LR "Libyan Arab Jamahiriya" LY Lybia LY push country.info Liechtenstein LI Lituania LT Luxembourg LU Macau MO push country.info Macedonia MK Madagascar MG Malawi MW Malaysia MY push country.info Maldives MV Mali ML Malta MT "Marshall Islands" MH push country.info Martinique MQ Mauritania MR Mauritius MU Mexico MX push country.info Micronesia FM Moldova MD Monaco MC Mongolia MN Montserrat MS push country.info Morocco MA Mozambique MZ Myanmar MM Namibia NA Nauru NR push country.info Nepal NP Netherlands NL "Netherlands Antilles" AN push country.info "Neutral Zone" NT "New Caledonia" NC "New Zealand" NZ push country.info Nicaragua NI Niger NE Nigeria NG Niue NU "Norfolk Island" NF push country.info "Northern Mariana Islands" MP Norway NO Oman OM Pakistan PK push country.info Palau PW Panama PA "Papua New Guinea" PG Papua PG push country.info "New Guinea" PG Paraguay PY Peru PE Philippines PH Pitcairn PN push country.info Poland PL Portugal PT "Puerto Rico" PR Qatar QA Reunion RE push country.info Romania RO "Russian Federation" RU Rwanda RW push country.info "Saint Kitts and Nevis" KN "Saint Lucia" LC push country.info "Saint Vincent and the Grenadines" VC Samoa WS push country.info "San Marino" SM "Sao Tome and Principe" ST "Saudi Arabia" SA push country.info Senegal SN Seychelles SC "Sierra Leone" SL Singapore SG push country.info Slovania SI "Solomon Islands" SB Somalia SO "South Africa" ZA push country.info Spain ES "Sri Lanka" LK "St. Helena" SH push country.info "St. Pierre and Miquelon" PM Sudan SD Suriname SR push country.info "Svalbard and Jan Mayen Islands" SJ Swaziland SZ Sweeden SE push country.info Switzerland CH "Cantons of Helvetia" CH push country.info "Confederation Helvetique" CH "Syrian Arab Republic" SY push country.info Syria SY Taiwan TW Tajikistan TJ Tanzania TZ Thailand TH push country.info Togo TG Tokelau TK Tonga TO "Trinidad and Tobago" TT push country.info Tunisia TN Turkey TR Turkmenistan TM "Turks and Caicos Islands" TC push country.info Tuvalu TV Uganda UG "Ukranian SSR" UA "United Arab Emirates" AE push country.info "United Kingdom" UK "Great Britain" GB push country.info "United States of America" US "United States" US push country.info "Unites States Minor Outlying Islands" UM Uruguay UY USSR SU push country.info "Soviet Union" SU Uzbekistan UZ Vanuatu VU Vatican VA push country.info "Vatican City State" VA Venezuela VE "Viet Nam" VN push country.info "Virgin Islands (US)" VI "Virgin Islands (UK)" VG push country.info "Wallis and Futuna Islands" WF "Western Sahara" EH push country.info Yemen YE Yugoslavia YU Zaire ZR Zambia ZM Zimbabwe ZW #EXTRAS push country.info "Commercial Organization (US)" COM push country.info "Educational Institution (US)" EDU push country.info "Networking Organization (US)" NET push country.info "U.S. Military" MIL "Non-Profit Organization" ORG push country.info "Government (US)" GOV push country.info "Korea - Democratic People's Republic of" KP push country.info "Korea - Republic Of" KR push country.info "Lao People's Democratic Republic" LA push country.info Slovakia SK ############# END OF THE /COUNTRY FUNCTION /* This file has not been truncated! */ epic4-2.10.2.orig/script/altchan.bj0000644000000000000000000000172107763141216013670 0ustar /* Copyright (c) 2003 David B. Kratter (BlackJac@EFNet) Version: 1.0.2003.12.02.1 This will allow you to toggle between hidden windows 1 through 20 more easily. Press Esc+1 to toggle between windows 1 and 11, Esc+2 for win- dows 2 and 12, etc., up through Esc+0 for windows 10 and 20. */ alias toggle.window (number, void) { if (@number) { if (number) { @ :window = winnum() == number ? [1$number] : number if (winnum($window) != -1) { window swap $window } else { if (window < 10 && winnum(1$window) != -1) { window swap 1$window } else if (window > 10 && winnum($right(1 $window) != -1)) { window swap $right(1 $window) } else { xecho -c Window $window does not exist } } } else { @ :window = winnum() == 10 ? 20 : 10 if (winnum($window) != -1) { window swap $window } else { xecho -c Window $window does not exist } } } } fe ($jot(0 9 1)) tt { bind ^[$tt parse_command toggle.window $tt } epic4-2.10.2.orig/script/nicks0000644000000000000000000000055507213031315012763 0ustar # This lets you assign aliases for peoples nicknames. # For example, of you do: /ASSIGN BC BigCheese # Then you can do: /MSG BC Hi there! # # These dont "link" well with other aliases... should # probably be handled another way. # alias msg { if ( [$($0)] ) { //msg $($0) $1- } { //msg $0 $1- } } alias query { if ( [$($0)] ) { //query $($0) } { //query $0- } } epic4-2.10.2.orig/script/events.hop0000644000000000000000000000175307213031315013746 0ustar # This set of filters was done to replace the # 'set MODERN_ART' function which used to be # in an ancient ircII shortly before invention # of the '/on' command. :) # on ^timer "*:00*" echo *** The time is $0 on #-msg 30 * set status_user - last: $0 on ^names * echo $[15]0 $1- on ^names \* echo * $1- on ^who "Channel *" # on ^who * { if ( [$0] == [*] ) { echo $[9]1 [$[3]2] [ ] \($3@$4) } { echo $[9]1 [$[3]2] [$[10]0] \($3@$4) } @ who_counter++ } on ^315 * { echo TOTAL NUMBER OF LISTINGS - $who_counter @ who_counter = 0 } on ^list * echo $[15]0 $[4]1 $2- on ^list "\* *" echo -- -- $[4]1 $2- on #-list 3 "Channel" @ numlists = 0 on #-list 3 * @ numlists++ on ^323 * { echo TOTAL CHANNELS  - $numlists @ numlists = 0 } on ^send_public * { if ( [$0] == C ) { echo <$N> $1- } { echo -->[$0] $1- } } /* bans are automatically counted by the client */ on ^368 * echo Total number of bans - $1 # lynx92/hop'94 epic4-2.10.2.orig/script/keybinds0000644000000000000000000000170107525764605013503 0ustar #$EPIC: keybinds,v 1.2 2002/08/12 16:59:49 jnelson Exp $ /* * KEY BINDINGS, 1993 */ /********************* Key Bindings *********************************/ # the cursor keys bind ^[. end_of_line bind ^[, beginning_of_line # these are set automatically, but this is just in case. bind ^? backspace bind ^h backward_character bind ^b bold bind ^c switch_channels bind ^[i toggle_insert_mode bind ^w next_window # erasing bindings bind ^U erase_line bind ^d^w delete_next_word bind ^d^p delete_previous_word bind ^d^e erase_to_end_of_line bind ^d^a erase_line bind ^d^y yank_from_cutbuffer bind ^d^d erase_line # nice stuff to have bind ^d^j parse_command flush bind ^[c clear_screen bind ^[r refresh_screen bind ^[l parse_command leave * bind ^[i parse_command join -invite # vt100-type keys bind ^[[1~ beginning_of_line bind ^[[2~ toggle_insert_mode bind ^[[3~ delete_character bind ^[[4~ end_of_line bind ^[[5~ scroll_backward bind ^[[6~ scroll_forward epic4-2.10.2.orig/script/alias0000644000000000000000000000153007415131614012746 0ustar # Comfortable aliases... see /help load alias # alias mr msg $, $* alias ma msg $. $* alias wa whois $. alias ia invite $. $C # # command collision kludges alias no notice alias nf notify alias la lastlog # # other quickies alias " quote alias lf set logfile $* alias unset set -$* alias unalias alias -$* alias alarm set clock_alarm $* alias clock set clock $* alias h+ ^set hold_mode on alias h- ^set hold_mode off # # These aliases have been taken and adapted from the .ircrc's # posted to alt.irc some time ago... # alias shields_up ignore $, msgs notices alias protect mode $C +ni alias unprotect mode $C -ni alias chops who $C -chop alias wjoin window new channel $0 name $* alias talkto window new name $0;query $0 alias wquery talkto alias oops { ^assign alias.oops $B msg $. Sorry, that wasn't meant for you. msg $0 $alias.oops } # # lynx91,92 epic4-2.10.2.orig/script/data_array0000644000000000000000000001410707750415413013774 0ustar # Array manipulation functions. # # # General one liners. Brief description: # # The *item functions operate on one array element. # The *items functions operate on as many elements as there are args. # # Note that unlike their inbuilt counterparts, these generally accept negative # item numbers as the distance from the top of the array, starting with -1. # # Let's start with some basics: # # getndelitems: splice the items $1- from the array and return them as a list. # getndelindex: splice the indices $1- from the array and return them as a list. # getnrolitems: Splice items $2- from $0, put them at the end of $1, and return them. # itemnorm: Supporting function. Fixes/removes invalid item numbers. # alias itemnorm (ar,it) @:ni=numitems($ar);fe it it {@it+=0<=it?0:ni,it=0<=it&&it numitems else setranditem. # setuniqitem[s]: setnextitem if the array item[s] doesn't already exist. # alias setnextitem (ar,args) return $setitem($ar $numitems($ar) $args) alias setnextitems (ar,args) fe args foo {@foo=setitem($ar $numitems($ar) $foo)};return $args alias setranditem (ar,args) return $setitem($ar $rand($numitems($ar)) $args) alias setranditems (ar,args) fe args foo {@foo=setitem($ar $rand($numitems($ar)) $foo)};return $args alias setrmaxitem (ar,it,args) @:ni=numitems($ar);return $setitem($ar ${it>ni?ni:rand($ni)} $args) alias setrmaxitems (ar,it,args) @:ni=numitems($ar);fe args foo {@foo=setitem($ar ${it>ni?ni++:rand($ni)} $foo)};return $args alias setuniqitem (ar,args) if (0>finditem($ar $args)){return $setitem($ar $numitems($ar) $args)} alias setuniqitems (ar,args) fe args foo {@foo=0>finditem($ar $foo)?setitem($ar $numitems($ar) $foo):-1};return $args # # Delete contents matching $1- of array $0. # If an arg isn't specified, it equates to *. # alias array.purge (args) { @ :mask = [] fe ($getarrays($shift(args))) foo { @ 1>#args ? delarray($foo) : delitems($foo $getmatches($foo $args)) } } # # Load files $1- into array $0 # alias array.read (args) { @ :ar = shift(args) @ :it = numitems($ar) fe ($glob($args)) fn { @ :fd = open($fn r) while ((:dt = read($fd)) || !eof($fd)) { @ usetitem($ar ${it++} $dt) } @ close($fd) } } # # Load files $* into arrays of the same name. # alias array.nread (args) { fe ($glob($args)) fn { @ :it = numitems($fn) @ :fd = open($fn r) while ((:dt = read($fd)) || !eof($fd)) { @ usetitem($fn ${it++} $dt) } @ close($fd) } } # # Give a brief summary of all matching arrays, or all arrays. alias array.stat { fe ($getarrays($*)) foo { echo $numitems($foo)/$#listarray($foo)/$@listarray($foo) $foo } } # # I tried to clean these up. Really I did. Just give me some time. # # Brief summary: # .dump/.grep displays matching contents of matching arrays (in different ways). # .codump/.cogrep as above but sews together multiple arrays for displaying. # .idump/.igrep/.coidump/.coigrep sorted versions of above. # .write/.iwrite/.nwrite/.niwrite inverse of .read, differing in the order in which lines are written. # .flush/.iflush/.nflush/.niflush write and delete the arrays. # stack push alias alias fe (dump " -banner" "[\$[-4]item \$[-2]#content \$[-3]@content] " grep " -nobanner" "") cmd banner fnord { fe (i$cmd igetitem igetmatches $cmd getitem getmatches) foo bar baz { alias array.$foo (arrays default *, mask default *) fe ($getarrays($arrays)) array \{echo \$numitems($array)/\$#listarray($array)/\$@listarray($array) \$array\;fe \(\$${baz}($array $mask)\) item \{@:content=${bar}($array $item)\;echo $fnord\$content\}\}\;echo $chr(2)\$#getarrays($arrays)$chr(2) arrays listed } } fe (dump "\$array [\$[-4]item \$[-2]#content \$[-3]@content] " grep "") cmd fnord { fe (coi$cmd "indextoitem($array $igetmatches" ")" co$cmd getmatches "") foo bar baz { alias array.$foo @:array=[\$0]\;@:mk=[\$1]\;@:ar=beforew($mk $2-)\;fe \(\$${bar}($array $afterw($mk $2-))$baz\) item \{@:content=\;fe ($ar) foo {@push(content $getitem($foo $item))}\;echo $fnord\$content\} } } alias alias (args) { //alias $args fe (write flush getmatches getitem) foo { @ sar(gr/i$foo/$foo/args) } //alias $args } alias array.iwrite (args) { @ :fd = open($shift(args) w) fe ($getarrays($shift(args))) foo { fe ($igetmatches($foo ${args?args:[*]})) bar { @ write($fd $igetitem($foo $bar)) } } @ close($fd) } alias array.niwrite (args) { fe ($getarrays($shift(args))) foo { @ :fd = open($foo w) fe ($igetmatches($foo ${args?args:[*]})) bar { @ write($fd $igetitem($foo $bar)) } @ close($fd) } } alias array.iflush array.iwrite $*;array.purge $1- alias array.niflush array.niwrite $*;array.purge $* stack pop alias alias epic4-2.10.2.orig/script/scan0000644000000000000000000000100407415131614012575 0ustar # # Just a quick and dirty /scan routine. It's about as fast as I could # make it. It could be fast if the nicks weren't aligned but that'd be # ugly. # # - whitefang (thall@magenet.com) # alias scan (chan) { @ chan = ischannel($chan) ? chan : C unless (chan) { return } xecho -b Users on $chan: fe ($strip(?. $channel($chan))) n1 n2 n3 n4 n5 n6 { echo $[11]n1 $[11]n2 $[11]n3 $[11]n4 $[11]n5 $[11]n6 } } # tjbh/2000 epic4-2.10.2.orig/script/ls0000644000000000000000000000423607213031315012272 0ustar /* ls.irc by archon August 16, 1996 because /exec ls is just too easy! and i couldn't think of another use for $glob() */ alias ls { switch ($0) { () { fe ($glob(*)) ii jj kk ll { echo $lformat(15, $ii) $lformat(15, $jj) $lformat(15, $kk) $lformat(15, $ll) } } (-a) { if ([$1]) { if ((match($1 $glob(.* *))) || (match($1/ $glob(.* *)))) { if (match($1/ $glob(.* *))) { fe ($pattern($1/ $glob(.* *))) qq { push tols $qq* } fe ($pattern($1 $glob(.* *))) qq { push tols $qq } }{ @ tols = [$1] } }{ echo ls: $1\: No such file or directory } }{ @ tols = [.* *] } fe ($glob($tols)) ii jj kk ll { echo $lformat(10, $ii) $lformat(10, $jj) $lformat(10, $kk) $lformat(10, $ll) } } (-s) { if ([$1]) { if ((match($1 $glob(.* *))) || (match($1/ $glob(.* *)))) { if (match($1/ $glob(.* *))) { fe ($pattern($1/ $glob(.* *))) qq { push tols $qq* } fe ($pattern($1 $glob(.* *))) qq { push tols $qq } }{ @ tols = [$1] } }{ echo ls: $1\: No such file or directory } }{ @ tols = [*] } echo $tols fe ($glob($tols)) ii jj kk { echo $lformat(20, $fsize($ii) $ii) $lformat(20, $fsize($jj) $jj) $lformat(20, $fsize($kk) $kk) } } (*) { if ((match($0 $glob(.* *))) || (match($0/ $glob(.* *)))) { if (match($0/ $glob(.* *))) { fe ($pattern($0/ $glob(.* *))) qq { push tols $qq* } fe ($pattern($0 $glob(.* *))) qq { push tols $qq } }{ @ tols = [$0] } fe ($glob($tols)) ii jj kk ll mm { echo $lformat(10, $ii) $lformat(10, $jj) $lformat(10, $kk) $lformat(10, $ll) $lformat(10, $mm) } }{ echo ls: $0\: No such file or directory } } } @ tols = qq = [] } /* format alias written by someone else */ alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] }{ @ function_return = [$IRCII.word] } @ ircii.word = [] } #archon'96 epic4-2.10.2.orig/script/sound0000644000000000000000000000151407213031315013000 0ustar /* * A simple script to support DCC SOUND as specified by mirc * I got my info directly from Tjerk, so I claim total innocence * if the implementation is wrong. :P */ on ^ctcp "% % SOUND ?*" { # Do the 'action' part of it switch ($4) { () {echo *** This sound ($3) courtesy of $0} (*) {echo * $0 $4-} } switch ($3) { (*.wav) {exec -direct ${PLAYWAV} $3} (*) {exec -direct ${PLAYWAV} $3.wav} } } /* * Usage: /sound * All the arguments are required, according to the specification. * * The first argument is who to send it to, '*' goes to current target * The second argument is the wav file to be played. The receiver is * assumed to have this wav file already.. * The rest of the arguments are "action text", ala the /me command. */ alias sound ctcp $0 SOUND $1- #hop'96 epic4-2.10.2.orig/script/starutils0000644000000000000000000000562007213031315013704 0ustar ### StarUtils.irc.epic by archon ### January 1996 ### *** REQUIRES AN IRCII-EPIC CLIENT *** /* Submitted by archon on 1/25/96, archon gave me permission to tidy up */ echo [StarUtils] Loading StarUtils v1.2.EPIC by archon - lusers beware - echo [StarUtils] Type /starhelp for help! if (!star.load) { eval ^set client_information $CLIENT_INFORMATION -&- StarUtils v1.2.EPIC by archon : clones beware. } @ star.load++ alias tkill star.tkill alias star.tkill { if ([$1] && (rmatch($0 *@*) == 1)) { @ star.killrsn = [$*] @ star.killpat = shift(star.killrsn) @ star.killcnt = 0 star.setup ^on ^205 * { @ star.killhrm = split(\[\] $3) if (#star.killhrm == 2) { @ star.killnuh = sar(r/ /!/star.killhrm) if (rpattern($star.killnuh $star.killpat)) { kill $before(! $star.killnuh) $star.killrsn @ star.killcnt++ } } { echo [TraceKill] Too many brackets in $1- } } trace wait star.cleanup echo [TraceKill] You just wasted $star.killcnt clients. @ star.killcnt = star.killpat = star.killrsn = star.killhrm = star.killnuh = [] } { echo [TraceKill] Usage: /tkill } } alias tfilter star.tfilter alias star.tfilter { if (star.pat == [$*]) { star.setup ^on ^205 * { @ star.hrm = split(\[\] $3) if (#star.hrm == 2) { @ star.nuh = sar(r/ /!/star.hrm) if (rpattern($star.nuh $star.pat)) { echo [TraceFilter] $1- } } { echo [TraceFilter] Too many brackets in $1- } } trace wait star.cleanup @ star.pat = star.hrm = star.nuh = [] } { echo [TraceFilter] Usage: /tfilter } } alias mkill star.mkill alias star.mkill { if (match(! $*)) { @ star.killdo = before(! $*) @ star.killrsn = after(! $*) fe ($star.killdo) x { kill $x $star.killrsn } @ star.killdo = star.killrsn = [] } { echo [MultiKill] Usage: /mkill nick1 nick2 nick3.. ! reason } } alias starhelp star.help alias star.help { echo *** TKILL echo *** Kills all nick!user@hosts on your server matching echo *** TFILTER echo *** Returns nick!user@hosts on your server matching echo *** MKILL ... ! echo *** Kills each nick specified before the ! with } alias star.setup { stack push on 203 stack push on 204 stack push on 205 stack push on 206 stack push on 209 ^on ^203 * ^on ^204 * ^on ^205 * ^on ^206 * ^on ^209 * } alias star.cleanup { stack pop on 203 stack pop on 204 stack pop on 205 stack pop on 206 stack pop on 209 } alias star.unload { alias_purge star assign_purge star alias -tkill alias -tfilter alias -mkill } # general aliases not specific to this script alias alias_purge { foreach -$0 ii {alias_purge $0.$ii} ^alias -$0 } alias assign_purge { foreach $0 ii {assign_purge $0.$ii} @ $0 = ii = [] } #archon'96 epic4-2.10.2.orig/script/meta0000644000000000000000000000055607525764605012630 0ustar #$EPIC: meta,v 1.2 2002/08/12 16:59:49 jnelson Exp $ /* Meta script... binds to function characters do ^[[1x~ where x is the function key */ bind ^[[11~ type f1 bind ^[[12~ type f2 bind ^[[13~ type f3 bind ^[[14~ type f4 bind ^[[15~ type f5 bind ^[OP switch_channels bind ^[OQ clear_screen bind ^[OR type msg santabot bind ^[OS parse_command leave * epic4-2.10.2.orig/script/netsplit.env0000644000000000000000000000767707415131614014330 0ustar # NETSPLIT 7 - This script does it's best to suppress the excessive # joins and signoffs due ONLY to netsplits. It should pass regular # signoffs. Need at least ircII2.2pre6 # Version II handles multiple channels. # Version III ignores bogus signoff messages # Version IV handles multiple splits. # Version V handles multiple splits and ignores bogus signoff messages. also # adds timestamps to split/join messages # Version VI For ircII2.2pre8 and beyond. Uses encode() and decode() # Version VII Fixed a problem with encode() and decode() and case # sensitive channel names, + adding lformat() # # This one by Daemon # CONVERTED for ircII2.2pre8 # Version V by poxaV (cgw@unt.edu), from Daemon's code # modified last 7-03-93 #shows the current time in HH:MM:SS format alias currtime @ function_return = strftime(%T) # This function tests for bogus splits. alias isbogus { if ([$3]) { @ function_return = 1 } if (rmatch(.$1. $isbogus.pats *..*)) { @ function_return = 1 } if (rmatch(.$2. $isbogus.pats *..*)) { @ function_return = 1 } } # Add patterns.. like /boguspat *bonk* *thud* *haha* # that will NOT be treated as server names.. alias boguspat ^assign isbogus.pats $isbogus.pats $0-;echo $0- added # Next two are pretty obvious alias boguslist echo Pats: $isbogus.pats alias bogusclear ^assign -isbogus.pats;echo Bogus list clean # If first word in Signoff contains a period then assume servername # and thus a a split. Stash in assoc array. ON ^CHANNEL_SIGNOFF "% % %.% %.%" { if (isbogus($1-)) { echo *** Quit: $1 \($0, $2-\) } { ^netbroke $encode($tolower($0)) $encode($1) $encode($2).$encode($3) $2 $3 } } # Stuff array. Tell us what server broke and set split flag. ^alias netbroke { @ signcross[$2][$0][$1] = 1 @ signoffs[$0][$1] = [$2] @ splittime[$2] = time() if ( !isbroke[$2] ) { xecho -level OPNOTES *** Netsplit at $currtime() \($3-\) @ isbroke[$2] = 1 @ splitname[$2] = [$3-] } } # When a person joins a channel.. Check them against the array. # If they are in array, then remove silently. Otherwards echo normally ON #^JOIN -10 * { ^netjoined $encode($tolower($1)) $encode($0) $1 $0 $USERHOST() } # Unset the split flag alias netjoined { if ( signoffs[$0][$1] ) { if ( isbroke[$signoffs[$0][$1]] ) { xecho -level OPNOTES *** Netjoined at $currtime() \($splitname[$signoffs[$0][$1]]\) } ^assign -isbroke[$signoffs[$0][$1]] ^assign -signcross[$signoffs[$0][$1]][$0][$1] ^assign -signoffs[$0][$1] @ rejoin = 1 } } # Clear the array every 10 minutes to prevent excess garbage on #^timer 70 * netclean alias netclean { foreach splittime ii { foreach splittime.$ii jj { if ( time() - splittime[$ii][$jj] > 300 ) { foreach signcross.$(ii).$jj xx { foreach signcross.$(ii).$(jj).$xx yy { ^assign -signcross[$ii][$jj][$xx][$yy] ^assign -signoffs[$xx][$yy] } } ^assign -xx ^assign -yy ^assign -isbroke[$ii][$jj] ^assign -splitname[$ii][$jj] ^assign -splittime[$ii][$jj] } } } ^assign -ii ^assign -jj } alias netpurge { purge isbroke purge splitname purge splittime purge signcross purge signoffs } # If you want to suppress mode changes by servers.. (usually after a split) # then uncomment next line # ^on ^mode "%.%" # # If you want to look an array.. Type /show # Lists keys and contents alias showsplit { if ([$($0)]) {echo $0 $($0)} foreach $0 ii { showsplit $0.$ii } } alias purge { foreach $0 ii { purge $0.$ii } ^assign -ii ^assign -$0 } alias wholeft { foreach signoffs ii { foreach signoffs.$ii jj { echo $lformat(15 $decode($ii)) $lformat(10 $decode($jj)) $splitname[$signoffs[$ii][$jj]] } } ^assign -ii ^assign -jj } # format and lformat differ from $[-num]var and $[num]var in that # They don't chop off the string if it is too long. alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } epic4-2.10.2.orig/script/CVS/0000755000000000000000000000000012200242556012362 5ustar epic4-2.10.2.orig/script/CVS/Root0000644000000000000000000000006212171117135013227 0ustar :pserver:anoncvs@epicsol.org:/home/cvs/repository epic4-2.10.2.orig/script/CVS/Entries0000644000000000000000000000776312171117135013734 0ustar /2.8script/1.3/Thu Sep 5 03:55:53 2002// /alias/1.2/Thu Jan 3 19:39:56 2002// /altchan/1.3/Mon Aug 12 16:59:49 2002// /altchan.bj/1.1/Tue Dec 2 16:49:18 2003// /autoget/1.7/Sat Aug 30 06:18:23 2003// /autokick/1.1.1.1/Tue Dec 5 00:11:57 2000// /autoop/1.3/Thu Jan 3 19:39:56 2002// /away/1.2/Thu Jan 3 19:39:56 2002// /basical/1.5/Fri Oct 10 06:09:01 2003// /columns/1.1.1.1/Tue Dec 5 00:11:57 2000// /commandqueues/1.19/Fri Feb 20 06:29:03 2004// /country/1.2/Thu Jan 3 19:39:56 2002// /data_array/1.6/Fri Oct 31 08:19:23 2003// /data_struct/1.7/Sat Jan 3 19:57:25 2004// /dcc_spacefix/1.2/Sun Jan 18 10:14:01 2004// /dcc_timeout/1.1.1.1/Tue Dec 5 00:11:57 2000// /deban/1.4/Sat Aug 30 06:18:23 2003// /debug.irc/1.6/Fri Oct 31 08:19:23 2003// /dig/1.2/Thu Jan 3 19:39:56 2002// /dns/1.1.1.1/Tue Dec 5 00:11:57 2000// /edit/1.1.1.1/Tue Dec 5 00:11:57 2000// /edit_topic/1.1/Wed Mar 28 23:52:47 2001// /efnext/1.1/Wed Mar 28 23:52:47 2001// /environment/1.3/Mon Aug 12 16:59:49 2002// /epic-crypt-gpg/1.5/Mon Dec 3 08:03:34 2001// /epic-crypt-gpg-aa/1.6/Mon Dec 3 08:03:34 2001// /events/1.1.1.1/Tue Dec 5 00:11:57 2000// /events.hop/1.1.1.1/Tue Dec 5 00:11:57 2000// /fake-dcc/1.2/Thu Jan 3 19:39:56 2002// /fe/1.2/Wed Mar 14 20:01:46 2001// /fe.pf/1.2/Mon Jul 14 18:22:03 2003// /files/1.3/Sat Aug 30 06:18:23 2003// /functions/1.9/Sat Jan 3 19:57:25 2004// /genalias/1.2/Tue Sep 3 11:43:12 2002// /global/1.1.1.1/Tue Dec 5 00:11:57 2000// /grep/1.3/Mon Nov 3 02:49:30 2003// /guh/1.5/Thu Jan 9 01:10:56 2003// /help/1.2/Sun Jan 18 15:33:55 2004// /hold_mode/1.2/Tue Jan 15 13:04:54 2008// /hybrid6/1.4/Thu Jan 3 19:39:56 2002// /imap/1.2/Thu Jan 3 19:39:56 2002// /ip-to-int/1.2/Wed Mar 14 20:01:46 2001// /ircprimer/1.2/Wed Mar 14 20:01:46 2001// /keybinds/1.2/Mon Aug 12 16:59:49 2002// /killpath/1.1.1.1/Tue Dec 5 00:11:57 2000// /kpstat/1.1.1.1/Tue Dec 5 00:11:57 2000// /langtrans/1.1.1.1/Tue Dec 5 00:11:57 2000// /less/1.3/Sun Jan 18 15:33:55 2004// /less-pipe/1.1.1.1/Tue Dec 5 00:11:57 2000// /list/1.2/Thu Jan 3 19:39:56 2002// /local.examp/1.2/Thu Jan 3 19:39:56 2002// /ls/1.1.1.1/Tue Dec 5 00:11:57 2000// /mail/1.2/Thu Aug 1 00:51:08 2002// /man/1.2/Tue Jan 14 15:43:36 2003// /map/1.1/Wed Jul 31 23:39:35 2002// /meta/1.2/Mon Aug 12 16:59:49 2002// /meta-compat/1.2/Sat Dec 13 17:39:52 2003// /mkpdir/1.1/Fri Aug 2 22:13:55 2002// /more/1.1.1.1/Tue Dec 5 00:11:57 2000// /motd/1.1.1.1/Tue Dec 5 00:11:57 2000// /mudirc/1.2/Wed Dec 11 19:20:23 2002// /netsplit/1.2/Thu Jan 3 19:39:56 2002// /netsplit.env/1.2/Thu Jan 3 19:39:56 2002// /newaway/1.1.1.1/Tue Dec 5 00:11:57 2000// /newformat/1.2/Mon Aug 12 16:59:49 2002// /nicks/1.1.1.1/Tue Dec 5 00:11:57 2000// /nopaste/1.1.1.1/Tue Dec 5 00:11:57 2000// /notify/1.10/Thu Dec 18 02:49:00 2003// /old-dcc/1.1.1.1/Tue Dec 5 00:11:57 2000// /paste/1.2/Wed Jul 2 03:55:14 2003// /pipe/1.1.1.1/Tue Dec 5 00:11:57 2000// /prefix/1.1.1.1/Tue Dec 5 00:11:57 2000// /recursion/1.1.1.1/Tue Dec 5 00:11:57 2000// /repeat/1.2/Wed Mar 14 20:01:46 2001// /revdcc/1.1.1.1/Tue Dec 5 00:11:57 2000// /scan/1.2/Thu Jan 3 19:39:56 2002// /scandir/1.2/Wed Mar 14 20:01:46 2001// /screen/1.3/Mon Aug 12 16:59:49 2002// /sdiff/1.1.1.1/Tue Dec 5 00:11:57 2000// /setmail/1.2/Thu Jan 3 19:39:56 2002// /silent/1.1.1.1/Tue Dec 5 00:11:57 2000// /sound/1.1.1.1/Tue Dec 5 00:11:57 2000// /sping/1.4/Sat Dec 6 02:03:11 2003// /starutils/1.1.1.1/Tue Dec 5 00:11:57 2000// /stat/1.1.1.1/Tue Dec 5 00:11:57 2000// /status_lag/1.1.1.1/Tue Dec 5 00:11:57 2000// /suppressmotd/1.2/Fri May 30 20:47:19 2003// /tabkey/1.1.1.1/Tue Dec 5 00:11:57 2000// /tabkey.ce/1.17/Fri Oct 31 08:19:23 2003// /tabkey.jm/1.15/Fri Feb 20 20:00:12 2004// /tabkey.th/1.2/Sat Jan 12 21:13:15 2002// /tc/1.2/Wed Mar 14 20:01:46 2001// /time/1.2/Thu Jan 3 19:39:56 2002// /tls/1.3/Mon Aug 12 16:59:49 2002// /urlgrab/1.1/Mon Jan 19 04:10:57 2004// /utime/1.1.1.1/Tue Dec 5 00:11:57 2000// /vi-binds/1.3/Mon Aug 12 16:59:49 2002// /webster/1.1.1.1/Tue Dec 5 00:11:57 2000// /window/1.3/Tue Aug 13 05:05:21 2002// D epic4-2.10.2.orig/script/CVS/Repository0000644000000000000000000000001512171117135014461 0ustar epic4/script epic4-2.10.2.orig/script/imap0000644000000000000000000001524007415131614012606 0ustar # imap version 1.0 by Ian Frechette. # To give credit where credit is due, this was inspired by Run's # ircmap2 script. I looked at it once and decided it was slow and kludgy to # deal with and wrote my own. All code here is original to me. # # Currently the only commands are # /initmap [stuff] - which will create a the data by issuing a /links # from the current server. # - stuff can be whatever.. The map is split up if you # you try to use stuff.. try '*.ca *' # /gomap [server_name] - will show the current map of the visible irc # network. If a servername is given it'll try to # recurse outward from that server instead of the # current server. # Note: you may issue the /gomap command as many times as you want after # the data has been created. You may also /initmap at any time to update the # data. # # Note Also.. as of yet hostmasks are not possible, nor would they really # make much sense. # # This script has been modified to work correctly on the EPIC client. # ^set novice off ^set max_recursion 50 @ RCS.imap = [$$Header: /home/cvs/repository/epic4/script/imap,v 1.2 2002/01/03 19:39:56 crazyed Exp $$] eval @ map.mask = encode(*.) # @ map.str = [| | | | | | | | | | | | | | | | | | | | | | | ] # It starts builds the map data list. working on args now alias initmap { echo *** imap: removing any old map data around purge maplist purge maplist2 purge maphublist echo *** imap: building links list to use later echo *** imap: please wait until it's finished ..... map.buildlist $* } # This alias may take a server name as an argument or it may # be left blank. # gomap tries to display the entire irc map from the point of view of # the given server or if no arg is given from the server the list was # built on. alias gomap { if ([$0] != []) {@ map.toptree = encode($tolower($0))} {@ map.toptree = encode($tolower($map.from))} echo *** Displaying map from $decode($map.toptree) echo 0 $decode($map.toptree) makemap 1 $map.toptree map.restore echo *** imap: done displaying map } # used internally to build the actual map data list. Takes no args. # This also constructs a list of hostmasks to be used by map.cleanmasks alias map.buildlist { ^on ^364 * { @ map.from = [$0] @ map.srv = [$1] @ map.uplink = [$2] @ map.hops = [$3] # ^set status_user2 . if (left(1 $map.srv) == [*]) { @ mapmasklist[$encode($tolower($map.srv))] = map.srv } @ map.hub = encode($tolower($map.uplink)) @ maphublist[$map.hub] = maphublist[$map.hub] + 1 @ maplist[$map.hub][$encode($tolower($map.srv))] = map.hops # ^set status_user2 . } ^on ^365 * { ^on 364 -* echo *** imap: Done building links list ^set -status_user2 ^on 365 -* @ map.tmp = encode($tolower($map.from)) ^assign -maplist[$map.tmp][$map.tmp] @ maphublist[$map.tmp] = maphublist[$map.tmp] - 1 map.cleanmasks map.save echo *** imap: you may now issue a /gomap to view irc map ^set show_end_of_msgs $map.old_seom } @ map.old_seom = SHOW_END_OF_MSGS ^set show_end_of_msgs on //links $* } # called after the initial list is constructed. no args. # This go through the main list of hubs and strips the names down to # the hostmask so.. hub goren.u.washington.edu becomes *.washington.edu # the mask are determined from the servername field so this step cannot # be done until after the data list is complete alias map.cleanmasks { foreach mapmasklist ii { foreach maplist jj { if (match(*$mid(2 100 $ii) $jj)) { foreach maplist.$jj kk { @ maplist[$ii][$kk] = maplist[$jj][$kk] ^assign -maplist[$jj][$kk] } @ maphublist[$ii] = maphublist[$jj] ^assign -maphublist[$jj] } } ^assign -mapmasklist[$ii] } echo *** imap: map data masks have been cleaned } # used for debugging only # /showmap will show you a list of the raw data. Lists all hub servers # sorted alphabetically with leafs of that hub following # a servername may be supplied as an argument and this will list only # the info for that one hub alias showmap { if ([$0] == []) { foreach maplist ii { foreach maplist.$ii jj { echo $decode($ii) links $decode($jj) } } } { foreach maplist.$encode($tolower($0)) ii { foreach maplist.$ii jj { echo $decode($ii) links $decode($jj) } } } } # called with makemap level server # this is the real workhorse.. It's a recursive function.. It starts at # recursion level 1 and follows the servers through the data. # The following example doesn't use real argument types. # e.g. makemap 1 colorado looks at colorado's list of links # displays each one and then recurses into that # link if it can. So when it gets to uiuc # makemap is called. makemap 2 uiuc # and it follows it's links etc etc.. # loops in the data are avoided by removing each link from the list entirely # as it's used. map.restore can be called later to restore data # alias makemap { @ map.ind[$0] = 0 foreach maplist.$1 ii$0 { echo $lformat(3 $0) $map.outmask(1 $0)`-$decode($(ii$0)) $maplist[$1][$(ii$0)] ^assign -maplist[$1][$(ii$0)] if ((map.ind[$0] = map.ind[$0] +1) >= maphublist[$1]) {@mask[$0] = 0} {@mask[$0] = 1} makemap ${[$0] + 1} $(ii$0) ^assign -ii$0 } } # called after the data is created and cleaned to keep for future use # no args alias map.save { foreach maplist ii { foreach maplist.$ii jj { @ maplist2[$ii][$jj] = maplist[$ii][$jj] } } echo *** imap: Map data saved } # called after gomap has run makemap to restore data. # makemap destroys the entire list on purpose # no args. alias map.restore { foreach maplist2 ii { foreach maplist2.$ii jj { @ maplist[$ii][$jj] = maplist2[$ii][$jj] } } echo *** imap: Map data restored } # no stranger to the default scripts.. repeated here for completeness. alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = IRCII.word } } # /purge # removes all assignments under that name recursively. ^alias purge { foreach $0 ii { purge $0.$ii } ^assign -ii ^assign -$0 } # This special little recursive function scans the mask[] # array and generates an output string of the format # | | | | | and so on.. depending on whether a mask[x] is # turned on or not alias map.outmask { if ([$0] < [$1]) { if (mask[$0]) {@ mask.mask = mask.mask ## [| ]} {@ mask.mask = mask.mask ## [ ]} @ function_return = map.outmask(${[$0] + 1} $1) } { @ function_return = mask.mask ^assign -mask.mask } } epic4-2.10.2.orig/script/epic-crypt-gpg0000644000000000000000000000147707402630726014525 0ustar #!/bin/bash # # This is a simplistic encryption demonstrating the principles # of the protocol, while being quite usable. # # the first input line contains words, the first of which is the key, # and additional arguments, which aren't used right now, so they are # discarded. # # When the end of the line is reached, the rest of the input is to be # read as binary input of the plaintext or cyphertext in _binary_ mode. # What this means for plaintext is that the newline terminator won't # be present. function encrypt { ( echo "$KEY" ; cat ) | gpg -c -z 9 --batch --passphrase-fd 0 } function decrypt { ( echo "$KEY" ; cat ) | gpg --batch --passphrase-fd 0 } proto="$1" shift 1 read KEY TRASH case "$proto" in encrypt) encrypt "$@" ;; decrypt) decrypt "$@" ;; *) echo `basename $0` "{encrypt|decrypt} < text" 1>&2 ;; esac epic4-2.10.2.orig/script/epic-crypt-gpg-aa0000644000000000000000000000256007402630726015076 0ustar #!/bin/bash # # This script demonstrates ascii armoring. It is rather complicated # because it uses the ascii armoring present in gpg, which wraps in # a way that is unusable for irc. One of the things that can be # done is to join all the cyphertext lines together, and reformat # them into a valid gpg message again at the other end. # # Decryption is a little tricky. What we do is create a token ascii # armored gpg message, strip it of the message content, fill it in # with the reformatted message and pipe it back into gpg for # decryption. # # Since the plaintext and cyphertext are read in non-newline binary # mode, echo -n is used. function encrypt { ( echo "$KEY" ; cat ) | gpg -ca -z 9 --batch --passphrase-fd 0 | ( while read && [ -n "$REPLY" ] ; do : ; done while read && [ -n "$REPLY" ] ; do [ -n "$LAST" ] && echo -n "$LAST " ; LAST="$REPLY" done ) } function decrypt { read -a input ( echo x | gpg -ca --batch --passphrase-fd 0 | ( while read && [ -n "$REPLY" ] ; do echo "$REPLY" ; done while read && [ -n "$REPLY" ] ; do LAST="$REPLY" ; done echo for foo in "${input[@]}" ; do echo "$foo" ; done echo "$LAST" ) ) | ( echo "$KEY" ; cat ) | gpg -a --batch --passphrase-fd 0 } proto="$1" shift 1 read KEY TRASH case "$proto" in encrypt) encrypt "$@" ;; decrypt) decrypt "$@" ;; *) echo `basename $0` "{encrypt|decrypt} < text" 1>&2 ;; esac epic4-2.10.2.orig/script/kpstat0000644000000000000000000000065607213031315013164 0ustar # No Kill Path Script II (status bar version) # converted to 2.2.1 by phone # CONVERTED for ircII2.2 # Version for servers 2.7.1* by Nap@irc # Original script from YeggMan # Simplification by Daemon # Super Simplification by hop # Even more simplification by hop on ^kill "% % %.% % *" { set status_user ### server KILL for $1 by $2 } on ^kill * { set status_user ### KILL for $1 by $2 \($4-\) } epic4-2.10.2.orig/script/tabkey.jm0000644000000000000000000003403110015463514013540 0ustar # tabkey.jm: a full-featured tab key script for epic4 # # written by nsx # # this script features: # # * target history cycling for /msg and /notice # * match possibility cycling (zsh-style completion) # * reverse cycling (ctrl + r) # * shell-like completion for /exec # * script name completion for /load # * the ability to complete words anywhere in the input line # * proper handling of file names that contain spaces # * multi-server support # * completion of aliases, command names, channel names, nicknames, # /set variables, /help topics and file names # # # /set variables this script uses: # # NICK_COMPLETION_CHAR -- the value of this set will be appended each time # nickname completion occurs as the first word of the # input line. a typical value might be ':'. # # TAB_HISTORY_CYCLE_SIZE -- how many nicknames to keep in the /msg history # # ZSH_STYLE_COMPLETION -- turning this on allows you to cycle through completion # possibilities, when there is more than one completion # possibility, similar to how zsh behaves for tab # completion # # # note: this script uses the serial number 110 for its serial hooks # # *** config variables *** @nick_completion_char = [] @tab_history_cycle_size = 10 @zsh_style_completion = [off] # *** global variables *** @last_input_line = [] @match_index = -1 @match_cycle_list = [] @target_index = 0 @target_cycle_list = [] bind ^I parse_command do_tabkey 1 bind ^R parse_command do_tabkey -1 xdebug +extractw alias add_target (msg_cmd, target) { if (numwords($myservers()) > 1 && count(: $target) == 0 && left(1 $target) != [=]) { @:target = [${servernum()}:${target}] } @target_cycle_list = remw("$msg_cmd $target" $target_cycle_list) if (#target_cycle_list > ((tab_history_cycle_size * 2) -1)) { @target_cycle_list = restw(2 $target_cycle_list) } @target_index = 0 @push(target_cycle_list $msg_cmd) @push(target_cycle_list $target) } alias current_fragment_start { @:i = 0 @:j = curpos() - 1 @:last_space = 0 @:last_quote = 0 @:quotes = 0 while (i < j) { @:char = mid($i 1 $L) if (char == [ ]) { @:last_space = i } elsif (char == ["]) { @:last_quote = i @:quotes++ } @:i++ } if (quotes % 2) { if (mid($curpos() 1 $L) == ["] || last_quote > last_space) { return ${last_quote + 1} } elsif (mid(${curpos() - 1} 1 $L) == ["]) { parsekey backward_character return ${last_quote + 1} } else { return ${last_space + 1} } } else { if (mid(${curpos() - 1} 1 $L) == [ ]) { return $curpos() } elsif (last_space) { return ${last_space + 1} } else { return 0 } } } alias do_match_cycle (direction) { @:frag_start = current_fragment_start() if (frag_start == -1) { return } @:fraglen = curpos() - frag_start if (mid($curpos() 1 $L) == ["]) { parsekey forward_character repeat ${fraglen + 1} parsekey backspace } elsif (mid(${curpos() - 1} 1 $L) == ["]) { repeat ${fraglen + 1} parsekey backspace } else { repeat $fraglen parsekey backspace } if (mid(${curpos() - 1} 1 $L) == ["]) { parsekey backspace } @match_index += direction if (match_index == #match_cycle_list) { @match_index = 0 } elsif (match_index < 0) { @match_index = #match_cycle_list - 1 } @:new_match = word($match_index $match_cycle_list) if (index("$chr(32)" $new_match) == -1) { xtype -l $new_match } else { xtype -l "$new_match" parsekey backward_character } @last_input_line = L } alias do_msg_cycle (direction) { if (#target_cycle_list < 2) { return } @target_index -= (direction * 2) if (target_index == #target_cycle_list) { @target_index = 0 } elsif (target_index < 0) { @target_index = #target_cycle_list - 2 } @:msg_cmd = word($target_index $target_cycle_list) @:msg_targ = word(${target_index + 1} $target_cycle_list) parsekey erase_line xtype -l /${msg_cmd} ${msg_targ}${chr(32)} @last_input_line = [] } alias do_set (variable, value) { if (value == []) { ^eval @:setval = $variable if (setval == []) { xecho -b No value for $variable has been set } else { xecho -b Current value of $variable is $setval } return } switch ($variable) { (NICK_COMPLETION_CHAR) { if (value == []) { @nick_completion_char = [] xecho -b Value of NICK_COMPLETION_CHAR set to } else { @nick_completion_char = value xecho -b Value of NICK_COMPLETION_CHAR set to $value } } (TAB_HISTORY_CYCLE_SIZE) { if (!isnumber($value)) { xecho -b Value of TAB_HISTORY_CYCLE_SIZE must be numeric! } elsif (value < 1) { xecho -b Value of TAB_HISTORY_CYCLE_SIZE cannot be less than 1 } else { @tab_history_cycle_size = value @target_cycle_list = rightw(${value * 2} $target_cycle_list) xecho -b Value of TAB_HISTORY_CYCLE_SIZE set to $value } } (ZSH_STYLE_COMPLETION) { if (value == [on]) { @zsh_style_completion = [ON] xecho -b Value of ZSH_STYLE_COMPLETION set to ON } elsif (value == [off]) { @zsh_style_completion = [OFF] xecho -b Value of ZSH_STYLE_COMPLETION set to OFF } else { xecho -b Value of ZSH_STYLE_COMPLETION must be ON or OFF! } } (*) { xecho -b I don't know how to handle "$variable" } } } alias do_tabkey (cycle_direction) { @:input_line = left($curpos() $L) if (L == []) { @target_index = #target_cycle_list @do_msg_cycle($cycle_direction) return } elsif (encode($L) == encode($last_input_line)) { if (zsh_style_completion == [ON] && #match_cycle_list > 1) { @do_match_cycle($cycle_direction) return } else { return } } elsif (leftw(1 $L) == [/msg] || leftw(1 $L) == [/notice]) { if (#L == 2 && mid(${@L - 1} 1 $L) == [ ]) { @do_msg_cycle($cycle_direction) return } } @:frag_start = current_fragment_start() if (frag_start == -1 || cycle_direction == -1) { return } @:fragment = mid($frag_start ${curpos() - frag_start} $L) @:fraglen = strlen($fragment) @:padding = [] switch ($input_line) { (/dcc %) { @:matches = match_dcc($fragment) if (#matches == 1) { @:padding = [ ] } } (/dcc send % *) (/exec % *) { @:matches = match_file($fragment) if (#matches == 1 && !isdirectory($matches)) { @:padding = [ ] } } (/exec %) { @:matches = match_exec($fragment) if (#matches == 1 && !isdirectory($matches)) { @:padding = [ ] } } (/help %) { @:matches = match_help($fragment) if (#matches == 1) { if (!isdirectory(${getset(HELP_PATH)}/${matches})) { @:padding = [ ] } } } (/load *) (/unload *) { @:matches = match_load($fragment) if (#matches == 1 && !isdirectory($matches)) { @:padding = [ ] } } (/notify -%) { @:fragment = rest($fragment) @:fraglen-- @:matches = match_notify($fragment) if (#matches == 1) { @:padding = [ ] } } (/set -%) { @:fragment = rest($fragment) @:fraglen-- @:matches = match_set($fragment) if (#matches == 1) { @:padding = [ ] } } (/set %) { @:matches = match_set($fragment) if (#matches == 1) { @:padding = [ ] } } (/%) { @:fragment = rest($fragment) @:fraglen-- @:matches = match_command($fragment) if (#matches == 1) { @:padding = [ ] } } (*) { @:matches = [] @push(matches $match_chan($fragment)) @push(matches $match_nick($fragment)) if (#matches == 1) { if (#L == 1 && !ischannel($matches)) { if (nick_completion_char != []) { @:padding = [$nick_completion_char ] } } else { @:padding = [ ] } } } } @last_input_line = L @match_index = -1 @:match_prefix = prefix($matches) if (@match_prefix <= fraglen && #matches > 1) { xecho -c Possible matches: xecho -c -- $matches xecho -c return } if (match_prefix != []) { @:new_fragment = left($fraglen $match_prefix) if (encode($fragment) != encode($new_fragment)) { repeat $fraglen parsekey backspace xtype -l $new_fragment } } @:completion = rest($fraglen $match_prefix) if (completion == [] && padding == []) { return } if (index("$chr(32)" $fragment) == -1) { if (index("$chr(32)" $match_prefix) > -1) { repeat $fraglen parsekey backspace if (mid($curpos() 1 $L) == ["] && mid(${curpos() - 1} 1 $L) == ["]) { xtype -l $match_prefix if (padding != []) { parsekey forward_character } } else { xtype -l "$match_prefix" if (padding == []) { parsekey backward_character } } } else { xtype -l $completion } } else { xtype -l $completion if (padding == []) { if (mid($curpos() 1 $L) != ["]) { xtype -l " parsekey backward_character } } else { if (mid($curpos() 1 $L) == ["]) { parsekey forward_character } else { xtype -l " } } } if (mid(${curpos()} 1 $L) != padding) { xtype -l $padding } @last_input_line = [] } alias isdirectory (pathname) { @:statret = stat("$pathname") @:file_type = left(1 $word(2 $statret)) if (file_type & 4) { return 1 } else { return 0 } } alias isexe (pathname) { @:statret = stat("$pathname") @:file_mode = word(2 $statret) @:file_type = left(1 $file_mode) @:permissions = right(3 $file_mode) @:user_perm = left(1 $permissions) @:group_perm = mid(1 1 $permissions) @:other_perm = right(1 $permissions) if (file_type == 1) { if ((user_perm & 1) || (group_perm & 1) || (other_perm & 1)) { return 1 } else { return 0 } } else { return 0 } } alias match_chan (fragment) { @:matches = pattern("${fragment}*" $mychannels()) @match_cycle_list = matches return $matches } alias match_command (fragment) { @:matches = [] @:command_matches = [] @push(matches $getcommands(${fragment}*)) @push(matches $aliasctl(alias pmatch ${fragment}*)) fe ($matches) match { @push(command_matches /${match}) } @match_cycle_list = uniq($command_matches) return $uniq($matches) } alias match_dcc (fragment) { @:dcc_cmds = [chat close closeall get list raw rename resume send] @:matches = pattern(${fragment}% $dcc_cmds) @match_cycle_list = matches return $matches } alias match_exec (fragment) { @:matches = [] if (index(/ $fragment) == -1) { @:path_list = PATH while (path_list != []) { @:pathname = before(: $path_list) if (pathname == []) { @:pathname = path_list @:path_list = [] } else { @:path_list = after(: $path_list) } fe ($glob("${pathname}/${fragment}*")) filename { if (isexe($filename)) { @push(matches $after(-1 / $filename)) } } } fe ($glob("${fragment}*")) filename { if (isdirectory($filename)) { @push(matches $filename) } } } else { fe ($glob("${fragment}*")) filename { if (isexe($filename) || isdirectory($filename)) { @push(matches $filename) } } } @match_cycle_list = matches = uniq($matches) return $matches } alias match_file (fragment) { @:matches = glob("${fragment}*") @match_cycle_list = matches return $matches } alias match_help (fragment) { @:matches = [] @:help_path = getset(HELP_PATH) @:help_matches = globi("${help_path}/${fragment}*") fe ($help_matches) match { @push(matches $rest(${@help_path + 1} $match)) } @match_cycle_list = matches return $matches } alias match_load (fragment) { @:matches = [] if (index(/ $fragment) == -1) { @:path_list = LOAD_PATH while (path_list != []) { @:pathname = before(: $path_list) if (pathname == []) { @:pathname = path_list @:path_list = [] } else { @:path_list = after(: $path_list) } fe ($glob("${pathname}/${fragment}*")) filename { @push(matches $after(-1 / $filename)) } } } @push(matches $glob("${fragment}*")) @match_cycle_list = matches = uniq($matches) return $matches } alias match_nick (fragment) { @:nick_matches = pattern("${fragment}*" $onchannel()) if (nick_matches == []) { @:nick_list = [] fe ($remw($C $mychannels())) chan { @push(nick_list $onchannel($chan)) } @push(nick_list $notify(on)) @:nick_matches = pattern(${fragment}* $nick_list) } if (nick_completion_char != [] && #matches > 1 && #L == 1) { fe ($nick_matches) nickname { @push(matches ${nickname}${nick_completion_char}) } } else { @:matches = nick_matches } @:matches = uniq($matches) @match_cycle_list = matches return $matches } alias match_notify (fragment) { @:matches = pattern(${fragment}* $notify()) @match_cycle_list = matches return $matches } alias match_set (fragment) { @:matches = [] @:my_sets = [NICK_COMPLETION_CHAR TAB_HISTORY_CYCLE_SIZE ZSH_STYLE_COMPLETION] @push(matches $getsets(${fragment}*)) @push(matches $pattern(${fragment}* $my_sets)) @match_cycle_list = matches return $matches } alias match_theme (fragment) { @:matches = [] @:theme_matches = globi("${theme_directory}/${fragment}*.theme") fe ($theme_matches) match { @push(matches $before(-1 . $rest(${@theme_directory + 1} $match))) } @match_cycle_list = matches return $matches } alias tclear { @target_cycle_list = [] @target_index = -2 xecho target history cleared } # *** hooks *** on #^action 110 "*" { if (!rmatch($1 #* &* +*) ) { @add_target(msg $0) } } on #^dcc_chat 110 "*" { @add_target(msg =$0) } on #^dcc_connect 110 "% CHAT *" { @add_target(msg =$0) } on #^general_notice 110 "% *" { @add_target(notice $1) } on #^msg 110 "*" { @add_target(msg $0) } on #^send_action 110 "*" { if (!rmatch($0 #* &* +*) ) { @add_target(msg $0) } } on #^send_dcc_chat 110 "*" { @add_target(msg =$0) } on #^send_msg 110 "*" { @add_target(msg $0) } on #^send_notice 110 "*" { @add_target(notice $0) } on ?send_to_server "% % NOTICE %:% *" { if (ischannel($3)) { return 0 } @:refnum = before(: $3) @:target = after(: $3) xquote -server $refnum NOTICE $target $4- return 1 } on ?send_to_server "% % PRIVMSG %:% *" { if (ischannel($3)) { return 0 } @:refnum = before(: $3) @:target = after(: $3) xquote -server $refnum PRIVMSG $target $4- return 1 } on ^set "NICK_COMPLETION_CHAR *" { @do_set(NICK_COMPLETION_CHAR $1) } on ^set "TAB_HISTORY_CYCLE_SIZE *" { @do_set(TAB_HISTORY_CYCLE_SIZE $1) } on ^set "ZSH_STYLE_COMPLETION *" { @do_set(ZSH_STYLE_COMPLETION $1) } epic4-2.10.2.orig/script/autokick0000644000000000000000000000104707213031315013463 0ustar /* Autokick and kicknban 1993, 1994 */ load guh @ auto.kicks = [] alias autokick { if (is_on($0) == [$0]) { push auto.kicks $uh($0) } { echo *** $0 is not on irc right now } } alias unkick { if (is_on($0) == [$0]) { @ auto.kicks = remw($uh($0) $auto.kicks) } { echo *** $0 is not on irc right now } } ^on #-join -30 '% % \\[$auto.kicks\\]' { kick $1 $0 autokicked echo *** AUTOKICK PROTECTION ACTIVATED AGAINST $0 mode $1 +b *!$2 } alias kicknban { kick * $0 $1 if (onchannel($0 $C)) { mode * +b *!$userhost($0) } } #hop'94 epic4-2.10.2.orig/script/netsplit0000644000000000000000000001006307415131614013520 0ustar # NETSPLIT 7 - This script does it's best to suppress the excessive # joins and signoffs due ONLY to netsplits. It should pass regular # signoffs. Need at least ircII2.2pre6 # Version II handles multiple channels. (mycroft) # Version III ignores bogus signoff messages # Version IV handles multiple splits. # Version V handles multiple splits and ignores bogus signoff messages. also # adds timestamps to split/join messages # Version VI For ircII2.2pre8 and beyond. Uses encode() and decode() # Version VII Fixed a problem with encode() and decode() and case # sensitive channel names, + adding lformat() # # This one by Daemon # CONVERTED for ircII2.2pre8 # Version V by poxaV (cgw@unt.edu), from Daemon's code # modified last 7-03-93 #shows the current time in HH:MM:SS format ^alias currtime @ function_return = strftime(%T) # This function tests for bogus splits. ^alias isbogus { ^if ([$3]) { @ function_return = 1 } ^if (rmatch(.$1. $isbogus.pats *..*)) { @ function_return = 1 } ^if (rmatch(.$2. $isbogus.pats *..*)) { @ function_return = 1 } } # Add patterns.. like /boguspat *bonk* *thud* *haha* # that will NOT be treated as server names.. ^alias boguspat ^assign isbogus.pats $isbogus.pats $0-;echo $0- added # Next two are pretty obvious ^alias boguslist echo Pats: $isbogus.pats ^alias bogusclear ^assign -isbogus.pats;echo Bogus list clean # If first word in Signoff contains a period then assume servername # and thus a a split. Stash in assoc array. ^ON ^CHANNEL_SIGNOFF "% % %.% %.%" { if (isbogus($1-)) { echo *** Signoff: $1 \($2-\) } { ^netbroke $encode($tolower($0)) $encode($1) $encode($2).$encode($3) $2 $3 } } # Stuff array. Tell us what server broke and set split flag. ^alias netbroke { @ signcross[$2][$0][$1] = 1 @ signoffs[$0][$1] = [$2] @ splittime[$2] = time() ^if ( !isbroke[$2] ) { xecho -level OPNOTES *** Netsplit at $currtime() \($3-\) @ isbroke[$2] = 1 @ splitname[$2] = [$3-] } } # When a person joins a channel.. Check them against the array. # If they are in array, then remove silently. Otherwards echo normally ^ON ^JOIN * { ^netjoined $encode($tolower($1)) $encode($0) $1 $0 $USERHOST() } # Unset the split flag ^alias netjoined { if ( signoffs[$0][$1] ) { ^if ( isbroke[$signoffs[$0][$1]] ) { xecho -level OPNOTES *** Netjoined at $currtime() \($splitname[$signoffs[$0][$1]]\) } ^assign -isbroke[$signoffs[$0][$1]] ^assign -signcross[$signoffs[$0][$1]][$0][$1] ^assign -signoffs[$0][$1] } { echo *** $3 \($4-\) has joined channel $2 } } # Clear the array every 10 minutes to prevent excess garbage ^on #^timer 70 * netclean ^alias netclean { foreach splittime ii { foreach splittime.$ii jj { if ( time() - splittime[$ii][$jj] > 300 ) { foreach signcross.$(ii).$jj xx { foreach signcross.$(ii).$(jj).$xx yy { @ signcross[$ii][$jj][$xx][$yy] = signoffs[$xx][$yy] = [] } } @ xx = yy = isbroke[$ii][$jj] = [] @ splitname[$ii][$jj] = splittime[$ii][$jj] = [] } } } } ^alias netpurge { purge isbroke purge splitname purge splittime purge signcross purge signoffs } # If you want to suppress mode changes by servers.. (usually after a split) # then uncomment next line # ^on ^mode "%.%" # # If you want to look an array.. Type /show # Lists keys and contents ^alias showsplit { if ( [$($0)] ) { echo $0 $($0) } foreach $0 ii { showsplit $0.$ii } ^assign -ii } ^alias purge { foreach $0 ii { purge $0.$ii } ^assign -ii ^assign -$0 } ^alias wholeft { foreach signoffs ii { foreach signoffs.$ii jj { echo $lformat(15 $decode($ii)) $lformat(10 $decode($jj)) $splitname[$signoffs[$ii][$jj]] } } ^assign -ii ^assign -jj } # format and lformat differ from $[-num]var and $[num]var in that # They don't chop off the string if it is too long. alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } # Many people contributed to this script. epic4-2.10.2.orig/script/tabkey.th0000644000000000000000000000430507420123353013546 0ustar # # These are my tabkey routines. Pressing the tabkey with nothing in your buffer # will cycle through people you are talking to or if you type part of a # nickname and then tab it will complete the nickname. Enjoy. # # - whitefang (thall@epicsol.org) # bind ^i parse_command proc.tabkey alias proc.tabkey { ^local text,word,comp,comm,nick,temp @ text = L, word = rightw(1 $text), comp = pattern($^\word* $chanusers()) unless (text) { type /msg @ text = L } @ comm = word(0 $text), nick = word(1 $text) /* msg buffer routine */ if (comm == [/msg]) { if (finditem(TK $nick) >= 0) { parsekey erase_line @ temp = getitem(TK ${finditem(TK $nick)-1}) xtype -l /msg ${temp?temp:getitem(TK ${numitems(TK)-1})}$chr(32) } { parsekey erase_line xtype -l /msg $getitem(TK ${numitems(TK)-1})$chr(32) } return } /* nick completion routine */ if (!word || !numwords($comp) || right(1 $word) == [:]) { return } if (numwords($comp) > 1) { xecho -b Matches: echo $comp return } if (numwords($text) == 1) { parsekey erase_line xtype -l $comp:$chr(32) } { pop text parsekey erase_line xtype -l $text $comp } } alias proc.add_tabkey (nick) { if (nick) { if (finditem(TK $nick) >= 0) {@ delitem(TK $finditem(TK $nick))} @ setitem(TK $numitems(TK) $nick) if (numitems(TK) == 10) {@ delitem(TK 0)} } } on #-dcc_chat -420 * proc.add_tabkey =$0 on #-dcc_connect -420 "% CHAT *" proc.add_tabkey =$0 on #-msg -420 * proc.add_tabkey $0 on #-send_dcc_chat -420 * proc.add_tabkey =$0 on #-send_msg -420 * proc.add_tabkey $0 alias m msg alias msg { //msg $* if (@) { proc.add_tabkey $0 } } # tjbh/2000 epic4-2.10.2.orig/script/prefix0000644000000000000000000000032407213031315013143 0ustar # prefix each message with the channel name on ^public * echo $1 <$0> $2- on ^public_other * echo $1 <$0> $2- on ^public_msg * echo $1 \($0) $2- on ^send_public * echo $C <$N> $1- set input_prompt $T> # lynx90 epic4-2.10.2.orig/script/urlgrab0000644000000000000000000000355310002654321013311 0ustar #$EPIC: urlgrab,v 1.1 2004/01/19 04:10:57 jnelson Exp $ package urlgrab # # urlgrab - URL Grabber Script for EPIC # Copyright 2004 Brian Hauber # Originally written for WC's Toolbox (WCTB) # Please use and distribute this script like crazy! # # # Why this script: # With mIRC dominating the IRC scene these days, people paste long URLs # that those of us with a text-based IRC client can't just click on. Add # to that EPIC's line breaks, cutting and pasting these URLs to your browser # can be a pain. # # What it does: # Save a URL sent to a channel or sent via msg to a file as a hyperlink # in your ~/public_html that you can then browse and click in a web browser # of your choice. # # Usage: # /URLGRAB toggles the script on and off # Change this file to whatever you want. @ urlfile = [$HOME/public_html/urls.html] # Create file if it doesn't exist if (fexists($urlfile) == -1) { @ fd = open($urlfile W) @ close($fd) } # Make sure perms are correct so you can browse it if (fexists($urlfile) == 1) { @ chmod($urlfile 644) } # Converts boolean numbers to words alias onoff return ${([$0] == 1) ? [ON] : [OFF]} # Turn URL grabber on/off alias urlgrab { @ urlgrab = (urlgrab) ? 0 : 1 xecho -b URL grabber is $onoff($urlgrab). } # Grabs URL out of message and writes it as a hypertext link to a file. alias grabit { if (urlgrab) { @ :fd = open($urlfile W) @ :wordno = match("\\[http:% *www.%\\]" $1-) @ :wordno = wordno - 1 @ :url = word($wordno $1-) if (!match(http% $url)) { @ :url = [http://] ## url } @ :datetime = strftime(%m-%d-%Y %H:%M) @ :link = [] ## url ## [
] @ write($fd [$datetime] <$0\> $link) @ close($fd) } } on #-public 7763 '% * \\[http:% *www.%\\]' { grabit $* } on #-msg 7763 '* \\[http:% *www.%\\]' { grabit $0 MSG $1- } on #-public_other 7763 '% * \\[http:% *www.%\\]' { grabit $* } #wc'y2k4 epic4-2.10.2.orig/script/langtrans0000644000000000000000000000522107213031315013640 0ustar /* * IRC Script Program. For use with ircii-EPIC4 clients. * Copyright (C) 1999 whitefang (thall@bc1.com) * * --------------------------------------------------------------------------- * All code by whitefang, unless specified. * Thanks SrfRoG for help in optimizing. * --------------------------------------------------------------------------- */ PACKAGE langtrans ON ^DCC_RAW "% babelfish.altavista.com *" # ON ^DCC_RAW "% babelfish.altavista.com D *<%>" # ON ^DCC_RAW "% babelfish.altavista.com D *" { @ temp.trans_text = after(> $5-) } ON ^DCC_RAW "% babelfish.altavista.com C" { IF (temp.trans_text) { XECHO -b Translating text from $temp.trans_desc\... XECHO -b $word(0 $temp.trans_desc)\: $temp.trans_orig XECHO -b $word(2 $temp.trans_desc)\: $temp.trans_text ^ASSIGN -temp.trans_text } { xecho -b Translation failed. } ^ASSIGN -temp.trans_orig ^ASSIGN -temp.trans_desc } ^ASSIGN trans.0 en_fr English to French ^ASSIGN trans.1 en_de English to German ^ASSIGN trans.2 en_pt English to Portuguese ^ASSIGN trans.3 en_es English to Spanish ^ASSIGN trans.4 en_it English to Italian ^ASSIGN trans.5 fr_en French to English ^ASSIGN trans.6 de_en German to English ^ASSIGN trans.7 pt_en Portuguese to English ^ASSIGN trans.8 es_en Spanish to English ^ASSIGN trans.9 it_en Italian to English ALIAS trans { @ :flag = findw($0 -ef -ed -ep -es -ei -fe -de -pe -se -ie --help) IF (flag == 10) { _transhelp RETURN } IF (!strlen($1) || lang == -1) { xecho -b Usage: /TRANS <-flag> RETURN } @ temp.trans_desc = restw(1 $trans[$flag]) ^ASSIGN temp.trans_orig $1- @ :orig = fnexist(urlencode) ? urlencode($temp.trans_orig) : msar(g/'/%27/`/%60/ /%20/$temp.trans_orig) @ :lang = word(0 $trans[$flag]) @ :sock = connect(babelfish.altavista.com 80) //^DCC RAW $sock babelfish.altavista.com GET /cgi-bin/translate\?doit=done\&urltext=$orig\&languagepair=$lang } ALIAS _transhelp { ECHO Usage: TRANS  ECHO ECHO Attempts to translate using altavista's babelfish server. ECHO ECHO Language flags: ECHO ECHO -ef English to French -fe French to English ECHO -ed English to German -de German to English ECHO -es English to Spanish -se Spanish to English ECHO -ep English to Portuguese -pe Portuguese to English ECHO ECHO Examples: ECHO ECHO /TRANS -ep I love whitefang. ECHO /TRANS -ie We all love whitefang. ECHO /TRANS -de Ich liebe meine EPIC4! } XECHO -b Translation script for EPIC4 by whitefang [thall@bc1.com] XECHO -b For help type: /TRANS --help XECHO -b To unload: /UNLOAD langtrans #tjbh/99 epic4-2.10.2.orig/script/help0000644000000000000000000002105710002523543012603 0ustar # # Help replacement written by howl 2003 # package help alias h help.help alias help help.help # help.isdir is stolen more or less from nsx's tabkey script. Thanks nsx! alias help.isdir (dir) { return ${(left(1 $word(2 $stat("$dir"))) & 4)? 1 : 0} } alias help.help { ^local pager,prompt,dir,file,fp,dp,size,win,line,list,name,match,width,pad ^local tmp,tmp1,tmp2,tmp3,tmp4,tmp5,var,taken,varlist,unset,clear,padlen ^local more,break,nohelp,myinput,oldinput,noparse,helppath,path,root ^local nocheck,helpwin,last,realroot,window push varlist dir dp file fp line match name pad pager path prompt realroot push varlist win window @ path = getset(help_path) @ window = getset(help_window) == [on] ? 1 : 0 @ prompt = getset(help_prompt) == [on] ? 1 : 0 @ pager = getset(help_pager) == [on] ? 1 : 0 @ noparse = nohelp = nocheck = 0 @ list = [$*] push list * while (tmp = shift(list)) { if (!noparse && tmp =~ [-*]) { switch ($tmp) { (-var) (-v) { @ var = shift(list) @ tmp = aliasctl(assign pmatch help.cache.${var}.*)) while (tmp2 = shift(tmp)) { ^eval @ $after(3 . $tmp2) = $tmp2 } @ nocheck = 1 } (-break) { @ close($fp) @ fp = dp = file = dir = [] } (-newhelp) { ^local realroot,name,line,match,root,file,dir,dp,fp ^local nocheck 0 } (-kill) { @ tmp = shift(list) if (tmp != [] && tmp != [*] && numwords($aliasctl(assign pmatch help.cache.${tmp}.*)) == 0) { xecho -say -b -c -- HELP: No such cache: $tmp return } if (tmp == [*]) { fe ($aliasctl(assign pmatch help.cache.*.fp)) tmp2 { @ tmp2 = aliasctl(assign get $tmp2) if (tmp2 != -1 && tmp2 != []) { @ tmp3 = close($tmp2) } } fe ($aliasctl(assign pmatch help.cache.*.win)) tmp2 { if (aliasctl(assign get ${tmp2}dow) == 1) { @ tmp2 = aliasctl(assign get $tmp2) if (0 < tmp2 && windowctl(GET $tmp2 REFNUM) != []) { ^window $tmp2 kill } } } fe ($aliasctl(assign pmatch help.cache.*.*)) tmp2 { ^assign -$tmp2 } } else { @ tmp2 = aliasctl(assign get help.cache.${tmp}.fd) if (tmp2 != -1 && tmp2 != []) { @ tmp3 = close($tmp2) } @ tmp2 = aliasctl(assign get help.cache.${tmp}.win) if (0 < tmp2 && windowctl(GET $tmp2 REFNUM) != [] && aliasctl(assign get help.cache.${tmp}.window) == 1) { ^window $tmp2 kill } fe ($aliasctl(assign pmatch help.cache.${tmp}.*)) tmp2 { ^assign -$tmp2 } } xecho -say -b -c -- HELP: Cleared cache for $tmp return } (-path) { @ path = shift(list) } (-pager) { @ pager = 1 } (-nopager) { @ pager = 0 } (-prompt) { @ prompt = 1 } (-noprompt) { @ prompt = 0 } (-window) { @ window = 1 } (-nowindow) { @ window = 0 } (-help) { xecho -b -c -say -- HELP supports the following switches xecho -b -c -say -- -path * Override HELP_PATH xecho -b -c -say -- -[no]pager Override HELP_PAGER xecho -b -c -say -- -[no]prompt Override HELP_PROMPT xecho -b -c -say -- -[no]window Override HELP_WINDOW xecho -b -c -say -- Usage: /help [--] return } (--) { @ noparse = 1 } } continue } @ noparse = 1 if (nocheck) break if (@path == 0 && @root == 0) { xecho -say -b -c -- No HELP_PATH set. return } if (tmp == [?]) { @ tmp = [*] } if (@root == 0) { while (tmp2 = shift(path)) { if (fexist($tmp2/$tmp) == 1) { @ root = tmp2 @ realroot = tmp2 } elif (0 < numwords($glob($tmp2/$tmp*))) { @ root = tmp2 @ realroot = tmp2 } else { @ break = 1 @ nohelp = 1 xecho -w ${win == [] ? 0 : win} -b -- No help available on $tmp: Use ? for list of topics. break } } if (@root == 0) { break } } if (fexist($root/$tmp) == 1) { @ tmp2 = [$root/$tmp] } elif (numwords($glob($root/$tmp*)) == 1) { @ tmp2 = glob($root/$tmp*) } elif (numwords($glob($root/$tmp*)) == 0) { @ break = 1 @ nohelp = 1 xecho -w ${win == [] ? 0 : win} -b -- No help available on $tmp: Use ? for list of topics. break } else { # More than one match, dispatch and we're done. @ match = [${tmp == [*] ? [] : tmp}*] @ dir = [$root] @ break = 1 break } @ last = after(${count(/ $root)+1} / $tmp2) if (last =~ [*/]) @ last = before(-1 / $last) @ name #= (@name > 0 ? [ ] : []) ## last if (!help.isdir($tmp2)) { @ file = tmp2 @ dir = [] @ break = 1 @ match = [] break } else { @ root = [$tmp2] @ dir = [] } } if (break != 1 && nocheck != 1) { @ dir = root @ match = [*] } if (dir != []) { @ tmp = split(/ $rest($strlen($realroot) $dir)) } else { @ tmp = split(/ $rest($strlen($realroot) $file)) @ tmp = revw($restw(1 $revw($tmp))) } @ myinput = tmp @ line = more = nohelp = 0 @ pad = (pad == [] ? [ ] : pad) if (var == []) { @ var = 0 until (help[cache][$var][taken] != 1) @ var++ @ help[cache][$var][taken] = 1 } elif (help[cache][$var][taken] != 1) { @ help[cache][$var][taken] = 1 } if (clear == 1) { xecho -say -b -- HELP: Cleared cache fe ($aliasctl(assign pmatch help.cache.*.fp)) fp { @ tmp = close($fp) # echo close\($fp\) returned $tmp } fe ($aliasctl(assign pmatch help.cache.*.*)) tmp { ^assign -$tmp } return } if (unset == 1 && var != []) { ^help.help -kill $var } if (!nohelp) { if (window && win == []) { window new @ win = winnum(0) } @ size = (size == [] ? winsize($win) : size) @ width = (width == [] ? word(0 $geom($win)) -1 : width) if (file == [] && dir != [] && fexist($dir/$last) == 1 && match == [*]) { @ file = [$dir/$last] } if (dp == [] && file != [] && fexist($file) == 1 && !help.isdir($file)) { if (fp == []) { @ fp = open("$file" "R") @ tmp = [$G Help on $name] @ line += numlines($width $tmp) xecho -w $win -- $tmp } if (fp != []) { while (!eof($fp) && (pager == 0 || line < size)) { @ tmp = read($fp) if (tmp =~ [#*] || tmp =~ [!*]) continue ^stack push set indent ^set indent off @ line += numlines($width $tmp) if (!eof($fp)) { xecho -w $win -- $tmp } ^stack pop set indent } if (eof($fp)) { @ close($fp) @ fp = [] if (dir != []) { @ line++ xecho -w $win -- } } } } if (fp == [] && dir != []) { if (dp == []) xecho -b -w $win -- ${name ? [$name choices] : [Choices]} \($match\) @ tmp = stripcrap(ALL $glob("$dir/$match")) @ tmp1 = strlen($dir/) @ tmp2 = maxlen($tmp) - strlen($dir/) @ tmp3 = [] @ padlen = strlen(ALL $pad) while (tmp4 = shift(tmp)) { if (tmp4 =~ [*/CVS/] || (dp != [] && dp != tmp4)) continue @ dp = [] @ tmp5 = pad($tmp2 " " $rest($tmp1 $tmp4)) if (tmp3 == []) { @ tmp3 = tmp5 } elif ((strlen($tmp3) + padlen + tmp2) <= width) { @ tmp3 #= pad ## tmp5 } else { @ line++ if (pager == 0 || line < size) { xecho -w $win -- $tmp3 @ tmp3 = tmp5 } else { @ dp = tmp4 @ more = 1 break } } } if (more != 1) { if (tmp3 != []) { @ line++ xecho -w $win -- $tmp3 @ tmp = dp = [] } elif (numwords($tmp) == 0) { @ dp = [] } } } } while (tmp = shift(varlist)) { ^eval @ help[cache][$var][$tmp] = $tmp } if (nohelp == 0 && (fp != [] && !eof($fp)) || more == 1) { help.more $var } if (fp == [] && dp == []) { if (prompt) { help.prompt $var $encode(Help?) $encode(-. $unsplit(" " $myinput)) . } else { ^help.help -kill $var } } } alias help.more (var, key) { if (@key != 1) { ^eval input_char "*** Hit any key for more. Q to quit, A for all, and F to finish ***" \{ help.more $var \$* \} return } if (key == [q]) { ^help.help -var $var -break } elif (key == [a]) { ^help.help -var $var -nopager } elif (key == [f]) { ^help.help -var $var -noprompt -nopager } else { ^help.help -var $var } } alias help.prompt (var, prompt, old, ...) { ^local tmp,input @ old = after(- $decode($old)) @ prompt = decode($prompt) @ tmp = unsplit(" " $afterw(. $old) $prompt) if ([$0] == [.]) { ^eval input "$tmp " help.prompt $var $encode($prompt) $encode(-$unsplit(" " $old)) \\\$* return } if ([$0] == []) { @ old = revw($restw(1 $revw($old))) if (numwords($old) == 0) { ^help.help -kill $var return } @ tmp = unsplit(" " $afterw(. $old) $prompt) ^eval input "$tmp " help.prompt $var $encode($prompt) $encode(-$unsplit(" " $old)) \\\$* } else { help.help -var $var -newhelp $unsplit(" " $afterw(. $old) $*) } } # howl (2003) epic4-2.10.2.orig/script/debug.irc0000644000000000000000000000344407750415413013531 0ustar # 23 Feb 1999 - Dracus alias debug_section { @ logstate = log if (log == [on]) { @ logfile_old = logfile ^set log off } ^set logfile epic.dbg ^set log on ^set debug 7 } alias debug_endsection { set debug 0 ^set log off ^set logfile $logfile_old ^set log $logstate } #dracus'99 # Time the execution of a given command. # # Usage: # call.time [command] # alias call.time { @ :u1 = utime() $* @ :u2 = utime() stack push set floating_point_math ^set floating_point_math on @ :time = (shift(u2) - shift(u1)) + ((shift(u2) - shift(u1)) / 1000000) @ :time = trunc(6 $time) stack pop set floating_point_math if (functioncall()) { return $time } else { echo $tdiff($time): $* } } # Trace a given command. # # This works by setting the value of debug to debug_level. # See "/help 4 set debug" for information about this setting. # # Usage: # call.trace [debug_level [command]] # alias call.trace { @ :hooks = [set debug set output_rewrite on window on yell on status_update] fe ($hooks) foo bar { stack push $foo $bar $foo -$bar } ^set debug $0 $1- fe ($hooks) foo bar { stack pop $foo $bar } } # Trace a given command. # # Debug_levels is a comma seperated list of values to apply to /xdebug. # See "/help 4 xdebug" for information about debug_levels, but seperate # the values with commas instead of spaces. # # Usage: # call.xtrace [debug_levels [command]] # alias call.xtrace { @ :hooks = [set output_rewrite on window on yell on status_update] @ :debugon = split(, $0) @ :oxd = strip(+- $debugon) fe oxd foo { @ foo = xdebug(*$foo*) } fe ($hooks) foo bar { stack push $foo $bar } xdebug $debugon $1- xdebug $oxd fe ($hooks) foo bar { stack pop $foo $bar } } epic4-2.10.2.orig/script/basical0000644000000000000000000000364207741446375013300 0ustar # This script is intended for use with all installations of ircII. # ircII is unlikely to work properly without loading this script # from 'global'. # # by troy & lynx # Standard ircI-like abbreviations # No irc client can call itself irc client if its not ircI-compatible! # alias a away alias c channel alias ch channel alias e exit alias h help alias i invite alias j join alias l leave #alias log set log alias m msg alias n names alias s signoff alias t topic alias w whois # Standard ircII aliases.. # alias chop mo +o alias unchop mo -o $* alias mo mode $C $* alias k kick $C alias wdetected whois $D alias show exec -msg $T alias umode mode $N # # Because of a logic error, /DMSG and /DQUERY have new aliases. # The old format didnt handle things like /DMSG nick1,nick2 # correctly. However, these aliases will handle multiple targets # correctly. # alias dmsg msg =$tr(/ //$sar(g/,/,=/$0)) $1- alias dquery query =$0 # Reverse text with Ctrl-R bind ^r type  window name ircII # # These functions are _absolutely_ necessary for other scripts to work # correctly. That means that loading this script from global is _not_ # optional. # alias mode3 modethree alias modethree fe ($2-) x y z {mode $0 $1 $x $y $z} alias cinfo echo $info(c) alias o.b @ function_return = (SHOW_NUMERICS==[ON]) ? H : [***] alias locdomain { if (!(function_return = after(-2 . $X))) { @ function_return = X } } alias localwho who -host *.$locdomain() alias recho eval echo $* alias rwhois quote whois $0 $1 # Sent notices should by default not be visible on ^send_notice * : ## Either the two /on's or the /load should be commented out. By default ## the /on's are there for epic backwards compatability and the user can ## do the /load to get ircII backwards compatability. ## Comment out these... on ^set "hold_mode *" window $* on ^set "hold_mode_interval *" window $* ## ... or comment out this. #load hold_mode epic4-2.10.2.orig/script/sping0000644000000000000000000001511007764234337013011 0ustar # sping.irc: a script to calculate the lag between you and a server # # written by nsx # # note: this script uses the serial number 105 for its serial hooks # package sping # *** config variables ** @sping_timeout = 1200 # *** commands *** alias sping (server) { @:source_server = servernum() if (server == []) { @:server = servername() } @:now = utime() quote PING $server $server @:ping_id = get_ping_id() @:sping_data = [$ping_id $now $source_server $server] push sping_list $sping_data ^eval timer -refnum $ping_id $sping_timeout @timeout_sping\($ping_id $server\) xecho -b -w $serv_win() -- Sent PING to $server } alias vping (server) { @:refnum = servernum() if (server == []) { @:server = servername() } @:serv = [!] @:vping_list = vpings[$refnum] for (@:i = 3, serv != [], @:i += 4) { @:serv = word($i $vping_list) if (serv == server) { xecho -b -w $serv_win() -- Waiting for reply to previous VPING to $server return } } @:now = utime() quote VERSION $server @:ping_id = get_ping_id() @:vping_data = [$ping_id $now $server] push vpings[$servernum()] $vping_data ^eval timer -refnum $ping_id $sping_timeout @timeout_vping\($ping_id $server\) ^on ^351 "$server *" { @:now = utime() @:retval = handle_version($0 $now) if (retval) { xecho -b -w $serv_win() -- $1- } ^on ^351 -"$0 *" ^on ^263 -"$0 VERSION *" } ^on ^263 "$server VERSION *" { @:now = utime() @:retval = handle_version($0 $now) if (retval) { xecho -b -w $serv_win() -- $1- } ^on ^351 -"$0 *" ^on ^263 -"$0 VERSION *" } xecho -b -w $serv_win() -- Sent VPING to $server } # *** functions *** alias calculate_ping_time (ithen, fthen, inow, fnow) { @:idiff = inow - ithen @:fdiff = fnow - fthen if (fdiff < 0) { @:fdiff += 1000000 @:idiff-- } repeat ${6 - @fdiff} @:fdiff = [0] ## fdiff @:minute_diff = my_floor(${idiff / 60}) @:second_diff = idiff % 60 if (idiff >= 60) { if (minute_diff == 1) { return $minute_diff min ${second_diff}.${fdiff} secs } else { return $minute_diff mins ${second_diff}.${fdiff} secs } } else { return ${second_diff}.${fdiff} secs } } alias clear_pings { @sping_list = [] @ping_number = 0 fe ($myservers(*)) refnum { @vpings[$refnum] = [] } } alias get_ping_id { @ping_number++ return ping${ping_number} } alias handle_pong (server_name, now) { @:inow = word(0 $now) @:fnow = word(1 $now) @:server = [!] for (@:i = 4, server != [], @:i += 5) { @:server = word($i $sping_list) if (server == server_name) { @:ping_id = word(${i - 4} $sping_list) @:sping_itime = word(${i - 3} $sping_list) @:sping_ftime = word(${i - 2} $sping_list) @:reply_msg = calculate_ping_time($sping_itime $sping_ftime $inow $fnow) @:new_list_start = leftw(${i - 4} $sping_list) @:new_list_end = rightw(${(#sping_list - (i - 4)) - 5} $sping_list) if (new_list_start == []) { @sping_list = new_list_end } else { @sping_list = new_list_start ## [ ] ## new_list_end } ^eval timer -del $ping_id xecho -b -w $serv_win() -- PONG received from $server_name in $reply_msg xecho -w $serv_win() return } } xecho -b -w $serv_win() -- Received PONG from $server_name } alias handle_version (server_name, now) { @:inow = word(0 $now) @:fnow = word(1 $now) @:refnum = servernum() @:server = [!] @:vping_list = vpings[$refnum] for (@:i = 3, server != [], @:i += 4) { @:server = word($i $vping_list) if (server == server_name) { @:ping_id = word(${i - 3} $vping_list) @:vping_itime = word(${i - 2} $vping_list) @:vping_ftime = word(${i - 1} $vping_list) @:reply_msg = calculate_ping_time($vping_itime $vping_ftime $inow $fnow) @:new_list_start = leftw(${i - 3} $vping_list) @:new_list_end = rightw(${(#vping_list - (i - 3)) - 4} $vping_list) if (new_list_start == []) { @:vping_list = new_list_end } else { @:vping_list = new_list_start ## [ ] ## new_list_end } @vpings[$refnum] = vping_list ^eval timer -del $ping_id xecho -b -w $serv_win() -- VPING reply received from $server_name in $reply_msg xecho -w $serv_win() return 0 } } return 1 } alias my_floor (number) { switch ($count(. $number)) { (1) { return $before(. $number) } (0) { return $number } (*) { return -1 } } } alias remove_matching_pings (field, value, entry_size, list) { @:item = [!] @:new_list = [] for (@:i = field, item != [], @:i += entry_size) { @:item = word($i $list) if (item != value) { @:ping_entry = midw(${i - field} $entry_size $list) push new_list $ping_entry } else { @:ping_id = word(${i - field} $list) ^eval timer -del $ping_id } } return $new_list } alias serv_win (refnum) { @:win_max = [255] @:i = [1] if (refnum == []) { @:refnum = servernum() } while (i < win_max) { if (winserv($i) == refnum) { return $i } @:i++ } } alias timeout_sping (ping_id, server) { if (sping_list == []) { return } @sping_list = remove_matching_pings(0 $ping_id 5 $sping_list) xecho -b -w $serv_win() -- PING to $server timed out } alias timeout_vping (ping_id, server) { @:refnum = servernum($server) @:vping_list = vpings[$refnum] if (vping_list == []) { return } @:vping_list = remove_matching_pings(0 $ping_id 4 $vping_list) @vpings[$refnum] = vping_list xecho -b -w $serv_win() -- VPING to $server timed out } # *** hooks *** # upon connection to any server, let's make sure we're not still waiting for # any responses previously sent from that server on #^connect 105 "*" { @:refnum = servernum($0) @:vpings[$refnum] = [] @sping_list = remove_matching_pings(3 $refnum 5 $sping_list) } on ^pong "*" { @:now = utime() @handle_pong($0 $now) } # upon disconnection from any server, let's make sure we're not still waiting # for a response to any pings we sent while connected to that server. on #^server_lost 105 "*" { @:refnum = [$0] @:vpings[$refnum] = [] @sping_list = remove_matching_pings(3 $refnum 5 $sping_list) } # if we're told that a server doesn't exist, let's make sure we're not waiting # a ping reply from that server. on #^402 105 "*" { @sping_list = remove_matching_pings(4 $1 5 $sping_list) fe ($myservers(*)) refnum { @vpings[$refnum] = remove_matching_pings(3 $1 4 $vpings[$refnum]) } } on ^set "SPING_TIMEOUT *" { if ([$1] == []) { xecho -b Current value of SPING_TIMEOUT is: $sping_timeout } elsif (!isnumber($1)) { xecho -b Value of SPING_TIMEOUT must be numeric! } elsif ([$1] < 1) { xecho -b Value of SPING_TIMEOUT must be greater than or equal to 1 } else { @sping_timeout = [$1] xecho -b Value of SPING_TIMEOUT set to $sping_timeout } } @clear_pings() epic4-2.10.2.orig/script/map0000644000000000000000000000533607522072467012453 0ustar # map script. lifted from anduril by wd. # this script is in the public domain # $Id: map,v 1.1 2002/07/31 23:39:35 wd Exp $ # here's how it works. we retrieve links from the server using a /links # command. we then sort them out into an array as below, and then iterate # over the array to generate the map. on servers with 005 support and the # map token, we simply use their map command unless mapping from a specific # server is requested. alias map.encode {return $encode($tolower($*))} alias map.retrieve_links { ^on ^364 * { @:client = [$1] @:hub = [$2] @:hops = [$3] @:gecos = [$4-] @map.links.all #= [$client ] @:henc = map.encode($hub) @:cenc = map.encode($client) @map.links[$cenc][hub] = hub @map.links[$cenc][hops] = hops @map.links[$cenc][info] = gecos if (hops == 0) { return } @push(map.links[$cenc][servers] $hub) @push(map.links[$henc][servers] $client) } ^eval on ^365 "*" map.finish_links $* //^links } alias map.finish_links { ^on 364 -"*" ^on 365 -"*" for xx in ($map.links.all) { @:senc = map.encode($xx) @map.links[$senc][servers] = uniq($map.links[$senc][servers]) if (numwords($map.links[$map.encode($xx)][servers]) > 1) { @push(map.links.hubs $xx) } } # sort our hubs by distance in hops @:hops = 0 @:newlist = [] while (sort($newlist) != sort($map.links.hubs)) { @:new = [] for xx in ($map.links.hubs) { if (map.links[$map.encode($xx)][hops] == hops) { @push(:new $xx) } } if (new != []) { @push(:newlist $new) } @:hops++ } @map.links.hubs = newlist $* fe ($aliasctl(assign pmatch map.links*)) xx { ^assign -$xx } } alias map (server) { if (serverctl(GET $servernum() 005 MAP) != [] && server == []) { quote map return } map.retrieve_links map.exec $server } ### this displays a single branch of a map. I changed this alias slightly (to ### make it work properly) after observing the way Liandrin's script worked. alias map.map_branch (server, prefix) { @push(map.links.seen $server) @:senc = map.encode($server) echo [map] $prefix$server \($map.links[$senc][hops] $map.links[$senc][info]\) @:servers = remws($map.links.seen / $map.links[$senc][servers]) if (numwords($servers) == 0) { return } @:prefix = msar(/`-/ /-/ /$prefix) for xx in ($servers) { if (xx == rightw(1 $servers)) { map.map_branch $xx $prefix`- } else { map.map_branch $xx $prefix|- } } } alias map.exec (server) { if (server == []) { @:server = builtin_expando(S) } if (findw($server $map.links.all) == -1) { aerrecho server $server does not appear to be online return } map.map_branch $server } ### vi:set ts=8 sts=4 sw=4 tw=79 syntax=off ai smartindent: epic4-2.10.2.orig/script/dig0000644000000000000000000000234207415131614012422 0ustar # Contributed to the epic project by Steve Horan on April 21, 1999. # # Here's a few useful functions I thought others might find useful # Find the minimum/maximum number. $min() $max() alias max {@ function_return = pop($numsort($*))} alias min {@ function_return = shift($numsort($*))} # $commasep(one,two,three) returns "one two three" # $commamake(one two three) returns "one,two,three" # Useful in opnotice scripts + other aliases. alias commasep {@ function_return = split(, $*)} alias commamake {@ function_return = tr(/ /,/$*)} # Somewhat kludge function here. This function finds the parent domain # to given host, rather than using a assumed approach # e.g. Many would view www.syd.lucid.net.au as being from the domain # lucid.net.au - when it's parent domain is in fact syd.lucid.net.au # This function has it's uses, to some more than others. # requires hop's pipe function, as well as the "dig" program. # $digdomain(squishycow.syd.lucid.net.au) returns "syd.lucid.net.au" alias digdomain { if (isalpha($right(1 $*))) {@ function_return = pipe(dig SOA $* | perl -lane 'print \$1 if /^([^;]. *?)\\.\\s+.*SOA/')} {@ function_return = [$*]} } load pipe # - Wuhphy '99 # sjhoran@syd.lucid.net.au epic4-2.10.2.orig/script/suppressmotd0000644000000000000000000000225307665741527014451 0ustar # # Here's the story. We want to suppress server-side MOTDs. # I don't know why anyone would want to do this, but eh, this # used to be an epic function and i removed it and people noticed # it so I'm honor bound to script it at the very least. # @ suppress_server_motd = 0 on ^set "suppress_server_motd on" {@suppress_server_motd = 1} on ^set "suppress_server_motd off" {@suppress_server_motd = 0} do { @ negser = getserial(HOOK - 0) @ posser = getserial(HOOK + 0) # The first time we see the MOTD, trigger the "doing motd" flag. on #^375 $negser * { if (!done_motd[$lastserver()]) { ^assign doing_motd[$lastserver()] 1 } } # When we see the end of the first MOTD, trigger the "done motd" flag. on #^376 $posser * { if (doing_motd[$lastserver()]) { ^assign -doing_motd[$lastserver()] ^assign done_motd[$lastserver()] 1 } } # When the connection is closed, reset the flag. on #^server_lost $posser * { ^assign -done_motd[$lastserver()] } # Only suppress the first MOTD from each server connection. for i in (372 375 376 377) { on ^$i * { if (suppress_server_motd && doing_motd[$lastserver()]) { return } xecho -b $1- } } } #hop'y2k+3 epic4-2.10.2.orig/script/meta-compat0000644000000000000000000000541507766647350014114 0ustar # $EPIC: meta-compat,v 1.2 2003/12/13 17:39:52 jnelson Exp $ # meta-compat - compatibility layer for old-style /bind METAx-y sequences # # Copyright 2003 Ben Winslow # # Released under the same license as ircII-EPIC # # Caveat: The sticky behavior of META4 isn't supported; META4 will behave # like any other meta level. package meta-compat alias bind (binding, boundto) { # we're resetting everything to the defaults - clear our list of # meta keys and reinitialize @metacompat.depth++ if (metacompat.depth > 100) { xecho -b meta-compat: recursed too many times for /bind $binding $boundto return } # echo bind: $repeat($metacompat.depth $chr(9)) $binding $boundto if (binding == [-DEFAULTS]) { //bind -defaults metacompat.defaults @metacompat.depth-- return } # this binding uses a meta type, resolve it into a key sequence if (binding =~ [META%-%]) { @:spec=rest(4 $binding) @:meta=before(- $spec) @:keys=after(- $spec) foreach metacompat[$meta][defs] curmeta { bind $decode($curmeta)$keys $boundto } if (boundto == [NOTHING]) { @:boundto=[] } @metacompat[$meta][keys][$encode($keys)]=boundto @metacompat.depth-- return } # look for an existing meta level on this key and clear it because # we're binding to something else. additionally, remove any underlying # bindings that will no longer be relevant when this key is removed @:encoded=encode($binding) foreach metacompat curmeta { if (metacompat[$curmeta][defs][$encoded]) { # unbind any affected keys foreach metacompat[$curmeta][keys] curkey { ^bind $decode($encoded$curkey) NOTHING } ^assign -metacompat[$curmeta][defs][$encoded] } } # this binding sets a meta level, save it and NOP if (boundto =~ [META%]) { @:spec=rest(4 $boundto) @:meta=before(_ $spec) # allow shortcutting to METAx instead of METAx_CHARACTER if (meta == []) { @:meta=spec } @metacompat[$meta][defs][$encode($binding)]=1 # rebind keys for this meta level so that the new meta character # takes effect foreach metacompat[$meta][keys] curkey { bind META$META-$decode($curkey) $metacompat[$meta][keys][$curkey] } @metacompat.depth-- return } # we've either resolved the binding to a key sequence, or this is # a new-style bind that we don't need to mangle if (boundto == []) { //bind $binding }{ //bind $binding $boundto } @metacompat.depth-- } alias metacompat.defaults { fe ($aliasctl(ASSIGN PMATCH metacompat\.*)) metainfo { ^assign -$metainfo } # defaults from EPIC4-1.0.1 bind ^X META2_CHARACTER bind ^[ META1_CHARACTER bind META1-O META2_CHARACTER bind META1-[ META2_CHARACTER bind META2-1 META32_CHARACTER bind META2-4 META33_CHARACTER bind META2-5 META30_CHARACTER bind META2-6 META31_CHARACTER } metacompat.defaults epic4-2.10.2.orig/script/autoop0000644000000000000000000000404007415131614013163 0ustar # AutoOp by Ian Frechette 12-10-92 # EPIC modifications as necessary by Jeremy Nelson # the people you want to be opped by default. Wildcards are allowed. # the patterns must be of the form user@host if (!op_list) {@ op_list = [bob@example.bob.edu foo@*.bar.com]} # the channels you want people to be opped on by default. Wildcards # are allowed. '*' simply means all channels apply. if (!chan_list) {@ chan_list = [* #example]} # Show the the people currently in the autoop list alias showop { @ count = 0 @ ao.name = [] echo *** AutoOp list. Addop user@host to add. Delop to remove echo *** nickname!username@hostname for ao.name in ($op_list) { echo *** $[5]count $ao.name @ count++ } } # Just like showop but works with channels. alias showchan { @ count = 0 @ ao.name = [] echo *** AutoOp chan list. Addchan #channel add. Delchan to remove echo *** #channel for ao.name in ($chan_list) { echo *** $[5]count $ao.name @ count++ } } # Given a number.. deletes that person from the autoop list.. # use SHOWOP to list. alias delop { if (rmatch("$0" *1 *2 *3 *4 *5 *6 *7 *8 *9 *0)) { @ op_list = notw($0 $op_list) } { echo *** Usage: delop ;echo *** See showop } } # Given a number.. deletes that channel from the autoop channel list.. # use SHOWCHAN to list. alias delchan { if (rmatch("$0" *1 *2 *3 *4 *5 *6 *7 *8 *9 *0)) { @ chan_list = notw($0 $chan_list) } { echo *** Usage: delchan ;echo *** See showchan } } # Add an autochanop to the list. alias addop { if ([$0]) { push op_list $0 } { echo *** Usage addop username@host;echo *** wildcards are allowed } } # Add an autochanop channel to the list. alias addchan { if ([$0]) { push chan_list $0 } { echo *** Usage addchan #channel;echo *** wildcards are allowed } } # # the actual ON that does the work # This is the hook as it would be used in ircii-EPIC # on #-join 666 '% \\[$chan_list\\] \\[$op_list\\]' { timer ${10 + rand(10)} if \(!ischanop\($0 $1\)\) \{//mode $1 +o $0\} } epic4-2.10.2.orig/script/webster0000644000000000000000000000431207213031315013322 0ustar /* * A webster client for ircII * Written by Jeremy Nelson (C) 1994 - This is Freeware * * This script requires ircII-EPIC to run. * Since there is no more webster server, this script stands * as an intellectual exercise. */ echo *** The webster server at webster.cs.indiana.edu echo *** is no longer operational. The webster script echo *** is obsolete. alias define { webster.connect webster.out DEFINE $0 } alias complete { webster.connect webster.out COMPLETE $0 } alias endings { webster.connect webster.out ENDINGS $0 } alias spell { webster.connect webster.out SPELL $0 } alias webster.out { dcc raw $webster.fd $webster.host $*$chr(13)$chr(10) } alias webster.connect { ^set display off echo *** Webster: Hang on..... @ webster.host = [webster.cs.indiana.edu] @ webster.port = 2627 @ webster.fd = connect($webster.host $webster.port) if (webster.fd) { eval ^on ^dcc_raw "$webster.fd $webster.host D *" { hook WEBSTER $strip($chr(13) $3-) } } { echo *** Webster: connection failed } ^set display on } # The DEFINE command replies on hook "WEBSTER DEFINITION 0" { echo *** Webster: Definition Found. } on hook "WEBSTER DEFINITION %" { echo *** Webster: There are $2 cross references for this word } on hook "WEBSTER WILD" { echo *** Webster: These words match the pattern. } on hook "WEBSTER WILD 0" { echo *** Webster: No words match this pattern. } on hook "WEBSTER ERROR*" { echo *** Webster: Error: unknown command. Ack! } # The COMPLETE command replies on hook "WEBSTER AMBIGUOUS %" { echo *** Webster: There are $2 possible completions to the word. } on hook "WEBSTER COMPLETION %" { echo *** Webster: Try completing the word as $2. } # The ENDINGS command replies on hook "WEBSTER MATCHS 0" { echo *** Webster: No words begin with that prefix } on hook "WEBSTER MATCHS" { echo *** Webster: These words complete that suffix } # The SPELL command replies on hook "WEBSTER SPELLING 0" { echo *** Webster: I have NO idea how to spell that word } on hook "WEBSTER SPELLING 1" { echo *** Webster: That word is spelled correctly } on hook "WEBSTER SPELLING" { echo *** Webster: Try using one of these words instead } # Everything else gets echoed on hook "WEBSTER *" { echo $1- } epic4-2.10.2.orig/script/events0000644000000000000000000000143007213031315013151 0ustar if ( SHOW_WHO_HOPCOUNT == [ON] ) { on ^who * { if ( [$0] == [*] ) { echo $[9]1 [$2$6] $7- \($3@$4) } { echo $[9]1 [$2$6] $7- on $0 \($3@$4) } } } { on ^who * { if ( [$0] == [*] ) { echo $[9]1 [$2] $7- \($3@$4) } { echo $[9]1 [$2] $7- on $0 \($3@$4) } } } on ^who Channel comment on ^timer *00 echo *** The time is $0 on -msg * set status_user - last: $0 on ^names * echo $[15]0 $1- on ^names \* echo * $1- on ^list \* echo --  -- $[4]1 $2- on ^list * echo $[15]0 $[4]1 $2- on ^notify_signon * userhost $* -cmd echo *** $$0 is here [$$3@$$4] on ^notify_signoff * set status_user + signoff: $0 #on ^send_public * { # if ( [$0] == C ) { echo <$N> $1- } { echo -> <$0> $1- } #} #on ^send_msg * echo -> *$0* $1- # lynx92,93 epic4-2.10.2.orig/script/man0000644000000000000000000000030107611030050012411 0ustar alias man { if ([$0]) { fe (1 2 3 4 5 6 7 8 n) man.type { if (glob($help_path/$man.type*/$0)) { help $man.type $* help -wait break } } } } #Dawid Kuroczko'97 epic4-2.10.2.orig/script/hold_mode0000644000000000000000000000236010743127566013622 0ustar # Simulate /set hold_mode and /set hold_mode_interval for ircII users on #^window_create -125 * { if (default_hold_mode == [on]) { window $1 hold_mode on } if (default_hold_mode_interval != []) { window $1 hold_mode_interval $default_hold_mode_interval } } on ^set "hold_mode *" { if ([$1] != [on] && [$1] != [off] && [$1] != [toggle]) { xecho -b SET HOLD_MODE must be ON, OFF, or TOGGLE return } if ([$1] == [on]) { @ default_hold_mode = [on] } else if ([$1] == [off]) { @ default_hold_mode = [off] } else if ([$1] == [toggle] && default_hold_mode == [on]) { @ default_hold_mode = [off] } else if ([$1] == [toggle] && default_hold_mode == [off]) { @ default_hold_mode = [on] } fe ($winrefs()) x { window $x hold_mode $default_hold_mode } xecho -b SET HOLD_MODE set to $default_hold_mode } on ^set "hold_mode_interval *" { @ default_hold_mode_interval = [$1] fe ($winrefs()) x { window $x hold_interval $default_hold_mode_interval } xecho -b SET HOLD_MODE_INTERVAL set to $default_hold_mode_interval } on ^set "hold_interval *" { @ default_hold_mode_interval = [$1] fe ($winrefs()) x { window $x hold_interval $default_hold_mode_interval } xecho -b SET HOLD_INTERVAL set to $default_hold_mode_interval } #hop'y2k3 epic4-2.10.2.orig/script/screen0000644000000000000000000000304507525764605013155 0ustar # $EPIC: screen,v 1.3 2002/08/12 16:59:49 jnelson Exp $ # screen - makes ircII like screen. # original idea from Avalon (avalon@coombs.anu.edu.au) # this script by phone (phone@coombs.anu.edu.au) # # Lines like # # window [new] level NONE hold [off|on] scroll [off|on] chan #some_channel # window hide # # Are useful for setting up these windows, with the first occurrence not # having a "new" ..and the last not having a "hide". # # ^X1 - ^X0 swap windows 1 to 10. # ^Xa goes to the last window.. # ^Xc creates a new window # ^Xk kills the current window, and swaps it with another. # ^Xl lists the windows. # ^Xn swaps the next window (in refnumbers) # ^Xp swap the previous window (in refnumbers) # ^X (space) swap the next window. # ^XC clears all windows visible alias win.newwin window new hide;window swap last bind ^X1 parse_command window swap 1 bind ^X2 parse_command window swap 2 bind ^X3 parse_command window swap 3 bind ^X4 parse_command window swap 4 bind ^X5 parse_command window swap 5 bind ^X6 parse_command window swap 6 bind ^X7 parse_command window swap 7 bind ^X8 parse_command window swap 8 bind ^X9 parse_command window swap 9 bind ^X0 parse_command window swap 10 bind ^Xa parse_command window swap last bind ^Xc parse_command win.newwin bind ^X^c parse_command win.newwin bind ^Xk parse_command window killswap bind ^Xl parse_command window list bind ^Xn swap_next_window bind ^Xp swap_previous_window bind ^X^` swap_next_window # does a space, for some reason. bind ^XC parse_command clear all bind ^X^X parse_command window swap last epic4-2.10.2.orig/script/utime0000644000000000000000000000220107213031315012765 0ustar # # Here's the plan # Kanan wants a way to manipulate $utime() values. Because theyre # thrown about as two words, we cant actually have the math parser # handle them automatically (alas), and writing built in functions # just to do this seems like overkill. So i wrote these aliases for # his (and your) convenience. Use this is as a starting point for you # own alias needs, or drop me a line if you have more suggestions. # (jnelson@acronet.net) # # # Add two utimes. # alias utime_add { local sec,usec @ sec = [$0] + [$2] @ usec = [$1] + [$3] if (usec > 1000000) { @ usec -= 1000000, sec++ } @ function_return = sec ## [ ] ## right(6 000000$usec) } # # Subtract two utimes. The LARGER utime (the more recent) should # be the first one specified # alias utime_sub { local sec,usec @ sec = [$0] - [$2] @ usec = [$1] - [$3] if (usec < 0) { @ usec += 1000000, sec-- } @ function_return = sec ## [ ] ## right(6 000000$usec) } # # You pass a utime as $0, $1, and this function will return # how many useconds have passed since then. # alias time_since { local now $utime() @ function_return = utime_sub($now $0 $1) } #hop'97 epic4-2.10.2.orig/script/global0000644000000000000000000000046507213031315013114 0ustar # This is the global ircrc # Please make your installation changes in 'local' # # These two aliases are used by the scripts alias d- ^set display off alias d+ ^set display on # # The basic setup for ircII load basical load 2.8script # If you want this script, load it in your .ircrc #load newaway load local epic4-2.10.2.orig/script/hybrid60000644000000000000000000002065307415131614013233 0ustar ############################################################################### # hybrid-6 script (c) 2000 Edward Brocklesby # includes modified code from da5id's newons.irc # # usage: (stuff in [] is optional) # /kline [time] [reason] (add a tkline, defaults to 60) # /pkline [reason] (add a kline) # /dline [reason] (add a dline) # /gline [reason] (request a gline) # (reason in the above commands defaults to 'No reason') # # /unkline (remove a kline or tkline) # /operwall (send an Operwall) # /locops (send a locops) # /opermsg (send 'message' to all opers on 'server' # Note: only works if target server is running hybrid-6) # # mail bugs/fixes/feature requests to ejb@leguin.org.uk ############################################################################### alias operwall quote operwall :$* alias locops quote locops :$* alias opermsg msg opers@$0 $1- alias dline { {if ([$1-]) {quote dline $0 :[$N] $1-} {quote dline $0 :[$N] No reason}}} alias pkline { {if ([$1-]) {quote kline $0 :[$N] $1-} {quote kline $0 :[$N] No reason}}} alias kline { if (isnumber($0)) {if ([$2-]) {quote kline $0 $1 :[$N] $2-} {quote kline $0 $1 :[$N] No reason}} {if ([$1-]) {quote kline 60 $0 :[$N] $1-} {quote kline 60 $0 :[$N] No reason}}} alias unkline { quote unkline $*} alias gline { if ([$1-]) {quote gline $0 :$1-} {quote gline $0 :No reason} } on ^211 * { echo $cparse(%K[%w servstats%K]%n $[-40]1%K%K: %wS%K:%W$[4]{[$4]/1024} % wR%K:%n$[4]{[$6]/1024} %wQ%K:%n$2 %wT%K:%n$[12]tdiff2($7) %wI%K:%n$[3]8 %K[%w$9- %K])} on ^249 * { echo $cparse(%K[%w servstats%K]%n $1-)} on ^kill "% % % *" echo $cparse(%K[%w operkill%K]%n $2 killed $1 reason: $4-) on ^kill "% % %.% *" echo $cparse(%K[%w servkill%K]%n $2 killed $1) on ^351 "*" echo $fmt.num.ver($*) on ^oper_notice "* unauthori%ed client connection *" echo $fmt.snot.ucon($*) on ^oper_notice "* client connecting% *" echo $fmt.snot.con($*) on ^oper_notice "* client exit% *" echo $fmt.snot.disco($*) on ^oper_notice "* stats *" echo $fmt.snot.stats($*) on ^oper_notice "* links *" echo $fmt.snot.links($*) on ^oper_notice "* % added k-line *" echo $fmt.snot.kline($*) on ^oper_notice "* % added d-line *" echo $fmt.snot.dline($*) on ^oper_notice "* %-line active *" echo $fmt.snot.active($*) on ^server_notice "% % added %line *" echo $fmt.snot.addline($*) on ^server_notice "* %line for * removed" echo $fmt.snot.remline($*) on ^oper_notice "* % has removed the K-Line*" echo $fmt.snot.unkline($*) on ^oper_notice "* % has removed the temporary K-Line*" echo $fmt.snot.untkline($*) on ^oper_notice "* * is doing a %whois *" echo $fmt.snot.whois($*) on ^oper_notice "* Nick change: From*" echo $fmt.snot.nick($*) on ^oper_notice "* * count off by %" echo $fmt.snot.count($*) on ^oper_notice "* % added temp% *" echo $fmt.snot.tempk($*) on ^oper_notice "* % is clearing temp *" echo $fmt.snot.rehash($*) on ^oper_notice "* % is forcing %reading *" echo $fmt.snot.rehash($*) on ^oper_notice "* % is rehashing server *" echo $fmt.snot.rehash($*) on ^oper_notice "* got signal sighup% *" echo $fmt.snot.rehash($*) on ^oper_notice "* % high-traffic *" echo $fmt.snot.htm($*) on ^oper_notice "* resuming standard *" echo $fmt.snot.htm($*) on ^oper_notice "* user % % tried to *" echo $fmt.snot.mflood($*) on ^oper_notice "* MOTD requested *" echo $fmt.snot.motd($*) on ^oper_notice "* Flooder * on * target: *" echo $fmt.snot.flood($*) on ^oper_notice "* Possible Drone Flooder*" echo $fmt.snot.dflood($*) on ^oper_notice "* % % is now operator %" echo $fmt.snot.oper($*) on ^oper_notice "* Quarantined nick *" echo $fmt.snot.qline($*) on ^oper_notice "* X-Line Warning *" echo $fmt.snot.xline($*) on ^oper_notice "* X-Line Rejecting *" echo $fmt.snot.xline($*) on ^oper_notice "* spoofing:* *as*" echo $fmt.snot.spoof($*) on ^oper_notice "* POSSIBLE /names abuser *" echo $fmt.snot.names($*) on ^oper_notice "* New Max Local Clients: *" echo $fmt.snot.maxcli($*) on ^oper_notice "* server % being introduced by *" echo $fmt.snot.netjoin($*) on ^oper_notice "*" echo $fmt.snot.onot($*) on ^server_notice "*" echo $fmt.snot.gen($*) @ opermotd = [NO] on ^server_notice "*Start of OPER MOTD*" @ opermotd = [YES] on ^server_notice "*End" @ opermotd = [NO] alias fmt.num.ver return $cparse(%K[%w version%K]%n) ^Bserver^B $2 ^Bversion^B $chop(1 $1) ^Bflags^B $3 $4 alias fmt.snot.gen { if (opermotd == [YES]) { return $cparse(%K[%w opermotd%K]%n) $2- } else { return $cparse(%K[%w server%K]%n) $1- } } alias fmt.snot.netjoin return $cparse(%K[%w netjoin%K]%n) $2 -> $6 alias fmt.snot.maxcli return $cparse(%K[%wmaxclients%K]%n) $1- alias fmt.snot.names return $cparse(%K[%w names%K]%n) $1- alias fmt.snot.spoof return $cparse(%K[%w spoof%K]%n) $1 [$3] as $5 alias fmt.snot.qline return $cparse(%K[%w q-line%K]%n) $2- alias fmt.snot.xline return $cparse(%K[%w x-line%K]%n) $2- alias fmt.snot.con return $cparse(%K[%w connect%K]%n) $3 $4 alias fmt.snot.ucon return $cparse(%K[%w unauth%K]%n) $5 $6 alias fmt.snot.disco return $cparse(%K[%w exit%K]%n) $3 $4 $5- alias fmt.snot.stats return $cparse(%K[%w stats%K]%n) $2 requested by $5 $6 from $7 alias fmt.snot.links return $cparse(%K[%w links%K]%n) $2 requested by $5 $6 from $7 alias fmt.snot.kline return $cparse(%K[%w kline%K]%n) $1 for $chop(1 $rest(1 $5)) reason: $chop(1 $rest(1 $6-)) alias fmt.snot.dline return $cparse(%K[%w dline%K]%n) $1 for $5 $6- alias fmt.snot.active return $cparse(%K[%w active%K]%n) $1- alias fmt.snot.addline return $cparse(%K[%w added%K]%n) $2 $3- alias fmt.snot.remline return $cparse(%K[%w removed%K]%n) $2 $3 $4 alias fmt.snot.unkline return $cparse(%K[%w unkline%K]%n) $1 for $chop(1 $rest(1 $7)) alias fmt.snot.untkline return $cparse(%K[%w unkline%K]%n) $1 for $chop(1 $rest(1 $8)) alias fmt.snot.whois return $cparse(%K[%w whois%K]%n) $1- alias fmt.snot.nick return $cparse(%K[%w nick%K]%n) $[-9]4 to $[9]6 $7 alias fmt.snot.flood return $cparse(%K[%w flooder%K]%n) $2- alias fmt.snot.dflood return $cparse(%K[%w flooder%K]%n) $1- alias fmt.snot.count return $cparse(%K[%w client%K]%n) $1- alias fmt.snot.tempk return $cparse(%K[%w tempk%K]%n) $1 for $8 lasting $4 mins reason: $chop(1 $rest(1 $9-)) alias fmt.snot.rehash return $cparse(%K[%w rehash%K]%n) $1- alias fmt.snot.htm return $cparse(%K[%w htm%K]%n) $1- alias fmt.snot.skill return $cparse(%K[%w servkill%K]%n) $7 killed $3 $10- alias fmt.snot.okill return $cparse(%K[%w operkill%K]%n) $4 $5 $6 $7 $10- alias fmt.snot.mflood return $cparse(%K[%w msgflood%K]%n) $[-9]2 $3- alias fmt.snot.motd return $cparse(%K[%w motd%K]%n) requested by $4 $5 from $6 alias fmt.snot.oper return $cparse(%K[%w oper%K]%n) $1- alias fmt.snot.onot return $cparse(%K[%w server%K]%n) $1- on ^wallop "% *" { switch ($2) { (Received) { xecho -level snote $fmt.wallops.squit($*) } (Remote) { xecho -level snote $fmt.wallops.connect($*) } (WALLOPS) { xecho -level snote $fmt.wallops.wallops($*) } (OPERWALL) { xecho -level snote $fmt.wallops.operwall($*) } (LOCOPS) { xecho -level snote $fmt.wallops.locops($*) } (*) { xecho -level snote $fmt.wallops.none($*) } } } alias fmt.wallops.squit return $cparse(%K[%w servwall%K]%n %r!%R$0%r!%n) $2- alias fmt.wallops.connect return $cparse(%K[%w servwall%K]%n %r!%R$0%r!%n) $2- alias fmt.wallops.wallops return $cparse(%K[%w wallops%K]%n %r!%R$0%r!%n) $4- alias fmt.wallops.operwall return $cparse(%K[%w operwall%K]%n %r!%R$0%r!%n) $4- alias fmt.wallops.locops return $cparse(%K[%w locops%K]%n %r!%R$0%r!%n) $4- alias fmt.wallops.none return $cparse(%K[%w wallops%K]%n %r!%R$0%r!%n) $2- #ejb'y2k epic4-2.10.2.orig/script/fe0000644000000000000000000000154007253747052012261 0ustar /* * The FE script... showing you the wonders of /fe! * Current supported version: ircii-EPIC * Mass* has never been easier! (tm) */ alias opalot fe ($2-) xx yy zz {mode $0 $1ooo $xx $yy $zz} alias banalot fe ($2-) xx yy zz {mode $0 $1bbb $xx $yy $zz} #alias kickalot fe ($1-) xx {kick $0 $xx} alias kickalot for xx in ($1-) {kick $0 $xx} alias masskick kickalot ${[$0]?[$0]:C} $remw($N $onchannel($0)) alias massdeop opalot ${[$0]?[$0]:C} - $remw($N $chops($0)) alias opall opalot ${[$0]?[$0]:C} + $nochops($0) alias cuh { ^local foobar # fe ($onchannel($0)) ix { push foobar $userhost($ix) } for ix in ($onchannel($0)) { push foobar $userhost($ix) } @ function_return = foobar } alias botsweep (target, chan default "$C") { @ :nicks = onchannel($chan) @ :uhs = cuh($nicks) kickalot $chan $copattern($uh($target) uhs nicks) } load guh #hop'94 epic4-2.10.2.orig/script/revdcc0000644000000000000000000001275407213031315013126 0ustar /******************************************************************************* September 1, 1996 they said it couldn't be done... THEY WERE WRONG. Reverse DCC for ircii-epic by archon The purpose of this script is to allow clients behind firewalls to dcc send. If you and your intended recipient are both firewalled, use mail or ftp. Basically, instead of telling the recipient to connect to your machine where you will send them the file, you tell them to use their own own machine, then you send it. Both you and the recipient must be running this script for it to work. Thanks: hop for writing EPIC, and for helping to get this script working smoothly. Versions/Updates ---------------- 1.0a: it actually works for text files. wow, that wasn't so hard now was it? 1.0b: added uuencoding to work for binary files fixed fexist() test in revsend 1.0c: changed port selection to be decided by the receiver 1.0d: minor fixes and cleaning up. completed revclose. added help. *******************************************************************************/ set novice off alias ento { @ function_return = encode($tolower($0)) } alias revsend { if ([$1]) { @ rev.file = [$1] userhost $0 -cmd if (index(. $4) > 0) { @ rev.nick = ento($0) @ rev.host[$rev.nick] = [$4] if (fexist($rev.file) > 0) { push sendqueue[$rev.nick] $rev.file echo *** Sending reverse DCC request to $0 ^on ^ctcp_reply "$0 REVDCC REJECT $rev.file" { echo *** $0 has rejected reverse DCC SEND of $3 @ rev.host[$rev.nick] = sendqueue[$rev.nick] = [] ^on ctcp_reply -"$0 REVDCC REJECT $rev.file" } quote privmsg $0 :REVDCC SEND $rev.file\ @ rev.nick = rev.file = rev.seed = [] }{ echo *** Cannot access $W/$rev.file } }{ echo *** $0\: No such nick } }{ echo *** Usage: /revsend nick file } } alias revget { if ([$1]) { @ rev.rnick = ento($0) if (rev.fname[$rev.rnick]) { echo *** Getting $1 from $0 @ listen($rev.port[$rev.rnick]) quote notice $0 :REVDCC GET $1 $rev.port[$rev.rnick]\ @ rev.rnick = [] }{ echo *** No reverse DCC SENDS pending from $0 } }{ echo *** Usage: /revget nick file } } alias receivefile { @ rev.snick = [$3] @ rev.file[$rev.snick] = [$0\.uu] @ rev.lsocket = [$1] @ rev.lport = [$2] @ fd = open($rev.file[$rev.snick] W) stack push on dcc_raw ^on ^dcc_raw "$1 % D*" { # exec -name decodefile$rev.file[$rev.snick] $3- @ write($fd $3-) } ^on ^dcc_lost "$1 RAW *" { echo *** Connection closed: File transfer complete... decoding. ^on dcc_raw -"$rev.lsocket % D*" ^on dcc_lost -"$0 RAW *" dcc close raw_listen $rev.lport @ close($fd) ^on ^exec_exit "decodefile$rev.file[$rev.snick] *" { echo *** Decoding complete ^on exec_exit -"decodefile$rev.file[$rev.snick] *" ^on dcc_raw -"% % N $rev.port[$rev.snick]" @ unlink($rev.file[$rev.snick]) @ fd = sendnick = rev.file[$rev.snick] = rev.lsocket = rev.lport = rev.fname[$rev.snick] = rev.port[$rev.snick] = rev.snick = [] } stack pop on dcc_raw exec -name decodefile$rev.file[$rev.snick] uudecode $rev.file[$rev.snick] } } alias revclose { quote notice $0 :REVDCC REJECT $1\ } on ^ctcp_reply "% REVDCC GET *" { @ getnick = ento($0) @ rev.sfile[$getnick] = [$3] @ rev.sendport[$getnick] = [$4] if (match($3 $sendqueue[$getnick])) { ^on ^exec "sendfile$getnick *" { dcc raw $rev.socket[$getnick] $rev.host[$getnick] $1- } ^on ^exec_exit "sendfile$getnick *" { ^on exec -"sendfile$getnick *" ^on exec_exit -"sendfile$getnick *" ^on dcc_raw -"$rev.socket[$getnick] $rev.host[$getnick] C*" ^on ctcp_reply -"$decode($getnick) REVDCC REJECT $rev.sfile[$getnick]" timer 2 ^dcc close raw $rev.socket[$getnick] echo *** Connection closed. File transfer complete. @ rev.host[$getnick] = sendqueue[$getnick] = rev.sendport[$getnick] = rev.socket[$getnick] = rev.sfile[$getnick] = getnick = [] } @ rev.socket[$getnick] = connect($rev.host[$getnick] $rev.sendport[$getnick]) echo *** Sending $3 to $0 ^exec -name sendfile$getnick uuencode $3 $3 } } on ^ctcp "% % REVDCC SEND *" { @ sendnick = ento($0) @ rev.fname[$sendnick] = [$4] @ rev.seed = srand($time()) @ rev.port[$sendnick] = rand(10000) + 8000 ^on ^dcc_raw "% % N $rev.port[$sendnick]" { receivefile $rev.fname[$sendnick] $0 $rev.port[$sendnick] $sendnick } echo *** Received reverse DCC SEND request from $0\: $4- echo *** Use /revget $0 $4\ to get this file or /revclose $0 $4\ to cancel } alias revhelp { echo _-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_ echo *** $center($word(0 $geom()) RevDCC.irc by archon v1.0d.epic) echo *** Note: anything in <>'s is required. anything in []'s is optional echo *** REVSEND echo *** Sends to echo *** REVGET echo *** Receives from echo *** REVCLOSE echo *** Rejects send of from echo _-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_-^-_ } echo [RevDCC] Reverse DCC v1.0d.epic by archon loaded! Help: /revhelp /************************************************************ to do: - flood protection - test for file existance (receiver) - rename - uudecode from stdin ************************************************************/ epic4-2.10.2.orig/script/mudirc0000644000000000000000000000317507575707767013200 0ustar # EPIC's mud client, 1998 # Based on the old 1994-vintage script by the same name # This script requires EPIC4pre1.050 or better # Here's the plan: # # Usage: newmud keyword hostname portnum # registers "keyword" in the mud array # # Usage: mud # shows you the muds in the array # # Usage: mud keyword # logs you into that mud # alias mud { if ([$0]) { if (mud[$encode($0)][name]) { if (mud[$encode($0)][mark]) { echo *** Already connected to that mud! } {c_mud $0 $mud[$encode($0)][name] $mud[$encode($0)][port]} } {echo *** No such mud on file} } { foreach mud i { echo *** MUD: $decode($i) - $mud[$i][name] $mud[$i][port] } } } alias c_mud { @ keyw = [$0] @ mudcon = mudcon + 1 if (mudcon > 4) { @ mudcon = mudcon - 1 echo *** Too many muds open (limit of 4) } elsif (fd = mud[$encode($0)][fd] = connect($1 $2)) { window new name $keyw level NONE ^on ^dcc_raw "$fd % d *" \{xecho -w $keyw $$chop($3-)\} ^on ^dcc_raw "$fd % c" { on dcc_raw -"$0 % c" on dcc_raw -"$0 % d *" @ mudcon = mudcon - 1 } window query =$fd } } bind ^W next_window alias newmud { @ mud[$encode($0)][name] = [$1] @ mud[$encode($0)][port] = [$2] } newmud onyx stimpy.cs.iastate.edu 3456 newmud moo lambda.moo.mud.org 8888 @ mudcon = 0 #hop'98 epic4-2.10.2.orig/script/tls0000644000000000000000000001411707525764605012502 0ustar #$EPIC: tls,v 1.3 2002/08/12 16:59:49 jnelson Exp $ /* * TRACE/LINKS/STATS BEAUTIFYING SCRIPT * This script is immortal, it just wont go away! * * The original author is unknown. * TG (Daniel Cedras) picked it up, fixed it, and distribd with SuperPak * This version was syntactically modified by Jeremy Nelson for EPIC 3 */ /* * * TRACE * * * For the use of /TRACE, you have the option of seeing users on a * server or not: -t turns this option on and off. * * It also effects the output of /STAT L * SEEING USERS ON A SERVER IS AN OPERATOR PRIVILEGE. :p * */ /* These special formatting aliases are courtesy of SIO and hop */ alias tls.sname { if (!(tmp = before([ $0))) {@ tmp = $0} @ function_return = tmp } alias tls.sip { if (!(tmp = after([ $0))) {@ tmp = $0} @ function_return = tmp } alias tls.stu { @ function_return = sar(/.undernet.org//$0) } #Users seen by default: #Make ESC-t the toggle combination keys @ tls.trace = [x] alias tls.tt if (tls.trace) {@ tls.trace = []} {@ tls.trace = [x]} bind ^[t parse_command tls.tt ###TRACEING alias TRACE { tls.cleantr @ tls._tn = [$0] @ tls._tt = [Trace:$before(. $S)] //trace $* } on ^server_notice *LINK* comment on ^NOTICE "*.* *LINK*" @ tls._tt = [$tls._tt-$before(. $3)] on ^notice "*.* *OPER*" { @ tls._tx = [$6] ? [$6] : [$5] if ( rmatch($before([ $tls._tx) $tls._tn) == 1 ) { tls._trace_parse $0 $tls._tx * } { tls._trace_servb $* } @ tls._tx = [] } on ^notice "*.* *USER*" { @ tls._tx [$6] ? [$6] : [$5] if ( rmatch($before([ $tls._tx) $tls._tn) == 1 ) { tls._trace_parse $0 $tls._tx } { tls._trace_servb $* } @ tls._tx = [] } on ^notice "%.% *SERV*" tls._trace_servb $* on ^200 * { xecho -b $before(-1 . $after(-2 . $tls.stu($0))) ==> $4 @ tls._tt = tls._tt ## [-] ## before(. $0) } on ^204 * { if ( rmatch($left($index([ $3)-1 $3) $tls._tn) == 1 ) { tls._trace_parse $0 $3 * } { tls._trace_serva $* } xecho -b $before(-1 . $after(-2 . $tls.stu($0))) $1 Class$format(5, [$2]) $format(4, 1C) ==> $left(36 $3) } on ^205 * { if ( rmatch($left($index([ $3)-1 $3) $tls._tn) == 1 ) { tls._trace_parse $0 $3 } { tls._trace_serva $* } if (tls.trace) {xecho -b $before(-1 . $after(-2 . $tls.stu($0))) $1 Class$format(5, [$2]) $format(4, 1C) ==> $left(36 $3)} } on ^206 * { tls._trace_serva $* echo *** $[7]0 $1 Class$format(7, [$2]) $format(4, $3) $format(5, $4) ==> $tls.stu($tls.sname($5))$tls.sip($5) } alias _trace_servb { if ( rmatch($0 $tls._tn) == 1 ) { echo $tls._tt-$0 } @ tls._tt = [] @ tls._tr = [] @ tls._tn = [qwertyuipoadfg] echo $1-3 $5- } alias _trace_serva { if ( rmatch($0 $tls._tn) == 1 ) { echo $tls._tt-$0 } @ tls._tt = [] @ tls._tr = [] @ tls._tn = [qwertyuiopzxc] } alias _trace_parse { @ tls._tr = [-] ## before([ $1) echo $tls._tt-$0$tls._tr$2 @ tls._tn = [qwertuipzxc] @ tls._tr = [] @ tls._tt = [] } ############ # Stores the output of a trace for use with conall ^alias storetrace { if (index([ $0) > -1) {@ trace.$encode($0) = before([ $0)} {@ trace.$encode($0) = $0} } ^alias tls.cleantr foreach trace ii { @ trace[$ii] = []} # connect to all the servers listed in the last trace # good for when you restart the server. ^alias conall foreach trace ii { connect $trace[$ii] } ^alias format { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([-$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } ^alias lformat { @ IRCII.word = [$1-] if (@IRCII.word < [$0]) { @ function_return = [$([$0]IRCII.word)] } { @ function_return = [$IRCII.word] } } # Trace information (extras') # ----------------- # define RPL_TRACECONNECTING 201 ^on ^201 * echo *** $[7]0 $1 Class$format(7, [$2]) trying... ==> $[30]3- # define RPL_TRACEHANDSHAKE 202 ^on ^202 * echo *** $[7]0 $1 Class$format(7, [$2]) handshake ==> $[30]3- # define RPL_TRACEUNKNOWN 203 ^on ^203 * echo *** $[7]0 $1 Class$format(7, [$2]) *unknown* ==> $[30]3- # define RPL_TRACESERVICE 207 ^on ^207 * echo *** $[7]0 $1 Class[$format(7, $2)] service ==> $[30]3- # define RPL_TRACENEWTYPE 208 ^on ^208 * echo *** $[7]0 $1 Class[$format(7, $2)] newtype ==> $[30]3- # define RPL_TRACECLASS 209 ^on ^209 * echo *** $[7]0 -==- $1$format(7, [$2]) Entries linked: $3 ################################ # STATS ################################ # Stats information # ----------------- # define RPL_STATSLINKINFO 211 ^on ^211 * ^echo *** $tls.stu($[40]1) $tls.stu($left(19 $7-));echo *** $[10]2 $[10]3 $[10]4 $[10]5 $[7]6 ^on ^211 "% *.*[*.*] *" $tls.stu($[40]1) $tls.stu($left(19 $7-));echo *** $[10]2 $[10]3 $[10]4 $[10]5 $[7]6 ^on ^211 "% *[*" if (trace) {^echo *** $tls.stu($[40]1) $tls.stu($left(19 $7-));echo *** $[10]2 $[10]3 $[10]4 $[10]5 $[7]6} # define RPL_STATSCOMMANDS 212 ^on ^212 * ^echo *** $[7]0 $[10]1 : $[-10]2 times # define RPL_STATSCLINE 213 ^on ^213 * ^echo *** $[7]0 $1: $tls.stu($[25]2):$3:$tls.stu($[40]4):$5:$6- # define RPL_STATSNLINE 214 ^on ^214 * ^echo *** $[7]0 $1: $tls.stu($[25]2):$3:$tls.stu($[40]4):$5:$6- # define RPL_STATSILINE 215 #^on ^215 * ^echo *** $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSKLINE 216 #^on ^216 * ^echo *** $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSQLINE 217 #^on ^217 * ^echo *** $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # define RPL_STATSYLINE 218 ^on ^218 * ^echo *** $[7]0 $1:$[5]2:$[5]3:$[5]4:$[5]5:$6- # Return information on # host masks being enforced locally. # ^on ^220 * ^echo *** $[7]0 $1: $[25]2:$3: $[25]4:$5:$6- # User Mode (2.1.5 actually knows about this. This is for 2.1.4e) # define RPL_UMODEIS 221 ^on ^221 * ^echo *** Your user mode is $1 # Service list: ^on ^231 * ^echo $[7]0 Service $1 ($0) ######################################## # LINKS ######################################## alias links { @ lcounter = 1 echo *** No. Class Server Link stack push on 364 ^on ^364 * { echo *** \[$[-3]lcounter\] \[$[-3]3\] \[$[-25]tls.stu($1)\] <-> \[$tls.stu($2)\] @ lcounter++ } //links $0 wait stack pop on 364 } ###########END OF STATS/LINKS/TRACE BEAUTIFIER epic4-2.10.2.orig/script/motd0000644000000000000000000000041307213031315012610 0ustar # Here's the plan # Output the MOTD for the user. # Load this in "local" for maximum effect. load less @ date = ftime(~/.ircII.motd) @ fdate = ftime($irclib()/ircII.motd) if (fdate && (date < fdate)) { less $irclib()/ircII.motd exec touch ~/.ircII.motd } #hop'97 epic4-2.10.2.orig/script/ip-to-int0000644000000000000000000000073707253747052013516 0ustar : { This converts an ip address (which you provide) into a 32 bit internet address, ala what DCC uses. One small problem -- epic does math with 'long's and not 'unsigned long's and so ip addresses above 128.* result in negative values. How to fix this is left as an exercise for the reader. Written in November, 2000 } alias ip_to_int (ip, void) { @ :ip_list = split(. $ip) @ :ip32 = 0 for xx in ($ip_list) { @ ip32 = (ip32 << 8) + xx } return $ip32 } #hop'y2k epic4-2.10.2.orig/script/fake-dcc0000644000000000000000000000135607415131614013320 0ustar /* * Ok. Here is the plan: * * We have a variable, $fake_dcc, that contains a list of words that can * be substituted for ``DCC'' as a CTCP. * * The sender randomly picks a word off that list and uses it. * The receiver then reparses the handshake if its on his list. * * Don't be fooled. This script is not nearly as useful as it * might be made to be. Its just a contrived example. */ @ fake_dcc = [FOO BAR GOOTCHIE] /* * Sender's side */ on ^send_to_server "% % % PRIVMSG % :$chr(1)DCC*" { quote PRIVMSG $4 :$chr(1)$getrandword($fake_dcc) $6- } /* * Receiver's side */ on ^raw_irc "% PRIVMSG % :$chr(1)\\[$fake_dcc\\]*" { pretend $0 $1 $2 :$chr(1)DCC $4- } alias getrandword @ function_return = word($rand($#) $*) #jfn'96 epic4-2.10.2.orig/script/repeat0000644000000000000000000000353207253747052013152 0ustar /* * Repeat -- a zillion and one ways to do the classic alias... */ /* * REPEAT is now a built in command in EPIC3.003 and up. * That means you dont need this script any more. */ /* * Post-modern format: * Requires EPIC4-0.9.17 and up * Method: Iterative loop * Can be called recursively? Yes. (/for uses local variables) */ : alias repeat { : for aa from 1 to $0 { $1- } : } /* * Modern format: * Requires: EPIC4pre0 and up * Method: word-selection * Can be called recursively? Yes. (/fe uses local variables now) */ : alias repeat { : fe ($jot(1 $0)) aa { $1- } : } /* * Modern format: * Requires: EPIC3pre5 and up * Method: word-selection * Can be called recursively? Yes. (global variables and push) */ : alias repeat { : stack push assign aaa.r : fe ($jot(1 $0)) aaa.r { $1- } : stack pop assign aaa.r : } /* * Modern format: * Requires ircII2.2.9+6 and up. * Method: word-selection * Can be called recursively? No. (no local variables in epic yet) */ : alias repeat fe ($jot(1 $0)) r.x {$1-} /* * Modern format: * Requires ircII2.2.9+5 and up. * Method: iterative * Can be called recursively? No. */ : alias repeat for (@rx=0,$rx < [$0],@rx++) {$1-} /* * New format: * Requires 2.2pre6 and up * Method: iterative * Can be called recursively? No. */ : alias repeat { : @ rep.cnt = [$0] : while ( rep.cnt > 0 ) : { : $1- : @rep.cnt = rep.cnt - 1 : } : ^assign -rep.cnt : } /* * New format: * Requires 2.2pre6 and up * Method: recursion * Can be called recursively? Yes. */ : alias repeat { : if ([$0] > 0) : { : $1- : repeat ${[$0]-1} $1- : } : } /* * Old format: * Requires 2.2pre5 or older. * Method: Iterative * Can be called recursively? No. */ : alias repeat ^assign repcnt $0;while "$repcnt>$0" "decrement $1-";^assign -repcnt : alias decrement $*;^assign repcnt ${$repcnt-1} #hop'96 epic4-2.10.2.orig/script/newaway0000644000000000000000000000153607213031315013327 0ustar # newaway.m # v1.2 by Joseph Carter # v1.0-1.1 by Matthew Green # # Public domain, as was the original # # Changes: # 28 Jun 1999, v1.2 - rewrote the whole thing for epic4 => # 5 Jul 1999, v1.3 - replaced some @ var ='s with ^assign # - moved the whois check out of _na.show # - we now display away differently if in whois package newaway alias _na.show { @ :nick = encode($tolower($0)) @ :away = encode($tolower($1-)) unless (_na.nick[$nick] == away) { @ _na.nick[$nick] = away return 1 } return 0 } on #^311 311 "*" ^assign _na.whois.$lastserver() 1 on #^318 311 "*" ^assign -_na.whois.$lastserver() on ^301 "*" { if (_na.whois[$lastserver()]) { xecho -b away : $1- } elsif (_na.show($*)) { xecho -b $0 is away: $1- } } on ^unload "newaway *" purge _na epic4-2.10.2.orig/script/setmail0000644000000000000000000000131007415131614013307 0ustar # SetMail -- Here's the plan. # # When you have /set mail 1, you want to see (Mail). # When you have /set mail 2, you want to see (Mail :%d). # Where (Mail) is controlled by /set mail_format1 # And (Mail :%d) is controlled by /set mail_format2. # # This script is a good example of how to use /on set to add a new /set # and change the default behavior of an existing /set to do something that # you otherwise couldn't do! =) # @ mail.format1 = [ (Mail)] @ mail.format2 = [ (Mail: %M)] on -set "mail 1" { ^set status_mail $mail.format1 } on -set "mail 2" { ^set status_mail $mail.format2 } on -set "mail_format1 *" { @ mail.format1 = [$1-] } on -set "mail_format2 *" { @ mail.format2 = [$1-] } #hop'97 epic4-2.10.2.orig/script/files0000644000000000000000000000344607724040657013000 0ustar /* * FILES script -- complements the new file functions. * Written by Jeremy Nelson -- EPIC project * * These aliases are not anywhere near as fast as /exec'ing the * c programs, but they are here to illustrate the usage of the fns. */ /* dump a file out to the screen w/o using /exec */ alias cat { @ fd = open($0 R) while (!eof($fd)) { echo $read($fd) } @ close($fd) } /* Search for a string in a group of files */ /* This is, of course, case insensitive */ alias grep { for x in ($1-) { @ fd = open($x R) while (!eof($fd)) { @ line = read($fd) if (match(*$0* $line)) {echo $x: $line} } @close($fd) } } /* Write a line to a file w/o using the logging features */ alias log_it { @ fd = open($0 W) @ write($fd $1-) @ close($fd) } # # Call as /exclude filename pattern # alias exclude { @ :reg = regcomp($1-) @ :rd = open($0 R) @ :wd = open($0.new W) @ line = read($rd) do { if (regexec($reg $line)) { @ write($wd $line) } @ line = read($rd) } while (!eof($rd)) @ close($rd) @ close($wd) @ regfree($reg) @ unlink($0) @ rename($0.new $0) } # # This is exactly the same as $randread() except that # $randread() seeks to a random _point_ in the file # whereas this seeks to a random _line_. # # Also, you can specify any number of files/globs and # it will return one line from every file. # alias randomread { @ :ret = glob($*) fe ret ret { @ :fd = open("$ret" r) @ :line = 2 ** 30 @ :line = fskip($fd $line) @ :line = rand($line) @ fseek($fd 0 set) @ fskip($fd $line) @ :ret = read($fd) @ close($fd) } if (functioncall()) { return $ret } else { echo $ret } } epic4-2.10.2.orig/script/more0000644000000000000000000000130607213031315012611 0ustar # # A file pager. A demonstration of how to do something useful in ircII. # Written by archon in 1996 # alias more { if ([$0]) { @ line = 0 @ done = 0 @ rows = winsize() - 1 if (fexist($0) == 1) { @ fd = open($0 R) while (!eof($fd) && (pause!=[q])) { while (line++ != rows) { @ ugh = read($fd) if (eof($fd)) { @ line = rows @ done = 1 } { echo $ugh } } if (!done) { ^assign pause $"Enter q to quit, or anything else to continue " @ line = 0 } } @ close($fd) @ fd = line = done = rows = pause = ugh = [] } { echo $0\: no such file. } } { echo Usage: /more } } #archon'96 epic4-2.10.2.orig/script/environment0000644000000000000000000001335707525764605014251 0ustar #$EPIC: environment,v 1.3 2002/08/12 16:59:49 jnelson Exp $ # # A NEW ENVIRONMENT (C) 1993 # Written by Jeremy Nelson (jnelson@acronet.net) # # **************** New environment *************************** alias howlong @ function_return = tdiff(${time()-[$0]}) alias now @ function_return = strftime(%T) alias tia @ function_return = A?[<$now()>]:[] on ^msg * { if (msgrecv[$encode($0)] != userhost()) { @ msgrecv[$encode($0)] = userhost() echo msg from $0!$userhost(): $1- $tia() } { echo msg from $0: $1- $tia() } } on ^dcc_chat * echo \($0\): $1- $tia() on ^notice * echo -$0\- $1- on ^public * echo <$0> $2- $tia() on ^public_other * echo $1 <$0> $2- $tia() on ^send_msg * echo -> \($0\) $1- on ^send_dcc_chat * echo DCC -> \($0\) $1- on ^send_notice * echo -> \($0\) $1- on ^send_public * echo -> \($0\) $1- on ^join * { if (rejoin == 1) { (rejoin = []) } elsif (iscurchan($1)) { echo *** join $1: \($0 - $2\) $now() } else { echo *** join $1: \($0 - $2\) $now() } } on ^mode * echo *** Mode Change for $1 by $0: $2- on ^leave * echo *** Leaving $1: \($0\) $now() on ^channel_signoff * echo *** Quit: $1 \($0, $2-\) $now() on ^kick * { if ([$0] == N) { echo *** You have been kicked off channel $2 by $1 \($3-\) $now() } { echo *** $0 has been kicked off channel $2 by $1 \($3-\) $now() } } on ^action * { if (iscurchan($1)) { echo :Action: \($1\) $0 $2- $tia() } { echo $1 :Action: \($1\) $0 $2- $tia() } } on ^send_action * echo :Action: \($0\) $N $1- on ^ctcp_reply * echo CTCP from $0. $1: $2- $tia() on -ctcp_reply "% PING *" comment on ^invite * echo *** Invitation to $1 received from $0 $now(). on ^topic * echo *** topic The topic on $1 is now $2- \($0\) $now() on ^notify_signoff * echo NOTIFY $0 signed OFF [$now()] set notify_userhost_automatic on on ^notify_signon * {echo NOTIFY $0 \($1\) signed ON [$now()];Addnick $0} on -dcc_request "% SEND *" { push dccgets $0 echo DCC $0 has offered you a file. $now() echo DCC Press -F to get this file. } on -dcc_request "% CHAT *" { push dccchats $0 echo DCC $0 wants to talk to you privately. $now() echo DCC Press -F to respond to $0. } bind ^f parse_command dcc get $pop(dccgets) bind ^[f parse_command dcc chat $pop(dccchats) on ^256 * echo ADMIN $1- on ^257 * echo ADMIN $1- on ^258 * echo ADMIN $1- on ^259 * echo ADMIN $1- on ^301 * echo AWAY  $0 is away: $1- on ^311 * echo WHOIS $1 is $2@$3, \($5-\) on ^312 * echo WHOIS $1 is on $2- on ^313 * echo WHOIS $1- on ^314 * echo WHOWAS $1 was $2@$3 \($5-\) on ^317 * echo WHOIS $1: Idle - \($tdiff($2)\), On for $howlong($3) on ^318 * echo END OF LIST on ^319 * echo WHOIS $1 is on channels $2- on ^324 * echo MODE The channel mode for $1 is $2- on ^331 * echo TOPIC Channel $1 does not have a topic on ^332 * echo TOPIC The topic for $1 is $2- on ^333 * echo TOPIC The topic has been set for $howlong($3) \($2\) on ^341 * echo INVITE Inviting $1 to $2 on ^342 * echo SUMMON Summoning $1 to IRC on ^351 * echo VERSION $* on ^364 * echo LINKS [$[2]3] [$[25]1] [$[35]4-] on ^365 * echo END OF LIST;echo on ^367 * echo BANS [$[11]1] [$[30]2] [$[10]3] [$[10]howlong($4)] on ^369 * echo END OF LIST on ^381 * echo OPER You are now an IRC operator on ^382 * echo REHASH Re-reading the ircd.conf file now. on ^385 * echo DEOP You are no longer an operator on ^386 * echo *** Error: You are not allowed to use operator commands. on ^391 * echo TIME At the tone, the time is: $2- on ^393 * echo USERS $* on ^401 * echo WHOIS $1 is not on IRC on ^402 * echo SERVER The server $1 does not exist on ^403 * echo MODE The channel $1 does not exist on ^404 * echo MODE You need ops to send to channel \($1\) [From $0] on ^405 * echo JOIN You cant join that many channels! on ^406 * echo WHOWAS $1 has not been on recently on ^407 * echo MSG You arent allowed to send to that many targets on ^408 * echo SERVER The server $1 does not exist on ^411 * echo MSG Who do you want me to send this to? on ^412 * echo MSG You have not specified anything to send on ^413 * echo MSG You havent specified a top level for the domain. on ^414 * echo MSG You cant send a msg with a wildcard in the domain. on ^421 * echo ERROR I dont recognize that command on ^431 * echo MSG You did not specify a nickname to send to on ^432 * echo NICK That is not a valid nickname! on ^433 * echo NICK The nickname \'$0\' is already in use on ^436 * echo ERROR Sorry, your nick is already in use. on ^441 * echo KICK $0 is not on this channel on ^442 * echo ERROR You are not on channel $1 on ^443 * echo INVITE No need to invite, $1 is already here! on ^444 * echo SUMMON $1 is not logged in now. \(from $0\) on ^445 * echo SUMMON You can't summon someone no that machine on ^446 * echo USERS You cant do that command: it is turned off on ^461 * echo ERROR That command requires more arguments on ^464 * echo ERROR You have entered an incorrect password on ^465 * echo NOTICE You are banned from this server \(from $0\) on ^465 * echo NOTICE You are now K-lined on ^471 * echo JOIN $1 has a maximum limit, and is full on ^472 * echo MODE The mode change $1 is unknown to me on ^473 * echo JOIN Sorry, you need an invitation to join channel $1 on ^474 * echo JOIN Sorry, you are banned from channel $1 on ^475 * echo JOIN Sorry, that channel key is wrong. on ^476 * echo JOIN Hmmm. i dont like the looks of that channel name. on ^481 * echo ERROR You need to be an IRC operator to do that on ^482 * echo ERROR You need to be an channel operator to do that [from $0] on ^483 * echo KILL You cant kill a server, silly! on ^501 * echo UMODE You can't change your umode: $1- epic4-2.10.2.orig/script/silent0000644000000000000000000000201707213031315013145 0ustar # This is necessary when you join crowded channels like #report... # All the join,leave,quit,nick and mode change messages do not appear # on the screen, unless you have %U somewhere in your STATUS_FORMAT, # then the changes will be displayed in your status line, which is # a lot less annoying and distracting. ;-) alias silent { stack push on join stack push on leave stack push on signoff stack push on channel_signoff stack push on nick stack push on mode stack push on topic ^on ^join * set status_user Join: $$0 \($$1\) ^on ^leave * set status_user Leave: $$0 \($$1\) ^on ^signoff * set status_user Signoff: $$* ^on ^channel_signoff * set status_user Signoff: $$* ^on ^nick * set status_user Nick: $$0 now $$1 ^on ^mode * set status_user Mode: $$* ^on ^topic * set status_user Topic by $$0: $$1- } alias unsilent { stack pop on join stack pop on leave stack pop on signoff stack pop on channel_signoff stack pop on nick stack pop on mode stack pop on topic } epic4-2.10.2.orig/script/altchan0000644000000000000000000000131407525764605013305 0ustar #$EPIC: altchan,v 1.3 2002/08/12 16:59:49 jnelson Exp $ # # "altchan" -- a script to implement ALT- key bindings # BitchX I guess does this by default. So here is a compatibility script. # bind ^[1 parse_command to_window 1 bind ^[2 parse_command to_window 2 bind ^[3 parse_command to_window 3 bind ^[4 parse_command to_window 4 bind ^[5 parse_command to_window 5 bind ^[6 parse_command to_window 6 bind ^[7 parse_command to_window 7 bind ^[8 parse_command to_window 8 bind ^[9 parse_command to_window 9 bind ^[0 parse_command to_window 10 alias to_window (window default 0) { if (winnum($window) == -1) { xecho -c -b SWAP: No such window: $window } { window refnum_or_swap $window } } #hop'y2k+1 epic4-2.10.2.orig/script/less-pipe0000644000000000000000000000177207213031315013557 0ustar # # Open up a pipe and then page the output. # I wrote this in a race with Archon (hop, 1997) # # # Usage: # $0 - name of the pipe # $1- - stuff to run # alias less_pipe { @ line = 0 if ([$1]) { ^on ^exec "$0 *" { @ lessline[$line] = [$1-] @ line++ } ^on ^exec_error "$0 *" { echo *** Error on exec: $* } ^on ^exec_exit "$0 *" { on exec -"$0 *" on exec_error -"$0 *" on exec_exit -"$0 *" less_array lessline 0 $line } exec -name $* } } /* * $0 is the array name to use * $1 is the starting line * $2 is the final line */ alias less_array { local line $1 local cr 0 local rows $winsize() while ((line < [$2]) && (cr < rows)) { echo $($0[$line]) assign -$0[$line] @ line++, cr++ } if (cr >= rows) { @ aaa.array_name = [$0] @ aaa.next_line = line @ aaa.final_line = [$2] input_char "Enter q to quit, or anything else to continue " { if ([$0] != [q]) { ^less_array $aaa.array_name $aaa.next_line $aaa.final_line } } } } #hop'97 epic4-2.10.2.orig/script/edit0000644000000000000000000000116207213031315012574 0ustar # The original (hack-around) was written 4/20/93 # by Mycroft!mycroft@gnu.ai.mit.edu (Charles Hannum) # who deserves bonus points for coming up with a clever way # to get around stupid limitations in the client # # This version was written 12/3/95 # by hop!jnelson@acronet.net (Jeremy Nelson) # who hacked the $aliasctl() function into EPIC3pre5-fixit1 # which allows you to do this cleanly. # alias edit { ^local edit.name $toupper($0) ^local edit.stuff $aliasctl(ALIAS GET $edit.name) if (edit.stuff) { type ^U xtype -literal /alias $^\edit.name $^\edit.stuff } { xecho -w 0 *** Unknown alias: $edit.name } } epic4-2.10.2.orig/script/less0000644000000000000000000000264410002523543012622 0ustar # # A file pager. A demonstration of how to do something useful in ircII. # This cheesy rip-off was written by hop in 1996. # My apologies in advance to archon. # Modified on Jan 25, 1999 as an example of how to use arglists. # # Modified by howl on Des(1) 8, 2003, to honour numlines(), and close file # on 'q' # # Modified by howl on Jan 14, 2004, to turn indent, and continue line off # when paging a file. # # (1: Des (Desember) is Dec (December) in Norwegian) alias less (file default "-help") { @ winnum = winnum() if (file == [-help]) { xecho -w $winnum Usage: /less } elsif (fexist($file) == 1) { less_file $open($file R) ${winsize() - 1} $winnum } else { xecho -w $winnum $file\: no such file. } } alias less_file (file, count, winnum default 0, void) { ^local line 0 ^local ugh ^local width ${word(0 $geom())-1} stack push set indent stack push set continue_line ^set indent off ^set -continue_line while (!eof($file) && (line < count)) { @ ugh = read($file) @ line += numlines($width $ugh) if (!eof($file)) { xecho -w $winnum $ugh } } stack pop set indent stack pop set continue_line if (!eof($file)) { @ less.fd = file @ less.nl = count @ less.w = winnum input_char "Enter q to quit, or anything else to continue " { if ([$0] != [q]) { less_file $less.fd $less.nl $less.w } { @ close($file) } } } { @ close($file) } } #hop'96,99 #howl'03 epic4-2.10.2.orig/script/data_struct0000644000000000000000000001460407775617245014222 0ustar # # Struct/Assign manipulation functions. # # The distinction between the two is that the assign functions operate on # the entire alias space whereas the struct functions operate only on sub # structures. The assign functions are typically slower per call, but since # they do all the work in one call, they can be faster than the recursive # struct functions. # # For each assign.* alias, a corresponding alias.*, but some of them have # implicit bugs from the fact that arg lists can't yet be retrieved for stored # aliases. # # # Assign functions. # # Make two aliases for every alias. One for assign handling, one for alias # handling, then make two more for forward and reverse modes. # stack push alias alias.ttt stack push alias alias.tt alias alias.ttt (args) { alias $args @ sar(gr/assign/alias/args) alias $args } alias alias.tt (args) { alias.ttt $args @ sar(gr/assign./assign.r/args) @ sar(gr/pmatch/rpmatch/args) @ sar(gr/;@ :list = revw($list);/;/args) alias.ttt $args } # # Check the consistency of the internal structures. The only # reason to use these is if an epic bug is suspected. # alias.ttt assign.check { @ :omr = aliasctl(maxret 0) @ :last = [] @ :list = aliasctl(assign pmatch "\\[$*\\]") fe ($list) foo { if (uniq($last $foo)!=sort($last $foo)) { echo assign consistancy failure: $last >= $foo @ last = foo } } @ aliasctl(maxret $omr) echo Checked $#list assigns matching $* } # # Faster version. Tells you whether there's an error, not where it is. # alias.ttt assign.qcheck { @ :omr = aliasctl(maxret 0) @ :list = aliasctl(assign pmatch "\\[$*\\]") @ :status = uniq($list) == sort($list) ? [passed] : [failed] @ aliasctl(maxret $omr) echo Checked $#list assigns matching $*: $status } # # Dump all assigns with name matching the given masks. # alias.tt assign.dump { @ :list = aliasctl(assign pmatch "\\[$*\\]") fe ($list) e { echo [$aliasctl(assign getpackage $e)] $e$chr(9)$aliasctl(assign get $e) } @ list = #list if (functioncall()) { return $list } else { echo Dumped $list matching $* } } # # Dump all assigns with name matching the first arg and # contents matching the rest. # alias.tt assign.grep (args) { @ :list = aliasctl(assign pmatch "\\[$shift(args)\\]") fe ($list) e { if (aliasctl(assign get $e) =~ args) { echo [$aliasctl(assign getpackage $e)] $e$chr(9)$aliasctl(assign get $e) } } @ list = #list if (functioncall()) { return $list } else { echo Dumped $list matching $* } } # # Delete and reassign all matching vars. Theoretically, this is a no-op, # however, alias.pack will destroy the arg lists of the alias. # alias.tt assign.pack { do { @ :list = aliasctl(assign $start pmatch "\\[$*\\]") fe ($list) foo { @ :baz = aliasctl(assign getpackage $foo) @ aliasctl(assign set $foo $aliasctl(assign get $foo)) @ aliasctl(assign setpackage $foo $baz) } @ list = #list if (functioncall()) { return $list } elsif (isdisplaying()) { echo Packed $list matching $* } } while (list && (:start += aliasctl(maxret))) } # # Delete all matching vars. # alias.tt assign.purge { if (functioncall()) { @ :list = aliasctl(assign pmatch "\\[$*\\]") @ :list = revw($list) fe ($list) bar {^assign -$bar} return $#list } else { do { @ :list = assign.purge($*) if (isdisplaying()) { echo Purged $list matching $* } } while (list && list == aliasctl(maxret)) } } # # Write matching assigns to a file which can then be /load'ed. Any arg lists # in the original definition won't be saved by alias.save. # alias.tt assign.save { @ :pkg = rand(0) @ :fh = open($0 W) @ :start = [] do { @ :list = aliasctl(assign $start pmatch "\\[$1-\\]") fe list foo { if (pkg != aliasctl(assign getpackage $foo)) { @ write($fh PACKAGE ${pkg=aliasctl(assign getpackage $foo)}) } @ write($fh assign $foo $sar(g/\{/\\\{/$sar(g/\}/\\\}/$aliasctl(assign get $foo)))) @ foo = 0 } if (functioncall()) { break } elsif (isdisplaying()) { echo Wrote $#list matching $1- } @ :start += aliasctl(maxret) } while (#list && start) @ close($fh) return $#list } # # As for .save, but write a $decode() encoded file which won't be # damaged by certain variable contents. # alias.tt assign.esave { @ :pkg = rand(0) @ :fh = open($0 W) @ :start = [] do { @ :list = aliasctl(assign $start pmatch "\\[$1-\\]") fe list foo { if (pkg != aliasctl(assign getpackage $foo)) { @ write($fh PACKAGE ${pkg=aliasctl(assign getpackage $foo)}) } @ write($fh @aliasctl\(assign set $foo \$decode\($encode($aliasctl(assign get $foo))\)\)) @ foo = 0 } if (functioncall()) { break } elsif (isdisplaying()) { echo Wrote $#list matching $1- } @ :start += aliasctl(maxret) } while (#list && start) @ close($fh) return $#list } # # Save the data, then delete it. Repeat until no more data exists. # The reason the procedure is repeated is because of the aforementioned # potential bug that .check checks for. # alias.tt assign.flush { do { @ :bar = assign.save($*) @ :bar = assign.purge($1-) echo Flushed $bar matching $1- } while (foo != (:foo = bar) || (foo && foo == aliasctl(maxret))) } # # As above but use .esave. # alias.tt assign.eflush { do { @ :bar = assign.esave($*) @ :bar = assign.purge($1-) echo Flushed $bar matching $1- } while (foo != (:foo = bar) || (foo && foo == aliasctl(maxret))) } # # End of /assign.* functions. # stack pop alias alias.tt stack pop alias alias.ttt # # struct functions. # # # Recursively erase a structure. # alias struct.purge { fe ($*) foo { ^assign -$foo } return ${struct.purgesub($*)+#} } # # Continued. # The third sub-loop does what the first does and should never be entered. # It's there for company. # alias struct.purgesub { fe ($*) foo { @ :bar = aliasctl(assign match ${foo}.) @ :bar = revw($bar) @ :hit += #bar fe ($bar) baz { ^assign -$baz } foreach $foo bar { @ hit += struct.purgesub(${foo}.${bar}) } foreach $foo bar { ^assign -${foo}.${bar} } } return ${0+hit} } # # Save a structure, like array.save. # alias struct.savefn { @ :fd = open($0 w) @ :hit = struct.savefd($fd $1-) @ close($fd) return $hit } # # Continued. Save to an FD. # alias struct.savefd { @:fd=[$0] fe ($1-) foo { if (strlen($($foo))) { @ write($fd assign $foo $sar(g/\{/\\\{/$sar(g/\}/\\\}/$aliasctl(assign get $foo)))) @ :hit = 1 } else { @ :hit = 0 } foreach $foo bar { @ hit += struct.savefd($fd ${foo}.${bar}) } } return $hit } epic4-2.10.2.orig/script/deban0000644000000000000000000000233707724040657012745 0ustar /* * ban removers, 1993, 1997 * This script requires ircII-EPIC4. */ # returns non-0 if $0 matches or is matched by $1-, 0 if not. alias comatch @ function_return = match($*) || rmatch($*) alias deban_mode { fe ($*) bx by bz { @ :moder = bz?[-bbb]:by?[-bb]:bx?[-b]:[] if (moder) { mode * $moder $bx $by $bz } } } # remove all bans on current channel alias deban uniban * # remove all bans that could cover nickname alias unban uniban $0!$uh($0) # remove all bans matching or matched by pattern alias uniban { ^local unbanlist ^local p $0 stack push on 367 stack push on 368 ^on ^367 * { bless if (comatch($2 $p)) { push unbanlist $2 } } ^on ^368 * { bless stack pop on 367 stack pop on 368 deban_mode $unbanlist } ^mode ${[$1]?[$1]:C} +b wait } # remove all bans that contain a literal text substring alias nban { local unbanlist local p $0 stack push on 367 stack push on 368 ^on ^367 * { bless if (rmatch($2 *$p*)) { push unbanlist $2 } } ^on ^368 * { bless stack pop on 367 stack pop on 368 deban_mode $unbanlist } ^mode ${[$1]?[$1]:C} +b wait } #hop'93 epic4-2.10.2.orig/script/ircprimer0000644000000000000000000000505507253747052013670 0ustar # Sample .ircrc script, from the IRCprimer v1.1 # ------------------------------------------------------------------- # IRCII sample configuration file (~/.ircrc) (Nicolas Pioch) # ------------------------------------------------------------------- # The aim of this file is to shorten all useful commands to 1 letter. ^set DISPLAY off set NOVICE off set INPUT_ALIASES off set AUTO_WHOWAS on set SHOW_CHANNEL_NAMES on set SHOW_AWAY_ONCE on # Speeds up ircII display 2 times set SCROLL_LINES 2 # Put Hack notices down under on ^SERVER_NOTICE "% \*\*\* Notice -- Hack: *" set status_user Hack: $5- # do something logical with kill notices. on ^server_notice "% * Notice -- Received KILL*" hook KILL $8 $10 $12 $13- on hook "KILL % %.% *" echo ### server KILL for $1 by $2 on hook "KILL % % *" echo ### KILL for $1 by $2 \($4-\) # Function to strip the less significant part of an internet hostname alias userdomain @ function_return = before(@ $0) ## [@] ## after(. $0) # Who is that ? on ^msg * echo *$0!$userdomain($userhost())* $1- # /w [] get info on someone # /q [] query someone # /m send a message # /n send a notice # /r reply to last message I got # /a followup on my last message alias w whois alias q query alias m msg alias n notice alias r msg $, alias a msg $. # /j join a channel # /l list people in a channel # /ll list in the current channel # /i [] invite someone # /hop leave the current channel alias j join alias l who alias ll who * alias i invite alias hop part * # /o [ ] give channel op status # /d [ ] remove channel op status # /k kick someone # /mo [+|-] change current channel mode alias o fe ($*) x y z {mode * +ooo $x $y $z} alias d fe ($*) x y z {mode * -ooo $x $y $z} alias k for x in ($*) {kick * $x} alias mo mode * # the "wrong person" alias! /oops to resend message to alias oops { @ _whoops = B msg $. Whooops! Please ignore, that wasn't meant for you. msg $0 $_whoops } alias unset set -$* alias unalias alias -$* ^set DISPLAY on # ------------------------------------------------------------------- epic4-2.10.2.orig/script/sdiff0000644000000000000000000000061107213031315012740 0ustar # Here's the plan # # $sdiff() -- convert bytes to kilobytes # $sdiff2() -- convert bytes to megabytes # alias sdiff { ^set floating_point on ^local kb $trunc($1 ${[$0] / 1024}) @ function_return = kb ## [K] ^set floating_point off } alias sdiff2 { ^set floating_point on ^local mb $trunc($1 ${[$0] / (1024 * 1024)}) @ function_return = mb ## [mb] ^set floating_point off } #hop'97 epic4-2.10.2.orig/script/time0000644000000000000000000000135607415131614012621 0ustar # This will put the current time, date, etc according to your server # in the appropriate variables alias servertime { stack push on 391 ^on ^391 * { @ day = [$2] @ month = [$3] @ date = [$4] @ time = [$7] } time wait stack pop on 391 } # This will get the time from the uptime program and put it in the # variable uptime on ^exec "uptime *" { @ uptime = [$1] } on ^exec_exit "uptime" alias uptime { exec -name uptime uptime wait %uptime } # This will get the time, date, etc from the date program and # put them in the appropriate variables. on ^exec "date % % % *" { @ day = [$1] @ month = [$2] @ date = [$3] @ time = [$4] } on ^exec_exit "date" alias datetime { exec -name date date wait %date } #modernized by hop'95 epic4-2.10.2.orig/script/local.examp0000644000000000000000000000107207415131614014061 0ustar /* This file is supposed to be configured to your needs. * Go ahead, change everything you want! :) * This should never be overwritten by "make installscript" */ echo *** eval echo *** You are running ircII version $J echo *** echo *** If you see anything you suspect to be a bug, please echo *** notify list@epicsol.org immediately for correction. echo *** echo *** End of Message. load disc load guh set client_information Starting all over again... set status_user * ircII use /help for help. alias wasteland server undernet.org 6667 alias undernet wasteland epic4-2.10.2.orig/script/mail0000644000000000000000000000776207522102774012620 0ustar # mail script. lifted from anduril by wd. # this script is in the public domain # $Id: mail,v 1.2 2002/08/01 00:51:08 wd Exp $ # this module is intended as a replacement for the built-in functionality of # epic's mail code. currently it only handles mbox-style mail boxes. it # allows the user to add and remove mboxes as desired, and change the # checking time. # you can /set mail_watch_time to change the time interval for scanning for # new mail # this script honors /set mail to completely enable/disable checking. # # you can use the /mbox command to list details about currently added # mailboxes. you can also use it to add or delete folders from the list. @mail.folders = getenv(MAIL) ^on ^set "mail_watch_time *" { if ([$1] == []) { echo $banner Current value of MAIL_WATCH_TIME is $mail.time return } if (mail.time > 0) { ^timer -del mailcheck } if ([$1] > 0) { @mail.time = [$1] ^timer -refnum mailcheck -rep -1 $mail.time mail.check } echo $banner Value of MAIL_WATCH_TIME set to $mail.time } alias mbox (cmd, args) { if (cmd != [] && cmd != [list] && numwords($args) != 1) { echo [mail] usage: /mbox [add|del|list] [folder] return } else if (cmd == []) { @:cmd = [list] } @:folder = twiddle($args) switch ($cmd) { (add) { if (findw($folder $mail.folders) != -1) { echo [mail] folder $args is already being monitored return } @:stat = stat($folder) if (stat == []) { echo [mail] stat\($folder\) failed. either the file is not accesible or the system does not support stat(2). return } @push(mail.folders $folder) @push(mail.times $word(11 $stat)) echo [mail] now monitoring $folder for new mail } (del) { if (findw($folder $mail.folders) == -1) { echo [mail] folder $folder is not being monitored return } @mail.folders = remw($folder $mail.folders) echo [mail] no longer monitoring $folder for new mail } (list) { @:mtot = 0 @:cols = word(0 $geom()) echo $pad(${cols - 40} \" \" folder) $pad(20 \" \" last modified) $pad(8 \" \" size) $pad(8 \" \" messages) for xx in ($mail.folders) { @:stat = stat($xx) @:out = pad(${cols - 40} \" \" $xx) if (stat != []) { @:out #= [ $pad(20 \" \" $strftime($word(11 $stat) %d/%m/%Y %H:%M:%S))] @:out #= [ $pad(8 \" \" $mail.size_fmt($word(7 $stat)))] } else { @:out #= [ $pad(20 \" \" unknown) $pad(8 \" \" unknown)] } @:mcnt = 0 @:fd = open($xx R) if (fd > -1) { while (!eof($fd)) { if (word(1 $read($fd)) == [From]) { @:mcnt++ } } } @close($fd) @:out #= [ $pad(8 \" \" $mcnt)] @:mtot += mcnt echo $out } } (*) { echo [mail] usage: /mbox [add|del|list] [folder] } } } alias mail.check { if (numwords($mail.folders) == 0 || MAIL == 0 || MAIL == []) { return } for (@:i = 0,i < numwords($mail.folders),@:i++) { @:folder = word($i $mail.folders) @:stat = stat($folder) if (stat == []) { continue } if (word(11 $stat) > word($i $mail.times)) { echo [mail] new mail in $folder \($strftime($word(11 $stat) %d/%m/%Y %H:%M:%S)\) @mail.times = chngw($i $word(11 $stat) $mail.times) } } } alias mail.size_fmt (n) { stack push set floating_point_math ^set floating_point_math on if (!n) { @function_return = [0b] } elsif (n < 1024) { @function_return = [${n}b] } elsif (n < 1048576) { @function_return = [$trunc(2 ${n / 1024})kb] } elsif (n < 1073741824) { @function_return = [$trunc(2 ${n / 1048576})mb] } elsif (n < 1099511627776) { @function_return = [$trunc(2 ${n / 1073741824})gb] } else { @function_return = [$trunc(2 ${n / 1099511627776})tb] } stack pop set floating_point_math } for xx in ($mail.folders) { @:stat = stat($xx) if (stat == []) { @mail.folders = remw($xx $mail.folders) } else { @push(mail.times $word(11 $stat)) } } @mail.time = [60] ^timer -refnum mailcheck -rep -1 $mail.time mail.check # vi:set ts=8 sts=4 sw=4 tw=79 syntax=off ai smartindent: epic4-2.10.2.orig/script/autoget0000644000000000000000000000766207724040657013352 0ustar # # Autoget! Because people keep asking me for this. # Ok. Here's the plan. # /autoget [ ....] will auto-get any file that matches # any of the patterns. # /autoget - will stop autogetting any file that matches this # pattern. # You can mix and match s and -s. # # New: Patterns will now be matched against nick!user@host,IP,file. # This shouldn't really be incompatible unless you autoget # files begining with specific names. # New: /autoreget acts much the same as /autoget, but the patterns apply # to requests for which the file already exists. # /autoclobber takes two arguments specifying the reget modes. # These can be one of GET, RESUME, RENAME. For RENAME, # a random string will be appended to the filename. # Note: All commas in the filename are replaced with dots for the purpose # of matching to make it harder for people to accidentally or # purposely bypass well written masks by sending you specific # filenames. Nevertheless, this isn't really a safe authentication # method. # # Note: If the sender (an fserv perhaps) sends elaborate messages before # the transfer begins and NO_CTCP_FLOOD is on (it is on by # default), the ctcp flood protection mechanism can be triggered # and the transfer can fail to start. It may be better for you # to turn this feature off and make other flood protection # arrangements. # package autoget # Take possession of these variables while not clobbering them. fe (patterns.get * patterns.reget * reget.part resume reget.full close) var val { @ autoget[$var] = autoget.$var ? autoget.$var : [$val] } on #-dcc_request 414 "% SEND *" { @ :path = [$getset(dcc_store_path)/$urldecode($2)] if ([$6] <= fsize("$path")) { @ :patterns = autoget.patterns.reget @ :action = autoget.reget.full } elsif (0 < fsize("$path")) { @ :patterns = autoget.patterns.reget @ :action = autoget.reget.part } else { @ :patterns = autoget.patterns.get @ :action = [get] } if (rmatch($0!$userhost(),$3,$tr(/,/./$2) $autoget.patterns.reject)) { # Nothing. } elsif (rmatch($0!$userhost(),$3,$tr(/,/./$2) $patterns)) { if (action == []) { return } elsif (action == [rename]) { @ :extra = 0 do { @ extra += rand(10) } while (0 < fexist("$path~$extra")) @ rename("$path" "$path~$extra") @ action = [get] } elsif (action == [close]) { @ action = [close get] } elsif (!rmatch("$action" get resume)) { echo $action? return } dcc $action $0 $2 } } stack push alias alias alias alias fe (get reget reject) cmd {//alias $sar(g/XXX/$cmd/$*)} alias autoXXX { if (strlen($*) == 0) { echo AutoXXX n!u@h,IP,files matching [$autoget.XXXpatterns] return } fe ($*) x { if (left(1 $x) == [-]) { @ x = rest(1 $x) @ autoget.XXXpatterns = remw($x $autoget.XXXpatterns) } else { push autoget.XXXpatterns $x } } } stack pop alias alias alias autoclobber (args) { @ :types = [part full] if (#args) { fe ($args) arg { if (!types) { break } elsif (!arg) { @ shift(types) } elsif (rmatch("$arg" get rename resume close)) { @ autoget[reget][$shift(types)] = arg } else { echo $arg isn't one of: GET RENAME RESUME CLOSE } } } else { echo Usage: /autoclobber [partial-mode] [full-mode] fe ($types) type { echo Autoclobber $type mode is: $autoget[reget][$type] } } } on ^unload "autoget" { ^assign -autoget.patterns.get ^assign -autoget.patterns.reget ^assign -autoget.patterns.reject ^assign -autoget.reget.part ^assign -autoget.reget.full ^alias -autoget ^alias -autoreget ^alias -autoreject ^alias -autoclobber ^on #dcc_request 414 -"% SEND *" } if ( getset(mirc_broken_dcc_resume) == [off] ) { echo Warning: Turning mIRC DCC resume on set mirc_broken_dcc_resume on } if ( getset(no_ctcp_flood) != [off] ) { echo Warning: You may need to enter "/set no_ctcp_flood off" to autoget files from certain hosts. } #hop'y2k+1 epic4-2.10.2.orig/script/recursion0000644000000000000000000000401607213031315013661 0ustar # This one from Daemon (frechett@spot.Colorado.EDU) # He also threw together the patch to allow this sort of thing. # For use with the recursion abilities of ircII2.2pre5+2 # set MAX_RECURSIONS however high you want and still think is safe for you. # Or use it as a limit to the number of times an alias will execute. It will # die with an error though. # /iterate command_word list_of_words # will execute the command for each word in order ^alias iterate { if ([$1]) {$0 $1;iterate $0 $2-} } # /conbunch server1 server2 server3 ^alias conbunch { if ( [$1] ) { conbunch $1- } connect $0 } # /kickbunch nick1 nick2 nick3 nick4 ^alias kickbunch { if ( [$1] ) { kickbunch $1-} kick $C $0 } # you get the point ^alias squitbunch { if ( [$1] ) { squitbunch $1- } squit $0 } ^alias versbunch { if ( [$1] ) { versbunch $1- } version $0 } # /opalot + nick1 nick2 nick3 or /opalot - nick1 nick2 nick3 for op or deop # It will op in an efficient fashion as well. ^alias opalot { if ( [$4] ) { opalot $0 $4- } mode $C $0ooo $1-3 } # /addlist word1 word2 word3 add to array ^alias addlist { if ( [$2] ) { addlist $0 $2- } assign $0.$%strip(#+\.-\*/\={}[]<>!@$$%^~`,?:|'\" $1) $1 } # not related to recursion directly but useful for dealing with arrays. # /do ^alias do foreach $0 ii \{ $1- $$($0[$$ii]) \} # /clean # removes all assignments under that name to a single level ^alias clean foreach $0 ii { assign -$0[$ii] } # /purge # removes all assignments under that name recursively. ^alias purge { foreach $0 ii { purge $0.$ii } ^assign -ii ^assign -$0 } # Assuming you've made a list with addlist of servers.. or people or whatever # the following alias should give you some idea of other things to do.. ^alias versall do $0 version # Yes.. it looks cryptic.. Try /addlist servers h.ece* ucsu* *.unm.edu # and then /versall servers # or maybe just type /do servers version ;) # so much more.. so little time.. epic4-2.10.2.orig/script/guh0000644000000000000000000000201407607146040012440 0ustar # test /* * guh Copyright 1993 - Dont ask me why i called it that. I just did. * * Written by Jeremy Nelson (jnelson@acronet.net) * Requires ircII-EPIC * * General aliases that are useful for tracking * "whatchan" - returns all the channels a person is on * "is_on" - returns the nickname of a user if s/he is on. * "uh" - takes a list of names and returns a list of userhosts * corresponding to those nicks * "inc" - more for antiquity's sake, proves a point */ alias whatchan { stack push on 319 ^on ^319 * { stack pop on 319 return $1- } wait for ^whois $0 } alias is_on { ^local blahblah stack push on 303 ^on ^303 * { bless push blahblah $* } wait for ison $* stack pop on 303 return $blahblah } alias is_off { ^local blahblah $* fe ($is_on($*)) foo { @ blahblah = remw($foo $blahblah) } return $blahblah } alias uh { ^local blahblah wait for { ^userhost $* -cmd { bless push blahblah $3@$4 } } return $blahblah } alias inc { @ $0 += [$1]?[$1]:1 } #hop'93 epic4-2.10.2.orig/script/killpath0000644000000000000000000000075007213031315013461 0ustar # No Kill Path Script II # converted to 2.2.1 by phone # CONVERTED for ircII2.2 # Version for servers 2.7.1* by Nap@irc # Original script from YeggMan # Simplification by Daemon # Super Simplification by hop # works with only the new kill format. # Now that we have on ^kill in EPIC4, this is ridiculously trivial. on ^kill "% % %.% *" xecho -level opnotes ### server KILL for $1 by $2 on ^kill "% % % *" xecho -level opnotes ### KILL for $1 by $2 \($4-\) epic4-2.10.2.orig/script/dns0000644000000000000000000000133407213031315012434 0ustar # # dns.irc - translates ip->host, host->ip or nick->ip, nick->host. # # quick hack by SrfRoG (srfrog@mistik.net) # alias dns.result (adr) { @ :res = convert($adr) echo *** $adr is ${res?res:[Unknown]} } alias dns { if (@) { ^local who $0 if (match(*.* $who)) { dns.result $who }{ userhost $who -cmd if ([$3]!=[]) { dns.result $4 }{ echo *** $who\: nick not found. } } }{ echo *** usage: /dns < nick | [host | ip address] > } } #srfrog'99 epic4-2.10.2.orig/UPDATES0000644000000000000000000000163611250355604011464 0ustar EPIC4-2.10.1 *** News 09/04/2009 -- Release just for the signal bug There was a signal bug in epic4-2.10 caused by the new signal handling code. A small release was done to give people something to download instead of having to cvs update to pick up the fix. EPIC4-2.8 *** News 09/06/2007 -- New functions $strtol() and $tobase. $strtol(b s) converts string s to an integer, as if the string is a number of the base b. $strtol(16 f) will return 15. $tobase(b i) converts integer i to base b. Backported from EPIC5 for |Rain|. *** News 07/04/2007 -- New $windowctl() option, $windowctl(GET refnum CHANNELS) You can now fetch all of the channels in a window by using $windowctl(GET CHANNELS) There is no defined order to the channels returned. This was backported from EPIC5 by special request of BlackJac. # End of file epic4-2.10.2.orig/regress/0000755000000000000000000000000012200242556012075 5ustar epic4-2.10.2.orig/regress/stat0000644000000000000000000000313307522602043012775 0ustar /* $EPIC: stat,v 1.1 2002/08/02 22:13:55 jnelson Exp $ */ @ cl = [\\[0m @ blk = [\\[0\;30m] @ blu = [\\[0\;34m] @ grn = [\\[0\;32m] @ cyn = [\\[0\;36m] @ red = [\\[0\;31m] @ mag = [\\[0\;35m] @ yel = [\\[0\;33m] @ wht = [\\[0\;37m] @ hblk = [\\[1\;30m] @ hblu = [\\[1\;34m] @ hgrn = [\\[1\;32m] @ hcyn = [\\[1\;36m] @ hred = [\\[1\;31m] @ hmag = [\\[1\;35m] @ hyel = [\\[1\;33m] @ hwht = [\\[1\;37m] @ bwht = [\\[47m] @ bmag = [\\[45m] @ bblu = [\\[44m] @ bred = [\\[41m] @ bblk = [\\[40m] @ bgrn = [\\[42m] @ byel = [\\[43m] @ bcyn = [\\[46m] #  @sc1=blu @sc2=hblu @sc3=bblu @sc4=hblu alias stat9 { ^set status_format1 $(sc2)Ú$(sc1)Ä$(hblk)Äú\(%*%=%@$(cl)%N$(hblk)..%#$(hblk)\)$(hblk)-[\(%C$(hblk)..%+$(hblk)\)]Ä%>Ä\($(cl)lag$(hblk)..$(cl)%1$(hblk)\) $(sc1)Ä$(sc2)ÄÄ¿ ^set input_prompt ^set status_format2 $(sc1)À$(sc2)Ä$(sc1)Ä$(hblk)úù $(sc1)o$(hblk)\($(cl)%2$(hblk)\) $(sc1)n$(hblk)\($(cl)%3$(hblk)\)ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ%>$(hblk)\($(cl)%T$(hblk)\)ÄÄÄ$(hblk)\($(sc1)win$(hblk)/$(sc2)%R$(hblk)\) $(hblk)úÄ$(sc1)Ä$(sc2)Ù ^set status_umode $(sc2)+$(sc1)%#$(hblk) ^set status_oper $(sc1)* ^set status_lag %L ^set status_channel $(cl)%C ^set status_mode $(sc2)+$(sc1)%+\) ^set status_clock %T ^set status_chanop $(sc1)@ ^set status_format5 %> %5 ^set status_mail $(hblk) $(hwht)m$(cl)ai$(hblk)l $(hwht)%M ^set status_user5 $(sc1)s$(hblk)/$(sc2)$S ^set status_voice + ^set status_away $(hblk)[$(sc1)away$(hblk)] ^set status_hold_lines $(hblk)\[$(hwht)%B$(hblk)] ^set status_query $(hblk)\[$(blu)Q$(wht): $(wht)%Q$(hblk)] } stat9 ^window double on epic4-2.10.2.orig/regress/kill0000644000000000000000000000066107213031315012753 0ustar on ^server_notice "% % notice -- received kill*" { if (rmatch($10 %.%)) { xecho -window OpView [^BSERVKILL^B] $strip(. $8) by $10 $13- [$star.mytime()] }{ local star.int.victim $strip(. $8) local star.int.reason $13- userhost $10 -cmd { bless if (index(. $4) > 0) { xecho -window OpView [^BKILL^B] $star.int.victim by $0 <$3@$4> $star.int.reason [$star.mytime()] } } wait } } epic4-2.10.2.orig/regress/arglist0000644000000000000000000002526507752613715013516 0ustar @ misses = 0 alias clear { if (misses) {@ [$"[RETURN]"];@ misses = 0} //clear } alias assert { eval @ foo = $* if (foo == 1) { echo Test [$[60]*] passed } { echo Test [$[60]*] FAILED! ;@misses++ } } alias t100 (arg1) {return $arg1} alias t101 (arg1) {return $*} alias t110 (arg1, arg2) {return $arg1} alias t111 (arg1, arg2) {return $arg2} alias t112 (arg1, arg2) {return $*} alias t120 (arg1 default "one", arg2 default "two") {return $arg1} alias t121 (arg1 default "one", arg2 default "two") {return $arg2} alias t122 (arg1 default "one", arg2 default "two") {return $*} alias t200 (arg1, arg2, ...) {return $arg1$()} alias t201 (arg1, arg2, ...) {return $arg2$()} alias t202 (arg1, arg2, ...) {return $*} alias t210 (arg1, arg2, void) {return $arg1$()} alias t211 (arg1, arg2, void) {return $arg2$()} alias t212 (arg1, arg2, void) {return $*} alias t300 (arg1 words 1, arg2, ...) {return $arg1$()} alias t301 (arg1 words 1, arg2, ...) {return $arg2$()} alias t302 (arg1 words 1, arg2, ...) {return $*} alias t310 (arg1 words 2, arg2, ...) {return $arg1$()} alias t311 (arg1 words 2, arg2, ...) {return $arg2$()} alias t312 (arg1 words 2, arg2, ...) {return $*} alias t320 (arg1 uwords 1, arg2, ...) {return $arg1$()} alias t321 (arg1 uwords 1, arg2, ...) {return $arg2$()} alias t322 (arg1 uwords 1, arg2, ...) {return $*} alias t330 (arg1 uwords 2, arg2, ...) {return $arg1$()} alias t331 (arg1 uwords 2, arg2, ...) {return $arg2$()} alias t332 (arg1 uwords 2, arg2, ...) {return $*} alias t340 (arg1 uwords 2, arg2 qwords 1, ...) {return $arg1$()} alias t341 (arg1 uwords 2, arg2 qwords 1, ...) {return $arg2$()} alias t342 (arg1 uwords 2, arg2 qwords 1, ...) {return $*} alias t350 (arg1 words 2, arg2 qwords 2 default "zoot", ...) {return $arg1$()} alias t351 (arg1 words 2, arg2 qwords 2 default "zoot", ...) {return $arg2$()} alias t352 (arg1 words 2, arg2 qwords 2 default "zoot", ...) {return $*} alias t360 (arg1 uwords 2, arg2 dwords 1, ...) {return $arg1$()} alias t361 (arg1 uwords 2, arg2 dwords 1, ...) {return $arg2$()} alias t362 (arg1 uwords 2, arg2 dwords 1, ...) {return $*} alias t370 (arg1 words 2, arg2 dwords 2 default "zoot", ...) {return $arg1$()} alias t371 (arg1 words 2, arg2 dwords 2 default "zoot", ...) {return $arg2$()} alias t372 (arg1 words 2, arg2 dwords 2 default "zoot", ...) {return $*} # Test #1.0 -- Simple Arg List -- One Arguments clear xdebug -extractw assert t100(one two three)==[one two three] assert t101(one two three)==[] assert t100("one two" three)==["one two" three] assert t101("one two" three)==[] # Test #1.1 -- Simple Arg List -- Two Arguments assert t110(one two three)==[one] assert t111(one two three)==[two three] assert t112(one two three)==[] assert t110("one two" three)==["one] assert t111("one two" three)==[two" three] assert t112("one two" three)==[] # Test #1.2 -- Simple Arg List -- Two Arguments With Defaults assert t120()==[one] assert t121()==[two] assert t122()==[] assert t120(boom)==[boom] assert t121(boom)==[two] assert t122(boom)==[] assert t120(boom bam)==[boom] assert t121(boom bam)==[bam] assert t122(boom bam)==[] assert t120(boom bam booya)==[boom] assert t121(boom bam booya)==[bam booya] assert t122(boom bam booya)==[] assert t120("boom")==["boom"] assert t121("boom")==[two] assert t122("boom")==[] assert t120("boom bam")==["boom] assert t121("boom bam")==[bam"] assert t122("boom bam")==[] assert t120("boom bam" booya)==["boom] assert t121("boom bam" booya)==[bam" booya] assert t122("boom bam" booya)==[] ############################################################################# # Test #2.0 -- Arg List With Elipses clear assert t200(one two three)==[one] assert t201(one two three)==[two] assert t202(one two three)==[three] assert t200("one two" three four)==["one] assert t201("one two" three four)==[two"] assert t202("one two" three four)==[three four] assert t200(one "two three" four)==[one] assert t201(one "two three" four)==["two] assert t202(one "two three" four)==[three" four] # Test #2.1 -- Arg List With Void assert t210(one two three)==[one] assert t211(one two three)==[two] assert t212(one two three)==[] assert t210("one two" three)==["one] assert t211("one two" three)==[two"] assert t212("one two" three)==[] ############################################################################## # Test #3.0 -- Arg List with 1 Word Count and Elipses clear assert t300(one two three four)==[one] assert t301(one two three four)==[two] assert t302(one two three four)==[three four] assert t300("one two" three four)==["one] assert t301("one two" three four)==[two"] assert t302("one two" three four)==[three four] xdebug extractw assert t300("one two" three four)==[one two] assert t301("one two" three four)==[three] assert t302("one two" three four)==[four] assert t300("one two" "three four")==[one two] assert t301("one two" "three four")==[three four] assert t302("one two" "three four")==[] xdebug -extractw # Test #3.1 -- Arg List with 2 Word Count and Elipses clear assert t310(one two three four)==[one two] assert t311(one two three four)==[three] assert t312(one two three four)==[four] assert t310("one two" three four)==["one two"] assert t311("one two" three four)==[three] assert t312("one two" three four)==[four] xdebug extractw assert t310("one two" three four)==["one two" three] assert t311("one two" three four)==[four] assert t312("one two" three four)==[] assert t310("one two" "three four")==["one two" "three four"] assert t311("one two" "three four")==[] assert t312("one two" "three four")==[] xdebug -extractw # Test #3.2 -- Arg List with 1 UWord (no double quotes) Count and Elipses clear assert t320(one two three four)==[one] assert t321(one two three four)==[two] assert t322(one two three four)==[three four] assert t320("one two" three four)==["one] assert t321("one two" three four)==[two"] assert t322("one two" three four)==[three four] xdebug extractw assert t320("one two" three four)==["one] assert t321("one two" three four)==[two"] assert t322("one two" three four)==[three four] assert t320("one two" "three four")==["one] assert t321("one two" "three four")==[two"] assert t322("one two" "three four")==["three four"] xdebug -extractw # Test #3.3 -- Arg List with 2 UWord Count (no double quotes) and Elipses clear assert t330(one two three four)==[one two] assert t331(one two three four)==[three] assert t332(one two three four)==[four] assert t330("one two" three four)==["one two"] assert t331("one two" three four)==[three] assert t332("one two" three four)==[four] xdebug extractw assert t330("one two" three four)==["one two"] assert t331("one two" three four)==[three] assert t332("one two" three four)==[four] assert t330("one two" "three four")==["one two"] assert t331("one two" "three four")==[three four] assert t332("one two" "three four")==[] xdebug -extractw # Test #3.4 -- Arg List with 2 UWord Count (no double quotes) # and 1 Word Count (double quotes) and Elipses clear assert t340(one two three four)==[one two] assert t341(one two three four)==[three] assert t342(one two three four)==[four] assert t340("one two" three four)==["one two"] assert t341("one two" three four)==[three] assert t342("one two" three four)==[four] assert t340("one two" "three four")==["one two"] assert t341("one two" "three four")==["three four"] assert t342("one two" "three four")==[] xdebug extractw assert t340("one two" three four)==["one two"] assert t341("one two" three four)==[three] assert t342("one two" three four)==[four] assert t340("one two" "three four")==["one two"] assert t341("one two" "three four")==["three four"] assert t342("one two" "three four")==[] xdebug -extractw # Test #3.5 -- Arg List with 2 Word Count (no double quotes) # and 2 QWord Count (double quotes) with default and Elipses clear assert t350()==[] assert t351()==[zoot] assert t352()==[] assert t350(one two)==[one two] assert t351(one two)==[zoot] assert t352(one two)==[] assert t350(one two three)==[one two] assert t351(one two three)==[three] assert t352(one two three)==[] assert t350(one two three four)==[one two] assert t351(one two three four)==[three four] assert t352(one two three four)==[] assert t350("one two" three four)==["one two"] assert t351("one two" three four)==[three four] assert t352("one two" three four)==[] assert t350("one two" "three four")==["one two"] assert t351("one two" "three four")==["three four"] assert t352("one two" "three four")==[] xdebug extractw assert t350("one two" three four)==["one two" three] assert t351("one two" three four)==[four] assert t352("one two" three four)==[] assert t350("one two" "three four" "five six" 7 8)==["one two" "three four"] assert t351("one two" "three four" "five six" 7 8)==["five six" 7] assert t352("one two" "three four" "five six" 7 8)==[8] xdebug -extractw # Test #3.6 -- Arg List with 2 UWord Count (no double-quoted word support) # and 1 DWord Count (no double quotes) and Elipses clear assert t360(one two three four)==[one two] assert t361(one two three four)==[three] assert t362(one two three four)==[four] assert t360("one two" three four)==["one two"] assert t361("one two" three four)==[three] assert t362("one two" three four)==[four] assert t360("one two" "three four")==["one two"] assert t361("one two" "three four")==[three four] assert t362("one two" "three four")==[] xdebug extractw assert t360("one two" three four)==["one two"] assert t361("one two" three four)==[three] assert t362("one two" three four)==[four] assert t360("one two" "three four")==["one two"] assert t361("one two" "three four")==[three four] assert t362("one two" "three four")==[] xdebug -extractw # Test #3.7 -- Arg List with 2 Word Count (no double quotes) # and 2 DWord Count (no double quotes) with default and Elipses clear assert t370()==[] assert t371()==[zoot] assert t372()==[] assert t370(one two)==[one two] assert t371(one two)==[zoot] assert t372(one two)==[] assert t370(one two three)==[one two] assert t371(one two three)==[three] assert t372(one two three)==[] assert t370(one two three four)==[one two] assert t371(one two three four)==[three four] assert t372(one two three four)==[] assert t370("one two" three four)==["one two"] assert t371("one two" three four)==[three four] assert t372("one two" three four)==[] assert t370("one two" "three four")==["one two"] assert t371("one two" "three four")==[three four] assert t372("one two" "three four")==[] xdebug extractw assert t370("one two" three four)==["one two" three] assert t371("one two" three four)==[four] assert t372("one two" three four)==[] assert t370("one two" "three four" "five six" 7 8)==["one two" "three four"] assert t371("one two" "three four" "five six" 7 8)==[five six 7] assert t372("one two" "three four" "five six" 7 8)==[8] xdebug -extractw echo echo echo echo ALL TESTS ARE DONE! epic4-2.10.2.orig/regress/window0000644000000000000000000000167407213031315013334 0ustar alias disptime_one xecho -window $0 [^Btime^O] $strftime(%Y-%m-%d %a %H:%M) alias disptime_all { foreach disptime_wins w { if (winvisible($w)==-1) { ^assign -disptime_wins[$w] } elsif (disptime_wins[$w]) { disptime_one $w } } } on #^timer 431 * disptime_all #on #^timer 431 *:30 disptime_all alias disptime { @disptime_wins[$winnum()] = [t] xecho -window $winnum() [time] $strftime(%Y-%m-%d %a %H:%M) parsekey refresh_status } alias disptimeoff { assign -disptime_wins[$winnum()] parsekey refresh_status } alias dtminon { @dt_min[$winnum()] = [m] parsekey refresh_status } alias dtminoff { ^assign -dt_min[$winnum()] parsekey refresh_status } on ^window * if (dt_min[$0]) { if (dt_min_last[$0] != [$Z]) { echo $cparse(%r$strftime(%M)%b+%n)$1- @dt_min_last[$0] = Z } else { echo $cparse(%b+++%n)$1- } } else { echo $1- } epic4-2.10.2.orig/regress/color0000644000000000000000000000230407213031315013132 0ustar alias testcolor { echo 0 $chr(3)0 Bright White echo 1 $chr(3)1 Black echo 2 $chr(3)2 Blue echo 3 $chr(3)3 Green echo 4 $chr(3)4 Red echo 5 $chr(3)5 Brown echo 6 $chr(3)6 Magenta echo 7 $chr(3)7 Bright Red echo 8 $chr(3)8 Yellow echo 9 $chr(3)9 Bright Green echo 10 $chr(3)10 Cyan echo 11 $chr(3)11 Bright Cyan echo 12 $chr(3)12 Bright Blue echo 13 $chr(3)13 Bright Magenta echo 14 $chr(3)14 Grey echo 15 $chr(3)15 Grey echo 30 $chr(3)30 Black echo 31 $chr(3)31 Red echo 32 $chr(3)32 Green echo 33 $chr(3)33 Brown echo 34 $chr(3)34 Blue echo 35 $chr(3)35 Magenta echo 36 $chr(3)36 Cyan echo 37 $chr(3)37 White echo 40 $chr(3),40 Black echo 41 $chr(3),41 Red echo 42 $chr(3),42 Green echo 43 $chr(3),43 Brown echo 44 $chr(3),44 Blue echo 45 $chr(3),45 Magenta echo 46 $chr(3),46 Cyan echo 47 $chr(3),47 White echo 50 $chr(3)50 Black echo 51 $chr(3)51 Red echo 52 $chr(3)52 Green echo 53 $chr(3)53 Brown echo 54 $chr(3)54 Blue echo 55 $chr(3)55 Magenta echo 56 $chr(3)56 Cyan echo 57 $chr(3)57 White echo 50 $chr(3),50 Black echo 51 $chr(3),51 Red echo 52 $chr(3),52 Green echo 53 $chr(3),53 Brown echo 54 $chr(3),54 Blue echo 55 $chr(3),55 Magenta echo 56 $chr(3),56 Cyan echo 57 $chr(3),57 White } testcolor epic4-2.10.2.orig/regress/crash-irc0000755000000000000000000000110307213031315013666 0ustar #!/usr/local/bin/perl5 -w # $Id: crash-irc,v 1.1.1.1 2000/12/05 00:11:57 jnelson Exp $ use strict; use Socket; if(!($ARGV[1])){print("usage: $0 host port","\n");exit;} my $port = $ARGV[1]; my $proto = getprotobyname("tcp"); my $iaddr = inet_aton($ARGV[0]) || die "No such host: $ARGV[0]"; my $paddr = sockaddr_in($port, $iaddr); socket(SKT, AF_INET, SOCK_STREAM, $proto) || die "socket() $!"; connect(SKT, $paddr) && print("Connected established.\n") || die "connect() $!"; my $infstr = "a"; while(1){ select(undef, undef, undef, rand); send(SKT,$infstr,0) || die "send() $!"; } epic4-2.10.2.orig/regress/fib0000644000000000000000000000354407213031315012563 0ustar # # The point of this is not to test the efficiency of the algorithm, # but to see how fast the client can crank out lots and lots and lots # of function calls and many many many evaluation switches. # # The point of fib vs. fibb is to demonstrate how a little bit of # care in coding can make a big difference in performance. # # These functions are considered to be "frozen". Dont you dare change # them under penalty of death, for that will foul up the long term # comparisons that we're trying to test! # # All of the times here are for my 486DX2/66, running FreeBSD 2.2 # load utime ^set max_recur 1000 alias fib { if ([$0]==0) { @ function_return = 0} { if ([$0]==1) { @ function_return = 1} { @ function_return = fib(${[$0]-1}) + fib(${[$0]-2}) } } } alias fibb { @function_return=[$0]>1?fibb(${[$0]-1})+fibb(${[$0]-2}):[$0]?1:0 } alias fibbb { @ [$0] > 1 ? { @ :x1 = [$0], x1--, :x2 = x1, x2-- return fibbb($x1)+fibbb($x2) } : { return $0 } } alias fib2 { @ start = utime() eval echo $fib(20) echo Total time = $utime_sub($utime() $start) } # (epic3.000 - 53 s), (epic3.004 - 45 s), (epic4pre0.020 - 37 s) alias fib3 { @ start = utime() eval echo $fibb(20) echo Total time = $utime_sub($utime() $start) } # (epic3.000 - 198 s), (epic3.004 - 180 s), (epic4pre0.020 - 144 s) alias fib4 { @ start = utime() eval echo $fib(22) echo Total time = $utime_sub($utime() $start) } alias fib4b { @ start = utime() eval echo $fibbb(22) echo Total time = $utime_sub($utime() $start) } # (epic3.000 - 141 s), (epic3.004 - 117 s), (epic4pre0.020 - 96 s) alias fib5 { @ start = utime() eval echo $fibb(22) echo Total time = $utime_sub($utime() $start) } alias fib6 { @ start = utime() eval echo $fib(6) echo Total time = $utime_sub($utime() $start) } alias fib7 { @ start = utime() eval echo $fibb(6) echo Total time = $utime_sub($utime() $start) } epic4-2.10.2.orig/regress/localvars0000644000000000000000000000131507213031315014003 0ustar alias foobar { local a @ a = [$0] - 1 echo *** Descending: Now $$a is $a echo *** Global $$a is ${::a} if (a >= 0) { foobar $a } echo *** Ascending: Now $$a is $a } alias go { assign a 31337 echo *** Ok. Lets see. $$a is $a (global) foobar 10 echo *** Ok, all done. $$a is $a (global) } alias local2 { local a. @ a.b = 43 echo a.b is $a.b, a.c is $a.c @ a.c = 23 echo a.b is $a.b, a.c is $a.c } alias go2 { @ a.c = 37 echo a.b is $a.b, a.c is $a.c local2 echo a.b is $a.b, a.c is $a.c } alias go3 { local a @ a = 10 if (1) { local b @ b = 20 echo $$a should be 10, its [$a] echo $$b should be 20, its [$b] } echo $$a should be 10, its [$a] echo $$b should be 20, its [$b] } epic4-2.10.2.orig/regress/eval-test0000644000000000000000000000007007213031315013716 0ustar on msg * { fe ($1-) x { eval echo ---- $x ---- } } epic4-2.10.2.orig/regress/README0000644000000000000000000000051607213031315012754 0ustar Here are some regression tests I use to check to make sure the features of EPIC are up to spec. I will usually run these tests before i release any new versions, so you can (hopefully) assume that ive already tested this version already. But i thought i should share with the public how i am testing the client's features. -jfn epic4-2.10.2.orig/regress/CVS/0000755000000000000000000000000012200242556012530 5ustar epic4-2.10.2.orig/regress/CVS/Root0000644000000000000000000000006212171117135013375 0ustar :pserver:anoncvs@epicsol.org:/home/cvs/repository epic4-2.10.2.orig/regress/CVS/Entries0000644000000000000000000000132512171117135014066 0ustar /README/1.1.1.1/Tue Dec 5 00:11:57 2000// /arglist/1.2/Fri Nov 7 03:55:57 2003// /color/1.1.1.1/Tue Dec 5 00:11:57 2000// /crash-irc/1.1.1.1/Tue Dec 5 00:11:57 2000// /eval-test/1.1.1.1/Tue Dec 5 00:11:57 2000// /fib/1.1.1.1/Tue Dec 5 00:11:57 2000// /funcs/1.9/Fri Feb 20 06:29:03 2004// /hangtest/1.1.1.1/Tue Dec 5 00:11:57 2000// /karll-arrays/1.1/Mon Aug 26 17:20:14 2002// /kill/1.1.1.1/Tue Dec 5 00:11:57 2000// /localvars/1.1.1.1/Tue Dec 5 00:11:57 2000// /math/1.1.1.1/Tue Dec 5 00:11:57 2000// /rainbug/1.1.1.1/Tue Dec 5 00:11:57 2000// /random/1.1.1.1/Tue Dec 5 00:11:57 2000// /scroll/1.1.1.1/Tue Dec 5 00:11:57 2000// /stat/1.1/Fri Aug 2 22:13:55 2002// /window/1.1.1.1/Tue Dec 5 00:11:57 2000// D epic4-2.10.2.orig/regress/CVS/Repository0000644000000000000000000000001612171117135014630 0ustar epic4/regress epic4-2.10.2.orig/regress/karll-arrays0000644000000000000000000000247507532461516014447 0ustar coredump on yell - set lastlog 100000 alias test (array, rest) { @:foo=jot(0 ${numitems($array)-1}) if (foo!=itemtoindex($array $indextoitem($array $foo))) { echo $array $numitems($array) failed itemof(indexof()) test: $array $rest } elsif (foo!=indextoitem($array $itemtoindex($array $foo))) { echo $array $numitems($array) failed indexof(itemof()) test: $array $rest } elsif (sort($getitem($array $foo))!=sort($igetitem($array $foo))) { echo $array $numitems($array) failed index consistancy test: $array $rest } else {echo OK: $array $rest} } fe (baz bar foo) qwer { @delarray($qwer) fe (4 49 499 4999) zxcv { fe (2 0 2) fnord { @ :asdf = numitems($qwer) / 2 @ igetitem($qwer 0) for foo from $asdf to $zxcv {@setitem($qwer $foo $rand($fnord))} repeat $asdf {@delitems($qwer $rand($numitems($qwer)))} test $qwer A: $asdf $zxcv $fnord for foo from $asdf to $zxcv {@usetitem($qwer $foo $rand($fnord))} repeat $asdf {@delitems($qwer $rand($numitems($qwer)))} test $qwer B: $asdf $zxcv $fnord } } } if (getarrays()!=sort($uniq($getarrays()))) { echo Array list destroyed: $getarrays() } elsif (3>numwords($getarrays())) { echo Too few arrays: $getarrays() } elsif (3>0==16 assert 16>>1==8 assert 16>>2==4 assert 16>>3==2 assert 16>>4==1 #define LES 18 assert 3<4==1 assert 4<3==0 assert 3<3==0 #define LEQ 19 assert 3<=4==1 assert 4<=3==0 assert 3<=3==1 #define GRE 20 assert 3>4==0 assert 4>3==1 assert 3>3==0 #define GEQ 21 assert 3>=4==0 assert 4>=3==1 assert 3>=3==1 #define DEQ 22 assert [1]==1 assert booya==[3] assert booya==3 assert [$booya]==[3] #define NEQ 23 assert 2!=1 assert 2!=[1] assert [2]!=[1] assert booya!=4 assert booya!=[foobar] #define DAND 24 alias ack {echo ack!;@counter++;@function_return = 1} @ counter = 0 assert (1&&0)==0 assert (0&&0)==0 assert (1&&1)==1 assert ([]&&1)==0 assert ([booya]&&1)==1 assert (0&&ack())==0 assert (ack()&&ack())==1 assert (ack()&&0)==0 assert (ack()&&1)==1 assert counter==4 #define DOR 25 @ counter = 0 assert (1||0)==1 assert (0||0)==0 assert (1||1)==1 assert ([]||1)==1 assert ([booya]||1)==1 assert (0||ack())==1 assert (ack()||ack())==1 assert (ack()||0)==1 assert (ack()||1)==1 assert counter==4 #define DXOR 26 #define QUEST 27 #define COLON 28 #define EQ 29 #define PLUSEQ 30 #define MINUSEQ 31 #define MULEQ 32 #define DIVEQ 33 #define MODEQ 34 #define ANDEQ 35 #define XOREQ 36 #define OREQ 37 #define SHLEFTEQ 38 #define SHRIGHTEQ 39 #define DANDEQ 40 #define DOREQ 41 #define DXOREQ 42 #define COMMA 43 #define PREPLUS 45 #define PREMINUS 46 #define NUM 47 #define POWER 50 #define POWEREQ 52 #define STRLEN 53 /* Added for epic */ assert @[foobar]==6 assert @(booya = [foobar])==6 #define STRCAT 54 /* Added for epic */ assert #[This is a test]==4 assert #(booya = [This is a test])==4 #define STRCATEQ 55 /* Added for epic */ #define WORDC 56 /* Added for epic */ } foobar # # Integer tests # #set floating_point_math off #assert 3+4==7 #assert 3-4==-1 #assert 3+4+4==11 ##sigh, yes, this is the right value. #assert 3+4-4==3 #assert (3+4)-4==3 # #assert 3*4==12 #assert 3/4==0 #assert 3%4==3 #assert 4%3==1 #assert 4/3==1 # #assert 3##4==34 #assert [3]##4==34 #assert 3##[4]==34 # # floating point tests # #set floating_point_math on #assert 3.0+4.3==7.3 #assert 3.0-4.3==-1.3 #assert 3.0+4.3+3.4==10.7 ###sigh, yes, this is the right value. #assert 3.0+4.3-4.3==3 epic4-2.10.2.orig/regress/hangtest0000644000000000000000000000026407213031315013634 0ustar alias hang { window new server /tmp/.ircd/6667 double on hide window swap last window new server /tmp/.ircd/6666 double on hide window swap last window discon window kill } epic4-2.10.2.orig/regress/random0000644000000000000000000000021207213031315013270 0ustar alias testit { @ i = 0 @ fd = open(random-num W) while (i < 10000) { @ write($fd $rand(100) $rand(100)) @ i++ } @ close($fd) } epic4-2.10.2.orig/regress/funcs0000644000000000000000000005102010015324457013137 0ustar # # EPIC3 ESL regression tests # built in functions test # (C) 1995 Jeremy Nelson, Distribute freely. # # NOTE: If you find a test that is missing, please let me know so # i can add it. Doubly so if you find a test that exposes a bug! # @ misses = 0 alias clear { if (misses) {@ [$"[RETURN]"];@ misses = 0} //clear } alias assert { eval @ foo = $* if (foo == 1) { echo Test [$[60]*] passed } { echo Test [$[60]*] FAILED! ;@misses++ } } # testing $after() clear assert after(!)==[] assert after(! one)==[] assert after(! one!)==[] assert after(! one!two)==[two] assert after(! one!two!three)==[two!three] assert after(1)==[] assert after(1 !)==[] assert after(1 ! one)==[] assert after(1 ! one!)==[] assert after(1 ! one!two)==[two] assert after(1 ! one!two!three)==[two!three] assert after(-1)==[] assert after(-1 !)==[] assert after(-1 ! one)==[] assert after(-1 ! one!)==[] assert after(-1 ! one!two!three)==[three] assert after(-1 ! one!two)==[two] assert after(2 ! one)==[] assert after(2 ! one!)==[] assert after(2 ! one!two)==[] assert after(2 ! one!two!three)==[three] assert after(-2 ! one)==[] assert after(-2 ! one!)==[] assert after(-2 ! one!two)==[] assert after(-2 ! one!two!three)==[two!three] # testing $afterw() clear assert afterw() == [] assert afterw(one) == [] assert afterw(one two) == [] assert afterw(one two three one four five) == [four five] assert afterw(two two three four five two) == [three four five two] assert afterw(one one) == [] assert afterw(one three four five) == [] # testing $ascii() -- see test for $jot() # testing $before() clear assert before(!)==[] assert before(! one)==[] assert before(! one!)==[one] assert before(! one!two)==[one] assert before(! one!two!three)==[one] assert before(1)==[] assert before(1 !)==[] assert before(1 ! one)==[] assert before(1 ! one!)==[one] assert before(1 ! one!two)==[one] assert before(1 ! one!two!three)==[one] assert before(-1)==[] assert before(-1 !)==[] assert before(-1 ! one)==[] assert before(-1 ! one!)==[one] assert before(-1 ! one!two)==[one] assert before(-1 ! one!two!three)==[one!two] assert before(2 ! one)==[] assert before(2 ! one!)==[] assert before(2 ! one!two)==[] assert before(2 ! one!two!three)==[one!two] assert before(-2 ! one)==[] assert before(-2 ! one!)==[] assert before(-2 ! one!two)==[] assert before(-2 ! one!two!three)==[one] # testing $beforew() clear assert beforew() == [] assert beforew(one) == [] assert beforew(one two) == [] assert beforew(one two three one four five) == [two three] assert beforew(two two three four five two) == [] assert beforew(one one) == [] assert beforew(one three four five) == [] # testing $center() clear assert center() == [] assert center(10) == [ ] assert center(10 foo) == [ foo] assert center(10 boog) == [ boog] # testing $chanusers() -- cant be tested right now. # testing $chngw() clear assert chngw() == [] assert chngw(1) == [] assert chngw(1 one) == [one] assert chngw(0 one) == [one] assert chngw(0 one two) == [one] assert chngw(1 one two) == [two one] assert chngw(1 one two three) == [two one] assert chngw(2 one two three) == [two three one] assert chngw(0 one five four three two one) == [one four three two one] # testing $chops() -- cant be tested right now. # testing $chr() -- see test for $jot() # testing $common() clear assert common() == [] assert common(/) == [] assert common(one/one) == [one] assert common(one/two) == [] assert common(one two / one two) == [one two] assert common(one three / one four) == [one] assert common(one three / three four one) == [one three] assert common(one two / phone foobar) == [] assert common(one two one / one three) == [one] assert common(/one two three) == [] assert common(one two three/) == [] # testing $connect() -- cant be tested right now # testing $convert() -- cant be tested right now # testing $copattern() clear @ one = [] @ two = [] assert copattern(* one two) == [] @ one = [foo] @ two = [bar] assert copattern(* one two) == [bar] assert copattern(b* one two) == [] assert copattern(*o one two) == [bar] @ one = [one two three four] @ two = [five six seven eight] assert copattern(* one two) == [five six seven eight] assert copattern(*e one two) == [five seven] assert copattern(t* one two) == [six seven] @ one = [one two three four] @ two = [boo] assert copattern(t* one two) == [] assert copattern(o* one two) == [boo] assert copattern(*o* one two) == [boo] # testing $curpos -- cant be tested right now # testing $decode() and $encode() clear assert encode() == [] assert decode() == [] assert decode($encode()) == [] assert decode($encode(foo)) == [foo] # testing $diff() clear assert diff() == [] assert diff(/) == [] assert diff(one/one) == [] assert diff(one/two) == [one two] assert diff(one two / one two) == [] assert diff(one three / one four) == [three four] assert diff(one three / three four one) == [four] assert diff(/one two three) == [one two three] assert diff(one two three/) == [one two three] # testing $eof() -- cant be tested right now # testing $filter() clear assert filter() == [] assert filter(*) == [] assert filter(* one two) == [] assert filter(o* one two) == [two] assert filter(t* one two) == [one] assert filter(r* one two) == [one two] assert filter(t* one two three) == [one] assert filter(*e one two three) == [two] # testing $fromw() clear assert fromw() == [] assert fromw(one) == [] assert fromw(one two) == [] assert fromw(one two three one four five) == [one four five] assert fromw(two two three four five two) == [two three four five two] assert fromw(one one) == [one] assert fromw(one three four five) == [] # testing $index() clear assert index() == [] assert index(/ one) == -1 assert index(/ /one) == 0 assert index(/ o/ne) == 1 assert index(/ on/e) == 2 assert index(/ one/) == 3 assert index(/ /one/) == 0 assert index(^/ ///one/) == 3 assert index(the one) == 2 assert index(the het) == 0 assert index(^the the) == -1 assert index(^the one) == 0 assert index(^the eon) == 1 clear assert indextoword(0 one . .. two ) == 0 assert indextoword(1 one . .. two ) == 0 assert indextoword(2 one . .. two ) == 0 assert indextoword(3 one . .. two ) == 0 assert indextoword(4 one . .. two ) == 1 assert indextoword(5 one . .. two ) == 1 assert indextoword(6 one . .. two ) == 2 assert indextoword(7 one . .. two ) == 2 assert indextoword(8 one . .. two ) == 2 assert indextoword(9 one . .. two ) == 3 assert indextoword(10 one . .. two ) == 3 assert indextoword(11 one . .. two ) == 3 assert indextoword(12 one . .. two ) == 3 assert indextoword(13 one . .. two ) == 3 assert indextoword(14 one . .. two ) == 3 assert indextoword(15 one . .. two ) == [] # testing $insertw() clear assert insertw() == [] assert insertw(-1) == [] assert insertw(1) == [] assert insertw(1 one) == [one] assert insertw(0 one) == [one] assert insertw(0 one two) == [one two] assert insertw(1 one two) == [two one] assert insertw(1 one two three) == [two one three] assert insertw(2 one two three) == [two three one] assert insertw(4 one two three) == [two three one] assert insertw(-1 one two three) == [one two three] # testing $iptoname() -- cant be tested right now # testing $isalpha() clear assert isalpha() == 0 assert isalpha(1) == 0 assert isalpha(x) == 1 assert isalpha(X) == 1 assert isalpha(^) == 0 # testing $ischannel() clear assert ischannel() == 0 assert ischannel(#) == 1 assert ischannel(&) == 1 assert ischannel(L) == 0 assert ischannel(#foo) == 1 assert ischannel(&foo) == 1 # testing $ischanop() -- cant be tested right now # testing $isdigit() clear assert isdigit() == 0 assert isdigit(1) == 1 assert isdigit(x) == 0 assert isdigit(X) == 0 assert isdigit(^) == 0 # testing $jot() clear assert jot() == [] assert jot(1 3) == [1 2 3] assert jot(3 1) == [3 2 1] assert jot(-10 10) == [-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10] assert jot(-10 10 2) == [-10 -8 -6 -4 -2 0 2 4 6 8 10] assert chr($jot($ascii(a) $ascii(z))) == [abcdefghijklmnopqrstuvwxyz] assert chr($jot($ascii(a) $ascii(z) 2)) == [acegikmoqsuwy] assert chr($jot($ascii(a) $ascii(z))) == reverse($chr($jot($ascii(z) $ascii(a)))) assert jot(10 -10 2) == [10 8 6 4 2 0 -2 -4 -6 -8 -10] assert jot(10 -10 2) == jot(10 -10 -2) /* # testing $key() clear assert key() == [] assert key(*) == [] assert key(#some_channel_that_doesnt_exist) == [] //join #some_channel_that_doesnt_exist //wait //mode #some_channel_that_doesnt_exist +k this_is_a_stupid_key //wait assert key() == [this_is_a_stupid_key] assert key(*) == [this_is_a_stupid_key] assert key(#some_channel_that_doesnt_exist) == [this_is_a_stupid_key] //join #some_stupid_channel_2 //wait //mode #some_stupid_channel_2 +k stupid_key_2 //wait assert key(*) == [stupid_key_2] //channel #some_channel_that_doesnt_exist assert key(*) == [this_is_a_stupid_key] assert key(#some_stupid_channel_2) == [stupid_key_2] //join 0 wait */ # testing $left() clear assert left(one)==[] assert left(1 one)==[o] assert left(2 one)==[on] assert left(3 one)==[one] assert left(4 one)==[one] # testing $leftw() clear assert leftw() == [] assert leftw(0) == [] assert leftw(0 one) == [] assert leftw(-1) == [] assert leftw(-1 one) == [] assert leftw(1) == [] assert leftw(1 one) == [one] assert leftw(1 one two) == [one] assert leftw(2) == [] assert leftw(2 one) == [one] assert leftw(2 one two) == [one two] assert leftw(2 one two three) == [one two] # testing $listen() -- cant be tested right now # testing $match() clear assert match() == [] assert match(one two three) == 0 assert match(two two three) == 1 assert match(three two three) == 2 assert match(*) == 0 assert match(* one) == 1 assert match(%) == 0 assert match(% one) == 1 assert match(?) == 0 assert match(? one) == 0 assert match(? o one) == 1 assert match(? one o) == 2 assert match(?? one on) == 2 assert match(m* marble mantle) == 1 assert match(m*n* marble mantle) == 2 assert match(f*o* marble mantle) == 0 assert match(one* one two) == 1 assert match(*one one two) == 1 assert match(*one* one two) == 1 assert match(** one two) == 1 assert match(*%* one two) == 1 # testing $mid() clear assert mid(-1) == [] assert mid(-1 3) == [] assert mid(-1 3 one) == [] assert mid(0 1 one) == [o] assert mid(1 1 one) == [n] assert mid(2 1 one) == [e] assert mid(3 1 one) == [] assert mid(0 2 one) == [on] assert mid(1 2 one) == [ne] assert mid(2 2 one) == [e] assert mid(3 2 one) == [] assert mid(0 3 one) == [one] assert mid(1 3 one) == [ne] assert mid(2 3 one) == [e] assert mid(3 3 one)==[] assert mid(4 3 one)==[] # testing $midw() clear assert midw() == [] assert midw(0) == [] assert midw(-1) == [] assert midw(1) == [] assert midw(0 0) == [] assert midw(0 1) == [] assert midw(1 1) == [] assert midw(1 -1) == [] assert midw(-1 1) == [] assert midw(0 1 one) == [one] assert midw(0 1 one two) == [one] assert midw(1 1 one two) == [two] assert midw(1 2 one two) == [two] assert midw(1 -1 one two) == [] assert midw(1 0 one two) == [] # testing $mychannels() -- cant be tested right now # testing $myservers() -- cant be tested right now # testing $nametoip() -- cant be tested right now # testing $nochops() -- cant be tested right now # testing $notw() clear assert notw() == [] assert notw(1) == [] assert notw(-1) == [] assert notw(1 one) == [one] assert notw(-1 one) == [one] assert notw(-1 one two) == [one two] assert notw(1 one two) == [one] assert notw(0 one two) == [two] assert notw(3 one two) == [one two] # testing $numonchannel() -- cant be tested right now. # testing $onchannel() -- cant be tested right now. # testing $pattern() clear assert pattern() == [] assert pattern(*) == [] assert pattern(* one two) == [one two] assert pattern(o* one two) == [one] assert pattern(t* one two) == [two] assert pattern(r* one two) == [] assert pattern(t* one two three) == [two three] assert pattern(*e one two three) == [one three] # testing $pid() clear assert pid() != [] assert pid(foo) != [] # testing $push() and $shift() clear @ one = [] assert push() == [] assert push(one) == [] assert push(one one) == [one] assert push(one two) == [one two] assert push(one three) == [one two three] assert push(one four) == [one two three four] clear assert shift() == [] assert shift(one) == [one] assert shift(one) == [two] assert shift(one) == [three] assert shift(one) == [four] assert shift(one) == [] assert one == [] # testing $pop(), $unshift() clear assert unshift() == [] assert unshift(one) == [] assert unshift(one one) == [one] assert unshift(one two) == [two one] assert unshift(one three) == [three two one] assert unshift(one four) == [four three two one] assert one == [four three two one] clear assert pop() == [] assert pop(one) == [one] assert pop(one) == [two] assert pop(one) == [three] assert pop(one) == [four] assert pop(one) == [] # testing $ppid() clear assert ppid() != [] assert ppid(foo) != [] # testing $prefix() assert prefix(12345 12340 1234) == [1234] assert prefix(asdfg asdfx asdf) == [asdf] assert prefix(ASDFG asdfx asdf) == [ASDF] # testing $rand() -- cant be tested right now # testing $remw() clear assert remw() == [] assert remw(one) == [] assert remw(one one) == [] assert remw(one two) == [two] assert remw(one two one three) == [two three] assert remw(one two three one) == [two three] assert remw(\\foo foo \\foo \\foo \\foo) == [foo \\foo \\foo] # remw() tests that failed previously assert remw(1 11 1) == [11] # testing $rename() -- cant be tested right now. # testing $restw() clear assert restw() == [] assert restw(1) == [] assert restw(-1) == [] assert restw(1 one) == [] assert restw(-1 one) == [] assert restw(1 one two) == [two] assert restw(0 one two) == [one two] assert restw(3 one two) == [] # testing $reverse() clear assert reverse() == [] assert reverse(madamimadam) == [madamimadam] assert reverse(foobar) == [raboof] assert reverse(one tiny tubesock) == [kcosebut ynit eno] # testing $revw() clear assert revw() == [] assert revw(1) == [1] assert revw(1 2 3) == [3 2 1] assert revw("1 2" 3) == [3 "1 2"] # testing $rfilter() clear assert rfilter() == [] assert rfilter(foo) == [] assert rfilter(*) == [] assert rfilter(one o* * *e *t*) == [*t*] assert rfilter(two o* * *e *t*) == [o* *e] assert rfilter(foo o* *e *t*) == [o* *e *t*] # testing $right() clear assert right(one) == [] assert right(1 one) == [e] assert right(2 one) == [ne] assert right(3 one) == [one] assert right(4 one) == [one] # testing $rightw() clear assert rightw() == [] assert rightw(0) == [] assert rightw(0 one) == [] assert rightw(-1) == [] assert rightw(-1 one) == [] assert rightw(1) == [] assert rightw(1 one) == [one] assert rightw(1 one two) == [two] assert rightw(2) == [] assert rightw(2 one) == [one] assert rightw(2 one two) == [one two] assert rightw(2 one two three) == [two three] # testing $rindex() clear assert rindex() == [] assert rindex(/ one) == -1 assert rindex(/ /one) == 0 assert rindex(/ o/ne) == 1 assert rindex(/ on/e) == 2 assert rindex(/ one/) == 3 assert rindex(/ /one/) == 4 assert rindex(^/ ///one/) == 5 assert rindex(the one) == 2 assert rindex(the het) == 2 assert rindex(^the the) == -1 assert rindex(^the one) == 1 assert rindex(^the eon) == 2 # testing $rmatch() clear assert rmatch() == [] assert rmatch(one two three) == 0 assert rmatch(two two three) == 1 assert rmatch(three two three) == 2 assert rmatch(one) == 0 assert rmatch(*) == 0 assert rmatch(one *) == 1 assert rmatch(%) == 0 assert rmatch(one %) == 1 assert rmatch(?) == 0 assert rmatch(o ?) == 1 assert rmatch(one ?) == 0 assert rmatch(one ???) == 1 assert rmatch(marble m* n*) == 1 assert rmatch(marble *e *r*b*) == 2 assert rmatch(marble * **) == 1 # testing $rmdir() -- cant be tested right now. # testing $rpattern() clear assert rpattern() == [] assert rpattern(foo) == [] assert rpattern(*) == [] assert rpattern(one o* * *e *t*) == [o* * *e] assert rpattern(two o* * *e *t*) == [* *t*] assert rpattern(foo o* *e *t*) == [] # testing $sar() clear assert sar() == [] assert sar(/) == [] assert sar(//) == [] assert sar(/one/two/foo one bar) == [foo two bar] assert sar(/one/two/foo one bar one) == [foo two bar one] assert sar(g/one/two/foo one bar one) == [foo two bar two] @ boo = [foo one bar] assert sar(r/one/two/boo) == [foo two bar] assert boo == [foo two bar] @ boo = [foo one bar one] assert sar(r/one/two/boo) == [foo two bar one] assert boo == [foo two bar one] @ boo = [foo one bar one] assert sar(rg/one/two/boo) == [foo two bar two] assert boo == [foo two bar two] # testing $splice() clear @ boo = [foo one bar one] assert splice(boo 1 2 booya booya) == [one bar] assert splice(boo 0 3 blah1) == [foo booya booya] assert splice(boo 3 0 blah2) == [] assert splice(boo 4 1 blah3) == [] assert splice(boo -1 3 blah4) == [blah1 one] assert splice(boo 0 0 blah5) == [] assert boo == [blah5 blah4 blah2 blah3] # testing $split() clear assert split() == [] assert split(#) == [] assert split(# one) == [one] assert split(# one##two) == [one two] assert split(# one##two##) == [one two ] # testing $srand() -- cant be tested right now # testing $time() and $stime() clear assert time() != [] assert time(FOO) != [] assert stime() == [] assert stime($time()) != [] # testing $strip() clear assert strip() == [] assert strip(~) == [] assert strip(~ ~) == [] assert strip(~ ~~) == [] assert strip(~ ~ ~) == [ ] assert strip(~ ~one t~o th~ree) == [one to three] assert strip(~ one two three) == [one two three] assert strip(~ ~on~ ~tw= thre~==) == [on tw= thre==] # testing $tdiff() clear assert tdiff() == [] assert tdiff(3663) == [1 hour 1 minute 3 seconds] assert tdiff(60) == [1 minute] assert tdiff(0) == [0 seconds] # testing $tolower() clear assert tolower() == [] assert tolower(one two three) == [one two three] assert tolower(ONE TWO THREE) == [one two three] assert tolower(oNe TwO tHrEe) == [one two three] assert tolower(one @#\$ t\$r!e) == [one @#\$ t\$r!e] # testing $toupper() clear assert toupper() == [] assert toupper(one two three) == [ONE TWO THREE] assert toupper(ONE TWO THREE) == [ONE TWO THREE] assert toupper(oNe TwO tHrEe) == [ONE TWO THREE] assert toupper(one @#\$ t\$r!e) == [ONE @#\$ T\$R!E] # testing $tow() clear assert tow() == [] assert tow(one) == [] assert tow(one two) == [] assert tow(one two three one four five) == [two three one] assert tow(two two three four five two) == [two] assert tow(one one) == [one] assert tow(one three four five) == [] # testing $tr() clear assert tr() == [] assert tr(/abc/def/Mary had a little lamb) == [Mdry hdd d little ldme] assert tr(/abc//Mary had a little lamb) == [Mry hd little lm] assert tr(/abc/d/Mary had a little lamb) == [Mdry hdd d little ldmd] # testing $trunc() #XXX NEEDS TEST # testing $unlink() -- cant be tested right now # testing $userhost() -- cant be tested right now # testing $version() -- cant be tested right now # testing $which() -- cant be tested right now # testing $winnam() -- cant be tested right now # testing $winnum() -- cant be tested right now # testing $word() clear assert word() == [] assert word(1) == [] assert word(0 one) == [one] assert word(1 one) == [] assert word(1 one two) == [two] assert word(2 one two three four five) == [three] # testing $open(), $read() $write() $close() assert (::rfd = open(/dev/zero r)) >= 3 assert (::wfd = open(/dev/zero w)) >= 4 assert writeb($wfd $read($rfd 100000)) == 100000 assert write($wfd $read($rfd 100000)) == 200001 assert close($rfd) == 0 assert close($rfd) == -1 assert close($wfd) == 0 assert close($wfd) == -1 # Testing Karll Arrays. #XXX Incomplete. clear assert delarray(testarray) <= 0 assert setitem(testarray 0 3) == 1 assert setitem(testarray 1 2) == 2 assert setitem(testarray 2 1) == 2 assert setitem(testarray 3 0) == 2 assert numitems(testarray) == 4 assert getitem(testarray 0 1 2 3) == [3 2 1 0] assert igetitem(testarray 0 1 2 3) == [0 1 2 3] assert itemtoindex(testarray 0 1 2 3) == [3 2 1 0] assert indextoitem(testarray 0 1 2 3) == [3 2 1 0] assert delitem(testarray 3) == 0 assert delitem(testarray 3) == -2 assert delitem(testarray 1) == 0 assert delarray(testarray) == 0 assert delarray(testarray) == -1 # Testing internal array consistency. echo fe (function fnexist command cexist set) label exist { @ :last = [] @ :array = [get${label}s] echo Checking $label array consistency. fe ( ${ [$array]() } ) fn { if ( sort($last $fn) != uniq($last $fn) ) { echo ${label}s $last and $fn are not in the correct order. } elsif ( exist && ![$exist]($fn) ) { echo Can't find $label $fn } @ :last = fn } } # Check whether documentation exists. echo if (fexist($getset(help_path))) { fe (function 6* command [1-5]* set 4*/set*) type section { @ :list = [get${type}s]() @ :list = tolower($list) @ :section = [$getset(help_path)/$section] fe list item { @ item = 0 < fsize($globi($section/$item)) ? [] : item } if (#list) { echo Undocumented ${type}s: $list } } } else { echo Skipping documentation test since no documentation was found. } echo echo echo echo ALL TESTS ARE DONE! epic4-2.10.2.orig/regress/scroll0000644000000000000000000000020707213031315013312 0ustar load repeat #set scroll_lines 15 @ var = 0 on ^hook * { repeat 10 echo #*#* $2 ${var++} } repeat 100 hook one two buckle my shoe epic4-2.10.2.orig/acconfig.h0000644000000000000000000001514610767641736012377 0ustar /* * @(#)$Id: acconfig.h,v 1.27 2008/03/18 04:23:58 jnelson Exp $ */ /* * Functions */ /* Define this if you have fpathconf(2) */ #undef HAVE_FPATHCONF /* define this if you have getpass(3) */ #undef HAVE_GETPASS /* define this if you have getpgid(2) */ #undef HAVE_GETPGID /* define this if you have gettimeofday(2) */ #undef HAVE_GETTIMEOFDAY /* define this if you have glob(3) */ #undef HAVE_GLOB /* Define this if you have killpg(2) */ #undef HAVE_KILLPG /* define this if you have memmove(3) */ #undef HAVE_MEMMOVE /* define this if you have scandir(3) */ #undef HAVE_SCANDIR /* define this if you have setenv(3) */ #undef HAVE_SETENV /* define this if you have unsetenv(3) */ #undef HAVE_UNSETENV /* define this if you have setsid(2) */ #undef HAVE_SETSID /* define this if you have snprintf(3) */ #undef HAVE_SNPRINTF /* define this if you have strerror(3) */ #undef HAVE_STRERROR /* define if you have strtoul(3) */ #undef HAVE_STRTOUL /* define this if you have sysconf(3) */ #undef HAVE_SYSCONF /* define this if you have uname(2) */ #undef HAVE_UNAME /* define this if you have vsnprintf(3) */ #undef HAVE_VSNPRINTF /* * Implicit Global variables */ /* define if you have sys_siglist */ #undef HAVE_SYS_SIGLIST /* * Header files */ /* define this if you have fcntl.h */ #undef HAVE_FCNTL_H /* define this if you have memory.h */ #undef HAVE_MEMORY_H /* define this if you have netdb.h */ #undef HAVE_NETDB_H /* define this if you have stdarg.h */ #undef HAVE_STDARG_H /* define this if you have string.h */ #undef HAVE_STRING_H /* define this if you have sys/fcntl.h */ #undef HAVE_SYS_FCNTL_H /* define this if you have sys/file.h */ #undef HAVE_SYS_FILE_H /* define this if you have sys/select.h */ #undef HAVE_SYS_SELECT_H /* define this if you have sys/time.h */ #undef HAVE_SYS_TIME_H /* define this if you have sys/wait.h */ #undef HAVE_SYS_WAIT_H /* * Libraries */ /* define this if -lnls exists */ #undef HAVE_LIB_NLS /* define this if -lnsl exists */ #undef HAVE_LIB_NSL /* define his if -lPW exists */ #undef HAVE_LIB_PW /* define this if you are using -ltermcap */ #undef USING_TERMCAP /* define this if you are using -lxtermcap */ #undef USING_XTERMCAP /* define this if you are using -ltermlib */ #undef USING_TERMLIB /* * System, library, and header semantics */ /* Define this if you have SUN_LEN in */ #undef HAVE_SUN_LEN /* define this if you don't have struct linger */ #undef NO_STRUCT_LINGER /* define if allow sys/time.h with time.h */ #undef TIME_WITH_SYS_TIME /* Define this if your getpgrp is broken posix */ #undef GETPGRP_VOID /* define this if signal's return void */ #undef SIGVOID /* define this if an unsigned long is 32 bits */ #undef UNSIGNED_LONG32 /* define this if an unsigned int is 32 bits */ #undef UNSIGNED_INT32 /* define this if you are unsure what is is 32 bits */ #undef UNKNOWN_32INT /* define this if you are on a svr4 derivative */ #undef SVR4 /* define this to the location of normal unix mail */ #undef UNIX_MAIL /* Define this if you have inet_aton(). */ #undef HAVE_INET_ATON /* Define this if you need to include sys/select.h */ #undef NEED_SYS_SELECT_H /* * SOCKS 4 && 5 support. */ #undef SOCKS #undef USE_SOCKS #undef USE_SOCKS5 #undef connect #undef getsockname #undef bind #undef accept #undef listen #undef select #undef dup #undef dup2 #undef fclose #undef gethostbyname #undef read #undef recv #undef recvfrom #undef rresvport #undef send #undef sendto #undef shutdown #undef write #undef Rconnect #undef Rgetsockname #undef Rgetpeername #undef Rbind #undef Raccept #undef Rlisten #undef Rselect /* * Perl support. */ #undef PERL /* Define this is DIRSIZ takes no argument */ #undef DIRSIZ_TAKES_NO_ARG /* Define this if you have setsid() */ #undef HAVE_SETSID /* Define this if you have a useful FIONREAD */ #undef HAVE_USEFUL_FIONREAD /* Define this if you have tparm(2) */ #undef HAVE_TPARM /* Define this if you have getlogin(3) */ #undef HAVE_GETLOGIN /* Define this if you have terminfo support */ #undef HAVE_TERMINFO /* Define this if you have fchdir() */ #undef HAVE_FCHDIR /* Define this if you have realpath() */ #undef HAVE_REALPATH /* Define this if you have strlcpy() */ #undef HAVE_STRLCPY /* Define this if you have strlcat() */ #undef HAVE_STRLCAT /* Define this if you have stpcpy() */ #undef HAVE_STPCPY /* Define this if you have a function decl for stpcpy() */ #undef STPCPY_DECLARED /* Define this if you have hstrerror, for h_errno use */ #undef HAVE_HSTRERROR /* Define this if you want OPENSSL support */ #undef HAVE_SSL /* Define this if you want OPENSSL2 support */ #undef WANT_SSL2 /* Define this if you have sysctlbyname() */ #undef HAVE_SYSCTLBYNAME /* Define this if you have SO_SNDLOWAT */ #undef HAVE_SO_SNDLOWAT /* Define this if you have struct sockaddr_storage */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define this if your system has SA_LEN in its sockaddrs */ #undef HAVE_SA_LEN /* Define this if you have inet_ntop() */ #undef HAVE_INET_NTOP /* Define this if you have inet_pton() */ #undef HAVE_INET_PTON /* Define this if you have gethostbyname2() */ #undef HAVE_GETHOSTBYNAME2 /* Define this if you don't have siglen_t */ #undef HAVE_SOCKLEN_T /* Define this if you have a getaddrinfo() with missing functionality */ #undef GETADDRINFO_DOES_NOT_DO_AF_UNIX /* Define this if you do not want INET6 support */ #undef DO_NOT_USE_IPV6 /* Define this if you have struct addrinfo */ #undef HAVE_STRUCT_ADDRINFO /* Define this if you have struct sockaddr_in6 */ #undef HAVE_STRUCT_SOCKADDR_IN6 /* Define this if you have getservbyport() */ #undef HAVE_GETSERVBYPORT /* Define this if you have getaddrinfo */ #undef HAVE_GETADDRINFO /* Define this if you have getnameinfo */ #undef HAVE_GETNAMEINFO /* Define this if you have sys_siglist declared */ #undef SYS_SIGLIST_DECLARED /* Define this if you have a broken realpath */ #undef HAVE_BROKEN_REALPATH /* Define this if you have TCL */ #undef TCL /* Define this if you have clock_gettime() */ #undef HAVE_CLOCK_GETTIME /* Define this if you have */ #undef HAVE_INTTYPES_H /* Define this if you have intptr_t */ #undef HAVE_INTPTR_T /* Define this if you have a (long long) */ #undef HAVE_LONG_LONG /* Define this if you have atoll() */ #undef HAVE_ATOLL /* Define this if you have strtoll() */ #undef HAVE_STRTOLL /* Define this if you have atoq() */ #undef HAVE_ATOQ /* Define this if you have finite() */ #undef HAVE_FINITE /* Define this if you have isfinite() */ #undef HAVE_ISFINITE /* Define this if your requires (x/open curses) */ #undef TERM_H_REQUIRES_CURSES_H /* Define this if your can't be used */ #undef DONT_USE_TERM_H epic4-2.10.2.orig/COPYRIGHT0000644000000000000000000000363610527174272011737 0ustar /* * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1994 Jake Khuon. * Copyright © 1993, 2006 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * Some files, (notably, glob.c, and compat.c) may contain some source that * is covered by the original BSD 3-clause license, rather than the above * license. Please refer to those files for more specific information. */ epic4-2.10.2.orig/README0000644000000000000000000001026207213031314011300 0ustar I guess the time has come to write one of these things. Here is some basic information that will help you get started with using EPIC. * THE EPIC HOME PAGE IS: http://www.epicsol.org/ THE EPIC MAIN FTP SITE IS: ftp://ftp.epicsol.org/ THE EPIC IRC CHANNEL IS: #epic on EFNet * The INSTALL file gives detailed instructions how to install EPIC. If you are not able to install epic by using these instructions, you will need specific help from a unix wizard. Please seek out your local unix guy and ask him to help you. Bribes work well; unix wizards love cookies. * If you find a bug in EPIC, please see the BUG_FORM file. Reporting a bug without filling out that file may end up wasting a lot of time and delay your bug being fixed. Please help us fix your bug quickly by providing all of the neccesary information. * The COPYRIGHT file contains the EPIC license. EPIC is licensed under the standard three-clause BSD license except that you are not permitted to remove the "Redistribution is permitted" clause of the license if you distribute binaries. * The KNOWNBUGS file contains a list of all of the "issues" that are currently outstanding with this release of EPIC. Please do not report any of these issues as bugs unless you also provide patches to fix the bug; otherwise it would be a waste of your time. You can also find in this file a list of changes since the last release of EPIC. You can find all of the changes made in EPIC4 at http://www.epicsol.org/CHANGELOG * The UPDATES file contains any amendments to the help files since the last release of EPIC. You can find all the amendments ever made since the very beginning of EPIC at http://www.epicsol.org/UPDATES * You can find a list of things that are coming in the future at http://www.epicsol.org/PROJECTS. Please do not report any of these projects as bugs, as you would only be wasting your time. * You can look in the 'doc' directory for interesting information: * EPIC_ABOUT - Gives a brief description of what the EPIC project is all about and where it has come from and where it is going. It also lists a (semi-current) list of EPIC mirrors that you can use. * EPIC_THANKS - The list of people who are responsible for EPIC. If you are not on this list and you think you should be, send an email to the address found in that file. * EPIC_VERSIONS - The list of all production betas and production releases during the EPIC project's lifetime, including the release date. * IRCII_VERSIONS - The list of all public releases for ircII up through the time that EPIC forked away from ircII. * SILLINESS - The list of all of the "silly" names and the EPIC release that the names belonged to. Ask me on irc if you are curious. * TS4 - A partial list of what TS4 (orabidoo's efnet TS patches) features are supported in this version of EPIC. * color.txt - The original mIRC colors document, with explanations how EPIC's implementation differs from mIRC. * colors - The original documentation that came with fireclown's implementation of mIRC color support (for epic4pre1.043). Some of this information is obsolete, but it is interesting reading. * dccresum.txt - The original mIRC DCC RESUME document. * epic.1 - The manual page for EPIC, sutiable for use with 'man'. * local_vars - The original EPIC document explaning how local variables work. * missing - A list of features present in EPIC3 that have been removed from EPIC4. Please do not report the absence of any of these features as a bug as you would only be wasting your time. * nicknames - The original EPIC document that details how EPIC keeps track of what your nickname is, and how it tries to prevent being confused. * outputhelp - *** VERY IMPORTANT *** This file gives practical tips how to configure EPIC so you can do various things relating to input and output, such as turning on eight bit characters, and getting colors to appear in GNU Screen, and so on. Please read this document before reporting any output problems as EPIC bugs. * server_groups - A prototype document explaining how server groups will probably be implemented in EPIC some day. [End of file] epic4-2.10.2.orig/mkinstalldirs0000755000000000000000000000131607213031314013226 0ustar #!/bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain # @(#)$Id: mkinstalldirs,v 1.1.1.1 2000/12/05 00:11:56 jnelson Exp $ errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || errstatus=$? fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here epic4-2.10.2.orig/test.c0000644000000000000000000002027707213031314011552 0ustar /* $NetBSD: test.c,v 1.15 1995/03/21 07:04:06 cgd Exp $ */ /* * test(1); version 7-like -- author Erik Baalbergen * modified by Eric Gisin to be used as built-in. * modified by Arnold Robbins to add SVR3 compatibility * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). * modified by J.T. Conklin for NetBSD. * * This program is in the Public Domain. */ #ifndef lint static char rcsid[] = "$NetBSD: test.c,v 1.15 1995/03/21 07:04:06 cgd Exp $"; #endif #include #include #include #include #include #include #include #include /* test(1) accepts the following grammar: oexpr ::= aexpr | aexpr "-o" oexpr ; aexpr ::= nexpr | nexpr "-a" aexpr ; nexpr ::= primary | "!" primary primary ::= unary-operator operand | operand binary-operator operand | operand | "(" oexpr ")" ; unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| "-nt"|"-ot"|"-ef"; operand ::= */ enum token { EOI, FILRD, FILWR, FILEX, FILEXIST, FILREG, FILDIR, FILCDEV, FILBDEV, FILFIFO, FILSOCK, FILSYM, FILGZ, FILTT, FILSUID, FILSGID, FILSTCK, FILNT, FILOT, FILEQ, FILUID, FILGID, STREZ, STRNZ, STREQ, STRNE, STRLT, STRGT, INTEQ, INTNE, INTGE, INTGT, INTLE, INTLT, UNOT, BAND, BOR, LPAREN, RPAREN, OPERAND }; enum token_types { UNOP, BINOP, BUNOP, BBINOP, PAREN }; struct t_op { const char *op_text; short op_num, op_type; } const ops [] = { {"-r", FILRD, UNOP}, {"-w", FILWR, UNOP}, {"-x", FILEX, UNOP}, {"-e", FILEXIST,UNOP}, {"-f", FILREG, UNOP}, {"-d", FILDIR, UNOP}, {"-c", FILCDEV,UNOP}, {"-b", FILBDEV,UNOP}, {"-p", FILFIFO,UNOP}, {"-u", FILSUID,UNOP}, {"-g", FILSGID,UNOP}, {"-k", FILSTCK,UNOP}, {"-s", FILGZ, UNOP}, {"-t", FILTT, UNOP}, {"-z", STREZ, UNOP}, {"-n", STRNZ, UNOP}, {"-h", FILSYM, UNOP}, /* for backwards compat */ {"-O", FILUID, UNOP}, {"-G", FILGID, UNOP}, {"-L", FILSYM, UNOP}, {"-S", FILSOCK,UNOP}, {"=", STREQ, BINOP}, {"!=", STRNE, BINOP}, {"<", STRLT, BINOP}, {">", STRGT, BINOP}, {"-eq", INTEQ, BINOP}, {"-ne", INTNE, BINOP}, {"-ge", INTGE, BINOP}, {"-gt", INTGT, BINOP}, {"-le", INTLE, BINOP}, {"-lt", INTLT, BINOP}, {"-nt", FILNT, BINOP}, {"-ot", FILOT, BINOP}, {"-ef", FILEQ, BINOP}, {"!", UNOT, BUNOP}, {"-a", BAND, BBINOP}, {"-o", BOR, BBINOP}, {"(", LPAREN, PAREN}, {")", RPAREN, PAREN}, {0, 0, 0} }; char **t_wp; struct t_op const *t_wp_op; static enum token t_lex(); static int oexpr(); static int aexpr(); static int nexpr(); static int binop(); static int primary(); static int filstat(); static int getn(); static int newerf(); static int olderf(); static int equalf(); static void syntax(); int main(argc, argv) int argc; char **argv; { int res; if (strcmp(argv[0], "[") == 0) { if (strcmp(argv[--argc], "]")) { fprintf(stderr, "missing ]"); exit(2); } argv[argc] = NULL; } /* Implement special cases from POSIX.2, section 4.62.4 */ switch (argc) { case 1: return 1; case 2: return (*argv[1] == '\0'); case 3: if (argv[1][0] == '!' && argv[1][1] == '\0') return !(*argv[2] == '\0'); break; case 4: if (argv[1][0] != '!' || argv[1][1] != '\0') { if (t_lex(argv[2]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[1]; return (binop() == 0); } } break; case 5: if (argv[1][0] == '!' && argv[1][1] == '\0') { if (t_lex(argv[3]), t_wp_op && t_wp_op->op_type == BINOP) { t_wp = &argv[2]; return !(binop() == 0); } } break; } t_wp = &argv[1]; res = !oexpr(t_lex(*t_wp)); if (*t_wp != NULL && *++t_wp != NULL) syntax(*t_wp, "unknown operand"); return res; } static void syntax(op, msg) char *op; char *msg; { if (op && *op) fprintf(stderr, "%s: %s", op, msg); else fprintf(stderr, "%s", msg); exit(2); } static int oexpr(n) enum token n; { int res; res = aexpr(n); if (t_lex(*++t_wp) == BOR) return oexpr(t_lex(*++t_wp)) || res; t_wp--; return res; } static int aexpr(n) enum token n; { int res; res = nexpr(n); if (t_lex(*++t_wp) == BAND) return aexpr(t_lex(*++t_wp)) && res; t_wp--; return res; } static int nexpr(n) enum token n; /* token */ { if (n == UNOT) return !nexpr(t_lex(*++t_wp)); return primary(n); } static int primary(n) enum token n; { int res; if (n == EOI) syntax(NULL, "argument expected"); if (n == LPAREN) { res = oexpr(t_lex(*++t_wp)); if (t_lex(*++t_wp) != RPAREN) syntax(NULL, "closing paren expected"); return res; } if (t_wp_op && t_wp_op->op_type == UNOP) { /* unary expression */ if (*++t_wp == NULL) syntax(t_wp_op->op_text, "argument expected"); switch (n) { case STREZ: return strlen(*t_wp) == 0; case STRNZ: return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); default: return filstat(*t_wp, n); } } if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { return binop(); } return strlen(*t_wp) > 0; } static int binop() { register const char *opnd1, *opnd2; struct t_op const *op; opnd1 = *t_wp; (void) t_lex(*++t_wp); op = t_wp_op; if ((opnd2 = *++t_wp) == (char *)0) syntax(op->op_text, "argument expected"); switch (op->op_num) { case STREQ: return strcmp(opnd1, opnd2) == 0; case STRNE: return strcmp(opnd1, opnd2) != 0; case STRLT: return strcmp(opnd1, opnd2) < 0; case STRGT: return strcmp(opnd1, opnd2) > 0; case INTEQ: return getn(opnd1) == getn(opnd2); case INTNE: return getn(opnd1) != getn(opnd2); case INTGE: return getn(opnd1) >= getn(opnd2); case INTGT: return getn(opnd1) > getn(opnd2); case INTLE: return getn(opnd1) <= getn(opnd2); case INTLT: return getn(opnd1) < getn(opnd2); case FILNT: return newerf (opnd1, opnd2); case FILOT: return olderf (opnd1, opnd2); case FILEQ: return equalf (opnd1, opnd2); } /* NOTREACHED */ } static int filstat(nm, mode) char *nm; enum token mode; { struct stat s; int i; if (mode == FILSYM) { #ifdef S_IFLNK if (lstat(nm, &s) == 0) { i = S_IFLNK; goto filetype; } #endif return 0; } if (stat(nm, &s) != 0) return 0; switch (mode) { case FILRD: return access(nm, R_OK) == 0; case FILWR: return access(nm, W_OK) == 0; case FILEX: return access(nm, X_OK) == 0; case FILEXIST: return access(nm, F_OK) == 0; case FILREG: i = S_IFREG; goto filetype; case FILDIR: i = S_IFDIR; goto filetype; case FILCDEV: i = S_IFCHR; goto filetype; case FILBDEV: i = S_IFBLK; goto filetype; case FILFIFO: #ifdef S_IFIFO i = S_IFIFO; goto filetype; #else return 0; #endif case FILSOCK: #ifdef S_IFSOCK i = S_IFSOCK; goto filetype; #else return 0; #endif case FILSUID: i = S_ISUID; goto filebit; case FILSGID: i = S_ISGID; goto filebit; case FILSTCK: i = S_ISVTX; goto filebit; case FILGZ: return s.st_size > 0L; case FILUID: return s.st_uid == geteuid(); case FILGID: return s.st_gid == getegid(); default: return 1; } filetype: return ((s.st_mode & S_IFMT) == i); filebit: return ((s.st_mode & i) != 0); } static enum token t_lex(s) register char *s; { register struct t_op const *op = ops; if (s == 0) { t_wp_op = (struct t_op *)0; return EOI; } while (op->op_text) { if (strcmp(s, op->op_text) == 0) { t_wp_op = op; return op->op_num; } op++; } t_wp_op = (struct t_op *)0; return OPERAND; } /* atoi with error detection */ static int getn(s) char *s; { char *p; long r; errno = 0; r = strtol(s, &p, 10); if (errno != 0) { fprintf(stderr, "%s: out of range", s); exit(2); } while (isspace(*p)) p++; if (*p) { fprintf(stderr, "%s: bad number", s); exit(2); } return (int) r; } static int newerf (f1, f2) char *f1, *f2; { struct stat b1, b2; return (stat (f1, &b1) == 0 && stat (f2, &b2) == 0 && b1.st_mtime > b2.st_mtime); } static int olderf (f1, f2) char *f1, *f2; { struct stat b1, b2; return (stat (f1, &b1) == 0 && stat (f2, &b2) == 0 && b1.st_mtime < b2.st_mtime); } static int equalf (f1, f2) char *f1, *f2; { struct stat b1, b2; return (stat (f1, &b1) == 0 && stat (f2, &b2) == 0 && b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); } epic4-2.10.2.orig/configure0000755000000000000000000045442510770363041012353 0ustar #! /bin/sh # From configure.in Revision: 1.45 # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-ssl[=PATH] Include SSL support (DIR is OpenSSL's install dir)." ac_help="$ac_help --with-termcap Forcibly refuse to use terminfo/ncurses " ac_help="$ac_help --with-ipv6 Include IPv6 support" ac_help="$ac_help --with-socks[=PATH] Compile with SOCKS firewall traversal support." ac_help="$ac_help --with-socks5[=PATH] Compile with SOCKS5 firewall traversal support." ac_help="$ac_help --with-perl[=PATH] Compile with perl support." ac_help="$ac_help --with-tcl[=PATH] Compile with tcl support." ac_help="$ac_help --with-bc[=PATH_TO_GCC] You have bounds checking gcc and want to use it." ac_help="$ac_help --with-warns You wish to use FreeBSD WARNS-like compiler warnings." # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= sitefile= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --site-file=FILE use FILE as the site file --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -site-file | --site-file | --site-fil | --site-fi | --site-f) ac_prev=sitefile ;; -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) sitefile="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=source/irc.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$sitefile"; then if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi else CONFIG_SITE="$sitefile" fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi VERSION=`sed -n -e 's/";$//' -e '/const char irc_version.. = "/s///p' -e '/const char irc_version/q' < $srcdir/source/irc.c` echo this is ircii version $VERSION echo # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:569: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:599: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:650: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:682: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 693 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:724: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:729: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:757: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O" else CFLAGS= fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:789: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:810: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:844: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 echo "configure:869: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then echo "$ac_t""yes" 1>&6 ISC=yes # If later tests want to check for ISC. cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF if test "$GCC" = yes; then CC="$CC -posix" else CC="$CC -Xp" fi else echo "$ac_t""no" 1>&6 ISC= fi echo $ac_n "checking for AIX""... $ac_c" 1>&6 echo "configure:890: checking for AIX" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF #define _ALL_SOURCE 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* unamer=`uname -r 2> /dev/null` unames=`uname -s 2> /dev/null` echo $ac_n "checking for qnx""... $ac_c" 1>&6 echo "configure:923: checking for qnx" >&5 case "$unames" in QNX*) echo "$ac_t""yes" 1>&6 LDFLAGS=-N64k CFLAGS="-w4 -O -g -fi=unix.h" ;; *) echo "$ac_t""no" 1>&6 esac if test -d /usr/ccs/lib; then LIBS="-L/usr/ccs/lib $LIBS" fi if test -z "$libsocket"; then echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 echo "configure:943: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsocket" else echo "$ac_t""no" 1>&6 fi fi # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then withval="$with_ssl" if test -z "$withval"; then with_ssl="yes" fi fi echo $ac_n "checking whether to include SSL support""... $ac_c" 1>&6 echo "configure:996: checking whether to include SSL support" >&5 if test "x$with_ssl" = "xno"; then echo "$ac_t""no" 1>&6 else saved_LIBS="$LIBS" saved_CFLAGS="$CFLAGS" # First just try to see if it exists in the default location LIBS="$saved_LIBS -lssl -lcrypto" CFLAGS="$saved_CFLAGS" cat > conftest.$ac_ext < int main() { SSL_accept(NULL); ; return 0; } EOF if { (eval echo configure:1014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_ssl="yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* # Otherwise, go hunting for it. if test -z "$have_ssl" ; then for ssldir in "$with_ssl" /usr/local/ssl /usr/local/openssl; do if test -n "$have_ssl"; then break; fi if test -z "$ssldir"; then continue; fi if test -f "$ssldir/include/openssl/ssl.h" && test -f "$ssldir/lib/libssl.a"; then CFLAGS="$saved_CFLAGS -I$ssldir/include" LIBS="$saved_LIBS -L$ssldir/lib -lssl -lcrypto" cat > conftest.$ac_ext < int main() { SSL_accept(NULL); ; return 0; } EOF if { (eval echo configure:1047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_ssl="yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* fi done fi # If we found it somewhere, great! Otherwise, revert. if test -n "$have_ssl"; then cat >> confdefs.h <<\EOF #define HAVE_SSL 1 EOF echo "$ac_t""yes" 1>&6 else LIBS="$saved_LIBS" CFLAGS="$saved_CFLAGS" echo "$ac_t""no" 1>&6 if test "x$with_ssl" != "x"; then { echo "configure: error: You requested SSL support, but OpenSSL was not found. Please supply a pathname to OpenSSL" 1>&2; exit 1; } fi fi fi if test -z "$libinet"; then echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:1078: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 libnsl=1; LIBS="$LIBS -linet -lnsl_s" else echo "$ac_t""no" 1>&6 fi fi if test -z "$libnsl"; then echo $ac_n "checking for gethostname in -lnsl""... $ac_c" 1>&6 echo "configure:1121: checking for gethostname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lnsl" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for getpwnam in -lsun""... $ac_c" 1>&6 echo "configure:1163: checking for getpwnam in -lsun" >&5 ac_lib_var=`echo sun'_'getpwnam | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsun $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsun" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for inet_addr in -ldgc""... $ac_c" 1>&6 echo "configure:1203: checking for inet_addr in -ldgc" >&5 ac_lib_var=`echo dgc'_'inet_addr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldgc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -ldgc" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6 echo "configure:1243: checking for gethostbyname in -lresolv" >&5 ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lresolv" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 echo "configure:1283: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lcrypt" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for pow in -lm""... $ac_c" 1>&6 echo "configure:1323: checking for pow in -lm" >&5 ac_lib_var=`echo m'_'pow | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lm" else echo "$ac_t""no" 1>&6 fi termcap=0; echo $ac_n "checking whether you want to use termcap""... $ac_c" 1>&6 echo "configure:1365: checking whether you want to use termcap" >&5 # Check whether --with-termcap or --without-termcap was given. if test "${with_termcap+set}" = set; then withval="$with_termcap" echo "$ac_t""yes" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 echo "configure:1371: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 termcap=1;LIBS="-ltermcap $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6 echo "configure:1409: checking for tgetent in -ltermlib" >&5 ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermlib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 termcap=1;LIBS="-ltermlib $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6 echo "configure:1447: checking for tgetent in -lcurses" >&5 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 termcap=1;LIBS="-lcurses $LIBS" else echo "$ac_t""no" 1>&6 echo "configure: warning: I cant find tgetent. Youll have to help me." 1>&2 fi fi fi else echo "$ac_t""no" 1>&6 echo $ac_n "checking for setupterm in -lncurses""... $ac_c" 1>&6 echo "configure:1494: checking for setupterm in -lncurses" >&5 ac_lib_var=`echo ncurses'_'setupterm | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lncurses $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for setupterm in -ltinfo""... $ac_c" 1>&6 echo "configure:1532: checking for setupterm in -ltinfo" >&5 ac_lib_var=`echo tinfo'_'setupterm | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltinfo $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-ltinfo $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for setupterm in -lcurses""... $ac_c" 1>&6 echo "configure:1570: checking for setupterm in -lcurses" >&5 ac_lib_var=`echo curses'_'setupterm | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lcurses $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6 echo "configure:1608: checking for tgetent in -lcurses" >&5 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lcurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-lcurses $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermlib""... $ac_c" 1>&6 echo "configure:1646: checking for tgetent in -ltermlib" >&5 ac_lib_var=`echo termlib'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermlib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-ltermlib $LIBS" else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 echo "configure:1684: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="-ltermcap $LIBS" else echo "$ac_t""no" 1>&6 echo "configure: warning: I cant find tgetent. Youll have to help me." 1>&2 fi fi fi fi fi fi fi for ac_hdr in fcntl.h netdb.h regex.h sys/fcntl.h sys/file.h sys/select.h sys/syslimits.h sys/un.h sys/time.h termcap.h sys/filio.h sys/sysctl.h inttypes.h stdint.h term.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1742: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1752: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test $termcap -eq 0 ; then echo $ac_n "checking for setupterm""... $ac_c" 1>&6 echo "configure:1781: checking for setupterm" >&5 if eval "test \"`echo '$''{'ac_cv_func_setupterm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setupterm(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setupterm) || defined (__stub___setupterm) choke me #else setupterm(); #endif ; return 0; } EOF if { (eval echo configure:1809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_setupterm=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_setupterm=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'setupterm`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_TERMINFO 1 EOF else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for uname""... $ac_c" 1>&6 echo "configure:1833: checking for uname" >&5 if eval "test \"`echo '$''{'ac_cv_func_uname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char uname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_uname) || defined (__stub___uname) choke me #else uname(); #endif ; return 0; } EOF if { (eval echo configure:1861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_uname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_uname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'uname`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_UNAME 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for setenv""... $ac_c" 1>&6 echo "configure:1884: checking for setenv" >&5 if eval "test \"`echo '$''{'ac_cv_func_setenv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setenv(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setenv) || defined (__stub___setenv) choke me #else setenv(); #endif ; return 0; } EOF if { (eval echo configure:1912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_setenv=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_setenv=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'setenv`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SETENV 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for unsetenv""... $ac_c" 1>&6 echo "configure:1935: checking for unsetenv" >&5 if eval "test \"`echo '$''{'ac_cv_func_unsetenv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char unsetenv(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_unsetenv) || defined (__stub___unsetenv) choke me #else unsetenv(); #endif ; return 0; } EOF if { (eval echo configure:1963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_unsetenv=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_unsetenv=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'unsetenv`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_UNSETENV 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for killpg""... $ac_c" 1>&6 echo "configure:1986: checking for killpg" >&5 if eval "test \"`echo '$''{'ac_cv_func_killpg'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char killpg(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_killpg) || defined (__stub___killpg) choke me #else killpg(); #endif ; return 0; } EOF if { (eval echo configure:2014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_killpg=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_killpg=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'killpg`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_KILLPG 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for gettimeofday""... $ac_c" 1>&6 echo "configure:2037: checking for gettimeofday" >&5 if eval "test \"`echo '$''{'ac_cv_func_gettimeofday'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gettimeofday(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gettimeofday) || defined (__stub___gettimeofday) choke me #else gettimeofday(); #endif ; return 0; } EOF if { (eval echo configure:2065: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gettimeofday=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gettimeofday=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gettimeofday`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETTIMEOFDAY 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getpass""... $ac_c" 1>&6 echo "configure:2088: checking for getpass" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpass'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpass(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpass) || defined (__stub___getpass) choke me #else getpass(); #endif ; return 0; } EOF if { (eval echo configure:2116: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpass=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpass=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpass`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETPASS 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strtoul""... $ac_c" 1>&6 echo "configure:2139: checking for strtoul" >&5 if eval "test \"`echo '$''{'ac_cv_func_strtoul'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strtoul(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strtoul) || defined (__stub___strtoul) choke me #else strtoul(); #endif ; return 0; } EOF if { (eval echo configure:2167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strtoul=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strtoul=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strtoul`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRTOUL 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6 echo "configure:2190: checking for vsnprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vsnprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vsnprintf) || defined (__stub___vsnprintf) choke me #else vsnprintf(); #endif ; return 0; } EOF if { (eval echo configure:2218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vsnprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vsnprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vsnprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VSNPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for snprintf""... $ac_c" 1>&6 echo "configure:2241: checking for snprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char snprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_snprintf) || defined (__stub___snprintf) choke me #else snprintf(); #endif ; return 0; } EOF if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_snprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_snprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'snprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SNPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sysconf""... $ac_c" 1>&6 echo "configure:2292: checking for sysconf" >&5 if eval "test \"`echo '$''{'ac_cv_func_sysconf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sysconf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sysconf) || defined (__stub___sysconf) choke me #else sysconf(); #endif ; return 0; } EOF if { (eval echo configure:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sysconf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sysconf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sysconf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSCONF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for fpathconf""... $ac_c" 1>&6 echo "configure:2343: checking for fpathconf" >&5 if eval "test \"`echo '$''{'ac_cv_func_fpathconf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char fpathconf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_fpathconf) || defined (__stub___fpathconf) choke me #else fpathconf(); #endif ; return 0; } EOF if { (eval echo configure:2371: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_fpathconf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_fpathconf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'fpathconf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_FPATHCONF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strerror""... $ac_c" 1>&6 echo "configure:2394: checking for strerror" >&5 if eval "test \"`echo '$''{'ac_cv_func_strerror'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strerror(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strerror) || defined (__stub___strerror) choke me #else strerror(); #endif ; return 0; } EOF if { (eval echo configure:2422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strerror=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strerror=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strerror`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRERROR 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for memmove""... $ac_c" 1>&6 echo "configure:2445: checking for memmove" >&5 if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char memmove(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_memmove) || defined (__stub___memmove) choke me #else memmove(); #endif ; return 0; } EOF if { (eval echo configure:2473: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_memmove=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_memmove=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_MEMMOVE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for setsid""... $ac_c" 1>&6 echo "configure:2496: checking for setsid" >&5 if eval "test \"`echo '$''{'ac_cv_func_setsid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char setsid(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_setsid) || defined (__stub___setsid) choke me #else setsid(); #endif ; return 0; } EOF if { (eval echo configure:2524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_setsid=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_setsid=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'setsid`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SETSID 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getlogin""... $ac_c" 1>&6 echo "configure:2547: checking for getlogin" >&5 if eval "test \"`echo '$''{'ac_cv_func_getlogin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getlogin(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getlogin) || defined (__stub___getlogin) choke me #else getlogin(); #endif ; return 0; } EOF if { (eval echo configure:2575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getlogin=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getlogin=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getlogin`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETLOGIN 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for fchdir""... $ac_c" 1>&6 echo "configure:2598: checking for fchdir" >&5 if eval "test \"`echo '$''{'ac_cv_func_fchdir'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char fchdir(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_fchdir) || defined (__stub___fchdir) choke me #else fchdir(); #endif ; return 0; } EOF if { (eval echo configure:2626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_fchdir=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_fchdir=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'fchdir`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_FCHDIR 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for realpath""... $ac_c" 1>&6 echo "configure:2649: checking for realpath" >&5 if eval "test \"`echo '$''{'ac_cv_func_realpath'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char realpath(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_realpath) || defined (__stub___realpath) choke me #else realpath(); #endif ; return 0; } EOF if { (eval echo configure:2677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_realpath=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_realpath=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'realpath`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_REALPATH 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for hstrerror""... $ac_c" 1>&6 echo "configure:2700: checking for hstrerror" >&5 if eval "test \"`echo '$''{'ac_cv_func_hstrerror'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char hstrerror(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_hstrerror) || defined (__stub___hstrerror) choke me #else hstrerror(); #endif ; return 0; } EOF if { (eval echo configure:2728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_hstrerror=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_hstrerror=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'hstrerror`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_HSTRERROR 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strlcpy""... $ac_c" 1>&6 echo "configure:2751: checking for strlcpy" >&5 if eval "test \"`echo '$''{'ac_cv_func_strlcpy'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strlcpy(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strlcpy) || defined (__stub___strlcpy) choke me #else strlcpy(); #endif ; return 0; } EOF if { (eval echo configure:2779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strlcpy=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strlcpy=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strlcpy`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRLCPY 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strlcat""... $ac_c" 1>&6 echo "configure:2802: checking for strlcat" >&5 if eval "test \"`echo '$''{'ac_cv_func_strlcat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strlcat(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strlcat) || defined (__stub___strlcat) choke me #else strlcat(); #endif ; return 0; } EOF if { (eval echo configure:2830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strlcat=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strlcat=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strlcat`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRLCAT 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sysctlbyname""... $ac_c" 1>&6 echo "configure:2853: checking for sysctlbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_sysctlbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sysctlbyname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sysctlbyname) || defined (__stub___sysctlbyname) choke me #else sysctlbyname(); #endif ; return 0; } EOF if { (eval echo configure:2881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sysctlbyname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sysctlbyname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sysctlbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSCTLBYNAME 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getservbyport""... $ac_c" 1>&6 echo "configure:2904: checking for getservbyport" >&5 if eval "test \"`echo '$''{'ac_cv_func_getservbyport'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getservbyport(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getservbyport) || defined (__stub___getservbyport) choke me #else getservbyport(); #endif ; return 0; } EOF if { (eval echo configure:2932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getservbyport=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getservbyport=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getservbyport`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETSERVBYPORT 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getaddrinfo""... $ac_c" 1>&6 echo "configure:2955: checking for getaddrinfo" >&5 if eval "test \"`echo '$''{'ac_cv_func_getaddrinfo'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getaddrinfo(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getaddrinfo) || defined (__stub___getaddrinfo) choke me #else getaddrinfo(); #endif ; return 0; } EOF if { (eval echo configure:2983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getaddrinfo=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getaddrinfo=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getaddrinfo`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETADDRINFO 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getnameinfo""... $ac_c" 1>&6 echo "configure:3006: checking for getnameinfo" >&5 if eval "test \"`echo '$''{'ac_cv_func_getnameinfo'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getnameinfo(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getnameinfo) || defined (__stub___getnameinfo) choke me #else getnameinfo(); #endif ; return 0; } EOF if { (eval echo configure:3034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getnameinfo=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getnameinfo=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getnameinfo`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETNAMEINFO 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for clock_gettime""... $ac_c" 1>&6 echo "configure:3057: checking for clock_gettime" >&5 if eval "test \"`echo '$''{'ac_cv_func_clock_gettime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char clock_gettime(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_clock_gettime) || defined (__stub___clock_gettime) choke me #else clock_gettime(); #endif ; return 0; } EOF if { (eval echo configure:3085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_clock_gettime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_clock_gettime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'clock_gettime`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_CLOCK_GETTIME 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for atoll""... $ac_c" 1>&6 echo "configure:3108: checking for atoll" >&5 if eval "test \"`echo '$''{'ac_cv_func_atoll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char atoll(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_atoll) || defined (__stub___atoll) choke me #else atoll(); #endif ; return 0; } EOF if { (eval echo configure:3136: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_atoll=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_atoll=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'atoll`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_ATOLL 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strtoll""... $ac_c" 1>&6 echo "configure:3159: checking for strtoll" >&5 if eval "test \"`echo '$''{'ac_cv_func_strtoll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strtoll(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strtoll) || defined (__stub___strtoll) choke me #else strtoll(); #endif ; return 0; } EOF if { (eval echo configure:3187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strtoll=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strtoll=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strtoll`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRTOLL 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for atoq""... $ac_c" 1>&6 echo "configure:3210: checking for atoq" >&5 if eval "test \"`echo '$''{'ac_cv_func_atoq'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char atoq(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_atoq) || defined (__stub___atoq) choke me #else atoq(); #endif ; return 0; } EOF if { (eval echo configure:3238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_atoq=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_atoq=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'atoq`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_ATOQ 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for finite""... $ac_c" 1>&6 echo "configure:3261: checking for finite" >&5 if eval "test \"`echo '$''{'ac_cv_func_finite'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char finite(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_finite) || defined (__stub___finite) choke me #else finite(); #endif ; return 0; } EOF if { (eval echo configure:3289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_finite=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_finite=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'finite`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_FINITE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for isfinite""... $ac_c" 1>&6 echo "configure:3312: checking for isfinite" >&5 if eval "test \"`echo '$''{'ac_cv_func_isfinite'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char isfinite(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_isfinite) || defined (__stub___isfinite) choke me #else isfinite(); #endif ; return 0; } EOF if { (eval echo configure:3340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_isfinite=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_isfinite=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'isfinite`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_ISFINITE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for tparm""... $ac_c" 1>&6 echo "configure:3363: checking for tparm" >&5 if eval "test \"`echo '$''{'ac_cv_func_tparm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char tparm(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_tparm) || defined (__stub___tparm) choke me #else tparm(); #endif ; return 0; } EOF if { (eval echo configure:3391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_tparm=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tparm=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tparm`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_TPARM 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether term.h works by itself""... $ac_c" 1>&6 echo "configure:3415: checking whether term.h works by itself" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < main () { exit(0); } EOF if { (eval echo configure:3431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 echo $ac_n "checking whether term.h requires termio.h and curses.h""... $ac_c" 1>&6 echo "configure:3440: checking whether term.h requires termio.h and curses.h" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include #include main () { exit(0); } EOF if { (eval echo configure:3458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define TERM_H_REQUIRES_CURSES_H 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define DONT_USE_TERM_H 1 EOF fi rm -fr conftest* fi fi rm -fr conftest* fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:3484: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3497: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:3564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:3588: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:3602: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 echo "configure:3627: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> int main() { DIR *dirp = 0; ; return 0; } EOF if { (eval echo configure:3640: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 echo "configure:3665: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -ldir" else echo "$ac_t""no" 1>&6 fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 echo "configure:3706: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lx" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:3748: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:3770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:3789: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_mode_t=yes else rm -rf conftest* ac_cv_type_mode_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_mode_t" 1>&6 if test $ac_cv_type_mode_t = no; then cat >> confdefs.h <<\EOF #define mode_t int EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo "configure:3822: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else rm -rf conftest* ac_cv_type_pid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_pid_t" 1>&6 if test $ac_cv_type_pid_t = no; then cat >> confdefs.h <<\EOF #define pid_t int EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:3855: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 echo "configure:3888: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uid_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uid_t=yes else rm -rf conftest* ac_cv_type_uid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uid_t" 1>&6 if test $ac_cv_type_uid_t = no; then cat >> confdefs.h <<\EOF #define uid_t int EOF cat >> confdefs.h <<\EOF #define gid_t int EOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo "configure:3924: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:3936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_alloca_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 if test $ac_cv_header_alloca_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA_H 1 EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo "configure:3957: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main() { char *p = (char *) alloca(1); ; return 0; } EOF if { (eval echo configure:3990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_alloca_works=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 if test $ac_cv_func_alloca_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA 1 EOF fi if test $ac_cv_func_alloca_works = no; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.${ac_objext} cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo "configure:4022: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "webecray" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_cray=yes else rm -rf conftest* ac_cv_os_cray=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_os_cray" 1>&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4052: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:4080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo "configure:4107: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF if { (eval echo configure:4134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_stack_direction=-1 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 cat >> confdefs.h <&6 echo "configure:4158: checking for intptr_t in inttypes.h or stdint.h" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "intptr_t" >/dev/null 2>&1; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_INTPTR_T 1 EOF have_intptr_t=yes fi rm -f conftest* cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "intptr_t" >/dev/null 2>&1; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_INTPTR_T 1 EOF have_intptr_t=yes fi rm -f conftest* if test "x$have_intptr_t" = "x"; then echo "$ac_t""no" 1>&6 else echo "$ac_t""yes" 1>&6 fi echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 echo "configure:4198: checking for socklen_t" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "socklen_t" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SOCKLEN_T 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking whether sys/types.h defines fd_set""... $ac_c" 1>&6 echo "configure:4220: checking whether sys/types.h defines fd_set" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "fd_set" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else rm -rf conftest* echo "$ac_t""no" 1>&6 echo $ac_n "checking whether sys/select.h defines fd_set""... $ac_c" 1>&6 echo "configure:4234: checking whether sys/select.h defines fd_set" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "fd_set" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define NEED_SYS_SELECT_H 1 EOF else rm -rf conftest* echo "$ac_t""no. ugh." 1>&6 fi rm -f conftest* fi rm -f conftest* echo $ac_n "checking for struct linger""... $ac_c" 1>&6 echo "configure:4261: checking for struct linger" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct( | )*linger" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else rm -rf conftest* cat >> confdefs.h <<\EOF #define NO_STRUCT_LINGER 1 EOF echo "$ac_t""no. ugh." 1>&6 fi rm -f conftest* echo $ac_n "checking for getpgid""... $ac_c" 1>&6 echo "configure:4286: checking for getpgid" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpgid'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpgid(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpgid) || defined (__stub___getpgid) choke me #else getpgid(); #endif ; return 0; } EOF if { (eval echo configure:4314: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpgid=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpgid=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpgid`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_GETPGID 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for getpgrp""... $ac_c" 1>&6 echo "configure:4337: checking for getpgrp" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpgrp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpgrp(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpgrp) || defined (__stub___getpgrp) choke me #else getpgrp(); #endif ; return 0; } EOF if { (eval echo configure:4365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpgrp=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpgrp=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpgrp`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6 echo "configure:4380: checking whether getpgrp takes no argument" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpgrp_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < #include int pid; int pg1, pg2, pg3, pg4; int ng, np, s, child; main() { pid = getpid(); pg1 = getpgrp(0); pg2 = getpgrp(); pg3 = getpgrp(pid); pg4 = getpgrp(1); /* * If all of these values are the same, it's pretty sure that * we're on a system that ignores getpgrp's first argument. */ if (pg2 == pg4 && pg1 == pg3 && pg2 == pg3) exit(0); child = fork(); if (child < 0) exit(1); else if (child == 0) { np = getpid(); /* * If this is Sys V, this will not work; pgrp will be * set to np because setpgrp just changes a pgrp to be * the same as the pid. */ setpgrp(np, pg1); ng = getpgrp(0); /* Same result for Sys V and BSD */ if (ng == pg1) { exit(1); } else { exit(0); } } else { wait(&s); exit(s>>8); } } EOF if { (eval echo configure:4443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_getpgrp_void=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_getpgrp_void=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_getpgrp_void" 1>&6 if test $ac_cv_func_getpgrp_void = yes; then cat >> confdefs.h <<\EOF #define GETPGRP_VOID 1 EOF fi else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for useful SO_SNDLOWAT""... $ac_c" 1>&6 echo "configure:4472: checking for useful SO_SNDLOWAT" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include main () { #ifndef SO_SNDLOWAT exit(1); #else int d = socket(AF_INET, SOCK_STREAM, 0); int size = 256; if (setsockopt(d, SOL_SOCKET, SO_SNDLOWAT, &size, sizeof(size)) < 0) exit(1); exit (0); #endif } EOF if { (eval echo configure:4496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SO_SNDLOWAT 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking for useful realpath""... $ac_c" 1>&6 echo "configure:4514: checking for useful realpath" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include main () { char resolved_path[MAXPATHLEN]; if (realpath("/etc/filethatdoesnotexist", resolved_path) == NULL) exit(1); exit(0); } EOF if { (eval echo configure:4534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_BROKEN_REALPATH 1 EOF fi rm -fr conftest* fi echo $ac_n "checking for sys_siglist declaration""... $ac_c" 1>&6 echo "configure:4553: checking for sys_siglist declaration" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include #include #include main() { char *s = sys_siglist[0]; exit(0); } EOF if { (eval echo configure:4572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 sys_siglist="1" cat >> confdefs.h <<\EOF #define SYS_SIGLIST_DECLARED 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi if test x$sys_siglist != x1 then echo "generating a list of signal names..." set X `cat /usr/include/signal.h /usr/include/sys/signal.h /usr/include/linux/signal.h 2>&1 | sed 's/^#[ ]*/#/' | awk ' $1 ~ /^#define$/ && $2 ~ /^SIG[A-Z0-9]*$/ && $3 ~ /^[1-9][0-9]*$/ { sig[$3] = substr($2,4,20) if (max < $3 && $3 < 60) { max = $3 } } END { for (i=1; i<=max; i++) { if (sig[i] == "") printf "%d", i else printf "%s", sig[i] if (i < max) printf " " } printf "\n" } '` shift case $# in 0) if test -f /bin/csh; then set X `/bin/csh -cf 'kill -l'` shift case $* in 0) set HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM ;; esac fi ;; esac sig_name="ZERO $*" if test -f sig.inc; then /bin/rm -f sig.inc fi echo $sig_name | sed -e 's/$/"};/' -e 's/ /", "/g' -e 's/^/static char *sys_siglist[] = { "/' >> sig.inc fi echo $ac_n "checking size of long long""... $ac_c" 1>&6 echo "configure:4637: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_long_long=0 else cat > conftest.$ac_ext < main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(long long)); exit(0); } EOF if { (eval echo configure:4656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_long_long=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6 cat >> confdefs.h <> confdefs.h <<\EOF #define HAVE_LONG_LONG 1 EOF fi echo $ac_n "checking size of unsigned int""... $ac_c" 1>&6 echo "configure:4684: checking size of unsigned int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_unsigned_int=4 else cat > conftest.$ac_ext < main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(unsigned int)); exit(0); } EOF if { (eval echo configure:4703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_unsigned_int=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_unsigned_int=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_unsigned_int" 1>&6 cat >> confdefs.h <> confdefs.h <<\EOF #define UNSIGNED_INT32 1 EOF else echo $ac_n "checking size of unsigned long""... $ac_c" 1>&6 echo "configure:4729: checking size of unsigned long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_sizeof_unsigned_long=4 else cat > conftest.$ac_ext < main() { FILE *f=fopen("conftestval", "w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(unsigned long)); exit(0); } EOF if { (eval echo configure:4748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_unsigned_long=`cat conftestval` else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_sizeof_unsigned_long=0 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_sizeof_unsigned_long" 1>&6 cat >> confdefs.h <> confdefs.h <<\EOF #define UNSIGNED_LONG32 1 EOF else cat >> confdefs.h <<\EOF #define UNKNOWN_32INT 1 EOF fi fi echo $ac_n "checking to see if your struct sockaddr includes a length field""... $ac_c" 1>&6 echo "configure:4782: checking to see if your struct sockaddr includes a length field" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include main() { struct sockaddr sa; sa.sa_len = 0; exit(0); } EOF if { (eval echo configure:4800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_SA_LEN 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking whether to support ipv6""... $ac_c" 1>&6 echo "configure:4819: checking whether to support ipv6" >&5 # Check whether --with-ipv6 or --without-ipv6 was given. if test "${with_ipv6+set}" = set; then withval="$with_ipv6" if test "x$withval" = "xno" ; then echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define DO_NOT_USE_IPV6 1 EOF else echo "$ac_t""yes" 1>&6 fi else echo "$ac_t""yes" 1>&6 fi echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 echo "configure:4840: checking for struct sockaddr_storage" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct( | )*sockaddr_storage" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for struct sockaddr_in6""... $ac_c" 1>&6 echo "configure:4862: checking for struct sockaddr_in6" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct( | )*sockaddr_in6" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRUCT_SOCKADDR_IN6 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for struct addrinfo""... $ac_c" 1>&6 echo "configure:4884: checking for struct addrinfo" >&5 cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct( | )*addrinfo" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRUCT_ADDRINFO 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking to see if your getaddrinfo supports AF_UNIX""... $ac_c" 1>&6 echo "configure:4907: checking to see if your getaddrinfo supports AF_UNIX" >&5 if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #include #include #include #include main() { struct addrinfo hints; struct addrinfo *results; int retval; memset(&hints, 0, sizeof(hints)); hints.ai_flags = 0; hints.ai_family = AF_UNIX; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; retval = getaddrinfo(0, "/tmp/.ircd/6667", &hints, &results); if (retval != 0) exit(1); else exit(0); } EOF if { (eval echo configure:4941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* cat >> confdefs.h <<\EOF #define GETADDRINFO_DOES_NOT_DO_AF_UNIX 1 EOF echo "$ac_t""no. ugh" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking whether to support SOCKS""... $ac_c" 1>&6 echo "configure:4960: checking whether to support SOCKS" >&5 # Check whether --with-socks or --without-socks was given. if test "${with_socks+set}" = set; then withval="$with_socks" case "$withval" in no) echo "$ac_t""no" 1>&6 ;; *) if test "x$withval" != "xyes"; then LIBS="$LIBS -L$withval" fi echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsocks" cat >> confdefs.h <<\EOF #define SOCKS 1 EOF cat >> confdefs.h <<\EOF #define connect Rconnect EOF cat >> confdefs.h <<\EOF #define getsockname Rgetsockname EOF cat >> confdefs.h <<\EOF #define bind Rbind EOF cat >> confdefs.h <<\EOF #define accept Raccept EOF cat >> confdefs.h <<\EOF #define listen Rlisten EOF cat >> confdefs.h <<\EOF #define select Rselect EOF ;; esac else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether to support SOCKS5""... $ac_c" 1>&6 echo "configure:5012: checking whether to support SOCKS5" >&5 # Check whether --with-socks5 or --without-socks5 was given. if test "${with_socks5+set}" = set; then withval="$with_socks5" case "$withval" in no) echo "$ac_t""no" 1>&6 ;; *) if test "x$withval" != "xyes"; then LIBS="$LIBS -L$withval" CFLAGS="$CFLAGS -I$withval/../include/" fi echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsocks5" cat >> confdefs.h <<\EOF #define SOCKS 1 EOF cat >> confdefs.h <<\EOF #define USE_SOCKS5 1 EOF ;; esac else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether to support Perl""... $ac_c" 1>&6 echo "configure:5046: checking whether to support Perl" >&5 # Check whether --with-perl or --without-perl was given. if test "${with_perl+set}" = set; then withval="$with_perl" test -z "$withval" && withval=yes fi test "xno" != "x$withval" && for base in $withval /usr/local /usr / do FOUND= for ext in so a dll ; do test -r $base/lib/libperl.$ext && FOUND=1 test -r $base/libperl.$ext && FOUND=1 done test -n "$FOUND" || continue echo "$ac_t""yes" 1>&6 LIBS="$LIBS `perl -MExtUtils::Embed -e ldopts`" PERLDOTOH="perl.o" cat >> confdefs.h <<\EOF #define PERL 1 EOF break done test -z "$PERLDOTOH" && echo "$ac_t""no" 1>&6 withval='' echo $ac_n "checking whether to support Tcl""... $ac_c" 1>&6 echo "configure:5075: checking whether to support Tcl" >&5 # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" test -z "$withval" && withval=yes fi test "xno" != "x$withval" && for base in $withval /usr/local /usr do for ver in 8.4 8.3 8.2 8.1 8.0 do incdir="$base/include/tcl$ver" test -r $incdir/tcl.h || continue test -r $base/lib/libtcl$ver.so || ver="`echo $ver | sed -e 's/\.//g'`" test -r $base/lib/libtcl$ver.so || continue echo "$ac_t""yes" 1>&6 CFLAGS="$CFLAGS -I $incdir" LIBS="-L$base/lib -ltcl$ver $LIBS" TCLDOTOH="tcl.o" cat >> confdefs.h <<\EOF #define TCL 1 EOF break 2 done done test -z "$TCLDOTOH" && echo "$ac_t""no" 1>&6 if test -z "$CFLAGS"; then CFLAGS="-g -O"; fi if test -z "$LDFLAGS"; then LDFLAGS= ; fi if test -z "$PERLDOTOH"; then PERLDOTOH= ; fi if test -z "$TCLDOTOH"; then TCLDOTOH= ; fi if test -z "$bindir"; then bindir=\${prefix}/bin; fi if test -z "$libdir"; then libdir=\${prefix}/lib; fi if test -z "$irclibdir"; then irclibdir=\${libdir}/irc; fi if test -z "$libexecdir"; then libexecdir=\${prefix}/libexec; fi epic=`echo "epic" | sed -e "$program_transform_name"` if test "$program_prefix" = "NONE" ; then program_prefix= fi echo $ac_n "checking whether to support bounds checking gcc""... $ac_c" 1>&6 echo "configure:5121: checking whether to support bounds checking gcc" >&5 # Check whether --with-bc or --without-bc was given. if test "${with_bc+set}" = set; then withval="$with_bc" case "$withval" in no) echo "$ac_t""no" 1>&6; ;; *) if test "x$withval" != "xyes" ; then CC="$withval" fi CFLAGS="$CFLAGS -Wall -fbounds-checking" LDFLAGS="$LDFLAGS -static" echo "$ac_t""yes" 1>&6 ;; esac else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether to turn on FreeBSD WARNS-like compiler warnings""... $ac_c" 1>&6 echo "configure:5146: checking whether to turn on FreeBSD WARNS-like compiler warnings" >&5 # Check whether --with-warns or --without-warns was given. if test "${with_warns+set}" = set; then withval="$with_warns" case "$withval" in no) echo "$ac_t""no" 1>&6; ;; *) if test "x$withval" != "xyes" ; then CFLAGS="$CFLAGS $withval" fi CFLAGS="$CFLAGS -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wuninitialized -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wformat-extra-args -Wno-unused -ansi -fno-builtin" echo "$ac_t""yes" 1>&6 ;; esac else echo "$ac_t""no" 1>&6 fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile source/Makefile source/info.c.sh include/defs.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@VERSION@%$VERSION%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@ALLOCA@%$ALLOCA%g s%@PERLDOTOH@%$PERLDOTOH%g s%@TCLDOTOH@%$TCLDOTOH%g s%@irclibdir@%$irclibdir%g s%@srcdir@%$srcdir%g s%@epic@%$epic%g s%@program_prefix@%$program_prefix%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 if test -f sig.inc ; then mv sig.inc include/ fi echo echo "There you go. Look at include/config.h for any options that " echo "you might want to change before you 'make'. Don't forget to " echo "do a 'make install' before you're done." echo epic4-2.10.2.orig/CVS/0000755000000000000000000000000012200242556011056 5ustar epic4-2.10.2.orig/CVS/Root0000644000000000000000000000006212171117135011723 0ustar :pserver:anoncvs@epicsol.org:/home/cvs/repository epic4-2.10.2.orig/CVS/Entries0000644000000000000000000000121612171117135012413 0ustar /BUG_FORM/1.3/Sat Jul 19 21:47:55 2003// /COPYRIGHT/1.5/Thu Nov 16 23:48:10 2006// /INSTALL/1.4/Sat Sep 5 03:31:16 2009// /KNOWNBUGS/1.368/Tue Jul 16 01:03:55 2013// /Makefile.in/1.11/Sat Mar 15 01:40:04 2008// /README/1.1.1.1/Tue Dec 5 00:11:56 2000// /UPDATES/1.106/Sat Sep 5 03:31:16 2009// /VOTES/1.8/Sat Dec 4 04:00:45 2004// /acconfig.h/1.27/Tue Mar 18 04:23:58 2008// /bsdinstall/1.1.1.1/Tue Dec 5 00:11:56 2000// /configure/1.46/Thu Mar 20 04:20:49 2008// /configure.in/1.46/Thu Mar 20 04:20:49 2008// /mkinstalldirs/1.1.1.1/Tue Dec 5 00:11:56 2000// /mkpatch/1.1.1.1/Tue Dec 5 00:11:56 2000// /test.c/1.1.1.1/Tue Dec 5 00:11:56 2000// D epic4-2.10.2.orig/CVS/Repository0000644000000000000000000000000612171117135013155 0ustar epic4 epic4-2.10.2.orig/CVS/Entries.Log0000644000000000000000000000013212171117135013127 0ustar A D/contrib//// A D/doc//// A D/include//// A D/regress//// A D/script//// A D/source//// epic4-2.10.2.orig/mkpatch0000755000000000000000000000330307213031314011773 0ustar #!/usr/bin/perl # # mkpatch -- Written for the EPIC project, 1996. # Send bug reports and improvements to jnelson@acronet.net # # Purpose: Some people have been unhappy because i roll snapshots without # making a patchfile between it and the previous snapshot. Generally i do # this for my own convenience, but also because patchfiles are a pain to # double-check, and i dont like having to do it very often. ;-) I wrote # this script so you can automatically generate your own patchfile between a # current snapshot and whatever previous snapshot you current have installed. # # Usage: # - Make sure the current snapshot's tarfile is in the directory you # would extract it if you were extracting (ie, your home directory). # - run this script specifying the tarfile as the sole argument: # # ./mkpatch e3000.tgz # # - Standard output from the script is a context diff between your # installation and whats in the tarfile. Standard error outputs # informational messages for your amusement while it works. # # - This script is somewhat slow because it runs 'tar' on the large # snapshot tarball for each file that differs between the two sets. # So just be patient when you run this. # # - This script probably requires GNU tar to work. If you dont have # GNU tar installed, you should. :^) # # Improvements, new ideas, bug reports are welcome. # print STDERR "diffing from tarfile $ARGV[0]\n"; $tar = open(TAR, "tar dfz $ARGV[0] |"); while () { s/:.*$//; chop; $filename = $_; if (!$seen{$filename}) { print STDERR "Generating diff for $filename\n"; open(DIFF, "tar xOfz $ARGV[0] $filename | diff -c - $filename|"); print ; close(DIFF); $seen{$filename}++ } } close(TAR); #eof epic4-2.10.2.orig/INSTALL0000644000000000000000000001171511250355604011464 0ustar How to compile this package: Its really quite simple -- its about the same difficulty as compiling any GNU software (however, this is _not_ GNU software) o !!! IMPORTANT !!! If you are upgrading from a prior version of your operating system, or you have changed operating systems, you must do a 'make distclean' and re-do all of the steps in this file for the new OS, or epic may get confused when it tries to compile for your old system! (Especially true for Redhat 5.2 to 6.1) o Run 'configure' by using one (and only one) of the following: ./configure sh configure o By default, 'configure' sets up the software to be run from /usr/local -- if this is not the case for you (ie, you are not the superuser compiling for the entire system) you can run configure with the "--prefix=/path/to/somewhere" flag, for example: ./configure --prefix=/usr/home/jnelson o You must not try to compile epic with "gcc -O2" because -O2 will generate bad code that leads to random crashes. When you use -O2, gcc assumes the source is conformant to ISO C99's requirements about alias-safety, and EPIC, being a C90 program, does not conform, so the result is undefined behavior (which means it crashes randomly.) This is not a bug in EPIC. You must only compile epic with -O. o EPIC's build infrastructure fully supports all the bells and whistles that configure provides for compiling in different places and for different systems and all that esoteric stuff only used by package maintainers. This support was added because Debian asked for it. o There are several options supported by our configure script: --with-termcap EPIC will use ONLY termcap, and not look for terminfo. You ought not specify this unless the terminfo support on your system is more broken than your termcap support. --with-socks[=PATH] EPIC will attempt to use SOCKS4 firewall code when making network connections. The PATH should specify the directory tree where all of the interesting files can be found. This is usually something like /usr/local --with-socks5[=PATH] Same thing as above, but for SOCKS5. --with-perl[=PATH] Enable the perl support in the scripting language. WARNING: Currently requires Perl 5.6+. --with-ssl[=PATH] Enable support for SSLv3 connections to servers. --with-ssl-ver=v2 Use SSLv2 instead of SSLv3 o This IRC II client should be able to compile and run on almost any modern unix (A ``modern'' unix is one that supports POSIX system calls and BSD networking in addition to the most commonly accepted non-standard unix extensions, like getpw*() functions.) All i can say is try it and see if it works. It will definitely work on Solaris, FreeBSD, Linux, Digital Unix, SCO ODT 5, AIX, etc. o To compile ircii, type `make'. This will compile the `epic' and `wserv' programs that live in the `source' subdirectory. o Once that you are happy with the compilation, you can install them with `make install'. This will install all the binaries, and scripts into the path specified in the Makefile (or when you ran configure). The help files are available as a seperate package. They should be available from the same place you got the source code from. This release uses a new layout format for its various parts that differs from the historical ircII defaults. The binary is called 'epic', the library is put into .../share/epic by default, and the 'wserv4' binary ends up as .../libexec/wserv4. o You can now delete the object files and binaries if you want to save some space by typing `make clean'. If you are sure you probably wont have to compile again, but you want to keep the source code around, you can use `make distclean'. You should `make distclean' before you try to compile again for a different architecture. o Help files are not shipped with the base distribution (because of their size and because they are not updated frequently.) You should be able to find the help files in the same place you got the source distribution, or you can find them at ftp://ftp.epicsol.org/pub/epic. To install the help files, you need to put the gzip'd tar file in the irc library as configured into the client. This is typically either /usr/local/lib/irc or $HOME/lib/irc. Extract it there (it will create a subdirectory named help). If you have problems, start up the irc client, and run the command /SET HELP_PATH -- the output should be the directory where you installed the help files. If its not, you either need to /SET HELP_PATH to the place where the help files are, or you need to move the help files to where the client is expecting to find them. ;-) o Bug reports go to list@epicsol.org. Please see the BUG_FORM file for information about how to file a bug report. Please include as much information as possible. epic4-2.10.2.orig/include/0000755000000000000000000000000012200242556012046 5ustar epic4-2.10.2.orig/include/config.h0000644000000000000000000005467310445307177013515 0ustar /* * 'new' config.h: * A configuration file designed to make best use of the abilities * of ircII, and trying to make things more intuitively understandable. * * Original: Michael Sandrof * V2 by Carl V. Loesch (lynx@dm.unirm1.it) * V2.EPIC by jfn (jnelson@acronet.net) */ #ifndef _CONFIG_H_ #define _CONFIG_H_ /* * Notes to the unwary: * * -- You cant just add a ``#define DEFAULT_X'' and expect it to work. * Those things that do not have defaults are that way on purpose. * Either they have their own defaults, or a default is inappropriate. * * -- Unless the description expliclity says that the #define is optional, * you may NOT remove it or #undef it, else the client will not compile * properly. */ /* * This is where you define a list of ``fallback'' servers in case the client * cannot under other circumstances figure out where to connect. Normally, * the server to use is determined by the ``SERVERS_FILE'' (see below), or * by a server specified on the command line. But if for some reason your * ``SERVERS_FILE'' isnt there or isnt readable, or the user doesnt specify * a server, then this list will be used. * * The list should be a space seperated list of the form * hostname:portnum:password. The portnum and password are optional. * An example is: * * #define DEFAULT_SERVER "irc.iastate.edu irc-2.mit.edu:6666:lag-2sux" * * THIS DEFINE IS -!-NOT-!- OPTIONAL. You must provide a fallback list or * the client will NOT compile and work properly! Use the default here if * you dont have other servers to use. */ #define DEFAULT_SERVER "localhost irc.efnet.net irc.undernet.org irc.dal.net" /* * Maildir support is experimental in EPIC4. More complete support is * available in EPIC5, including support for switching back and forth * between mbox and maildir at runtime. For now, you must pick one or * the other at compile time. * 0 - Mail checking for mbox * 1 - Mail checking for maildir */ #define MAIL_CHECKING_TYPE 0 /* * This is an experimental feature to thwart infinite recursion. It is not * very sophisticated so it's not turned on by default. In the future I * will probably do something less lame. * * When this many stack frames are created, epic will refuse to make any * more. This will stop epic from crashing with a segfault when you do * infinite recursion, but it's possible that epic may infinitely recurse * if your alias is tricky enough. Pick your poison */ #define MAX_STACK_FRAMES 20000 /* * The left and right brace characters ('{', '}') are special characters in * the IRC character set, becuase they represent scandanavian characters and * are not expected to be treated any differently than any other alphanumeric * character. When this is #define'd, the client makes a best guess attempt * to determine if a { is being used as a brace, or as an alphanumeric char. * * The way it determines is simple: * An lbrace ('{') is a normal character UNLESS ONE OF THE FOLLOWING: * * It is the first character on a line * * It is preceeded by whitespace * * It is preceeded by a right paren (')') * * It is preceeded by a right brace ('}') * Similarly, * An rbrace ('}') is a normal character UNLESS ONE OF THE FOLLOWING: * * It is the last character on a line * * It is followed by whitespace * * It is followed by a left paren ('(') * * It is followed by a left brace ('{') * * If the following is #define'd, the above rules are in effect. If the * following is #undef'd, then the normal, traditional rules apply and every * { and } is counted for bracing purposes. * * Some day, if this works out, this will become the default behavior -- * but not today. */ #undef BRACE_LOAD_HACK /* * A recent change was to make the %S status line expando always display * the server information, even if you were connected to only one server. * However, a few people expressly dislike this change and want the old * behavior. If this is #define'd, you get the old behavior. If this is * #undef'd, you get the new behavior. */ #define OLD_STATUS_S_EXPANDO_BEHAVIOR /* * Oooops! This was supposed to be here, but it never did make it. Which * explains a lot. Anyhow, #define this if you want to have the option of * doing floating point math in EPIC. #undef this if you always want integer * operations to always be done. The client can still do integer operations * if this is defined, just /set floating_point_math OFF. * * Note that if this is defined, the client actually will do all of your * operations in floating point and then the *result* will be truncated. * This is different from when this is #undef when *each term* will be * truncated. For example: * * #undef'd 4.2 - 2.6 -> (4 - 2) -> 2 * #define'd 4.2 - 2.6 -> 1.6 -> 1 */ #define FLOATING_POINT_SUPPORT /* * Undef this if your FIONREAD is not useful. At this time, it makes very * little difference because we dont use FIONREAD for anything useful. But * nevertheless, if youre allergic to mild bsd-isms, then you can #undef this. */ #define HAVE_USEFUL_FIONREAD /* * This sets how you want to see the 368 numeric to be hooked. The default * (#undef) is the traditional EPIC behavior. * EPIC ircII * $0 server server * $1 number of bans channel name * $2 channel name */ #undef IRCII_LIKE_BAN_SUMMARY /* * When this is define'd, the -z flag, the IRCUSER and USER environment * variables, as well as the /IRCUSER command will be honored. This is * not nearly as big a deal as it used to be, because every server uses * identd and ignores the client-specified username. There is no compelling * reason for any site using identd to forbid this behavior by default. * Any site that wont run identd i dont have a lot of sympathy for. */ #define ALLOW_USER_SPECIFIED_LOGIN /* * I moved this here because it seemed to be the most appropriate * place for it. Define this if you want support for ``/window create'' * and its related features. If you dont want it, youll save some code, * and you wont need 'wserv', and if you do want it, you can have it in * all of its broken glory. */ #define WINDOW_CREATE /* * Define this if you want an mIRC compatable /dcc resume capability. * Note that this BREAKS THE IRC PROTOCOL, and if you use this feature, * the behavior is NON COMPLIANT. If this warning doesnt bother you, * and you really want this feature, then go ahead and #define this. * * Unfortunately, due to popular pressure, im having to #define this by * default. The capability wont be turned on, however, unless you also * do a /set mirc_broken_dcc_resume on, which is OFF by default. No, * there will not be a way to default it to ON short of modifying vars.c. * This is a comprimise, and i wont give any further. Those who dont want * this feature can #undef this, or can hook /on set "mirc_broken_dcc_resume". */ #define MIRC_BROKEN_DCC_RESUME /* * Youll want to define this if your system is missing the glob() * call, or if its broken (solaris). * * Actually, you should #define this if you can compile the supplied * glob.c. If it works, dont mess with it. */ #define NEED_GLOB /* * ircII has a security feature for paranoid sysadmins or for those * users whose sysadmins are paranoid. The security feature allows * you to restrict who may use the ircII client. You have four options: * * 1) compile into the binary a list of uids who can use the program * *Pros: cant be hacked -- very secure * *Cons: cant be changed w/o recompiling * 2) compile into the binary a file which will contain the uids of * the people who can use the program * *Pros: can be changed as you need by just editing the file * *Cons: since the uids are in a file, prone to hacking * 3) compile into the binary a file which will contain the uids of * the people who cannot use the program * *Pros: allows for public use and allow you to exclude * troublemakers without enumerating everyone else * *Cons: since the uids are in a file, prone to hacking * 4) compile into the binary a password * *Pros: cant be hacked -- secure * *Cons: cant be changed w/o recompiling * * The first two options are mutually exclusive. The third and fourth * options can be specified at your option. If you specify both the * first and second options, the first option has precedence. */ /* * To use the first security feature, #define HARD_SECURE. You will also * have to #define VALID_UIDS which will be a list of those uids (integers, * not usernames) which will be allowed to execute the resulting program. * If you #define HARD_SECURE but do not define #VALID_UIDS, then noone * will be able to execute the program! */ #undef HARD_SECURE #define VALID_UIDS "100 101" /* * To use the second security measure, simply #define SOFT_SECURE to a * filename that will be world-readable that will contain the uids of * all the users who will be allowed to execute the program. It is important * that this file be readable by at least every person who can execute the * program or this security measure will be comprimised. * * The uid file should have one uid per line (integer, not username). * * You can define VALID_UID_FILE, but if SOFT_SECURE is not defined, it will * not be used. */ #undef SOFT_SECURE #define VALID_UID_FILE "/home/jnelson/..." /* * This allows you to use the third security option. If you define this, * it should be assigned to a file that will contain a listing of all of * the uids (integers, not usernames) that will not be allowed to execute * the resulting program. */ /*#define INVALID_UID_FILE "/home/jnelson/...."*/ /* * This part lets you deny certain hosts from running your irc client. * For instance, my university does not allow irc'ing from dialup machines, * So by putting the dialup's hostnames in the specified file, they can't * Run irc. * -- Chris Mattingly * * If you define this, it *absolutely* must be in double quotes ("s)! */ #undef HOST_SECURE #ifdef HOST_SECURE #define INVALID_HOST_FILE "/home/jnelson/...host.deny" #endif /* * This allows you to use the fourth security option. If you define this, * the program will prompt the user to enter this prompt before it will * continue executing the program. This password does not affect in any * way the other protection schemes. A user who is not allowed to run * the program will not be allowed to use the program even if they know * the password. */ /*#define PASSWORD "booya"*/ /* * This is the fun part. If someone runs your program who shouldnt run * it, either because the dont know the password or because they arent * on the valid list or whatever, ircII will execute this program to * "spoof" them into thinking your program is actually some other program. * * This can be defined to any valid C expression that will resolve to a * character string. (ie, a character literal or function call) */ #define SPOOF_PROGRAM getenv("SHELL") /* * If you define UNAME_HACK, the uname information displayed in the * CTCP VERSION info will appear as "*IX" regardless of any other * settings. Useful for paranoid users who dont want others to know * that theyre running a buggy SunOS machine. >;-) */ #undef UNAME_HACK /* And here is the port number for default client connections. */ #define IRC_PORT 6667 /* * If you want to have a file containing the list of irc servers to * use, define SERVERS_FILE to be that filename. Put the file in the * ircII library directory. This file should be whitespace seperated * hostname:portnum:password (with the portnum and password being * optional). This server list will supercede the DEFAULT_SERVER */ #define SERVERS_FILE "ircII.servers" /* * define this if you want your irc client to exit after an * operator kill. I have no idea why you would, though. */ #undef QUIT_ON_OPERATOR_KILL /* * The compile sequence records the user/host/time of the compile, * which can be useful for tampering and newbie reasons. If you want * the compile to remain anonymous, define this option. In this case, * the host and the time will remain, but the 'user' field will not * be displayed to the user. * * Please dont define this on a whim -- be sure you really want it. */ #undef ANONYMOUS_COMPILE /* * The /LOAD path is now generated at runtime, rather than at compile time. * This is to allow you to change IRCLIB and have its script library be * resepected without having to change IRCPATH as well. This is a printf * format of what the default load path is to be. The %s format indicates * the runtime IRCLIB value. This value is only used at startup time. */ #define DEFAULT_IRCPATH "~/.epic:~/.irc:%s/script:." /* * Below are the IRCII variable defaults. For boolean variables, use 1 for * ON and 0 for OFF. You may set string variable to NULL if you wish them to * have no value. None of these are optional. You may *not* comment out or * remove them. They are default values for variables and are required for * proper compilation. */ #define DEFAULT_ALLOW_C1_CHARS 0 #define DEFAULT_ALT_CHARSET 1 #define DEFAULT_ALWAYS_SPLIT_BIGGEST 1 #define DEFAULT_AUTO_NEW_NICK 1 #define DEFAULT_AUTO_RECONNECT 1 #define DEFAULT_AUTO_RECONNECT_DELAY 0 #define DEFAULT_AUTO_REJOIN 0 #define DEFAULT_AUTO_REJOIN_CONNECT 1 #define DEFAULT_AUTO_REJOIN_DELAY 0 #define DEFAULT_AUTO_UNMARK_AWAY 0 #define DEFAULT_AUTO_WHOWAS 1 #define DEFAULT_BAD_STYLE 0 #define DEFAULT_BANNER "***" #define DEFAULT_BEEP 1 #define DEFAULT_BEEP_MAX 3 #define DEFAULT_BEEP_ON_MSG "NONE" #define DEFAULT_BEEP_WHEN_AWAY 1 #define DEFAULT_BLINK_VIDEO 1 #define DEFAULT_BOLD_VIDEO 1 #define DEFAULT_CHANNEL_NAME_WIDTH 0 #define DEFAULT_CLOCK 1 #define DEFAULT_CLOCK_24HOUR 0 #define DEFAULT_CLOCK_FORMAT NULL #define DEFAULT_CLOCK_INTERVAL 60 #define DEFAULT_CMDCHARS "/" #define DEFAULT_COLOR 1 #define DEFAULT_COMMAND_MODE 0 #define DEFAULT_COMMENT_HACK 1 #define DEFAULT_CONNECT_TIMEOUT 30 #define DEFAULT_CONTINUED_LINE "+" #define DEFAULT_CPU_SAVER_AFTER 0 #define DEFAULT_CPU_SAVER_EVERY 60 #define DEFAULT_CURRENT_WINDOW_LEVEL NULL #define DEFAULT_DCC_AUTO_SEND_REJECTS 1 #define DEFAULT_DCC_DEQUOTE_FILENAMES 1 #define DEFAULT_DCC_LONG_PATHNAMES 1 #define DEFAULT_DCC_SLIDING_WINDOW 1 #define DEFAULT_DCC_TIMEOUT 3600 #define DEFAULT_DISPATCH_UNKNOWN_COMMANDS 0 #define DEFAULT_DISPLAY 1 #define DEFAULT_DISPLAY_ANSI 1 #define DEFAULT_DISPLAY_PC_CHARACTERS 4 #define DEFAULT_DO_NOTIFY_IMMEDIATELY 1 #define DEFAULT_EIGHT_BIT_CHARACTERS 1 #define DEFAULT_EXEC_PROTECTION 0 #define DEFAULT_FLOATING_POINT_MATH 0 #define DEFAULT_FLOATING_POINT_PRECISION 16 #define DEFAULT_FLOOD_AFTER 3 #define DEFAULT_FLOOD_IGNORE 0 #define DEFAULT_FLOOD_MASKUSER 0 #define DEFAULT_FLOOD_RATE 3 #define DEFAULT_FLOOD_RATE_PER 1 #define DEFAULT_FLOOD_USERS 3 #define DEFAULT_FLOOD_WARNING 0 #define DEFAULT_FULL_STATUS_LINE 1 #define DEFAULT_HELP_PAGER 1 #define DEFAULT_HELP_PROMPT 1 #define DEFAULT_HELP_WINDOW 0 #define DEFAULT_HIDE_PRIVATE_CHANNELS 0 #define DEFAULT_HIGH_BIT_ESCAPE 2 #define DEFAULT_HIGHLIGHT_CHAR "BOLD" #define DEFAULT_HISTORY 150 #define DEFAULT_HISTORY_CIRCLEQ 1 #define DEFAULT_HOLD_INTERVAL 10 #define DEFAULT_HOLD_MODE 0 #define DEFAULT_HOLD_SLIDER 100 #define DEFAULT_INDENT 0 #define DEFAULT_INPUT_ALIASES 0 #define DEFAULT_INPUT_PROMPT "> " #define DEFAULT_INPUT_PROTECTION 1 #define DEFAULT_INSERT_MODE 1 #define DEFAULT_INVERSE_VIDEO 1 #define DEFAULT_KEY_INTERVAL 1000 #define DEFAULT_LASTLOG 256 #define DEFAULT_LASTLOG_LEVEL "ALL" #define DEFAULT_LOG 0 #define DEFAULT_LOGFILE "irc.log" #define DEFAULT_MAIL 2 #define DEFAULT_MAIL_INTERVAL 60 /* #define DEFAULT_MAIL_TYPE "mbox" */ #define DEFAULT_MAX_RECONNECTS 4 #define DEFAULT_METRIC_TIME 0 #define DEFAULT_MODE_STRIPPER 0 #define DEFAULT_ND_SPACE_MAX 160 #define DEFAULT_NEW_SERVER_LASTLOG_LEVEL "ALL,-DCC" #define DEFAULT_NO_CTCP_FLOOD 1 #define DEFAULT_NO_FAIL_DISCONNECT 0 #define DEFAULT_NOTIFY 1 #define DEFAULT_NOTIFY_INTERVAL 60 #define DEFAULT_NOTIFY_LEVEL "ALL" #define DEFAULT_NOTIFY_ON_TERMINATION 1 #define DEFAULT_NOTIFY_USERHOST_AUTOMATIC 1 #define DEFAULT_NO_CONTROL_LOG 0 #define DEFAULT_NUM_OF_WHOWAS 1 #define DEFAULT_PAD_CHAR ' ' #define DEFAULT_QUIT_MESSAGE "ircII %s -- Are we there yet?" #define DEFAULT_RANDOM_LOCAL_PORTS 0 #define DEFAULT_RANDOM_SOURCE 0 #define DEFAULT_REVERSE_STATUS_LINE 1 #define DEFAULT_SCROLLBACK 256 #define DEFAULT_SCROLLBACK_RATIO 50 #define DEFAULT_SCROLL_LINES 1 #define DEFAULT_SECURITY 0 #define DEFAULT_SHELL "/bin/sh" #define DEFAULT_SHELL_FLAGS "-c" #define DEFAULT_SHELL_LIMIT 0 #define DEFAULT_SHOW_CHANNEL_NAMES 1 #define DEFAULT_SHOW_END_OF_MSGS 1 #define DEFAULT_SHOW_NUMERICS 0 #define DEFAULT_SHOW_STATUS_ALL 0 #define DEFAULT_SHOW_WHO_HOPCOUNT 1 #define DEFAULT_STATUS_AWAY " (Away)" #define DEFAULT_STATUS_CHANNEL " %C" #define DEFAULT_STATUS_CHANOP "@" #define DEFAULT_STATUS_HALFOP "%" #define DEFAULT_STATUS_SSL_ON "*SSL*" #define DEFAULT_STATUS_SSL_OFF "*RAW*" #define DEFAULT_STATUS_CLOCK " %T" #define DEFAULT_STATUS_CPU_SAVER " (%L)" #define DEFAULT_STATUS_FORMAT "%T [%R] %*%=%@%N%#%S%H%B%Q%A%C%+%I%O%M%F%L %D %U %W" #define DEFAULT_STATUS_FORMAT1 "%T [%R] %*%=%@%N%#%S%H%B%Q%A%C%+%I%O%M%F%L %U " #define DEFAULT_STATUS_FORMAT2 "%W %X %Y %Z " #define DEFAULT_STATUS_HOLD " Held: " #define DEFAULT_STATUS_HOLD_LINES "%B" #define DEFAULT_STATUS_INSERT "" #define DEFAULT_STATUS_MODE " (+%+)" #define DEFAULT_STATUS_MAIL " (Mail: %M)" #define DEFAULT_STATUS_NICK "%N" #define DEFAULT_STATUS_NO_REPEAT 0 #define DEFAULT_STATUS_NOSWAP "(NOSWAP)" #define DEFAULT_STATUS_NOTIFY " (W: %F)" #define DEFAULT_STATUS_OPER "*" #define DEFAULT_STATUS_OVERWRITE " (Overwrite)" #define DEFAULT_STATUS_QUERY " (Query: %Q)" #define DEFAULT_STATUS_SCROLLBACK " (Scroll)" #define DEFAULT_STATUS_SERVER " (%S)" #define DEFAULT_STATUS_TRUNCATE_RHS 1 #define DEFAULT_STATUS_UMODE " (+%#)" #define DEFAULT_STATUS_USER "ircII-EPIC4 -- Type /help for help" #define DEFAULT_STATUS_USER1 "" #define DEFAULT_STATUS_USER2 "" #define DEFAULT_STATUS_USER3 "" #define DEFAULT_STATUS_USER4 "" #define DEFAULT_STATUS_USER5 "" #define DEFAULT_STATUS_USER6 "" #define DEFAULT_STATUS_USER7 "" #define DEFAULT_STATUS_USER8 "" #define DEFAULT_STATUS_USER9 "" #define DEFAULT_STATUS_USER10 "" #define DEFAULT_STATUS_USER11 "" #define DEFAULT_STATUS_USER12 "" #define DEFAULT_STATUS_USER13 "" #define DEFAULT_STATUS_USER14 "" #define DEFAULT_STATUS_USER15 "" #define DEFAULT_STATUS_USER16 "" #define DEFAULT_STATUS_USER17 "" #define DEFAULT_STATUS_USER18 "" #define DEFAULT_STATUS_USER19 "" #define DEFAULT_STATUS_USER20 "" #define DEFAULT_STATUS_USER21 "" #define DEFAULT_STATUS_USER22 "" #define DEFAULT_STATUS_USER23 "" #define DEFAULT_STATUS_USER24 "" #define DEFAULT_STATUS_USER25 "" #define DEFAULT_STATUS_USER26 "" #define DEFAULT_STATUS_USER27 "" #define DEFAULT_STATUS_USER28 "" #define DEFAULT_STATUS_USER29 "" #define DEFAULT_STATUS_USER30 "" #define DEFAULT_STATUS_USER31 "" #define DEFAULT_STATUS_USER32 "" #define DEFAULT_STATUS_USER33 "" #define DEFAULT_STATUS_USER34 "" #define DEFAULT_STATUS_USER35 "" #define DEFAULT_STATUS_USER36 "" #define DEFAULT_STATUS_USER37 "" #define DEFAULT_STATUS_USER38 "" #define DEFAULT_STATUS_USER39 "" #define DEFAULT_STATUS_VOICE "+" #define DEFAULT_STATUS_WINDOW "^^^^^^^^" #define DEFAULT_SUPPRESS_FROM_REMOTE_SERVER 0 #define DEFAULT_SUPPRESS_SERVER_MOTD 0 #define DEFAULT_SWITCH_CHANNEL_ON_PART 1 #define DEFAULT_SWITCH_CHANNELS_BETWEEN_WINDOWS 1 #define DEFAULT_TAB 1 #define DEFAULT_TAB_MAX 0 #define DEFAULT_TERM_DOES_BRIGHT_BLINK 0 #define DEFAULT_UNDERLINE_VIDEO 1 #define DEFAULT_USERINFO "EPIC4 -- Get your laundry brighter, not just whiter!" #define DEFAULT_VERBOSE_CTCP 1 #define DEFAULT_WORD_BREAK ".,; \t" #define DEFAULT_WSERV_TYPE "screen" #define DEFAULT_XTERM "xterm" #define DEFAULT_XTERM_OPTIONS NULL /* * People have wanted me to explain some of these #defines. Well, * Ill tell you what i will do. I will tell you that some of these * defines turn on obscure features, and others turn on features that * are specificly placed there at the request of one of the debuggers, * but i am making the option of using it available to the general * public. You should always be aware of what changing one of these * #defines might do to affect the operation of the client. You can get * a good feel for the impact by grepping the source code for them. * General "themes" of what the defines do are listed on the right. * These "themes" describe the *spirit* of the define, but do NOT * annotate every reprocussion of defining it! * * Also, i dont guarantee that changing any of these defines will * or wont compile correctly, so you may have to be prepared to do * some minor debugging in that case (send patches along to me if * you do =) Dont change any of these unless you know what it will do. */ #undef EMACS_KEYBINDINGS /* meta-key keybindings. */ #undef EPIC_DEBUG /* force coredump on panic */ #define EXEC_COMMAND /* allow /exec comamnd */ #undef HACKED_DCC_WARNING /* warn if handshake != sender */ #undef HARD_UNFLASH /* do a hard reset instead of soft on refresh */ #undef NO_BOTS /* no bots allowed */ #undef NO_CHEATING /* always do it the "right" way, no shortcuts */ #undef STRIP_EXTRANEOUS_SPACES /* strip leading and trailing spaces */ #undef I_DONT_TRUST_MY_USERS /* There are certain things that the stock ircII client doesnt allow users to do that are neither illegal by the letter of the protocol nor the spirit of the protocol. These are the things that only a really anal retentive person would want to totaly prohibit his users from doing without any exceptions. When i find these things, i #ifdef them out under this define. The specific list of what may or may not be contained under this define can change from release to release. This replaces the I_AM_A_FASCIST_BASTARD define which several people found offensive because they wanted to define it =) */ /* Dont change these -- theyre important. */ #if defined(VALID_UIDS) && !defined(HARD_SECURE) #undef VALID_UIDS #endif #if defined(PASSWORD) && !defined(HARD_SECURE) && !defined(SOFT_SECURE) #undef PASSWORD #endif #if defined(HARD_SECURE) && !defined(VALID_UIDS) #error You must #define VALID_UIDS if you #define HARD_SECURE #endif #if defined(VALID_UID_FILE) && !defined(SOFT_SECURE) #undef VALID_UID_FILE #endif #if defined(SOFT_SECURE) && !defined(VALID_UID_FILE) #error You must #define VALID_UID_FILE if you #define SOFT_SECURE #endif #ifndef SPOOF_PROGRAM #define SPOOF_PROGRAM "/bin/sh" #endif /* end of section not to change */ #undef ALLOC_DEBUG #endif /* _CONFIG_H_ */ epic4-2.10.2.orig/include/ignore.h0000644000000000000000000000274707677734411013536 0ustar /* * ignore.h: header for ignore.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __ignore_h__ #define __ignore_h__ /* Type of ignored nicks */ #define IGNORE_NONE 0 /* 0 */ #define IGNORE_MSGS 1 << 0 /* 1 */ #define IGNORE_PUBLIC 1 << 1 /* 2 */ #define IGNORE_WALLS 1 << 2 /* 4 */ #define IGNORE_WALLOPS 1 << 3 /* 8 */ #define IGNORE_INVITES 1 << 4 /* 16 */ #define IGNORE_NOTICES 1 << 5 /* 32 */ #define IGNORE_NOTES 1 << 6 /* 64 */ #define IGNORE_CTCPS 1 << 7 /* 128 */ #define IGNORE_TOPICS 1 << 8 /* 256 */ #define IGNORE_NICKS 1 << 9 /* 512 */ #define IGNORE_JOINS 1 << 10 /* 1024 */ #define IGNORE_PARTS 1 << 11 /* 2048 */ #define IGNORE_CRAP 1 << 12 /* 4096 */ #define IGNORE_ALL (IGNORE_MSGS | IGNORE_PUBLIC | IGNORE_WALLS | \ IGNORE_WALLOPS | IGNORE_INVITES | IGNORE_NOTICES | \ IGNORE_NOTES | IGNORE_CTCPS | IGNORE_TOPICS | \ IGNORE_NICKS | IGNORE_JOINS | IGNORE_PARTS | \ IGNORE_CRAP) #define NOT_IGNORED 0 #define IGNORED 1 #define HIGHLIGHTED -1 BUILT_IN_COMMAND(ignore); int do_expire_ignores (void *); int check_ignore (const char *, const char *, int); int check_ignore_channel (const char *, const char *, const char *, int); char * get_ignores_by_pattern (char *, int); const char * get_ignore_types_by_pattern (char *); char * get_ignore_patterns_by_type (char *); char * ignorectl (char *); #endif /* _IGNORE_H_ */ epic4-2.10.2.orig/include/server.h0000644000000000000000000002712410105220177013530 0ustar /* * server.h: header for server.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __server_h__ #define __server_h__ /* To get definition of Who, Ison, and Userhost queues. */ #include "who.h" #ifdef NEED_SERVER_LIST /* To get definition of Notify */ #include "notify.h" #include "alist.h" /* XXXX Ick. Gross. Bad. XXX */ struct notify_stru; typedef array A005; typedef struct { char *name; u_32int_t hash; char *value; } A005_item; typedef struct WaitCmdstru { char *stuff; struct WaitCmdstru *next; } WaitCmd; /* Server: a structure for the server_list */ typedef struct { char *name; /* the name of the server */ char *itsname; /* the server's idea of its name */ char *password; /* password for that server */ int port; /* port number on that server */ char *group; /* Server group it belongs to */ char *nickname; /* Authoritative nickname for us */ char *s_nickname; /* last NICK command sent */ char *d_nickname; /* Default nickname to use */ char *unique_id; /* Unique ID (for ircnet) */ size_t fudge_factor; /* How much s_nickname's fudged */ int nickname_pending; /* Is a NICK command pending? */ int resetting_nickname; /* Is a nickname reset in progress? */ int registration_pending; /* Is a registration going on ? */ int registered; /* true if registration is assured */ int rejoined_channels; /* Has we tried to auto-rejoin? */ char *userhost; /* my userhost on this server */ char *away; /* away message for this server */ int operator; /* true if operator */ int version; /* the version of the server - * defined above */ int server2_8; /* defined if we get an 001 numeric */ char *version_string; /* what is says */ long flags; /* Various flags */ long flags2; /* More Various flags */ char *umodes; /* Possible user modes */ char umode[54]; /* Currently set user modes */ int s_takes_arg; /* Set to 1 if s user mode has arg */ int des; /* file descriptor to server */ int eof; /* eof flag for server */ int sent; /* set if something has been sent, * used for redirect */ char *redirect; /* Who we're redirecting to here */ WhoEntry * who_queue; /* Who queue */ IsonEntry * ison_wait; /* Ison wait queue */ IsonEntry * ison_queue; /* Ison queue */ UserhostEntry * userhost_queue; /* Userhost queue */ SS local_sockname; /* sockname of this connection */ SS remote_sockname; /* sockname of this connection */ SS uh_addr; /* ip address the server sees */ NotifyList notify_list; /* Notify list for this server */ int reconnects; /* Number of reconnects done */ char *cookie; /* Erf/TS4 "cookie" value */ int save_channels; /* True if abnormal connection */ int line_length; /* How long a protocol command may be */ int max_cached_chan_size; /* Bigger channels won't cache U@H */ int closing; /* True if close_server called */ int reconnect_to; /* Server to connect to on EOF */ char *quit_message; /* Where we stash a quit message */ A005 a005; /* 005 settings kept kere. */ int funny_min; /* Funny stuff */ int funny_max; int funny_flags; char * funny_match; #ifdef HAVE_SSL SSL_CTX* ctx; SSL_METHOD* meth; #endif void * ssl_fd; int try_ssl; /* SSL requested on next connection. */ int ssl_enabled; /* Current SSL status. */ int doing_privmsg; int doing_notice; int doing_ctcp; int waiting_in; int waiting_out; WaitCmd * start_wait_list; WaitCmd * end_wait_list; char * invite_channel; char * last_notify_nick; char * joined_nick; char * public_nick; char * recv_nick; char * sent_nick; char * sent_body; int (*dgets) (char *, int, int, void *); } Server; extern Server **server_list; #endif /* NEED_SERVER_LIST */ extern int number_of_servers; extern int connected_to_server; extern int primary_server; extern int from_server; extern int last_server; extern int parsing_server_index; #ifdef NEED_SERVER_LIST static __inline__ Server * get_server (int server) { if (server == -1 && from_server >= 0) server = from_server; if (server < 0 || server >= number_of_servers) return NULL; return server_list[server]; } /* * These two macros do bounds checking on server refnums that are * passed into various server functions */ #define CHECK_SERVER(x) \ { \ if (!get_server(x)) \ return; \ } #define CHECK_SERVER_RET(x, y) \ { \ if (!get_server(x)) \ return (y); \ } #define __FROMSERV get_server(from_server) #define SERVER(x) get_server(x) #endif /* NEED_SERVER_LIST */ #define NOSERV -2 #define FROMSERV -1 /* * type definition to distinguish different * server versions */ #define Server2_8 1 #define Server2_9 2 #define Server2_10 3 #define Server_u2_8 4 #define Server_u2_9 5 #define Server_u2_10 6 #define Server_u3_0 7 /* Funny stuff */ #define FUNNY_PUBLIC 1 << 0 #define FUNNY_PRIVATE 1 << 1 #define FUNNY_TOPIC 1 << 2 #define FUNNY_USERS 1 << 4 #define FUNNY_NAME 1 << 5 BUILT_IN_COMMAND(servercmd); BUILT_IN_COMMAND(disconnectcmd); void add_to_server_list (const char *, int, const char *, const char *, const char *, const char *, int); int find_in_server_list (const char *, int); void destroy_server_list (void); int find_server_refnum (char *, char **rest); int parse_server_index (const char *, int); void parse_server_info (char **, char **, char **, char **, char **, char **); void build_server_list (char *, char *); int read_server_file (void); void display_server_list (void); char * create_server_list (void); /* MALLOC */ int server_list_size (void); void do_server (fd_set *, fd_set *); void flush_server (int); void send_to_server (const char *, ...) __A(1); void send_to_aserver (int, const char *, ...) __A(2); void send_to_aserver_raw (int, size_t len, const char *buffer); int connect_to_new_server (int, int, int); int close_all_servers (const char *); void close_server (int, const char *); void set_server_away (int, const char *); const char * get_server_away (int); const char * get_possible_umodes (int); void set_possible_umodes (int, const char *); const char * get_umode (int); void clear_user_modes (int); void reinstate_user_modes (void); void update_user_mode (const char *); void set_server_flag (int, int, int); int get_server_flag (int, int); void set_server_version (int, int); int get_server_version (int); void set_server_name (int, const char *); const char * get_server_name (int); void set_server_itsname (int, const char *); const char * get_server_itsname (int); void set_server_group (int, const char *); const char * get_server_group (int); const char * get_server_type (int); void set_server_version_string (int, const char *); const char * get_server_version_string (int); int get_server_isssl (int); const char * get_server_cipher (int); void register_server (int, const char *); void server_registration_is_not_pending (int); void password_sendline (char *, char *); char * set_server_password (int, const char *); int is_server_open (int); int is_server_registered (int); void server_is_registered (int, int); int auto_reconnect_callback (void *); int server_reconnects_to (int, int); int reconnect (int, int); int get_server_port (int); int get_server_local_port (int); SS get_server_local_addr (int); SS get_server_uh_addr (int); const char * get_server_userhost (int); void got_my_userhost (int, UserhostItem *, const char *, const char *); int get_server_operator (int); void set_server_operator (int, int); void use_server_cookie (int); const char * get_server_nickname (int); int is_me (int, const char *); void change_server_nickname (int, const char *); const char * get_pending_nickname (int); void accept_server_nickname (int, const char *); void fudge_nickname (int); void nickname_sendline (char *, char *); void reset_nickname (int); void set_server_redirect (int, const char *); const char * get_server_redirect (int); int check_server_redirect (int, const char *); void save_servers (FILE *); void server_did_rejoin_channels (int); int did_server_rejoin_channels (int); void clear_reconnect_counts (void); int get_server_enable_ssl (int); void set_server_enable_ssl (int, int); void make_005 (int); void destroy_005 (int); const char* get_server_005 (int, const char *); void set_server_005 (int, char*, char*); void server_hard_wait (int); void server_passive_wait (int, const char *); int check_server_wait (int, const char *); void set_server_doing_privmsg (int, int); int get_server_doing_privmsg (int); void set_server_doing_notice (int, int); int get_server_doing_notice (int); void set_server_doing_ctcp (int, int); int get_server_doing_ctcp (int); void set_server_nickname_pending (int, int); int get_server_nickname_pending (int); void set_server_sent (int, int); int get_server_sent (int); void set_server_try_ssl (int, int); int get_server_try_ssl (int); void set_server_ssl_enabled (int, int); int get_server_ssl_enabled (int); void set_server_save_channels (int, int); int get_server_save_channels (int); void set_server_protocol_state (int, int); int get_server_protocol_state (int); void set_server_line_length (int, int); int get_server_line_length (int); void set_server_max_cached_chan_size (int, int); int get_server_max_cached_chan_size (int); void set_server_invite_channel (int, const char *); const char * get_server_invite_channel (int); void set_server_last_notify (int, const char *); const char * get_server_last_notify (int); void set_server_joined_nick (int, const char *); const char * get_server_joined_nick (int); void set_server_public_nick (int, const char *); const char * get_server_public_nick (int); void set_server_recv_nick (int, const char *); const char * get_server_recv_nick (int); void set_server_sent_nick (int, const char *); const char * get_server_sent_nick (int); void set_server_sent_body (int, const char *); const char * get_server_sent_body (int); void set_server_quit_message (int, const char *message); const char * get_server_quit_message (int); void set_server_cookie (int, const char *); const char * get_server_cookie (int); void set_server_last_notify_nick (int, const char *); const char * get_server_last_notify_nick (int); void set_server_unique_id (int, const char *); const char * get_server_unique_id (int); void set_server_funny_min (int, int); int get_server_funny_min (int); void set_server_funny_max (int, int); int get_server_funny_max (int); void set_server_funny_flags (int, int); int get_server_funny_flags (int); void set_server_funny_match (int, const char *); const char * get_server_funny_match (int); void set_server_funny_stuff (int, int, int, int, const char *); void set_server_window_count (int, int); int get_server_window_count (int); char * serverctl (char *); #endif /* _SERVER_H_ */ epic4-2.10.2.orig/include/input.h0000644000000000000000000000447707707324325013405 0ustar /* * input.h: header for input.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __input_h__ #define __input_h__ /* miscelaneous functions */ void edit_char (unsigned char); void change_input_prompt (int); void cursor_to_input (void); int do_input_timeouts (void *); char * get_input (void); char * get_input_prompt (void); void init_input (void); void input_move_cursor (int); char input_pause (char *); void set_input (char *); void set_input_prompt (const void *); void update_input (int); /* keybinding functions */ void backward_character (char, char *); void backward_history (char, char *); void clear_screen (char, char *); void command_completion (char, char *); void cpu_saver_on (char, char *); void forward_character (char, char *); void forward_history (char, char *); void highlight_off (char, char *); void input_add_character (char, char *); void input_backspace (char, char *); void input_backward_word (char, char *); void input_beginning_of_line (char, char *); void input_clear_line (char, char *); void input_clear_to_bol (char, char *); void input_clear_to_eol (char, char *); void input_delete_character (char, char *); void input_delete_next_word (char, char *); void input_delete_previous_word (char, char *); void input_delete_to_previous_space (char, char *); void input_end_of_line (char, char *); void input_forward_word (char, char *); void input_transpose_characters (char, char *); void input_unclear_screen (char, char *); void input_yank_cut_buffer (char, char *); void insert_altcharset (char, char *); void insert_blink (char, char *); void insert_bold (char, char *); void insert_reverse (char, char *); void insert_underline (char, char *); void parse_text (char, char *); void quote_char (char, char *); void refresh_inputline (char, char *); void send_line (char, char *); void toggle_insert_mode (char, char *); void type_text (char, char *); /* this was in keys.h, but it lives in input.c, so. */ BUILT_IN_COMMAND(typecmd); /* used by update_input */ #define NO_UPDATE 0 #define UPDATE_ALL 1 #define UPDATE_FROM_CURSOR 2 #define UPDATE_JUST_CURSOR 3 #endif /* _INPUT_H_ */ epic4-2.10.2.orig/include/gailib.h0000644000000000000000000001374107752613256013473 0ustar /* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __gailib_h__ #define __gailib_h__ /* special compatibility hack */ #undef EAI_ADDRFAMILY #undef EAI_AGAIN #undef EAI_BADFLAGS #undef EAI_FAIL #undef EAI_FAMILY #undef EAI_MEMORY #undef EAI_NODATA #undef EAI_NONAME #undef EAI_SERVICE #undef EAI_SOCKTYPE #undef EAI_SYSTEM #undef EAI_BADHINTS #undef EAI_PROTOCOL #undef EAI_MAX #undef AI_PASSIVE #undef AI_CANONNAME #undef AI_NUMERICHOST #undef AI_ALL #undef AI_MASK #undef AI_ADDRCONFIG #undef AI_V4MAPPED #undef AI_DEFAULT #undef NI_MAXHOST #undef NI_MAXSERV #undef NI_NOFQDN #undef NI_NUMERICHOST #undef NI_NAMEREQD #undef NI_NUMERICSERV #undef NI_DGRAM /* * Error return codes from getaddrinfo() */ #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_MAX 14 /* * Flag values for getaddrinfo() */ #define AI_PASSIVE 0x00000001 /* get address to use bind() */ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */ #define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ /* valid flags for addrinfo */ #define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ /* special recommended flags for getipnodebyname */ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) /* * Constants for getnameinfo() */ #define NI_MAXHOST 1025 #define NI_MAXSERV 32 /* * Flag values for getnameinfo() */ #define NI_NOFQDN 0x00000001 #define NI_NUMERICHOST 0x00000002 #define NI_NAMEREQD 0x00000004 #define NI_NUMERICSERV 0x00000008 #define NI_DGRAM 0x00000010 extern int getaddrinfo__compat ( const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res); extern int getnameinfo__compat ( const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); extern void freeaddrinfo__compat (struct addrinfo *); extern const char *gai_strerror__compat (int); /* In case there is no definition of offsetof() provided - though any proper Standard C system should have one. */ #ifndef offsetof #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) #endif /************************************************ sockport.h - $Author: jnelson $ $Date: 2003/11/07 03:51:10 $ created at: Fri Apr 30 23:19:34 JST 1999 ************************************************/ #ifndef SA_LEN # ifdef HAVE_SA_LEN # define SA_LEN(sa) (sa)->sa_len # else # ifdef INET6 # define SA_LEN(sa) \ (((sa)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \ : sizeof(struct sockaddr)) # else /* by tradition, sizeof(struct sockaddr) covers most of the sockaddrs */ # define SA_LEN(sa) (sizeof(struct sockaddr)) # endif # endif #endif #ifdef HAVE_SA_LEN # define SET_SA_LEN(sa, len) (sa)->sa_len = (len) #else # define SET_SA_LEN(sa, len) (len) #endif #ifdef HAVE_SIN_LEN # define SIN_LEN(si) (si)->sin_len # define SET_SIN_LEN(si,len) (si)->sin_len = (len) #else # define SIN_LEN(si) sizeof(struct sockaddr_in) # define SET_SIN_LEN(si,len) #endif #ifndef IN_MULTICAST # define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000) # define IN_MULTICAST(i) IN_CLASSD(i) #endif #ifndef IN_EXPERIMENTAL # define IN_EXPERIMENTAL(i) ((((long)(i)) & 0xe0000000) == 0xe0000000) #endif #ifndef IN_CLASSA_NSHIFT # define IN_CLASSA_NSHIFT 24 #endif #ifndef IN_LOOPBACKNET # define IN_LOOPBACKNET 127 #endif #ifndef AF_UNSPEC # define AF_UNSPEC 0 #endif #ifndef PF_UNSPEC # define PF_UNSPEC AF_UNSPEC #endif #ifndef PF_INET # define PF_INET AF_INET #endif #if defined(HOST_NOT_FOUND) && !defined(h_errno) && !defined(__CYGWIN__) extern int h_errno; #endif #endif epic4-2.10.2.orig/include/timer.h0000644000000000000000000000077307707324325013361 0ustar /* * timer.h: header for timer.c * * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __timer_h__ #define __timer_h__ BUILT_IN_COMMAND(timercmd); void ExecuteTimers (void); char * add_timer (int, const char *, double, long, int (*) (void *), void *, const char *, int); int timer_exists (const char *ref); int remove_timer (const char *ref); Timeval TimerTimeout (void); char * timerctl (char *); #endif /* _TIMER_H_ */ epic4-2.10.2.orig/include/ctcp.h0000644000000000000000000000211407702643603013157 0ustar /* * ctcp.h: header file for ctcp.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __ctcp_h__ #define __ctcp_h__ #define CTCP_PRIVMSG 0 #define CTCP_NOTICE 1 #define CTCP_SED 0 #define CTCP_UTC 1 #define CTCP_ACTION 2 #define CTCP_DCC 3 #define CTCP_VERSION 4 #define CTCP_CLIENTINFO 5 #define CTCP_USERINFO 6 #define CTCP_ERRMSG 7 #define CTCP_FINGER 8 #define CTCP_TIME 9 #define CTCP_PING 10 #define CTCP_ECHO 11 #define CTCP_CUSTOM 12 #define NUMBER_OF_CTCPS CTCP_CUSTOM #define CTCP_DELIM_CHAR '\001' #define CTCP_DELIM_STR "\001" #define CTCP_QUOTE_CHAR '\\' #define CTCP_QUOTE_STR "\\" #define CTCP_QUOTE_EM "\r\n\001\\" extern int sed; extern int in_ctcp_flag; char * do_ctcp (const char *, const char *, char *); char * do_notice_ctcp (const char *, const char *, char *); int in_ctcp (void); void send_ctcp (int, const char *, int, const char *, ...) /*__A(4)*/; int get_ctcp_val (char *); #endif /* _CTCP_H_ */ epic4-2.10.2.orig/include/lastlog.h0000644000000000000000000000412507707324325013701 0ustar /* * lastlog.h: header for lastlog.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __lastlog_h__ #define __lastlog_h__ typedef struct lastlog_stru { int level; char *target; char *msg; struct lastlog_stru *older; struct lastlog_stru *newer; } Lastlog; #define LOG_NONE 0x000000 #define LOG_CURRENT 0x000000 #define LOG_CRAP 0x000001 #define LOG_PUBLIC 0x000002 #define LOG_MSG 0x000004 #define LOG_NOTICE 0x000008 #define LOG_WALL 0x000010 #define LOG_WALLOP 0x000020 #define LOG_NOTES 0x000040 #define LOG_OPNOTE 0x000080 #define LOG_SNOTE 0x000100 #define LOG_ACTION 0x000200 #define LOG_DCC 0x000400 #define LOG_CTCP 0x000800 #define LOG_USER1 0x001000 #define LOG_USER2 0x002000 #define LOG_USER3 0x004000 #define LOG_USER4 0x008000 #define LOG_HELP 0x010000 /* LOG_HELP is reserved */ /* Idea to have LOG_ALL include LOG_USER? from Genesis K. */ #define LOG_ALL (LOG_CRAP | LOG_PUBLIC | LOG_MSG | LOG_NOTICE | LOG_WALL | \ LOG_WALLOP | LOG_NOTES | LOG_OPNOTE | LOG_SNOTE | LOG_ACTION | \ LOG_CTCP | LOG_DCC | LOG_USER1 | LOG_USER2 | LOG_USER3 | LOG_USER4) /* * Window and Lastlog are mutually referential. So we cant include * window.h here. so to break the loop we forward declare Window here. */ struct WindowStru; extern int beep_on_level; /* XXXX */ extern int current_window_level; extern int new_server_lastlog_level; BUILT_IN_COMMAND(lastlog); void set_lastlog_level (const void *); int set_lastlog_msg_level (int); void set_lastlog_size (const void *); void set_notify_level (const void *); void add_to_lastlog (struct WindowStru *, const char *); char *bits_to_lastlog_level (int); int real_lastlog_level (void); int real_notify_level (void); int parse_lastlog_level (const char *); void set_beep_on_msg (const void *); void remove_from_lastlog (struct WindowStru *); void set_current_window_level (const void *); char *function_line (char *); char *function_lastlog (char *); void set_new_server_lastlog_level (const void *); #endif /* __lastlog_h_ */ epic4-2.10.2.orig/include/mail.h0000644000000000000000000000065610445307177013162 0ustar /* * mail.h: header for mail.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __mail_h__ #define __mail_h__ extern char mail_timeref[]; const char * check_mail (void); void mail_systimer (void); void set_mail_interval (const void *); void set_mail (const void *); void set_mail_type (const void *); #endif /* _MAIL_H_ */ epic4-2.10.2.orig/include/stack.h0000644000000000000000000000057207213031315013325 0ustar /* * stack.h - header for stack.c * * Copyright 1993 Matthew Green * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file for license information. */ #ifndef __stack_h__ #define __stack_h__ #define STACK_POP 0 #define STACK_PUSH 1 #define STACK_SWAP 2 #define STACK_LIST 3 #define STACK_DO_ALIAS 0x0001 #define STACK_DO_ASSIGN 0x0002 #endif /* __stack_h_ */ epic4-2.10.2.orig/include/alist.h0000644000000000000000000000735610375014061013345 0ustar /* * alist.h -- resizeable arrays * Copyright 1997 EPIC Software Labs */ #ifndef __alist_h__ #define __alist_h__ #include "irc.h" #include "ircaux.h" #ifdef __need_cs_alist_hash__ /* * This hash routine is for case sensitive keys. Specifically keys that * have been prefolded to an apppropriate case. */ static __inline u_32int_t cs_alist_hash (const char *s, u_32int_t *mask) { u_32int_t x = 0; if (s[0] != 0) { if (s[1] == 0) x = (s[0] << 24), *mask = 0xff000000; else if (s[2] == 0) x = (s[0] << 24) | (s[1] << 16), *mask = 0xffff0000; else x = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3], (*mask = 0xffffff00 | (s[3] ? 0xff : 0x00)); } else *mask = 0; return x; } #endif #ifdef __need_ci_alist_hash__ /* * This hash routine is for case insensitive keys. Specifically keys that * cannot be prefolded to an appropriate case but are still insensitive */ static __inline u_32int_t ci_alist_hash (const char *s, u_32int_t *mask) { u_32int_t x = 0; if (s[0] != 0) { if (s[1] == 0) x = (stricmp_table[(int)(unsigned char)s[0]] << 24), *mask = 0xff000000; else if (s[2] == 0) x = ((stricmp_table[(int)(unsigned char)s[0]] << 24) | (stricmp_table[(int)(unsigned char)s[1]] << 16)), *mask = 0xffff0000; else x = ((stricmp_table[(int)(unsigned char)s[0]] << 24) | (stricmp_table[(int)(unsigned char)s[1]] << 16) | (stricmp_table[(int)(unsigned char)s[2]] << 8) | stricmp_table[(int)(unsigned char)s[3]]), (*mask = 0xffffff00 | (s[3] ? 0xff : 0x00)); } else *mask = 0; return x; } #endif /* * Everything that is to be filed with this system should have an * identifying name as the first item in the struct. */ typedef struct { char * name; u_32int_t hash; /* Dont fill this in */ } array_item; typedef int (*alist_func) (const char *, const char *, size_t); typedef enum { HASH_INSENSITIVE, HASH_SENSITIVE } hash_type; /* * This is the actual list, that contains structs that are of the * form described above. It contains the current size and the maximum * size of the array. */ typedef struct { array_item **list; int max; int total_max; alist_func func; hash_type hash; } array; array_item * add_to_array (array *, array_item *); array_item * remove_from_array (array *, const char *); array_item * array_lookup (array *, const char *, int, int); array_item * find_array_item (array *, const char *, int *, int *); array_item * array_pop (array *, int); void * find_fixed_array_item (void *, size_t, int, const char *, int *, int *); #define ARRAY_ITEM(array, loc) ((array_item *) ((array) -> list [ (loc) ])) #define LARRAY_ITEM(array, loc) (((array) -> list [ (loc) ])) /* Written by panasync */ /* Re-written by CE */ #define GET_SOME_ARRAY_NAMES_FUNCTION(fn, array, test) \ char *(fn)(const char *str) \ { \ int i; \ char *ret = NULL; \ size_t rclue = 0; \ for (i = 0; (test); ++i) \ if (!str || !*str || wild_match(str, (array))) \ malloc_strcat_wordlist_c(&ret, space, (array), &rclue); \ return ret ? ret : malloc_strdup(empty_string); \ } #define GET_FIXED_ARRAY_NAMES_FUNCTION(fn, array) GET_SOME_ARRAY_NAMES_FUNCTION((fn), ((array)[i].name), ((array)[i].name)) #define GET_ARRAY_NAMES_FUNCTION(fn, array) GET_SOME_ARRAY_NAMES_FUNCTION((fn), ((array.list)[i]->name), (i < (array).max)) #endif epic4-2.10.2.orig/include/irc_std.h0000644000000000000000000001676210766341405013672 0ustar /* * irc_std.h: This is where we make up for operating system lossage * Originally written by Matthew Green, Copyright 1993 * Various modifications by various people since then. * * See the copyright file, or do a help ircii copyright */ #ifndef __irc_std_h #define __irc_std_h #include "defs.h" /* * Try to turn back the IPv6 monster at the gate */ #ifdef DO_NOT_USE_IPV6 # undef INET6 #else # define INET6 #endif /* * Everybody needs these ANSI headers... */ #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif /* * Everybody needs these POSIX headers... */ #include #include #include #include #include #include #include /* * Everybody needs these INET headers... */ #include #include #include #ifdef HAVE_NETDB_H #include #endif #ifdef USE_SOCKS5 # define INCLUDE_PROTOTYPES # include #endif /* * Some systems define tputs, etc in this header */ #ifdef HAVE_TERMCAP_H #include #endif /* * Deal with brokenness in and */ #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif /* * Deal with brokenness in and */ #ifdef HAVE_SYS_FCNTL_H # include #else # ifdef HAVE_FCNTL_H # include # endif #endif /* * Deal with brokenness figuring out struct direct */ #if HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif /* * First try to figure out if we can use GNU CC special features... */ #ifndef __GNUC__ # define __inline__ /* delete gcc keyword */ # define __inline # define __A(x) # define __N #else # if (__GNUC__ >= 2) && (__GNUC_MINOR__ >= 7) # define __A(x) __attribute__ ((format (printf, x, x + 1))) # define __N __attribute__ ((noreturn)) # else # define __A(x) # define __N # endif #endif /* * Figure out how to make alloca work * I took this from the autoconf documentation */ #if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) # ifndef alloca # define alloca __builtin_alloca # endif #else # if HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca char *alloca(); # endif # endif # endif #endif /* * Define the MIN and MAX macros if they don't already exist. */ #ifndef MIN # define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX # define MAX(a,b) (((a)>(b))?(a):(b)) #endif /* * Deal with brokenness with sys_errlist. */ #ifndef HAVE_STRERROR # ifndef SYS_ERRLIST_DECLARED extern char *sys_errlist[]; # endif #define strerror(x) sys_errlist[x] #endif /* * Deal with brokenness with realpath. */ #ifdef HAVE_BROKEN_REALPATH # define realpath my_realpath #endif /* * Dont trust anyone else's NULLs. */ #ifdef NULL #undef NULL #endif #define NULL (void *) 0 /* * Make sure there is TRUE and FALSE */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* * Can you believe some systems done #define this? * I was told that hurd doesn't, so this helps us on hurd. */ #ifndef MAXPATHLEN # ifndef PATHSIZE # define MAXPATHLEN 1024 # else # define MAXPATHLEN PATHSIZE # endif #endif /* * Define generic macros for signal handlers and built in commands. */ typedef RETSIGTYPE sigfunc (int); int block_signal (int); int unblock_signal (int); sigfunc *my_signal (int, sigfunc *); #define SIGNAL_HANDLER(x) \ RETSIGTYPE x (int unused) #define BUILT_IN_COMMAND(x) \ void x (const char *command, char *args, const char *subargs) typedef char Filename[MAXPATHLEN + 1]; /* * It's really really important that you never use LOCAL_COPY in the actual * argument list of a function call, because bad things can happen. Always * do your LOCAL_COPY as a separate step before you call a function. */ #define LOCAL_COPY(y) strcpy(alloca(strlen((y)) + 1), y) #define SAFE(x) (((x) && *(x)) ? (x) : empty_string) /* * Deal with our brokenness wrt ANSI. Sigh. */ #ifndef HAVE_MEMMOVE #define memmove(x, y, z) bcopy(y, x, z) #endif /* * DCC specification requires exactly a 32 bit checksum. * Kind of lame, actually. */ #ifdef UNSIGNED_LONG32 typedef unsigned long u_32int_t; #else # ifdef UNSIGNED_INT32 typedef unsigned int u_32int_t; # else typedef unsigned long u_32int_t; # endif #endif /* * Some systems (AIX) have sys/select.h, but dont include it from sys/types.h * Some systems (Solaris) have sys/select.h, but include it from sys/types.h * and dont want you to do it again. Some systems dont have sys/select.h * Configure has this all figured out for us already. */ #if defined(HAVE_SYS_SELECT_H) && defined(NEED_SYS_SELECT_H) #include #endif /* * Now we deal with lame systems that dont have correct select() * support (like aix 3.2.5, and older linux systems.) */ #ifndef NBBY # define NBBY 8 /* number of bits in a byte */ #endif /* NBBY */ #ifndef NFDBITS # define NFDBITS (sizeof(long) * NBBY) /* bits per mask */ #endif /* NFDBITS */ #ifndef FD_SETSIZE #define FD_SETSIZE 256 #endif #ifndef howmany #define howmany(x, y) (((x) + ((y) - 1)) / (y)) #endif #if defined(HAVE_SYS_SYSCTL_H) #include #endif /* * Define an RFC2553 compatable "struct sockaddr_storage" if we do not * already have one. */ #ifndef HAVE_STRUCT_SOCKADDR_STORAGE struct sockaddr_storage { #ifdef HAVE_SA_LEN u_char ss_len; u_char ss_family; #else u_short ss_family; #endif u_char padding[128 - 2]; }; #endif #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif #ifndef HAVE_STRUCT_SOCKADDR_IN6 #undef INET6 #endif #if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO) || !defined(HAVE_STRUCT_ADDRINFO) # define NEED_GAILIB # undef INET6 # ifndef HAVE_GETADDRINFO # define getaddrinfo getaddrinfo__compat # define freeaddrinfo freeaddrinfo__compat # define gai_strerror gai_strerror__compat struct addrinfo__compat { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo__compat *ai_next; /* next structure in linked list */ }; # define addrinfo addrinfo__compat # endif # ifndef HAVE_GETNAMEINFO # define getnameinfo getnameinfo__compat # endif # include "gailib.h" #endif /* * Define some lazy shorthand typedefs for commonly used structures */ typedef struct sockaddr SA; typedef struct sockaddr_storage SS; typedef struct sockaddr_in ISA; typedef struct in_addr IA; #ifdef INET6 typedef struct sockaddr_in6 ISA6; typedef struct sockaddr_in6 I6SA; typedef struct in6_addr IA6; typedef struct in6_addr I6A; #endif typedef struct addrinfo AI; typedef struct hostent Hostent; typedef struct timeval Timeval; typedef struct stat Stat; /* * Interix's getpgrp() does not take an argument, but the configure script * detects it wrongly. */ #ifdef __INTERIX # define GETPGRP_VOID #endif #endif /* __irc_std_h */ epic4-2.10.2.orig/include/vars.h0000644000000000000000000001245310445307177013211 0ustar /* * vars.h: header for vars.c * * Copyright 1990, 1995 Michael Sandroff, Matthew Green and others. * Copyright 1997 EPIC Software Labs */ #ifndef __vars_h__ #define __vars_h__ /* indexes for the irc_variable array */ enum VAR_TYPES { ALLOW_C1_CHARS_VAR, ALT_CHARSET_VAR, ALWAYS_SPLIT_BIGGEST_VAR, AUTO_NEW_NICK_VAR, AUTO_RECONNECT_VAR, AUTO_RECONNECT_DELAY_VAR, AUTO_REJOIN_VAR, AUTO_REJOIN_CONNECT_VAR, AUTO_REJOIN_DELAY_VAR, AUTO_UNMARK_AWAY_VAR, AUTO_WHOWAS_VAR, BAD_STYLE_VAR, BANNER_VAR, BANNER_EXPAND_VAR, BEEP_VAR, BEEP_MAX_VAR, BEEP_ON_MSG_VAR, BEEP_WHEN_AWAY_VAR, BLINK_VIDEO_VAR, BOLD_VIDEO_VAR, CHANNEL_NAME_WIDTH_VAR, CLIENTINFO_VAR, CLOCK_VAR, CLOCK_24HOUR_VAR, CLOCK_FORMAT_VAR, CLOCK_INTERVAL_VAR, CMDCHARS_VAR, COLOR_VAR, COMMAND_MODE_VAR, COMMENT_HACK_VAR, CONNECT_TIMEOUT_VAR, CONTINUED_LINE_VAR, CPU_SAVER_AFTER_VAR, CPU_SAVER_EVERY_VAR, CURRENT_WINDOW_LEVEL_VAR, DCC_AUTO_SEND_REJECTS_VAR, DCC_DEQUOTE_FILENAMES_VAR, DCC_LONG_PATHNAMES_VAR, DCC_SLIDING_WINDOW_VAR, DCC_STORE_PATH_VAR, DCC_TIMEOUT_VAR, DCC_USE_GATEWAY_ADDR_VAR, DEBUG_VAR, DISPATCH_UNKNOWN_COMMANDS_VAR, DISPLAY_VAR, DISPLAY_ANSI_VAR, DISPLAY_PC_CHARACTERS_VAR, DO_NOTIFY_IMMEDIATELY_VAR, EIGHT_BIT_CHARACTERS_VAR, FLOATING_POINT_MATH_VAR, FLOATING_POINT_PRECISION_VAR, FLOOD_AFTER_VAR, FLOOD_IGNORE_VAR, FLOOD_MASKUSER_VAR, FLOOD_RATE_VAR, FLOOD_RATE_PER_VAR, FLOOD_USERS_VAR, FLOOD_WARNING_VAR, FULL_STATUS_LINE_VAR, HELP_PAGER_VAR, HELP_PATH_VAR, HELP_PROMPT_VAR, HELP_WINDOW_VAR, HIDE_PRIVATE_CHANNELS_VAR, HIGHLIGHT_CHAR_VAR, HIGH_BIT_ESCAPE_VAR, HISTORY_VAR, HISTORY_CIRCLEQ_VAR, HOLD_SLIDER_VAR, INDENT_VAR, INPUT_ALIASES_VAR, INPUT_PROMPT_VAR, INSERT_MODE_VAR, INVERSE_VIDEO_VAR, KEY_INTERVAL_VAR, LASTLOG_VAR, LASTLOG_LEVEL_VAR, LOAD_PATH_VAR, LOG_VAR, LOGFILE_VAR, LOG_REWRITE_VAR, MAIL_VAR, MAIL_INTERVAL_VAR, /* MAIL_TYPE_VAR, */ MANGLE_INBOUND_VAR, MANGLE_LOGFILES_VAR, MANGLE_OUTBOUND_VAR, MAX_RECONNECTS_VAR, METRIC_TIME_VAR, MIRC_BROKEN_DCC_RESUME_VAR, MODE_STRIPPER_VAR, ND_SPACE_MAX_VAR, NEW_SERVER_LASTLOG_LEVEL_VAR, NOTIFY_VAR, NOTIFY_INTERVAL_VAR, NOTIFY_LEVEL_VAR, NOTIFY_ON_TERMINATION_VAR, NOTIFY_USERHOST_AUTOMATIC_VAR, NO_CONTROL_LOG_VAR, NO_CTCP_FLOOD_VAR, NO_FAIL_DISCONNECT_VAR, NUM_OF_WHOWAS_VAR, OUTPUT_REWRITE_VAR, PAD_CHAR_VAR, QUIT_MESSAGE_VAR, RANDOM_SOURCE_VAR, REALNAME_VAR, REVERSE_STATUS_LINE_VAR, SCREEN_OPTIONS_VAR, SCROLL_VAR, SCROLLBACK_VAR, SCROLLBACK_RATIO_VAR, SCROLL_LINES_VAR, SECURITY_VAR, SHELL_VAR, SHELL_FLAGS_VAR, SHELL_LIMIT_VAR, SHOW_CHANNEL_NAMES_VAR, SHOW_END_OF_MSGS_VAR, SHOW_NUMERICS_VAR, SHOW_STATUS_ALL_VAR, SHOW_WHO_HOPCOUNT_VAR, SSL_CERTFILE_VAR, SSL_KEYFILE_VAR, SSL_PATH_VAR, STATUS_AWAY_VAR, STATUS_CHANNEL_VAR, STATUS_CHANOP_VAR, STATUS_CLOCK_VAR, STATUS_CPU_SAVER_VAR, STATUS_DOES_EXPANDOS_VAR, STATUS_FORMAT_VAR, STATUS_FORMAT1_VAR, STATUS_FORMAT2_VAR, STATUS_HALFOP_VAR, STATUS_HOLD_VAR, STATUS_HOLD_LINES_VAR, STATUS_INSERT_VAR, STATUS_MAIL_VAR, STATUS_MODE_VAR, STATUS_NICK_VAR, STATUS_NOSWAP_VAR, STATUS_NOTIFY_VAR, STATUS_NO_REPEAT_VAR, STATUS_OPER_VAR, STATUS_OVERWRITE_VAR, STATUS_QUERY_VAR, STATUS_SCROLLBACK_VAR, STATUS_SERVER_VAR, STATUS_SSL_OFF_VAR, STATUS_SSL_ON_VAR, STATUS_TRUNCATE_RHS_VAR, STATUS_UMODE_VAR, STATUS_USER0_VAR, STATUS_USER1_VAR, STATUS_USER10_VAR, STATUS_USER11_VAR, STATUS_USER12_VAR, STATUS_USER13_VAR, STATUS_USER14_VAR, STATUS_USER15_VAR, STATUS_USER16_VAR, STATUS_USER17_VAR, STATUS_USER18_VAR, STATUS_USER19_VAR, STATUS_USER2_VAR, STATUS_USER20_VAR, STATUS_USER21_VAR, STATUS_USER22_VAR, STATUS_USER23_VAR, STATUS_USER24_VAR, STATUS_USER25_VAR, STATUS_USER26_VAR, STATUS_USER27_VAR, STATUS_USER28_VAR, STATUS_USER29_VAR, STATUS_USER3_VAR, STATUS_USER30_VAR, STATUS_USER31_VAR, STATUS_USER32_VAR, STATUS_USER33_VAR, STATUS_USER34_VAR, STATUS_USER35_VAR, STATUS_USER36_VAR, STATUS_USER37_VAR, STATUS_USER38_VAR, STATUS_USER39_VAR, STATUS_USER4_VAR, STATUS_USER5_VAR, STATUS_USER6_VAR, STATUS_USER7_VAR, STATUS_USER8_VAR, STATUS_USER9_VAR, STATUS_VOICE_VAR, STATUS_WINDOW_VAR, SUPPRESS_FROM_REMOTE_SERVER, SWITCH_CHANNELS_BETWEEN_WINDOWS_VAR, SWITCH_CHANNEL_ON_PART_VAR, TAB_VAR, TAB_MAX_VAR, TERM_DOES_BRIGHT_BLINK_VAR, TRANSLATION_VAR, TRANSLATION_PATH_VAR, UNDERLINE_VIDEO_VAR, USER_INFO_VAR, #define USERINFO_VAR USER_INFO_VAR VERBOSE_CTCP_VAR, WORD_BREAK_VAR, WSERV_PATH_VAR, WSERV_TYPE_VAR, XTERM_VAR, XTERM_OPTIONS_VAR, NUMBER_OF_VARIABLES }; /* var_settings indexes ... also used in display.c for highlights */ #define OFF 0 #define ON 1 #define TOGGLE 2 #define DEBUG_COMMANDS 0x0001 #define DEBUG_EXPANSIONS 0x0002 #define DEBUG_FUNCTIONS 0x0004 BUILT_IN_COMMAND(setcmd); int do_boolean (char *, int *); int get_int_var (enum VAR_TYPES); char * get_string_var (enum VAR_TYPES); double get_float_var (enum VAR_TYPES); void set_int_var (enum VAR_TYPES, int); void set_float_var (enum VAR_TYPES, double); void set_string_var (enum VAR_TYPES, const char *); void init_variables (void); char *make_string_var (const char *); int charset_size (void); void save_variables (FILE *, int); void set_var_value (int, char *); void do_stack_set (int, char *); int parse_mangle (const char *, int, char **); char *get_set (const char *); #endif /* _VARS_H_ */ epic4-2.10.2.orig/include/newio.h0000644000000000000000000000105607656627300013357 0ustar /* * newio.h -- header file for newio.c * * Copyright 1990, 1995 Michael Sandrof, Matthew Green * Copyright 1997 EPIC Software Labs */ #ifndef __newio_h__ #define __newio_h__ extern int dgets_errno; ssize_t dgets (int, char *, size_t, int, void *); int new_select (fd_set *, fd_set *, struct timeval *); int new_open (int); int new_open_for_writing (int); int new_close (int); void set_socket_options (int); size_t get_pending_bytes (int); int new_hold_fd (int); int new_unhold_fd (int); #define IO_BUFFER_SIZE 8192 #endif epic4-2.10.2.orig/include/irc.h0000644000000000000000000001206210755674317013016 0ustar /* * irc.h: header file for all of ircII! * * Copyright 1990 Michael Sandrof * Copyright 1991 Troy Rollo * Copyright 1994 Matthew Green * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __irc_h__ #define __irc_h__ #define IRCII_COMMENT "Accept no limitations." #define IRCRC_NAME "/.ircrc" #define EPICRC_NAME "/.epicrc" #define EMAIL_CONTACT "list@epicsol.org" /* * Here you can set the in-line quote character, normally backslash, to * whatever you want. Note that we use two backslashes since a backslash is * also C's quote character. You do not need two of any other character. */ #define QUOTE_CHAR '\\' #include "defs.h" #include "config.h" #include "irc_std.h" #include "debug.h" /* these define what characters do, inverse, underline, bold and all off */ /* * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION * CAUTION CAUTION * CAUTION DONT CHANGE THESE! CAUTION * CAUTION CAUTION * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION * * If you want to change the key bindings for your highlight characters, * then please use /bind .. BOLD, /bind .. REVERSE, /bind .. UNDERLINE, * or /bind .. HIGHLIGHT_OFF. These are REQUIRED to be set to the way * they are now, as the keybindings simply change whatever you bind these * to these actual values, so if you change these, it will break how * other people see your messages! */ #define REV_TOG '\026' /* ^V */ #define REV_TOG_STR "\026" #define UND_TOG '\037' /* ^_ */ #define UND_TOG_STR "\037" #define BOLD_TOG '\002' /* ^B */ #define BOLD_TOG_STR "\002" #define BLINK_TOG '\006' /* ^F (think flash) */ #define BLINK_TOG_STR "\006" #define ALL_OFF '\017' /* ^O */ #define ALL_OFF_STR "\017" #define ROM_CHAR '\022' /* ^R */ #define ROM_CHAR_STR "\022" #define ND_SPACE '\023' /* ^S */ #define ND_SPACE_STR "\023" #define ALT_TOG '\005' /* ^E (think Extended) */ #define ALT_TOG_STR "\005" #define IRCD_BUFFER_SIZE 512 /* Last two bytes are always reserved for \r\n */ #define MAX_PROTOCOL_SIZE IRCD_BUFFER_SIZE - 2 #define BIG_BUFFER_SIZE (IRCD_BUFFER_SIZE * 4) /* * This assumes a channel size less than 10 characters. * That should suffice for most non-trivial situations. * Otherwise, your privmsg may get truncated... * This should be fixed by doing it dynamically. */ #ifndef INPUT_BUFFER_SIZE #define INPUT_BUFFER_SIZE (IRCD_BUFFER_SIZE - 20) #endif #define NICKNAME_LEN 30 #define NAME_LEN 80 #define REALNAME_LEN 50 #define PATH_LEN 1024 /* irc.c's global variables */ extern int away_set; extern int background; extern int current_numeric; extern int dead; extern volatile int dead_children_processes; extern int dumb_mode; extern int foreground; extern int global_beep_ok; extern int inhibit_logging; extern int irc_port; extern int ircrc_loaded; extern int loading_global; extern int oper_command; extern int privileged_output; extern int quick_startup; extern int trusted_output; extern int use_flow_control; extern int use_iexten; extern int who_mask; extern int use_input; extern int waiting_out; extern int waiting_in; extern char * args_str; extern char * cannot_open; extern const char * compile_info; extern char * cut_buffer; extern char * default_channel; extern char empty_string[]; extern char space[]; extern char star[]; extern char dot[]; extern char hostname[NAME_LEN + 1]; extern const char internal_version[]; extern char * ircrc_file; extern char * epicrc_file; extern char * startup_file; extern char * irc_lib; extern const char irc_version[]; extern char * last_notify_nick; extern char * LocalHostName; extern char * my_path; extern char nickname[NICKNAME_LEN + 1]; extern char off[]; extern char on[]; extern char one[]; extern char realname[REALNAME_LEN + 1]; extern const char ridiculous_version_name[]; extern const unsigned long commit_id; extern char * send_umode; extern const char * unknown_userhost; extern const char useful_info[]; extern char username[NAME_LEN + 1]; extern char userhost[NAME_LEN + 1]; extern char zero[]; extern char comma[]; extern char * highlight_char; extern ISA * LocalIPv4Addr; #ifdef INET6 extern ISA6 * LocalIPv6Addr; #endif extern fd_set readables, held_readables; extern fd_set writables, held_writables; extern int global_max_fd; extern struct timeval start_time; extern struct timeval idle_time; extern struct timeval now; extern struct timeval input_timeout; /* irc.c's extern functions */ char get_a_char (void); void get_line_return (char, char *); void get_line (char *, int, void (*) (char, char *)); void io (const char *); void irc_exit (int, const char *, ...) /*__A(2)*/ __N; void irc_quit (char, char *); #include "reg.h" void dump_load_stack (int); /* XXX command.c */ const char * current_filename (void); /* XXX command.c */ const char * current_loader (void); /* XXX command.c */ int current_line (void); /* XXX command.c */ char * current_package (void); /* XXX command.c */ /* keep track of signals for scripted events */ volatile int signals_caught[NSIG]; #endif /* __irc_h */ epic4-2.10.2.orig/include/keys.h0000644000000000000000000000417207707324325013211 0ustar /* * keys.h: header for keys.c * * Copyright 2002 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __keys_h__ #define __keys_h__ /* This is a typedef for a function used with the /BIND system. The * functions all live in input.c. Following it is a macro to quickly define * functions to handle keybindings. */ typedef void (*BindFunction) (char, char *); #define BUILT_IN_BINDING(x) void x (char key, char *string) /* This is the structure used to hold binding functions. */ struct Binding { struct Binding *next; /* linked-list stuff. :) */ char *name; /* the name of this binding */ BindFunction func; /* function to use ... */ char *alias; /* OR alias to call. one or the other. */ char *filename; /* the package which added this binding */ }; extern struct Binding *binding_list; /* list head for keybindings */ struct Binding *add_binding (const char *, BindFunction, char *); void remove_binding (char *); struct Binding *find_binding (const char *); void init_binds (void); #define KEYMAP_SIZE 256 struct Key { unsigned char val; /* the key value */ unsigned char changed; /* set if this binding was changed post-startup */ struct Binding *bound; /* the function we're bound to. */ struct Key *map; /* a map of subkeys (may be NULL) */ struct Key *owner; /* the key which contains the map we're in. */ char *stuff; /* 'stuff' associated with our binding */ char *filename; /* the package which added this binding */ }; extern struct Key *head_keymap; /* the head keymap. the root of the keys. */ struct Key *handle_keypress (struct Key *, struct timeval, unsigned char); struct Key *timeout_keypress(struct Key *, struct timeval); BUILT_IN_COMMAND(bindcmd); BUILT_IN_COMMAND(rbindcmd); BUILT_IN_COMMAND(parsekeycmd); void init_keys (void); void init_termkeys (void); void set_key_interval(const void *); void save_bindings (FILE *, int); void remove_bindings (void); void unload_bindings (const char *); void do_stack_bind (int, char *); char * bindctl (char *); #endif /* __keys_h_ */ epic4-2.10.2.orig/include/notify.h0000644000000000000000000000152107707324325013541 0ustar /* * notify.h: header for notify.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __notify_h__ #define __notify_h__ #include "alist.h" struct notify_stru; typedef struct notify_alist { struct notify_stru ** list; int max; int max_alloc; alist_func func; hash_type hash; char * ison; } NotifyList; extern char notify_timeref[]; BUILT_IN_COMMAND(notify); void do_notify (void); void notify_mark (int, const char *, int, int); void save_notify (FILE *); void set_notify_handler (char *); void make_notify_list (int); char * get_notify_nicks (int, int); void destroy_notify_list (int); void notify_systimer (void); void set_notify_interval (const void *); void set_notify (const void *); #endif /* _NOTIFY_H_ */ epic4-2.10.2.orig/include/words.h0000644000000000000000000000527607702643603013400 0ustar /* * Copyright © 1997, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __WORDS_H__ #define __WORDS_H__ #ifdef Char #undef Char #endif #define Char const char /* From words.c */ #define SOS -32767 #define EOS 32767 /* * These are the "extended" values, and determine whether move_word_rel * and real_move_to_abs_word are to honor "double quoted words" or not. */ #define DWORD_NEVER 0 /* Never honor double quoted words */ #define DWORD_YES 1 /* Support only if /xdebug extractw */ #define DWORD_ALWAYS 2 /* Always honor double quoted words */ char * search_for (char *, char **, char *, int); ssize_t move_word_rel (Char *, Char **, int, int, Char *); const char * real_move_to_abs_word (Char *, Char **, int, int, Char *); #define move_to_abs_word(a, b, c) real_move_to_abs_word(a, b, c, DWORD_YES, "\""); char * real_extract (char *, int, int, int); char * real_extract2 (Char *, int, int, int); #define extract(a, b, c) real_extract(a, b, c, DWORD_NEVER) #define extract2(a, b, c) real_extract2(a, b, c, DWORD_NEVER) #define extractw(a, b, c) real_extract(a, b, c, DWORD_YES) #define extractw2(a, b, c) real_extract2(a, b, c, DWORD_YES) int count_words (Char *str, int extended, Char *quotes); #endif epic4-2.10.2.orig/include/names.h0000644000000000000000000000421510642721425013331 0ustar /* * names.h: Header for names.c * * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __names_h__ #define __names_h__ #ifdef Char #undef Char #endif #define Char const char void add_channel (Char *, int); void remove_channel (Char *, int); void add_to_channel (Char *, Char *, int, int, int, int, int); void add_userhost_to_channel (Char *, Char *, int, Char *); void remove_from_channel (Char *, Char *, int); void rename_nick (Char *, Char *, int); int im_on_channel (Char *, int); int is_on_channel (Char *, Char *); int is_chanop (Char *, Char *); int is_chanvoice (Char *, Char *); int is_halfop (Char *, Char *); int number_on_channel (Char *, int); char * create_nick_list (Char *, int); char * create_chops_list (Char *, int); char * create_nochops_list (Char *, int); void update_channel_mode (Char *, Char *); Char * get_channel_key (Char *, int); char * get_channel_mode (Char *, int); int is_channel_private (Char *, int); int is_channel_nomsgs (Char *, int); void list_channels (void); void switch_channels (char, char *); void change_server_channels (int, int); void destroy_server_channels (int); void reconnect_all_channels (void); Char * what_channel (Char *); Char * walk_channels (int, Char *); Char * fetch_userhost (int, Char *); int get_channel_oper (Char *, int); int get_channel_voice (Char *, int); int get_channel_halfop (Char *, int); int chanmodetype (char); int get_channel_winref (Char *, int); void set_channel_window (Char *, int, int, int); char * create_channel_list (int); void channel_server_delete (int); void save_channels (int); void remove_from_mode_list (Char *); int auto_rejoin_callback (void *); void reassign_window_channels (int); void move_channel_to_window (Char *, int, int, int); char * scan_channel (char *); Char * check_channel_type (Char *); int channel_is_syncing (Char *, int); void channel_not_waiting (Char *, int); void channel_check_windows (void); void cant_join_channel (Char *, int); Char * window_current_channel (int, int); char * window_all_channels (int, int); #endif /* _NAMES_H_ */ epic4-2.10.2.orig/include/defs.h.in0000644000000000000000000002035010770363043013552 0ustar /* include/defs.h.in. Generated automatically from configure.in by autoheader. */ /* Define if on AIX 3. System headers sometimes define this. We just want to avoid a redefinition error message. */ #ifndef _ALL_SOURCE #undef _ALL_SOURCE #endif /* Define if using alloca.c. */ #undef C_ALLOCA /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define if the `getpgrp' function takes no argument. */ #undef GETPGRP_VOID /* Define to `int' if doesn't define. */ #undef gid_t /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to `int' if doesn't define. */ #undef mode_t /* Define if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Define if your Fortran 77 compiler doesn't accept -c and -o together. */ #undef F77_NO_MINUS_C_MINUS_O /* Define to `int' if doesn't define. */ #undef pid_t /* Define if you need to in order for stat and other things to work. */ #undef _POSIX_SOURCE /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define to the type of arg1 for select(). */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for select(). */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg5 for select(). */ #undef SELECT_TYPE_ARG5 /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if `sys_siglist' is declared by . */ #undef SYS_SIGLIST_DECLARED /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to `int' if doesn't define. */ #undef uid_t /* Define this if you have fpathconf(2) */ #undef HAVE_FPATHCONF /* define this if you have getpass(3) */ #undef HAVE_GETPASS /* define this if you have getpgid(2) */ #undef HAVE_GETPGID /* define this if you have gettimeofday(2) */ #undef HAVE_GETTIMEOFDAY /* Define this if you have killpg(2) */ #undef HAVE_KILLPG /* define this if you have memmove(3) */ #undef HAVE_MEMMOVE /* define this if you have setenv(3) */ #undef HAVE_SETENV /* define this if you have unsetenv(3) */ #undef HAVE_UNSETENV /* define this if you have setsid(2) */ #undef HAVE_SETSID /* define this if you have snprintf(3) */ #undef HAVE_SNPRINTF /* define this if you have strerror(3) */ #undef HAVE_STRERROR /* define if you have strtoul(3) */ #undef HAVE_STRTOUL /* define this if you have sysconf(3) */ #undef HAVE_SYSCONF /* define this if you have uname(2) */ #undef HAVE_UNAME /* define this if you have vsnprintf(3) */ #undef HAVE_VSNPRINTF /* define this if you don't have struct linger */ #undef NO_STRUCT_LINGER /* define if allow sys/time.h with time.h */ #undef TIME_WITH_SYS_TIME /* Define this if your getpgrp is broken posix */ #undef GETPGRP_VOID /* define this if an unsigned long is 32 bits */ #undef UNSIGNED_LONG32 /* define this if an unsigned int is 32 bits */ #undef UNSIGNED_INT32 /* define this if you are unsure what is is 32 bits */ #undef UNKNOWN_32INT /* Define this if you need to include sys/select.h */ #undef NEED_SYS_SELECT_H /* * SOCKS 4 && 5 support. */ #undef SOCKS #undef USE_SOCKS #undef USE_SOCKS5 #undef connect #undef getsockname #undef bind #undef accept #undef listen #undef select #undef dup #undef dup2 #undef fclose #undef gethostbyname #undef read #undef recv #undef recvfrom #undef rresvport #undef send #undef sendto #undef shutdown #undef write #undef Rconnect #undef Rgetsockname #undef Rgetpeername #undef Rbind #undef Raccept #undef Rlisten #undef Rselect /* * Perl support. */ #undef PERL /* Define this if you have setsid() */ #undef HAVE_SETSID /* Define this if you have tparm(2) */ #undef HAVE_TPARM /* Define this if you have getlogin(3) */ #undef HAVE_GETLOGIN /* Define this if you have terminfo support */ #undef HAVE_TERMINFO /* Define this if you have fchdir() */ #undef HAVE_FCHDIR /* Define this if you have realpath() */ #undef HAVE_REALPATH /* Define this if you have strlcpy() */ #undef HAVE_STRLCPY /* Define this if you have strlcat() */ #undef HAVE_STRLCAT /* Define this if you have hstrerror, for h_errno use */ #undef HAVE_HSTRERROR /* Define this if you want OPENSSL support */ #undef HAVE_SSL /* Define this if you have sysctlbyname() */ #undef HAVE_SYSCTLBYNAME /* Define this if you have SO_SNDLOWAT */ #undef HAVE_SO_SNDLOWAT /* Define this if you have struct sockaddr_storage */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define this if your system has SA_LEN in its sockaddrs */ #undef HAVE_SA_LEN /* Define this if you don't have siglen_t */ #undef HAVE_SOCKLEN_T /* Define this if you have a getaddrinfo() with missing functionality */ #undef GETADDRINFO_DOES_NOT_DO_AF_UNIX /* Define this if you do not want INET6 support */ #undef DO_NOT_USE_IPV6 /* Define this if you have struct addrinfo */ #undef HAVE_STRUCT_ADDRINFO /* Define this if you have struct sockaddr_in6 */ #undef HAVE_STRUCT_SOCKADDR_IN6 /* Define this if you have getservbyport() */ #undef HAVE_GETSERVBYPORT /* Define this if you have getaddrinfo */ #undef HAVE_GETADDRINFO /* Define this if you have getnameinfo */ #undef HAVE_GETNAMEINFO /* Define this if you have sys_siglist declared */ #undef SYS_SIGLIST_DECLARED /* Define this if you have a broken realpath */ #undef HAVE_BROKEN_REALPATH /* Define this if you have TCL */ #undef TCL /* Define this if you have clock_gettime() */ #undef HAVE_CLOCK_GETTIME /* Define this if you have intptr_t */ #undef HAVE_INTPTR_T /* Define this if you have a (long long) */ #undef HAVE_LONG_LONG /* Define this if you have atoll() */ #undef HAVE_ATOLL /* Define this if you have strtoll() */ #undef HAVE_STRTOLL /* Define this if you have atoq() */ #undef HAVE_ATOQ /* Define this if you have finite() */ #undef HAVE_FINITE /* Define this if you have isfinite() */ #undef HAVE_ISFINITE /* Define this if your requires (x/open curses) */ #undef TERM_H_REQUIRES_CURSES_H /* Define this if your can't be used */ #undef DONT_USE_TERM_H /* The number of bytes in a long long. */ #undef SIZEOF_LONG_LONG /* The number of bytes in a unsigned int. */ #undef SIZEOF_UNSIGNED_INT /* The number of bytes in a unsigned long. */ #undef SIZEOF_UNSIGNED_LONG /* Define if you have the header file. */ #undef HAVE_DIRENT_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have the header file. */ #undef HAVE_NDIR_H /* Define if you have the header file. */ #undef HAVE_NETDB_H /* Define if you have the header file. */ #undef HAVE_REGEX_H /* Define if you have the header file. */ #undef HAVE_STDINT_H /* Define if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define if you have the header file. */ #undef HAVE_SYS_FCNTL_H /* Define if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define if you have the header file. */ #undef HAVE_SYS_FILIO_H /* Define if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define if you have the header file. */ #undef HAVE_SYS_SYSCTL_H /* Define if you have the header file. */ #undef HAVE_SYS_SYSLIMITS_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYS_UN_H /* Define if you have the header file. */ #undef HAVE_TERM_H /* Define if you have the header file. */ #undef HAVE_TERMCAP_H epic4-2.10.2.orig/include/screen.h0000644000000000000000000001203407656627300013513 0ustar /* * screen.h: header for screen.c * * Copyright 1993 Matthew Green * Copyright 1997 EPIC Software Labs * See the copyright file, or type help ircii copyright */ #ifndef __screen_h__ #define __screen_h__ /* To get the definition of Window */ #include "window.h" #define WAIT_PROMPT_LINE 0x01 #define WAIT_PROMPT_KEY 0x02 #define WAIT_PROMPT_DUMMY 0x04 typedef struct PromptStru { char *prompt; char *data; int type; int echo; void (*func) (char *, char *); struct PromptStru *next; } WaitPrompt; typedef struct PhysicalTTY { /* Output stuff */ FILE *fpin; /* The input FILE (eg, stdin) */ int fdin; /* The input FD (eg, 0) */ FILE *fpout; /* The output FILE (eg, stdout) */ int fdout; /* The output FD (eg, 1) */ int control; /* The control FD (to wserv) */ int wserv_version; /* The version of wserv talking to */ /* Input line and prompt stuff */ char input_buffer[INPUT_BUFFER_SIZE+1]; /* Current user input for us */ int buffer_pos; /* Where on input line cursor is */ int buffer_min_pos; /* First position after prompt */ int input_cursor; /* Where the cursor is on input line */ int input_visible; int input_zone_len; int input_start_zone; int input_end_zone; char *input_prompt; int input_prompt_len; int input_prompt_malloc; int input_line; char saved_input_buffer[INPUT_BUFFER_SIZE+1]; int saved_buffer_pos; int saved_min_buffer_pos; WaitPrompt *promptlist; /* Key qualifier stuff */ int quote_hit; /* True after QUOTE_CHARACTER hit */ struct timeval last_press; /* The last time a key was pressed. Used to determine key-independence. */ struct Key *last_key; /* The last Key pressed. */ char *tty_name; int co; int li; int old_co; int old_li; } Pty; typedef struct ScreenStru { /* List stuff and overhead */ int screennum; /* Refnum for this screen */ Window *current_window; /* Current primary window target */ unsigned last_window_refnum; /* Most previous current window */ Window *window_list; /* The top window on me */ Window *window_list_end; /* The bottom window on me */ Window *cursor_window; /* The window that has my cursor */ int visible_windows; /* Number of windows on me */ WindowStack *window_stack; /* Number of windows on my stack */ struct ScreenStru *prev; /* Next screen in list */ struct ScreenStru *next; /* Previous screen in list */ /* Output stuff */ FILE *fpin; /* The input FILE (eg, stdin) */ int fdin; /* The input FD (eg, 0) */ FILE *fpout; /* The output FILE (eg, stdout) */ int fdout; /* The output FD (eg, 1) */ int control; /* The control FD (to wserv) */ int wserv_version; /* The version of wserv talking to */ /* Input line and prompt stuff */ char input_buffer[INPUT_BUFFER_SIZE+1]; /* Current user input for us */ int buffer_pos; /* Where on input line cursor is */ int buffer_min_pos; /* First position after prompt */ int input_cursor; /* Where the cursor is on input line */ int input_visible; int input_zone_len; int input_start_zone; int input_end_zone; char *input_prompt; int input_prompt_len; int input_prompt_malloc; int input_line; char saved_input_buffer[INPUT_BUFFER_SIZE+1]; int saved_buffer_pos; int saved_min_buffer_pos; WaitPrompt *promptlist; /* Key qualifier stuff */ int quote_hit; /* True after QUOTE_CHARACTER hit */ struct timeval last_press; /* The last time a key was pressed. Used to determine key-independence. */ struct Key *last_key; /* The last Key pressed. */ char *tty_name; int co; int li; int old_co; int old_li; int alive; } Screen; /* Stuff for the screen/xterm junk */ #define ST_NOTHING -1 #define ST_SCREEN 0 #define ST_XTERM 1 void add_wait_prompt (const char *, void (*)(char *, char *), char *, int, int); void set_current_screen (Screen *); void window_redirect (char *, int); int check_screen_redirect (char *); void add_to_screen (const unsigned char *); unsigned char** split_up_line (const unsigned char *, int); int output_line (const unsigned char *); void cursor_not_in_display (Screen *); void cursor_in_display (Window *); int is_cursor_in_display (Screen *); void repaint_one_line (Window *, int); /* Don't use */ void repaint_window_body (Window *); Screen *create_new_screen (void); Window *create_additional_screen (void); void kill_screen (Screen *); void close_all_screen (void); void do_screens (fd_set *, fd_set *); const u_char *all_off (void); extern int normalize_never_xlate; extern int normalize_permit_all_attributes; u_char *normalize_string (const u_char *, int); u_char *denormalize_string (const u_char *); char *normalize_color (int, int, int, int); ssize_t skip_ctl_c_seq (const u_char *, int *, int *); u_char **prepare_display (const u_char *, int, int *, int); int output_with_count (const unsigned char *, int, int); /* Dont do any word-wrapping, just truncate each line at its place. */ #define PREPARE_NOWRAP 0x01 extern Screen *main_screen; extern Screen *last_input_screen; extern Screen *screen_list; extern Screen *output_screen; #endif /* _SCREEN_H_ */ epic4-2.10.2.orig/include/options0000644000000000000000000000410607757770523013512 0ustar /* * What we're doing here is defining a unique string that describes what * compile-time options are in use. The string is then accessible though * a special builtin function. The point is to allow script writers to * know what has been enabled/disabled so they don't try to use a * feature that in't available. As such, only #define's that really * affect scripting or direct user interaction are included in the * string. Each option is assigned a unique letter, all of which are * concatenated together to form a strig that looks like an irc server's * version string. Some of the options are assigned to non-obvious letters * since the string has to be case insensitive. */ /* Letters left: dhjprwy */ const char compile_time_options[] = { #if 1 'a', #endif /* WIND_STACK is now the default */ #ifdef NO_BOTS 'b', #endif /* NO_BOTS */ #if 1 'c', #endif /* COLOR is now the default */ #ifdef EXEC_COMMAND 'e', #endif /* EXEC_COMMAND */ #ifdef USE_FLOW_CONTROL 'f', #endif /* USE_FLOW_CONTROL */ #if 1 'g', #endif /* INCLUDE_GLOB_FUNCTION is now the default */ #ifdef MIRC_BROKEN_DCC_RESUME 'i', #endif /* MIRC_BROKEN_DCC_RESUME */ #ifdef HACKED_DCC_WARNING 'k', #endif /* HACKED_DCC_WARNING */ #ifdef HAVE_LONG_LONG #if defined(HAVE_STRTOLL) || defined(HAVE_ATOQ) 'l', #endif #endif #if 1 'm', #endif /* Indicate that we have /SET COLOR instead of /SET CONTROL_C_COLOR */ #if 1 'n', #endif /* LONG NICKNAMES are now the default */ #ifdef ENFORCE_STRICTER_PROTOCOL 'o', #endif /* ENFORCE_STRICTER_PROTOCOL */ #ifdef QUIT_ON_OPERATOR_KILL 'q', #endif /* QUIT_ON_OPERATOR_KILL */ #ifdef STRIP_EXTRANEOUS_SPACES 's', #endif /* STRIP_EXTRANEOUS_SPACES */ #ifdef I_DONT_TRUST_MY_USERS 't', #endif /* I_DONT_TRUST_MY_USERS */ #ifdef UNAME_HACK 'u', #endif /* UNAME_HACK */ #ifdef USE_DCC_CHECKSUM 'v', #endif /* USE_DCC_CHECKSUM */ #if 1 'x', #endif /* EXPERIMENTAL_STACK_HACK is now the default */ #if 1 'z', #endif /* ALLOW_STOP_IRC is now the default */ '\0' }; epic4-2.10.2.orig/include/parse.h0000644000000000000000000000137407724250174013350 0ustar /* * parse.h * * Copyright 1993 Matthew Green * Copyright 1997 EPIC Software Labs * See the Copyright file for license information. */ #ifndef __parse_h__ #define __parse_h__ typedef struct { const char *command; void (*inbound_handler) (const char *, const char *, const char **); void (*outbound_handler) (char *); int flags; } protocol_command; extern protocol_command rfc1459[]; extern int num_protocol_cmds; #define PROTO_NOQUOTE 1 << 0 #define PROTO_DEPREC 1 << 1 void rfc1459_odd (const char *, const char *, const char **); const char *PasteArgs (const char **, int); void parse_server (const char *, size_t); int is_channel (const char *); extern const char *FromUserHost; #if 0 extern int doing_privmsg; #endif #endif epic4-2.10.2.orig/include/sgroup.h0000644000000000000000000000400707556071767013565 0ustar /* * server groups */ struct sgroup_typ { Protocol * proto; /* The protocol we belong to */ Server * server_list; /* The servers we own */ int active; /* One server is connected */ int reconnect_pending; /* Should be active but not */ char * name; /* The name of this group */ char * nickname; /* Our primary nickname */ char * s_nickname; /* Last NICK sent */ char * d_nickname; /* Default nickname */ int nickname_pending; /* Is a NICK pending? */ int fudge_factor; /* How much s_nickname fudged */ char * away; /* Current away message */ char * umodes; /* Possible user modes */ char umode[54]; /* Current user modes */ long flags; /* Miscelaneous flags */ }; typedef struct sgroup_typ SGroup; struct server_typ { SGroup * group; /* Server group we belong to */ char * name; /* Our idea of server's name */ char * itsname; /* Its idea of server's name */ int port; /* Port to use */ char * server_type /* Server type */ char * password; /* Password to use on server */ char * userhost; /* My userhost on server */ int oper; /* True if irc operator */ int version; /* class of server (above) */ int server2_8; /* True if 001 numeric seen */ char * version_string; /* Full server version */ long flags; /* Misc flags */ int s_takes_arg; /* True if +s takes argument */ int connected; /* True if we are connected */ int write; /* Writing fd (== read) */ int read; /* Reading fd (== write) */ int eof; /* True if we've seen an EOF */ int sent; /* True if we've sent stuff */ char * redirect; /* Who we're redirecting to */ WhoisEntry * who_queue; /* WHO Queue */ IsonEntry * ison_queue; /* ISON Queue */ UserhostEntry * userhost_queue; /* USERHOST Queue */ IA local_addr; /* My local ip address */ ISA local_sockname; /* My local sockname */ NotifyList notify_list; /* List of nicks to watch */ int reconnects; /* Number of retries */ char * cookie; /* EF/TS4 "cookie" value. */ }; typedef struct server_typ Server; epic4-2.10.2.orig/include/flood.h0000644000000000000000000000121407656627300013335 0ustar /* * flood.h: header file for flood.c * * Copyright 1991 Tomi Ollila * Copyright 1997 EPIC Software Labs * See the Copyright file for license information */ #ifndef __flood_h__ #define __flood_h__ typedef enum { CRAP_FLOOD = 0, CTCP_FLOOD, INVITE_FLOOD, JOIN_FLOOD, MSG_FLOOD, NICK_FLOOD, NOTE_FLOOD, NOTICE_FLOOD, PUBLIC_FLOOD, TOPIC_FLOOD, WALLOP_FLOOD, WALL_FLOOD, NUMBER_OF_FLOODS } FloodType; int check_flooding (const char *, const char *, FloodType, const char *); int new_check_flooding (const char *, const char *, const char *, const char *, FloodType); char * function_floodinfo (char *); #endif /* _FLOOD_H_ */ epic4-2.10.2.orig/include/CVS/0000755000000000000000000000000012200242556012501 5ustar epic4-2.10.2.orig/include/CVS/Root0000644000000000000000000000006212171117135013346 0ustar :pserver:anoncvs@epicsol.org:/home/cvs/repository epic4-2.10.2.orig/include/CVS/Entries0000644000000000000000000000443112171117135014040 0ustar /alias.h/1.8/Fri Nov 7 23:43:47 2003// /alist.h/1.9/Thu Feb 16 06:14:09 2006// /array.h/1.5/Wed Dec 25 06:26:45 2002// /clock.h/1.3/Tue Jul 22 21:12:53 2003// /commands.h/1.6/Fri Nov 7 23:43:47 2003// /compat.h/1.2/Mon Mar 17 03:42:46 2008// /config.h/1.33/Sun Jun 18 17:33:51 2006// /ctcp.h/1.6/Tue Jul 8 22:36:51 2003// /dcc.h/1.11/Fri May 9 04:29:52 2003// /debug.h/1.6/Wed Dec 3 22:17:40 2003// /defs.h.in/1.32/Thu Mar 20 04:20:51 2008// /exec.h/1.2/Thu Dec 19 03:22:58 2002// /files.h/1.8/Fri Nov 7 03:55:57 2003// /flood.h/1.4/Fri May 9 04:29:52 2003// /functions.h/1.5/Wed Jul 9 21:10:24 2003// /gailib.h/1.4/Fri Nov 7 03:51:10 2003// /glob.h/1.1.1.1/Tue Dec 5 00:11:57 2000// /help.h/1.1.1.1/Tue Dec 5 00:11:57 2000// /history.h/1.2/Tue Jul 22 21:12:53 2003// /hook.h/1.11/Sat Feb 16 23:59:11 2008// /if.h/1.2/Wed Mar 14 20:01:46 2001// /ignore.h/1.2/Mon Jun 30 04:14:01 2003// /input.h/1.5/Tue Jul 22 21:12:53 2003// /irc.h/1.28/Sat Feb 16 23:59:11 2008// /irc_std.h/1.20/Fri Mar 14 00:12:53 2008// /ircaux.h/1.61/Wed Nov 10 03:20:35 2004// /keys.h/1.6/Tue Jul 22 21:12:53 2003// /lastlog.h/1.4/Tue Jul 22 21:12:53 2003// /list.h/1.1.1.1/Tue Dec 5 00:11:57 2000// /log.h/1.6/Sun Apr 10 14:58:41 2005// /mail.h/1.5/Sun Jun 18 17:33:51 2006// /names.h/1.13/Wed Jul 4 13:39:33 2007// /network.h/1.2/Sat Dec 13 17:25:57 2003// /newio.h/1.8/Fri May 9 04:29:52 2003// /notice.h/1.5/Fri Jan 31 23:50:18 2003// /notify.h/1.7/Tue Jul 22 21:12:53 2003// /numbers.h/1.4/Sun Aug 15 03:28:23 2004// /options/1.4/Sat Nov 22 23:29:23 2003// /output.h/1.4/Fri Oct 10 06:22:38 2003// /parse.h/1.5/Sun Aug 31 01:33:48 2003// /queue.h/1.1.1.1/Tue Dec 5 00:11:57 2000// /reg.h/1.1/Fri Feb 1 23:05:54 2002// /screen.h/1.7/Fri May 9 04:29:52 2003// /sedcrypt.h/1.2/Fri Oct 31 08:19:23 2003// /server.h/1.36/Sat Aug 7 18:33:35 2004// /sgroup.h/1.4/Thu Oct 24 22:28:07 2002// /socks5p.h/1.1/Mon Nov 13 03:52:04 2006// /ssl.h/1.4/Thu Dec 26 16:40:31 2002// /stack.h/1.1.1.1/Tue Dec 5 00:11:57 2000// /status.h/1.5/Tue Jul 22 21:12:53 2003// /termx.h/1.1/Mon Mar 17 03:42:46 2008// /timer.h/1.9/Tue Jul 22 21:12:53 2003// /translat.h/1.3/Tue Jul 22 21:12:53 2003// /vars.h/1.27/Sun Jun 18 17:33:51 2006// /who.h/1.5/Fri May 9 04:29:52 2003// /window.h/1.17/Thu Dec 11 23:07:16 2003// /words.h/1.1/Tue Jul 8 22:36:51 2003// D epic4-2.10.2.orig/include/CVS/Repository0000644000000000000000000000001612171117135014601 0ustar epic4/include epic4-2.10.2.orig/include/array.h0000644000000000000000000000253607602247645013361 0ustar /* * array.h -- header file for array.c * * Copyright 1993 Aaron Gifford * Copyright 1995 EPIC Software Labs * See the COPYRIGHT file for copyright information */ #ifndef __array_h__ #define __array_h__ typedef struct an_array_struct { char **item; long *index; long size; int unsorted; } an_array; char * function_indextoitem (char *); char * function_itemtoindex (char *); char * function_igetitem (char *); char * function_getitem (char *); char * function_setitem (char *); char * function_usetitem (char *); char * function_finditem (char *); char * function_finditems (char *); char * function_matchitem (char *); char * function_rmatchitem (char *); char * function_getmatches (char *); char * function_igetmatches (char *); char * function_getrmatches (char *); char * function_igetrmatches (char *); char * function_delitem (char *); char * function_delitems (char *); char * function_numitems (char *); char * function_getarrays (char *); char * function_numarrays (char *); char * function_delarray (char *); char * function_ifinditem (char *); char * function_ifinditems (char *); char * function_ifindfirst (char *); char * function_listarray (char *); char * function_gettmatch (char *); int set_item (char* name, long item, char* input, int unsorted); an_array * get_array (char *name); #endif epic4-2.10.2.orig/include/who.h0000644000000000000000000000437707656627300013044 0ustar /* * who.h -- header info for the WHO, ISON, and USERHOST queues. * Copyright 1996 EPIC Software Labs */ #ifndef __who_h__ #define __who_h__ void clean_server_queues (int); /* WHO queue */ /* XXX This should be in who.c */ typedef struct WhoEntryT { int dirty; int piggyback; int undernet_extended; char *undernet_extended_args; int dalnet_extended; char *dalnet_extended_args; int who_mask; char *who_target; char *who_name; char *who_host; char *who_server; char *who_nick; char *who_real; char *who_stuff; char *who_end; struct WhoEntryT *next; void (*line) (int, const char *, const char *, const char **); void (*end) (int, const char *, const char *, const char **); } WhoEntry; BUILT_IN_COMMAND(whocmd); void whobase (int, char *, void (*)(int, const char *, const char *, const char **), void (*)(int, const char *, const char *, const char **)); void whoreply (int, const char *, const char *, const char **); void xwhoreply (int, const char *, const char *, const char **); void who_end (int, const char *, const char *, const char **); int fake_who_end (int, const char *, const char *, const char *); /* ISON queue */ typedef struct IsonEntryT { char *ison_asked; char *ison_got; struct IsonEntryT *next; void (*line) (int, char *, char *); } IsonEntry; BUILT_IN_COMMAND(isoncmd); void isonbase (int refnum, char *args, void (*line) (int, char *, char *)); void ison_returned (int, const char *, const char *, const char **); /* USERHOST queue */ typedef struct UserhostItemT { char * nick; int oper; int connected; int away; const char * user; const char * host; } UserhostItem; typedef struct UserhostEntryT { char * userhost_asked; char * text; struct UserhostEntryT * next; void (*func) (int, UserhostItem *, const char *, const char *); } UserhostEntry; BUILT_IN_COMMAND(userhostcmd); BUILT_IN_COMMAND(useripcmd); BUILT_IN_COMMAND(usripcmd); void userhostbase (int refnum, char *arg, void (*line) (int, UserhostItem *, const char *, const char *), int); void userhost_returned (int, const char *, const char *, const char **); void userhost_cmd_returned (int, UserhostItem *, const char *, const char *); #endif epic4-2.10.2.orig/include/ircaux.h0000644000000000000000000002200210144304403013501 0ustar /* * ircaux.h: header file for ircaux.c * * Written By Michael Sandrof * * Copyright(c) 1990 * * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT * * @(#)$Id: ircaux.h,v 1.61 2004/11/10 03:20:35 jnelson Exp $ */ #ifndef _IRCAUX_H_ #define _IRCAUX_H_ #include "compat.h" #include "network.h" #include "words.h" struct metric_time { long mt_days; double mt_mdays; }; typedef int comp_len_func (char *, char *, int); typedef int comp_func (char *, char *); #define new_malloc(x) really_new_malloc ((x), __FILE__, __LINE__) #define new_free(x) really_new_free ((void **)(x), __FILE__, __LINE__) #define new_realloc(x,y) really_new_realloc ((x), (y), __FILE__, __LINE__) #define MUST_BE_MALLOCED(x, y) \ fatal_malloc_check ((void *)(x), (y), __FILE__, __LINE__) #define RESIZE(x, y, z) new_realloc ((void **)& (x), sizeof(y) * (z)) #if 0 #define m_e3cat(x,y,z) m_ec3cat((x),(y),(z),NULL) #define m_s3cat(x,y,z) m_sc3cat((x),(y),(z),NULL) #define m_s3cat_s(x,y,z) m_sc3cat_s((x),(y),(z),NULL) #define m_3cat(x,y,z) m_c3cat((x),(y),(z),NULL) #endif #define malloc_strcat(x,y) malloc_strcat_c((x),(y),NULL) #define malloc_strcat_ues(x,y,z) malloc_strcat_ues_c((x),(y),(z),NULL) extern int need_delayed_free; void fatal_malloc_check (void *, const char *, const char *, int); void * really_new_malloc (size_t, const char *, int); void * really_new_free (void **, const char *, int); void * really_new_realloc (void **, size_t, const char *, int); void malloc_dump (const char *); char * check_nickname (char *, int); #if 0 char * dequote (char *); #define next_arg(a,b) next_arg_count((a),(b),1) char * next_arg_count (char *, char **, int); char * new_next_arg (char *, char **); char * new_next_arg_count (char *, char **, int); #endif char * new_new_next_arg_count (char *, char **, char *, int); char * s_next_arg (char **); char * last_arg (char **, size_t *cluep); int normalize_filename (const char *, Filename); int expand_twiddle (const char *, Filename); char * upper (char *); char * lower (char *); char * sindex (char *, const char *); char * rsindex (char *, char *, char *, int); int path_search (const char *, const char *, Filename); char * double_quote (const char *, const char *, char *); char * malloc_strcat_c (char **, const char *, size_t *); #if 0 char * malloc_str2cpy (char **, const char *, const char *); char * malloc_strcpy (char **, const char *); char * m_sc3cat_s (char **, const char *, const char *, size_t *clue); char * m_sc3cat (char **, const char *, const char *, size_t *clue); char * m_c3cat (char **, const char *, const char *, size_t *clue); char * m_ec3cat (char **, const char *, const char *, size_t *clue); char * m_2dup (const char *, const char *); char * m_3dup (const char *, const char *, const char *); char * m_opendup (const char *, ...) __A(1); #endif void wait_new_free (char **); char * malloc_sprintf (char **, const char *, ...) __A(2); int is_number (const char *); int is_real_number (const char *); char * my_ctime (time_t); extern unsigned char stricmp_table[]; int my_stricmp (const unsigned char *, const unsigned char *); int my_strnicmp (const unsigned char *, const unsigned char *, size_t); int scanstr (char *, char *); void really_free (int); char * chop (char *, size_t); char * malloc_strcat_ues_c (char **, const char *, const char *, size_t *); char * strlopencat (char *, size_t, ...); ssize_t stristr (const char *, const char *); ssize_t rstristr (const char *, const char *); char * findchar (char *, int); FILE * uzfopen (char **, const char *, int); int end_strcmp (const char *, const char *, size_t); char* exec_pipe (const char *, char *, size_t *, char *const *); FILE ** open_exec (const char *executable, char * const *args); void panic (const char *, ...) __A(1) __N; int vt100_decode (char); int count_ansi (char *, int); int fw_strcmp (comp_len_func *, char *, char *); int lw_strcmp (comp_func *, char *, char *); int open_to (char *, int, int); struct metric_time get_metric_time (double *); struct metric_time timeval_to_metric (const Timeval *); Timeval get_time (Timeval *); double time_diff (const Timeval, const Timeval); Timeval time_add (const Timeval, const Timeval); Timeval time_subtract (const Timeval, const Timeval); Timeval double_to_timeval (double); const char * plural (int); double time_to_next_minute (void); char * remove_trailing_spaces (char *, size_t *cluep); char * forcibly_remove_trailing_spaces (char *foo, size_t *cluep); char * ltoa (long); char * ftoa (double); char * strformat (char *, const char *, ssize_t, int); char * chop_word (char *); char * skip_spaces (char *); int split_args (char *, char **to, size_t); int splitw (char *, char ***); char * unsplitw (char ***, int); int check_val (const char *); char * strext (const char *, const char *); char * strextend (char *, char, int); char * pullstr (char *, char *); int empty (const char *); char * safe_new_next_arg (char *, char **); ssize_t MatchingBracket (const char *, char, char); int parse_number (char **); char * remove_brackets (const char *, const char *, int *); long my_atol (const char *); u_long hashpjw (char *, u_long); char * malloc_dupchar (int); off_t file_size (const char *); int file_exists (const char *); int isdir (const char *); int is_root (const char *, const char *, int); size_t streq (const char *, const char *); char * malloc_strndup (const char *, size_t); char * prntdump (const char *, size_t); char * ov_strcpy (char *, const char *); size_t ccspan (const char *, int); int last_char (const char *); char * next_in_comma_list (char *, char **); char * next_in_div_list (char *, char **, char); char * get_userhost (void); double time_to_next_interval (int interval); int charcount (const char *, char); void beep_em (int); void strip_control (const char *, char *); const char *strfill (char, int); char * encode (const char *, size_t); char * decode (const char *); char * chomp (char *); int opento (const char *, int, off_t); int figure_out_address (const char *, char **, char **, char **); int figure_out_domain (char *, char **, char **, int *); int count_char (const unsigned char *, const unsigned char); char * strnrchr (char *, char, int); void mask_digits (char **); char * strpcat (char *, const char *, ...) __A(2); char * strlpcat (char *, size_t, const char *, ...) __A(3); u_char *strcpy_nocolorcodes (u_char *, const u_char *); u_long random_number (u_long); char * urlencode (const char *); char * urldecode (char *, size_t *); char * enquote_it (char *str, size_t len); char * dequote_it (char *str, size_t *len); const char * my_strerror (int, int); int slurp_file (char **buffer, char *filename); size_t strlcpy_c (char *, const char *, size_t, size_t *); size_t strlcat_c (char *, const char *, size_t, size_t *); char * strlopencat_c (char *dest, size_t maxlen, size_t *cluep, ...); int is_string_empty (const char *str); char * malloc_strcpy_c (char **, const char *, size_t *); char * malloc_strcat_c (char **, const char *, size_t *); char * malloc_strdup (const char *); char * malloc_strdup2 (const char *, const char *); char * malloc_strdup3 (const char *, const char *, const char *); char * malloc_strcat2_c (char **, const char *, const char *, size_t *); char * malloc_strcat_wordlist_c (char **, const char *, const char *,size_t *); char * malloc_strcat_word_c (char **, const char *, const char *,size_t *); char * malloc_sprintf (char **, const char *, ...) __A(2); #define malloc_strcpy(x,y) malloc_strcpy_c((x),(y),NULL) #define malloc_strcat(x,y) malloc_strcat_c((x),(y),NULL) #define malloc_strcat2(x,y,z) malloc_strcat2_c((x),(y),(z),NULL) #define malloc_strcat_wordlist(x,y,z) malloc_strcat_wordlist_c((x),(y),(z),NULL) #define malloc_strcat_word(x,y,z) malloc_strcat_word_c((x),(y),(z),NULL) char * universal_next_arg_count (char *, char **, int, int, int, const char *); #define next_arg(a,b) universal_next_arg_count((a),(b),1,DWORD_NEVER,0,"\"") #define next_arg_count(a,b,c) universal_next_arg_count((a),(b),(c),DWORD_NEVER, 0,"\"") #define new_next_arg(a,b) universal_next_arg_count((a),(b),1,DWORD_ALWAYS,1,"\"") #define new_next_arg_count(a,b) universal_next_arg_count((a),(b),(c),DWORD_ALWAYS,1,"\"") void dequoter (char **, size_t *, int, int, const char *); #define my_isspace(x) isspace(x) #define my_isdigit(x) \ (isdigit(*x) || ((*x == '-' || *x == '+') && isdigit(x[1]))) /* Used for the inbound mangling stuff */ #define MANGLE_ESCAPES 1 << 0 #define MANGLE_ANSI_CODES 1 << 1 #define STRIP_COLOR 1 << 2 #define STRIP_REVERSE 1 << 3 #define STRIP_UNDERLINE 1 << 4 #define STRIP_BOLD 1 << 5 #define STRIP_BLINK 1 << 6 #define STRIP_ROM_CHAR 1 << 7 #define STRIP_ND_SPACE 1 << 8 #define STRIP_ALT_CHAR 1 << 9 #define STRIP_ALL_OFF 1 << 10 #define STRIP_OTHER 1 << 11 extern int outbound_line_mangler; extern int inbound_line_mangler; extern int logfile_line_mangler; size_t mangle_line (char *, int, size_t); #endif /* _IRCAUX_H_ */ epic4-2.10.2.orig/include/history.h0000644000000000000000000000104707707324325013735 0ustar /* * history.h: header for history.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __history_h__ #define __history_h__ BUILT_IN_COMMAND(history); void set_history_size (const void *); void add_to_history (char *); void get_history (int); char * do_history (char *, char *); void shove_to_history (char, char *); void abort_history_browsing (int); /* used by get_history */ #define NEWER 0 #define OLDER 1 #endif /* _HISTORY_H_ */ epic4-2.10.2.orig/include/ssl.h0000644000000000000000000000151107602630377013032 0ustar /* * ssl.h -- header file for ssl.c * * Original framework written by Juraj Bednar * Modified by B. Thomas Frazier * * Copyright 2000, 2002 EPIC Software Labs * */ #ifdef HAVE_SSL #include #include #include #include #include #define CHK_NULL(x) if ((x) == NULL) { say("SSL error - NULL data from server"); return; } #define CHK_ERR(err, s) if ((err) == -1) { say("SSL prime error - %s", s); return; } #define CHK_SSL(err,fd) if ((err) == -1) { say("SSL CHK error - %d %d", err, SSL_get_error(fd, err)); return; } /* Make these what you want for cert & key files */ /* extern SSL_CTX* ctx; */ /* extern SSL_METHOD *meth; */ void SSL_show_errors (void); SSL_CTX* SSL_CTX_init (int server); SSL *SSL_FD_init (SSL_CTX *ctx, int des); #endif epic4-2.10.2.orig/include/help.h0000644000000000000000000000036607213031315013151 0ustar /* * help.h: header for help.c * * Copyright 1994 Matthew Green * Copyright 1997 EPIC Software Labs * See the Copyright file for license information */ #ifndef __help_h__ #define __help_h__ BUILT_IN_COMMAND(help); #endif /* __help_h */ epic4-2.10.2.orig/include/sedcrypt.h0000644000000000000000000000131107750415413014060 0ustar /* * crypt.h: header for crypt.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __crypt_h__ #define __crypt_h__ /* * Crypt: the crypt list structure, consists of the nickname, and the * encryption key */ typedef struct CryptStru { struct CryptStru *next; char *nick; char *key; char *prog; int filename; } Crypt; BUILT_IN_COMMAND(encrypt_cmd); char *crypt_msg (char *, Crypt *); char *decrypt_msg (char *, Crypt *); char *do_crypt (char *, Crypt *, int); Crypt *is_crypted (const char *); void my_decrypt (char *, int, char *); void my_encrypt (char *, int, char *); #endif /* _CRYPT_H_ */ epic4-2.10.2.orig/include/dcc.h0000644000000000000000000000147207656627300012771 0ustar /* * dcc.h: Things dealing client to client connections. * * Copyright 1991 Troy Rollo * Copyright 1997 EPIC Software Labs * See the Copyright file for license information */ #ifndef __dcc_h__ #define __dcc_h__ void close_all_dcc (void); int dcc_chat_active (const char *); void dcc_chat_transmit (char *, char *, const char *, const char *, int); void dcc_check (fd_set *, fd_set *); BUILT_IN_COMMAND(dcc_cmd); char * dcc_raw_connect (const char *, const char *, int); char * dcc_raw_listen (int, unsigned short); void dcc_reject (const char *, char *, char *); void register_dcc_offer (const char *, char *, char *, char *, char *, char *, char *, char *); char * DCC_get_current_transfer (void); char *dccctl (char *input); extern time_t dcc_timeout; #endif /* _DCC_H_ */ epic4-2.10.2.orig/include/glob.h0000644000000000000000000000744407213031315013150 0ustar /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: @(#)glob.h 8.1 (Berkeley) 6/2/93 * $Id: glob.h,v 1.1.1.1 2000/12/05 00:11:57 jnelson Exp $ */ #ifndef _GLOB_H_ #define _GLOB_H_ struct stat; typedef struct { int gl_pathc; /* Count of total paths so far. */ int gl_matchc; /* Count of paths matching pattern. */ int gl_offs; /* Reserved at beginning of gl_pathv. */ int gl_flags; /* Copy of flags parameter to glob. */ char **gl_pathv; /* List of paths matching pattern. */ /* Copy of errfunc parameter to glob. */ int (*gl_errfunc) (const char *, int); /* * Alternate filesystem access methods for glob; replacement * versions of closedir(3), readdir(3), opendir(3), stat(2) * and lstat(2). */ void (*gl_closedir) (void *); struct dirent *(*gl_readdir) (void *); void *(*gl_opendir) (const char *); int (*gl_lstat) (const char *, struct stat *); int (*gl_stat) (const char *, struct stat *); } glob_t; #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ #define GLOB_ERR 0x0004 /* Return on error. */ #define GLOB_MARK 0x0008 /* Append / to matching directories. */ #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ #define GLOB_NOSORT 0x0020 /* Don't sort. */ #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ #define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_INSENSITIVE 0x1000 /* Don't worry about upper versus lower */ #define GLOB_NOSPACE (-1) /* Malloc call failed. */ #define GLOB_ABEND (-2) /* Unignored error. */ int bsd_glob (const char *, int, int (*)(const char *, int), glob_t *); void bsd_globfree (glob_t *); #endif /* !_GLOB_H_ */ epic4-2.10.2.orig/include/output.h0000644000000000000000000000151307741450056013571 0ustar /* * output.h: header for output.c * * Written By Michael Sandrof * * Copyright(c) 1990 * * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT * * @(#)$Id: output.h,v 1.4 2003/10/10 06:22:38 jnelson Exp $ */ #ifndef __output_h__ #define __output_h__ extern FILE *irclog_fp; struct ScreenStru; BUILT_IN_COMMAND(extern_write); void put_echo (const unsigned char *); void put_it (const char *, ...) __A(1); void say (const char *, ...) __A(1); void yell (const char *, ...) __A(1); void privileged_yell (const char *, ...) __A(1); void error (const char *, ...) __A(1); SIGNAL_HANDLER(sig_refresh_screen); void refresh_a_screen (struct ScreenStru *); void refresh_screen (char, char *); int init_screen (void); void file_put_it (FILE *fp, const char *format, ...); #endif /* _OUTPUT_H_ */ epic4-2.10.2.orig/include/clock.h0000644000000000000000000000444107707324325013330 0ustar /* * clock.h -- The status bar clock ($Z), cpu saver, and system timers * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1997, 2003 EPIC Software Labs * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __clock_h__ #define __clock_h__ #include "keys.h" extern char * time_format; extern char clock_timeref[]; void reset_clock (const void *); const char * get_clock (void); void clock_systimer (void); void set_clock_interval (const void *); void set_clock_format (const void *); void set_clock (const void *); extern int cpu_saver; int cpu_saver_timer (void *); void set_cpu_saver_after (const void *); void set_cpu_saver_every (const void *); BUILT_IN_BINDING(cpu_saver_on); int update_system_timer (const char *); void reset_system_timers (void); #endif epic4-2.10.2.orig/include/debug.h0000644000000000000000000000220407763460404013317 0ustar /* * debug.h -- the runtime debug settings. Can also be done on command line. * * Written by Jeremy Nelson * Copyright 1997 EPIC Software Labs */ #ifndef __debug_h__ #define __debug_h__ extern unsigned long x_debug; BUILT_IN_COMMAND(xdebugcmd); extern char * function_xdebug (char *); #define DEBUG_LOCAL_VARS 1 << 0 #define DEBUG_ALIAS 1 << 1 #define DEBUG_CTCPS 1 << 2 #define DEBUG_DCC_SEARCH 1 << 3 #define DEBUG_OUTBOUND 1 << 4 #define DEBUG_INBOUND 1 << 5 #define DEBUG_DCC_XMIT 1 << 6 #define DEBUG_WAITS 1 << 7 #define DEBUG_MEMORY 1 << 8 #define DEBUG_SERVER_CONNECT 1 << 9 #define DEBUG_CRASH 1 << 10 #define DEBUG_COLOR 1 << 11 #define DEBUG_NOTIFY 1 << 12 #define DEBUG_REGEX 1 << 13 #define DEBUG_REGEX_DEBUG 1 << 14 #define DEBUG_BROKEN_CLOCK 1 << 15 #define DEBUG_CHANNELS 1 << 16 #define DEBUG_UNKNOWN 1 << 17 #define DEBUG_BOLD_HELPER 1 << 18 #define DEBUG_NEW_MATH 1 << 19 #define DEBUG_NEW_MATH_DEBUG 1 << 20 #define DEBUG_AUTOKEY 1 << 21 #define DEBUG_EXTRACTW 1 << 22 #define DEBUG_SLASH_HACK 1 << 23 #define DEBUG_SSL 1 << 24 #define DEBUG_LASTLOG 1 << 25 #define DEBUG_EXTRACTW_DEBUG 1 << 26 #endif epic4-2.10.2.orig/include/socks5p.h0000644000000000000000000000144410525765744013632 0ustar /* * socks5p.h -- Compatability shim for , public domain * * If you #define INCLUDE_PROTOTYPES, then socks5 will try to * #include "socks5p.h" which isn't installed normally. But on amd64, * we *must* have prototypes to get functions ilke localtime() correct. * So this file provides the limited set of things necessary to make * #define INCLUDE_PROTOTYPES work with */ #ifndef __socks5p_h__ #define __socks5p_h__ #include #ifndef P #define P(x) x #endif #ifndef LIBPREFIX #ifdef USE_SOCKS4_PREFIX #define LIBPREFIX(x) R ## x #else #define LIBPREFIX(x) SOCKS ## x #endif #endif #ifndef IORETTYPE #define IORETTYPE int #endif #ifndef IOPTRTYPE #define IOPTRTYPE void * #endif #ifndef IOLENTYPE #define IOLENTYPE size_t #endif #endif /* __socks5p_h__ */ epic4-2.10.2.orig/include/notice.h0000644000000000000000000000054607616605672013526 0ustar /* * notice.h -- header file for notice.c * * Copyright 1990, 1995 Michael Sandrof, Matthew Green * Copyright 1997 EPIC Software Labs */ #ifndef __notice_h__ #define __notice_h__ void p_notice (const char *, const char *, const char **); void got_initial_version_28 (const char *, const char *, const char *); void load_ircrc (void); #endif epic4-2.10.2.orig/include/functions.h0000644000000000000000000000355407703102300014230 0ustar /* * functions.h -- header file for functions.c * * Copyright 1995, 2002 EPIC Software Labs * See the COPYRIGHT file for copyright information */ #ifndef __functions_h__ #define __functions_h__ /* * These are defined to make the construction of the built-in functions * easier and less prone to bugs and unexpected behaviors. As long as * you consistently use these macros to do the dirty work for you, you * will never have to do bounds checking as the macros do that for you. >;-) * * Yes, i realize it makes the code slightly less efficient, but i feel that * the cost is minimal compared to how much time i have spent over the last * year debugging these functions and the fact i wont have to again. ;-) */ #define EMPTY empty_string #define EMPTY_STRING malloc_strdup(EMPTY) #define RETURN_EMPTY return EMPTY_STRING #define RETURN_IF_EMPTY(x) if (empty( (x) )) RETURN_EMPTY #define GET_INT_ARG(x, y) {RETURN_IF_EMPTY((y)); x = my_atol(safe_new_next_arg((y), &(y)));} #define GET_FLOAT_ARG(x, y) {RETURN_IF_EMPTY((y)); x = atof(safe_new_next_arg((y), &(y)));} #define GET_STR_ARG(x, y) {RETURN_IF_EMPTY((y)); x = new_next_arg((y), &(y));} #define GET_A_STR_ARG(x, y) {GET_STR_ARG((x), (y));RETURN_IF_EMPTY((x));} #define RETURN_MSTR(x) return ((x) ? (x) : EMPTY_STRING) #define RETURN_STR(x) return malloc_strdup((x) ? (x) : EMPTY) #define RETURN_INT(x) return malloc_strdup(ltoa((x))) #define RETURN_FLOAT(x) return malloc_sprintf(NULL, "%.50g", (double) (x)) #define RETURN_FLOAT2(x) return malloc_sprintf(NULL, "%.2f", (double) (x)) /* * XXXX REALLY REALLY REALLY REALLY REALLY REALLY REALLY IMPORTANT! XXXX * * Don't ever Ever EVER pass a function call to the RETURN_* macros. * They _WILL_ evaluate the term twice, and for some function calls, * that can result in a memory leak, or worse. */ #define BUILT_IN_FUNCTION(x, y) static char * x (char * y) #endif epic4-2.10.2.orig/include/if.h0000644000000000000000000000111207253747052012625 0ustar /* * if.h: header for if.c * * Copyright 1994 Matthew Green * Copyright 1997 EPIC Software Labs * See the copyright file, or do a help ircii copyright */ #ifndef __if_h__ #define __if_h__ char * next_expr (char **, char); char * next_expr_failok (char **, char); char * next_expr_with_type (char **, char); BUILT_IN_COMMAND(ifcmd); BUILT_IN_COMMAND(docmd); BUILT_IN_COMMAND(whilecmd); BUILT_IN_COMMAND(foreach); BUILT_IN_COMMAND(fe); BUILT_IN_COMMAND(forcmd); BUILT_IN_COMMAND(fec); BUILT_IN_COMMAND(switchcmd); BUILT_IN_COMMAND(repeatcmd); #endif /* __if_h */ epic4-2.10.2.orig/include/hook.h0000644000000000000000000000420510755674317013201 0ustar /* * hook.h: header for hook.c * * Copyright 1990, 1995 Michael Sandrof, Matthew Green and others * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file for license information. */ #ifndef __hook_h__ #define __hook_h__ enum HOOK_TYPES { ACTION_LIST, CHANNEL_NICK_LIST, CHANNEL_SIGNOFF_LIST, CHANNEL_SYNC_LIST, CONNECT_LIST, CTCP_LIST, CTCP_REPLY_LIST, CTCP_REQUEST_LIST, DCC_ACTIVITY_LIST, DCC_CHAT_LIST, DCC_CONNECT_LIST, DCC_LIST_LIST, DCC_LOST_LIST, DCC_OFFER_LIST, DCC_RAW_LIST, DCC_REQUEST_LIST, DISCONNECT_LIST, ENCRYPTED_NOTICE_LIST, ENCRYPTED_PRIVMSG_LIST, ERROR_LIST, EXEC_LIST, EXEC_ERRORS_LIST, EXEC_EXIT_LIST, EXEC_PROMPT_LIST, EXIT_LIST, FLOOD_LIST, GENERAL_NOTICE_LIST, GENERAL_PRIVMSG_LIST, HELP_LIST, HOOK_LIST, IDLE_LIST, INPUT_LIST, INVITE_LIST, JOIN_LIST, KICK_LIST, KILL_LIST, LEAVE_LIST, LIST_LIST, MAIL_LIST, MODE_LIST, MODE_STRIPPED_LIST, MSG_LIST, MSG_GROUP_LIST, NAMES_LIST, NICKNAME_LIST, NOTE_LIST, NOTICE_LIST, NOTIFY_SIGNOFF_LIST, NOTIFY_SIGNON_LIST, ODD_SERVER_STUFF_LIST, OPER_NOTICE_LIST, PONG_LIST, PUBLIC_LIST, PUBLIC_MSG_LIST, PUBLIC_NOTICE_LIST, PUBLIC_OTHER_LIST, RAW_IRC_LIST, REDIRECT_LIST, SEND_ACTION_LIST, SEND_CTCP_LIST, SEND_DCC_CHAT_LIST, SEND_MSG_LIST, SEND_NOTICE_LIST, SEND_PUBLIC_LIST, SEND_TO_SERVER_LIST, SERVER_ESTABLISHED_LIST, SERVER_LOST_LIST, SERVER_NOTICE_LIST, SET_LIST, SIGNAL_LIST, SIGNOFF_LIST, SILENCE_LIST, SSL_SERVER_CERT_LIST, STATUS_UPDATE_LIST, SWITCH_CHANNELS_LIST, SWITCH_WINDOWS_LIST, TIMER_LIST, TOPIC_LIST, UNLOAD_LIST, WALL_LIST, WALLOP_LIST, WHO_LIST, WIDELIST_LIST, WINDOW_LIST, WINDOW_COMMAND_LIST, WINDOW_CREATE_LIST, WINDOW_BEFOREKILL_LIST, WINDOW_KILL_LIST, YELL_LIST, ZZZZ_THIS_ALWAYS_COMES_LAST_ZZZZ }; #define NUMBER_OF_LISTS ZZZZ_THIS_ALWAYS_COMES_LAST_ZZZZ #define INVALID_HOOKNUM -1001 BUILT_IN_COMMAND(oncmd); BUILT_IN_COMMAND(shookcmd); int do_hook (int, const char *, ...) __A(2); void flush_on_hooks (void); void unload_on_hooks (char *); void save_hooks (FILE *, int); void do_stack_on (int, char *); int hook_find_free_serial (int, int, int); #endif /* __hook_h_ */ epic4-2.10.2.orig/include/status.h0000644000000000000000000000173107707324325013557 0ustar /* * status.h: header for status.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __status_h__ #define __status_h__ struct WindowStru; #define MAX_FUNCTIONS 40 typedef struct status_line { char * raw; char * format; const char * (*func[MAX_FUNCTIONS]) (struct WindowStru *, int, int); int map[MAX_FUNCTIONS]; int key[MAX_FUNCTIONS]; int count; char * result; } Status_line; typedef struct status_stuff { Status_line line[3]; int double_status; char *special; } Status; extern Status main_status; char * convert_sub_format (const char *, char); int make_status (struct WindowStru *, int); /* Don't call */ void build_status (const void *); int permit_status_update (int); void rebuild_a_status (struct WindowStru *); /* Don't call */ #endif /* _STATUS_H_ */ epic4-2.10.2.orig/include/reg.h0000644000000000000000000000367607426617522013025 0ustar /* $EPIC: reg.h,v 1.1 2002/02/01 23:05:54 jnelson Exp $ */ /* * reg.h: pattern matching and other assorted things * * Copyright 2000 Jeremy Nelson and others ("EPIC Software Labs"). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __reg_h__ #define __reg_h__ #ifdef HAVE_REGEX_H # include #endif int wild_match (const char *, const char *); int pattern_regcomp (regex_t *, const char *, int); char * pattern2regex (const char *, int *); #endif epic4-2.10.2.orig/include/files.h0000644000000000000000000000151007752613715013335 0ustar /* * files.h -- header file for files.c * Direct file manipulation for irc? Unheard of! * * Copyright 1995 Jeremy Nelson * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file for copyright information */ #ifndef __files_h__ #define __files_h__ int open_file_for_read (const char *); int open_file_for_write (const char *, const char *); int * open_exec_for_in_out_err(const char *, char * const *); int target_file_write (const char *, const char *); int file_write (int, int, const char *); int file_writeb (int, int, char *); char * file_read (int); char * file_readb (int, int); int file_eof (int); int file_close (int); int file_valid (int); int file_rewind (int); int file_error (int); int file_seek (int, long, const char *); int file_tell (int); int file_skip (int, int); #endif epic4-2.10.2.orig/include/numbers.h0000644000000000000000000000060410107554127013676 0ustar /* * numbers.h: header for numbers.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * see the copyright file, or do a help ircii copyright */ #ifndef __numbers_h__ #define __numbers_h__ const char * banner (void); void numbered_command (const char *, const char *, const char **); void nickname_sendline (char *, char *); #endif /* _NUMBERS_H_ */ epic4-2.10.2.orig/include/exec.h0000644000000000000000000000113007600235622013142 0ustar /* * exec.h: header for exec.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the Copyright file for license information */ #ifndef __exec_h__ #define __exec_h__ BUILT_IN_COMMAND(execcmd); void do_processes (fd_set *, fd_set *); int get_child_exit (pid_t); void clean_up_processes (void); int text_to_process (int, const char *, int); void exec_server_delete (int); void add_process_wait (int, const char *); int get_process_index (char **); /* XXXX */ int is_valid_process (const char *); int process_is_running (char *); #endif /* _EXEC_H_ */ epic4-2.10.2.orig/include/queue.h0000644000000000000000000000031507213031315013337 0ustar /* * queue.h - header file for queue.c * * Copyright 1993 Jeremy Nelson * See the coypright file for more information */ #ifndef __queue_h__ #define __queue_h__ BUILT_IN_COMMAND(queuecmd); #endif epic4-2.10.2.orig/include/list.h0000644000000000000000000000105007213031315013163 0ustar /* * list.h: header for list.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __list_h__ #define __list_h__ typedef struct list_stru { struct list_stru *next; char *name; } List; void add_to_list (List **, List *); List *find_in_list (List **, const char *, int); List *remove_from_list (List **, const char *); List *list_lookup (List **, const char *, int, int); #define REMOVE_FROM_LIST 1 #define USE_WILDCARDS 1 #endif /* _LIST_H */ epic4-2.10.2.orig/include/network.h0000644000000000000000000000545107766645645013750 0ustar /* * Copyright © 2003 Jeremy Nelson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __NETWORK_H__ #define __NETWORK_H__ /* Used for connect_by_number */ #define SERVICE_SERVER 0 #define SERVICE_CLIENT 1 /* Used from network.c */ #define V0(x) ((SA *)&(x)) #define FAMILY(x) (V0(x)->sa_family) #define V4(x) ((ISA *)&(x)) #define V4FAM(x) (V4(x)->sin_family) #define V4ADDR(x) (V4(x)->sin_addr) #define V4PORT(x) (V4(x)->sin_port) #define V6(x) ((ISA6 *)&(x)) #define V6FAM(x) (V6(x)->sin6_family) #define V6ADDR(x) (V6(x)->sin6_addr) #define V6PORT(x) (V6(x)->sin6_port) int inet_strton (const char *, const char *, SA *, int); int inet_ntostr (SA *, char *, int, char *, int, int); char *inet_hntop (int, const char *, char *, int); char *inet_ptohn (int, const char *, char *, int); char *one_to_another (int, const char *, char *, int); int Accept (int, SA *, int *); char *switch_hostname (const char *); int ip_bindery (int family, u_short port, SS *storage); int client_bind (SA *, socklen_t); int client_connect (SA *, socklen_t, SA *, socklen_t); int connectory (int, const char *, const char *); int inet_vhostsockaddr (int, int, SS *, socklen_t *); #define GNI_INTEGER 0x4000 #endif epic4-2.10.2.orig/include/commands.h0000644000000000000000000000227307753027063014037 0ustar /* * commands.h: header for commands.c * * Copyright 1990 Michael Sandrof * Copyright 1994 Matthew Green * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __commands_h__ #define __commands_h__ /* flags used by e_away */ #define AWAY_ONE 0 #define AWAY_ALL 1 /* flags used by parse_line */ #define SECURITY_NO_VARIABLE_COMMAND 1 #define SECURITY_NO_NONINTERACTIVE_EXEC 2 #define SECURITY_NO_NONINTERACTIVE_SET 4 extern int will_catch_break_exceptions; extern int will_catch_continue_exceptions; extern int will_catch_return_exceptions; extern int break_exception; extern int continue_exception; extern int return_exception; extern int system_exception; extern int need_defered_commands; void ExecuteTimers (void); void parse_line (const char *, const char *, const char *, int, int); BUILT_IN_COMMAND(load); void send_text (const char *, const char *, const char *, int); int redirect_text (int, const char *, const char *, char *, int); int command_exist (char *); BUILT_IN_COMMAND(e_channel); void do_defered_commands (void); char *get_all_commands (void); char *get_command (const char *); #endif /* __commands_h__ */ epic4-2.10.2.orig/include/window.h0000644000000000000000000002507407766174244013561 0ustar /* * window.h: header file for window.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __window_h__ #define __window_h__ /* To get the definition of Lastlog */ #include "lastlog.h" /* To get the definition of Status */ #include "status.h" /* * Screen and Window are mutually referencial. * That means we cant include "screen.h", so we kind of fake it. */ struct ScreenStru; /* var_settings indexes */ #define OFF 0 #define ON 1 #define TOGGLE 2 /* Flags for "misc" */ #define WINDOW_NOTIFY 1 << 0 #define WINDOW_NOTIFIED 1 << 1 /* Should be a way to make static to window.c */ typedef struct DisplayStru { size_t count; char *line; struct DisplayStru *prev; struct DisplayStru *next; } Display; typedef struct WNickListStru { struct WNickListStru *next; char *nick; } WNickList; typedef struct WindowStru { unsigned refnum; /* Unique refnum for window */ char *name; /* Logical name for window */ int server; /* Server that win is connected to */ int last_server; /* Last server connected to */ int priority; /* "Current window Priority" */ int top; /* SCREEN line for top of window */ int bottom; /* SCREEN line for bottom of window */ int cursor; /* WINDOW line where the cursor is */ int noscrollcursor; /* Where the next line goes */ int absolute_size; /* True if window doesnt rebalance */ int scroll; /* True if the window scrolls */ int change_line; /* True if this is a scratch window */ int old_size; /* * Usu. same as display_size except * right after a screen resize, and * is used as a flag for resize_display */ int update; /* True if window display is dirty */ unsigned miscflags; /* Miscellaneous flags. */ int beep_always; /* True if a beep to win always beeps */ int notify_level; /* the notify level.. */ int window_level; /* Lastlog level for the window */ int skip; /* Whether window should be skipped */ int columns; /* How wide we are when hidden */ int swappable; /* Can it be swapped in or out? */ int scrolladj; /* Push back top-of-win on grow? */ /* Input and Status stuff */ char *prompt; /* Current EXEC prompt for window */ Status status; /* Current status line info */ /* Display stuff */ /* * The "scrollback" buffer is a linked list of lines that have * appeared, are appearing, or will appear on the visible window. * The "top" of the scrollback buffer usually floats forward in * the line as items are added. The visible part of the screen is * always somewhere in the buffer (usually at the bottom), unless * the user is in "scrollback mode" or "hold mode". When the user * is in either of these modes, then the top of the scrollback buffer * is frozen (so as not to disrupt the current contents of the screen) * and the bottom of the buffer floats as is neccesary. When the user * ends these modes, the buffer is reset to the "scrollback_point" and * then is floated to its original dimensions from there. The lastlog * has nothing to do with scrollback any longer. * * The "display_ip" is always a blank line where the NEXT displayable * line will go. When the user does a /clear, the screen is scrolled * up until display_ip is the top_of_display. "display_size" is the * number of rows that can appear on the screen at a given time. */ Display *top_of_scrollback; /* Start of the scrollback buffer */ Display *display_ip; /* End of the scrollback buffer */ int display_buffer_size; /* How big the scrollback buffer is */ int display_buffer_max; /* How big its supposed to be */ int display_size; /* How big the window is - status */ Display *scrolling_top_of_display; int scrolling_distance_from_display_ip; Display *holding_top_of_display; int holding_distance_from_display_ip; Display *scrollback_top_of_display; int scrollback_distance_from_display_ip; int display_counter; int hold_slider; #if 0 *top_of_display, /* Where the viewport starts */ *display_ip, /* Where next line goes in rite() */ *scrollback_point; /* Where we went into scrollback */ int hold_mode; /* True if we want to hold stuff */ int autohold; /* True if we are in temp hold mode */ int lines_held; /* Lines currently being held */ int distance_from_display_ip; /* How far t_o_d is from d_ip */ #endif int hold_interval; /* How often to update status bar */ int last_lines_held; /* Last time we updated "lines held" */ /* Channel stuff */ char *waiting_channel; /* * When you JOIN or reconnect, if this * is set, a JOIN to that channel will * put that channel into this win. */ char *bind_channel; /* Current bound channel for win */ char *query_nick; /* Current default target for win */ WNickList *nicks; /* List of nick-queries for this win */ /* /LASTLOG stuff */ Lastlog *lastlog_newest; /* pointer to top of lastlog list */ Lastlog *lastlog_oldest; /* pointer to bottom of lastlog list */ int lastlog_level; /* The LASTLOG_LEVEL, determines what * messages go to lastlog */ int lastlog_size; /* number of messages in lastlog. */ int lastlog_max; /* Max number of messages in lastlog */ /* /WINDOW LOG stuff */ int log; /* True if file logging is on */ char *logfile; /* window's logfile name */ FILE *log_fp; /* file pointer for the log file */ /* List stuff */ struct ScreenStru *screen; /* The screen we belong to */ struct WindowStru *next; /* Window below us on screen */ struct WindowStru *prev; /* Window above us on screen */ /* XXX - Help stuff */ struct HelpStru *helper; /* Info about current /help */ int deceased; /* Set when the window is killed */ } Window; /* * WindowStack: The structure for the POP, PUSH, and STACK functions. A * simple linked list with window refnums as the data */ typedef struct window_stack_stru { unsigned int refnum; struct window_stack_stru *next; } WindowStack; extern Window *current_window; extern Window *to_window; extern Window *invisible_list; extern int who_level; extern const char *who_from; #if 0 extern int in_window_command; #endif extern unsigned window_display; extern unsigned current_window_priority; BUILT_IN_COMMAND(windowcmd); Window *new_window (struct ScreenStru *); void delete_window (Window *); void delete_all_windows (void); int traverse_all_windows (Window **); void add_to_invisible_list (Window *); Window *add_to_window_list (struct ScreenStru *, Window *); void recalculate_window_positions (struct ScreenStru *); void window_statusbar_needs_update (Window *); void window_statusbar_needs_redraw (Window *); void window_body_needs_redraw (Window *); void redraw_all_windows (void); void recalculate_windows (struct ScreenStru *); void rebalance_windows (struct ScreenStru *); void update_all_windows (void); void set_current_window (Window *); void hide_window (Window *); void swap_last_window (char, char *); void next_window (char, char *); void swap_next_window (char, char *); void previous_window (char, char *); void swap_previous_window (char, char *); void back_window (void); Window *get_window_by_refnum (unsigned); Window *get_window_by_name (const char *); Window *get_window_by_desc (const char *); char *get_refnum_by_window (const Window *); int is_window_visible (char *); char *get_status_by_refnum (unsigned, int); #if 0 void redraw_window_statusbar (Window *); void update_window_statusbar (Window *); #endif void update_all_status (void); void set_prompt_by_refnum (unsigned, char *); char *get_prompt_by_refnum (unsigned); const char *get_target_by_refnum (unsigned); const char *query_nick (void); void set_query_nick (char *); int is_current_channel (const char *, int); const char * set_channel_by_refnum (unsigned, const char *); const char *get_echannel_by_refnum (unsigned); char *get_channel_by_refnum (unsigned); int is_bound_to_window (const Window *, const char *); Window *get_window_bound_channel (const char *); int is_bound_anywhere (const char *); int is_bound (const char *, int); void unbind_channel (const char *, int); char *get_bound_channel (Window *); void destroy_waiting_channels (int); int get_window_server (unsigned); int get_window_oldserver (unsigned); void set_window_server (int, int, int); void change_window_server (int, int); void reclaim_windows (int, int); void window_check_servers (void); void set_level_by_refnum (unsigned, int); void message_to (int); void save_message_from (const char **, int *); void restore_message_from (const char *, int); void message_from (const char *, int); int message_from_level (int); void clear_all_windows (int, int, int); void clear_window_by_refnum (unsigned, int); void unclear_all_windows (int, int, int); void unclear_window_by_refnum (unsigned, int); void set_scrollback_size (const void *); void set_scroll_lines (const void *); void set_continued_line (const void *); unsigned current_refnum (void); int number_of_windows_on_screen (Window *); void delete_display_line (Display *); int add_to_scrollback (Window *, const unsigned char *); int trim_scrollback (Window *); int flush_scrollback_after (Window *); void scrollback_backwards (char, char *); void scrollback_forwards (char, char *); void scrollback_end (char, char *); void scrollback_start (char, char *); void unstop_all_windows (char, char *); void toggle_stop_screen (char, char *); void flush_everything_being_held (Window *); int window_is_holding (Window *); int unhold_a_window (Window *); void recalculate_window_cursor_and_display_ip (Window *); char *get_nicklist_by_window (Window *); /* XXX */ void make_window_current_by_refnum (int); void make_window_current (Window *); Window *window_query (Window *, char **); Window *window_rejoin (Window *, char **); Window *window_scroll (Window *, char **); Window *window_server (Window *, char **); int unhold_windows (void); int channel_going_away (Window *, const char *); void window_check_channels (void); int add_to_scratch_window_scrollback (Window *, const unsigned char *); void check_window_cursor (Window *); void unhold_window (Window *); int get_geom_by_winref (const char *, int *, int *); int get_winref_by_servref (int); int is_window_waiting_for_channel (unsigned, const char *); void move_waiting_channel (unsigned oldref, unsigned newref); int get_winref_by_bound_channel (const char *channel, int server); const char * get_bound_channel_by_refnum (unsigned refnum); char * windowctl (char *); #endif /* __window_h__ */ epic4-2.10.2.orig/include/compat.h0000644000000000000000000000173310767364266013531 0ustar /* * Collected by EPIC Software Labs * Public Domain */ #ifndef __COMPAT_H__ #define __COMPAT_H__ #ifndef HAVE_TPARM char *my_tparm (const char *, ...); #define tparm my_tparm #endif #ifndef HAVE_STRTOUL unsigned long strtoul (const char *, char **, int); #endif #ifndef HAVE_STRLCPY size_t strlcpy (char *, const char *, size_t); #endif #ifndef HAVE_STRLCAT size_t strlcat (char *, const char *, size_t); #endif void bsd_arc4random_stir (void); void bsd_arc4random_addrandom (unsigned char *, int); u_32int_t bsd_arc4random (void); #ifndef HAVE_VSNPRINTF int vsnprintf (char *, size_t, const char *, va_list); #endif #ifndef HAVE_SNPRINTF int snprintf (char *, size_t, const char *, ...); #endif #ifndef HAVE_SETSID int setsid (void); #endif #ifndef HAVE_SETENV int setenv (const char *, const char *, int); #endif #ifndef HAVE_UNSETENV int unsetenv (const char *); #endif #ifdef HAVE_BROKEN_REALPATH char * my_realpath (const char *, char x[MAXPATHLEN]); #endif #endif epic4-2.10.2.orig/include/log.h0000644000000000000000000000102310226237441012777 0ustar /* * log.h: header for log.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __log_h__ #define __log_h__ FILE *do_log (int, const char *, FILE **); void logger (const void *); void set_log_file (const void *); void add_to_log (FILE *, long, const unsigned char *, int, const char *); BUILT_IN_COMMAND(logcmd); void add_to_logs (long, int, const char *, int, const char *); char * logctl (char *); #endif /* _LOG_H_ */ epic4-2.10.2.orig/include/alias.h0000644000000000000000000001041707753027063013326 0ustar /* * alias.h: header for alias.c * * Written by Jeremy Nelson * Copyright 1997 EPIC Software Labs * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __alias_h__ #define __alias_h__ /* * XXXX - These need to go away */ #define COMMAND_ALIAS 0 #define VAR_ALIAS 1 #define VAR_ALIAS_LOCAL 2 /* * These are the user commands. Dont call these directly. */ BUILT_IN_COMMAND(aliascmd); BUILT_IN_COMMAND(assigncmd); BUILT_IN_COMMAND(localcmd); BUILT_IN_COMMAND(stubcmd); BUILT_IN_COMMAND(dumpcmd); BUILT_IN_COMMAND(unloadcmd); void add_var_alias (const char *name, const char *stuff, int noisy); void add_local_alias (const char *name, const char *stuff, int noisy); #if 0 /* Internal now */ void add_cmd_alias (void); #endif void add_var_stub_alias (const char *name, const char *stuff); void add_cmd_stub_alias (const char *name, const char *stuff); char * get_variable (const char *name); char ** glob_cmd_alias (const char *name, int *howmany, int maxret, int start, int rev); char * get_cmd_alias (const char *name, int *howmany, char **complete_name, void **args); char ** get_subarray_elements (const char *root, int *howmany, int type); /* These are in expr.c */ /* * This function is a general purpose interface to alias expansion. * The second argument is the text to be expanded. * The third argument are the command line expandoes $0, $1, etc. * The fourth argument is a flag whether $0, $1, etc are used * The fifth argument, if set, controls whether only the first "command" * will be expanded. If set, this argument will be set to the "rest" * of the commands (after the first semicolon, or the null). If NULL, * then the entire text will be expanded. */ char * expand_alias (const char *, const char *, int *, ssize_t *); /* * This is the interface to the "expression parser" * The first argument is the expression to be parsed * The second argument is the command line expandoes ($0, $1, etc) * The third argument will be set if the command line expandoes are used. */ char * parse_inline (char *, const char *, int *); /* * This function is used to call a user-defined function. * Noone should be calling this directly except for call_function. */ char * call_user_function (const char *, char *); void call_user_alias (const char *, char *, char *, void *); /* * This function is used to call a lambda (``anonymous'') function. * You provide the lambda function name, its contents, and $*, and * it returns you $FUNCTION_RETURN. */ char * call_lambda_function (const char *, const char *, const char *); /* * This function is used to save all the current aliases to a global * file. This is used by /SAVE and /ABORT. */ void save_assigns (FILE *, int); void save_aliases (FILE *, int); /* * This function is in functions.c * This function allows you to execute a primitive "BUILT IN" expando. * These are the $A, $B, $C, etc expandoes. * The argument is the character of the expando (eg, 'A', 'B', etc) * * This is in functions.c */ char * built_in_alias (char, int *); /* BOGUS */ /* * This function is used to prepare the $* string before calling a user * alias or function. You should pass in the last argument from get_cmd_alias * to this function, and also the $* value. The second value may very well * be modified. */ void prepare_alias_call (void *, char **); void destroy_alias_call (void *); /* * This is in functions.c * This is only used by next_unit and expand_alias to call built in functions. * Noone should call this function directly. */ char * call_function (char *, const char *, int *); /* * These are the two primitives for runtime stacks. */ int make_local_stack (const char *); void destroy_local_stack (void); void set_current_command (char *); void bless_local_stack (void); void unset_current_command (void); void lock_stack_frame (void); void unlock_stack_frame (void); void destroy_call_stack (void); void dump_call_stack (void); void panic_dump_call_stack (void); /* * This is the alias interface to the /STACK command. */ void do_stack_alias (int, char *, int); /* * Truly bogus. =) */ char *canon_number (char *input); char *aliasctl (char *); char * after_expando (char *, int, int *); #endif /* _ALIAS_H_ */ epic4-2.10.2.orig/include/termx.h0000644000000000000000000011412110767364266013401 0ustar /* * term.h: header file for term.c * * Copyright 1990 Michael Sandrof * Copyright 1997 EPIC Software Labs * Copyright 1998 J. Kean Johnston * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #ifndef __term_h__ #define __term_h__ /* To get declaration of "output_screen" */ #include "screen.h" extern volatile int need_redraw; extern int meta_mode; /* * This puts a character to the current target, whatever it is. * All output everywhere should go through this. * This does not mangle its output, so its suitable for outputting * escape sequences. */ #if !defined(WTERM_C) && !defined(WSERV_C) #define current_ftarget (output_screen ? output_screen->fpout : stdout) #ifdef __need_putchar_x__ __inline__ static int putchar_x (int c) { return fputc((int) c, current_ftarget ); } #endif #ifdef __need_term_flush__ __inline__ static void term_flush (void) { fflush( current_ftarget ); } #endif #endif #define TERM_SGR_BOLD_ON 1 #define TERM_SGR_BOLD_OFF 2 #define TERM_SGR_BLINK_ON 3 #define TERM_SGR_BLINK_OFF 4 #define TERM_SGR_UNDL_ON 5 #define TERM_SGR_UNDL_OFF 6 #define TERM_SGR_REV_ON 7 #define TERM_SGR_REV_OFF 8 #define TERM_SGR_NORMAL 9 #define TERM_SGR_RESET 10 #define TERM_SGR_FOREGROUND 11 #define TERM_SGR_BACKGROUND 12 #define TERM_SGR_GCHAR 13 #define TERM_SGR_ALTCHAR_ON 14 #define TERM_SGR_ALTCHAR_OFF 15 #define TERM_SGR_MAXVAL 16 #define TERM_CAN_CUP 1 << 0 #define TERM_CAN_CLEAR 1 << 1 #define TERM_CAN_CLREOL 1 << 2 #define TERM_CAN_RIGHT 1 << 3 #define TERM_CAN_LEFT 1 << 4 #define TERM_CAN_SCROLL 1 << 5 #define TERM_CAN_DELETE 1 << 6 #define TERM_CAN_INSERT 1 << 7 #define TERM_CAN_DELLINES 1 << 8 #define TERM_CAN_INSLINES 1 << 9 #define TERM_CAN_REPEAT 1 << 10 #define TERM_CAN_BOLD 1 << 11 #define TERM_CAN_BLINK 1 << 12 #define TERM_CAN_UNDL 1 << 13 #define TERM_CAN_REVERSE 1 << 14 #define TERM_CAN_COLOR 1 << 15 #define TERM_CAN_GCHAR 1 << 16 #if 0 extern char *TI_cr, *TI_nl; extern int TI_lines, TI_cols; extern char *TI_sgrstrs[]; extern char *TI_forecolors[]; extern char *TI_backcolors[]; #endif extern int termfeatures; extern struct my_term *current_term; /* Our variable name Cap / Info Description */ struct my_term { int TI_bw; /* bw / bw cub1 wraps from column 0 to last column */ int TI_am; /* am / am terminal has automatic margins */ int TI_xsb; /* xb / xsb beehive (f1=escape, f2=ctrl C) */ int TI_xhp; /* xs / xhp standout not erased by overwriting (hp) */ int TI_xenl; /* xn / xenl newline ignored after 80 cols (concept) */ int TI_eo; /* eo / eo can erase overstrikes with a blank */ int TI_gn; /* gn / gn generic line type */ int TI_hc; /* hc / hc hardcopy terminal */ int TI_km; /* km / km Has a meta key (shift, sets parity bit) */ int TI_hs; /* hs / hs has extra status line */ int TI_in; /* in / in insert mode distinguishes nulls */ int TI_da; /* da / da display may be retained above the screen */ int TI_db; /* db / db display may be retained below the screen */ int TI_mir; /* mi / mir safe to move while in insert mode */ int TI_msgr; /* ms / msgr safe to move while in standout mode */ int TI_os; /* os / os terminal can overstrike */ int TI_eslok; /* es / eslok escape can be used on the status line */ int TI_xt; /* xt / xt tabs destructive, magic so char (t1061) */ int TI_hz; /* hz / hz can't print ~'s (hazeltine) */ int TI_ul; /* ul / ul underline character overstrikes */ int TI_xon; /* xo / xon terminal uses xon/xoff handshaking */ int TI_nxon; /* nx / nxon padding won't work, xon/xoff required */ int TI_mc5i; /* 5i / mc5i printer won't echo on screen */ int TI_chts; /* HC / chts cursor is hard to see */ int TI_nrrmc; /* NR / nrrmc smcup does not reverse rmcup */ int TI_npc; /* NP / npc pad character does not exist */ int TI_ndscr; /* ND / ndscr scrolling region is non-destructive */ int TI_ccc; /* cc / ccc terminal can re-define existing colors */ int TI_bce; /* ut / bce screen erased with background color */ int TI_hls; /* hl / hls terminal uses only HLS color notation (Tektronix) */ int TI_xhpa; /* YA / xhpa only positive motion for hpa/mhpa caps */ int TI_crxm; /* YB / crxm using cr turns off micro mode */ int TI_daisy; /* YC / daisy printer needs operator to change character set */ int TI_xvpa; /* YD / xvpa only positive motion for vpa/mvpa caps */ int TI_sam; /* YE / sam printing in last column causes cr */ int TI_cpix; /* YF / cpix changing character pitch changes resolution */ int TI_lpix; /* YG / lpix changing line pitch changes resolution */ int TI_cols; /* co / cols number of columns in a line */ int TI_it; /* it / it tabs initially every # spaces */ int TI_lines; /* li / lines number of lines on screen or page */ int TI_lm; /* lm / lm lines of memory if > line. 0 means varies */ int TI_xmc; /* sg / xmc number of blank characters left by smso or rmso */ int TI_pb; /* pb / pb lowest baud rate where padding needed */ int TI_vt; /* vt / vt virtual terminal number (CB/unix) */ int TI_wsl; /* ws / wsl number of columns in status line */ int TI_nlab; /* Nl / nlab number of labels on screen */ int TI_lh; /* lh / lh rows in each label */ int TI_lw; /* lw / lw columns in each label */ int TI_ma; /* ma / ma maximum combined attributes terminal can handle */ int TI_wnum; /* MW / wnum maximum number of defineable windows */ int TI_colors; /* Co / colors maximum number of colors on screen */ int TI_pairs; /* pa / pairs maximum number of color-pairs on the screen */ int TI_ncv; /* NC / ncv video attributes that can't be used with colors */ int TI_bufsz; /* Ya / bufsz numbers of bytes buffered before printing */ int TI_spinv; /* Yb / spinv spacing of pins vertically in pins per inch */ int TI_spinh; /* Yc / spinh spacing of dots horizontally in dots per inch */ int TI_maddr; /* Yd / maddr maximum value in micro_..._address */ int TI_mjump; /* Ye / mjump maximum value in parm_..._micro */ int TI_mcs; /* Yf / mcs character step size when in micro mode */ int TI_mls; /* Yg / mls line step size when in micro mode */ int TI_npins; /* Yh / npins numbers of pins in print-head */ int TI_orc; /* Yi / orc horizontal resolution in units per line */ int TI_orl; /* Yj / orl vertical resolution in units per line */ int TI_orhi; /* Yk / orhi horizontal resolution in units per inch */ int TI_orvi; /* Yl / orvi vertical resolution in units per inch */ int TI_cps; /* Ym / cps print rate in characters per second */ int TI_widcs; /* Yn / widcs character step size when in double wide mode */ int TI_btns; /* BT / btns number of buttons on mouse */ int TI_bitwin; /* Yo / bitwin number of passes for each bit-image row */ int TI_bitype; /* Yp / bitype type of bit-image device */ const char *TI_cbt; /* bt / cbt back tab (P) */ const char *TI_bel; /* bl / bel audible signal (bell) (P) */ const char *TI_cr; /* cr / cr carriage return (P*) (P*) */ const char *TI_csr; /* cs / csr change region to line #1 to line #2 (P) */ const char *TI_tbc; /* ct / tbc clear all tab stops (P) */ const char *TI_clear; /* cl / clear clear screen and home cursor (P*) */ const char *TI_el; /* ce / el clear to end of line (P) */ const char *TI_ed; /* cd / ed clear to end of screen (P*) */ const char *TI_hpa; /* ch / hpa horizontal position #1, absolute (P) */ const char *TI_cmdch; /* CC / cmdch terminal settable cmd character in prototype !? */ const char *TI_cup; /* cm / cup move to row #1 columns #2 */ const char *TI_cud1; /* do / cud1 down one line */ const char *TI_home; /* ho / home home cursor (if no cup) */ const char *TI_civis; /* vi / civis make cursor invisible */ const char *TI_cub1; /* le / cub1 move left one space */ const char *TI_mrcup; /* CM / mrcup memory relative cursor addressing */ const char *TI_cnorm; /* ve / cnorm make cursor appear normal (undo civis/cvvis) */ const char *TI_cuf1; /* nd / cuf1 non-destructive space (move right one space) */ const char *TI_ll; /* ll / ll last line, first column (if no cup) */ const char *TI_cuu1; /* up / cuu1 up one line */ const char *TI_cvvis; /* vs / cvvis make cursor very visible */ const char *TI_dch1; /* dc / dch1 delete character (P*) */ const char *TI_dl1; /* dl / dl1 delete line (P*) */ const char *TI_dsl; /* ds / dsl disable status line */ const char *TI_hd; /* hd / hd half a line down */ const char *TI_smacs; /* as / smacs start alternate character set (P) */ const char *TI_blink; /* mb / blink turn on blinking */ const char *TI_bold; /* md / bold turn on bold (extra bright) mode */ const char *TI_smcup; /* ti / smcup string to start programs using cup */ const char *TI_smdc; /* dm / smdc enter delete mode */ const char *TI_dim; /* mh / dim turn on half-bright mode */ const char *TI_smir; /* im / smir enter insert mode */ const char *TI_invis; /* mk / invis turn on blank mode (characters invisible) */ const char *TI_prot; /* mp / prot turn on protected mode */ const char *TI_rev; /* mr / rev turn on reverse video mode */ const char *TI_smso; /* so / smso begin standout mode */ const char *TI_smul; /* us / smul begin underline mode */ const char *TI_ech; /* ec / ech erase #1 characters (P) */ const char *TI_rmacs; /* ae / rmacs end alternate character set (P) */ const char *TI_sgr0; /* me / sgr0 turn off all attributes */ const char *TI_rmcup; /* te / rmcup strings to end programs using cup */ const char *TI_rmdc; /* ed / rmdc end delete mode */ const char *TI_rmir; /* ei / rmir exit insert mode */ const char *TI_rmso; /* se / rmso exit standout mode */ const char *TI_rmul; /* ue / rmul exit underline mode */ const char *TI_flash; /* vb / flash visible bell (may not move cursor) */ const char *TI_ff; /* ff / ff hardcopy terminal page eject (P*) */ const char *TI_fsl; /* fs / fsl return from status line */ const char *TI_is1; /* i1 / is1 initialization string */ const char *TI_is2; /* is / is2 initialization string */ const char *TI_is3; /* i3 / is3 initialization string */ const char *TI_if; /* if / if name of initialization file */ const char *TI_ich1; /* ic / ich1 insert character (P) */ const char *TI_il1; /* al / il1 insert line (P*) */ const char *TI_ip; /* ip / ip insert padding after inserted character */ const char *TI_kbs; /* kb / kbs backspace key */ const char *TI_ktbc; /* ka / ktbc clear-all-tabs key */ const char *TI_kclr; /* kC / kclr clear-screen or erase key */ const char *TI_kctab; /* kt / kctab clear-tab key */ const char *TI_kdch1; /* kD / kdch1 delete-character key */ const char *TI_kdl1; /* kL / kdl1 delete-line key */ const char *TI_kcud1; /* kd / kcud1 down-arrow key */ const char *TI_krmir; /* kM / krmir sent by rmir or smir in insert mode */ const char *TI_kel; /* kE / kel clear-to-end-of-line key */ const char *TI_ked; /* kS / ked clear-to-end-of-screen key */ const char *TI_kf0; /* k0 / kf0 F0 function key */ const char *TI_kf1; /* k1 / kf1 F1 function key */ const char *TI_kf10; /* k; / kf10 F10 function key */ const char *TI_kf2; /* k2 / kf2 F2 function key */ const char *TI_kf3; /* k3 / kf3 F3 function key */ const char *TI_kf4; /* k4 / kf4 F4 function key */ const char *TI_kf5; /* k5 / kf5 F5 function key */ const char *TI_kf6; /* k6 / kf6 F6 function key */ const char *TI_kf7; /* k7 / kf7 F7 function key */ const char *TI_kf8; /* k8 / kf8 F8 function key */ const char *TI_kf9; /* k9 / kf9 F9 function key */ const char *TI_khome; /* kh / khome home key */ const char *TI_kich1; /* kI / kich1 insert-character key */ const char *TI_kil1; /* kA / kil1 insert-line key */ const char *TI_kcub1; /* kl / kcub1 left-arrow key */ const char *TI_kll; /* kH / kll lower-left key (home down) */ const char *TI_knp; /* kN / knp next-page key */ const char *TI_kpp; /* kP / kpp previous-page key */ const char *TI_kcuf1; /* kr / kcuf1 right-arrow key */ const char *TI_kind; /* kF / kind scroll-forward key */ const char *TI_kri; /* kR / kri scroll-backward key */ const char *TI_khts; /* kT / khts set-tab key */ const char *TI_kcuu1; /* ku / kcuu1 up-arrow key */ const char *TI_rmkx; /* ke / rmkx leave 'keyboard_transmit' mode */ const char *TI_smkx; /* ks / smkx enter 'keyboard_transmit' mode */ const char *TI_lf0; /* l0 / lf0 label on function key f0 if not f0 */ const char *TI_lf1; /* l1 / lf1 label on function key f1 if not f1 */ const char *TI_lf10; /* la / lf10 label on function key f10 if not f10 */ const char *TI_lf2; /* l2 / lf2 label on function key f2 if not f2 */ const char *TI_lf3; /* l3 / lf3 label on function key f3 if not f3 */ const char *TI_lf4; /* l4 / lf4 label on function key f4 if not f4 */ const char *TI_lf5; /* l5 / lf5 label on function key f5 if not f5 */ const char *TI_lf6; /* l6 / lf6 label on function key f6 if not f6 */ const char *TI_lf7; /* l7 / lf7 label on function key f7 if not f7 */ const char *TI_lf8; /* l8 / lf8 label on function key f8 if not f8 */ const char *TI_lf9; /* l9 / lf9 label on function key f9 if not f9 */ const char *TI_rmm; /* mo / rmm turn off meta mode */ const char *TI_smm; /* mm / smm turn on meta mode (8th-bit on) */ const char *TI_nel; /* nw / nel newline (behave like cr followed by lf) */ const char *TI_pad; /* pc / pad padding char (instead of null) */ const char *TI_dch; /* DC / dch delete #1 characters (P*) */ const char *TI_dl; /* DL / dl delete #1 lines (P*) */ const char *TI_cud; /* DO / cud down #1 lines (P*) */ const char *TI_ich; /* IC / ich insert #1 characters (P*) */ const char *TI_indn; /* SF / indn scroll forward #1 lines (P) */ const char *TI_il; /* AL / il insert #1 lines (P*) */ const char *TI_cub; /* LE / cub move #1 characters to the left (P) */ const char *TI_cuf; /* RI / cuf move #1 characters to the right (P*) */ const char *TI_rin; /* SR / rin scroll back #1 lines (P) */ const char *TI_cuu; /* UP / cuu up #1 lines (P*) */ const char *TI_pfkey; /* pk / pfkey program function key #1 to type string #2 */ const char *TI_pfloc; /* pl / pfloc program function key #1 to execute string #2 */ const char *TI_pfx; /* px / pfx program function key #1 to transmit string #2 */ const char *TI_mc0; /* ps / mc0 print contents of screen */ const char *TI_mc4; /* pf / mc4 turn off printer */ const char *TI_mc5; /* po / mc5 turn on printer */ const char *TI_rep; /* rp / rep repeat char #1 #2 times (P*) */ const char *TI_rs1; /* r1 / rs1 reset string */ const char *TI_rs2; /* r2 / rs2 reset string */ const char *TI_rs3; /* r3 / rs3 reset string */ const char *TI_rf; /* rf / rf name of reset file */ const char *TI_rc; /* rc / rc restore cursor to position of last save_cursor */ const char *TI_vpa; /* cv / vpa vertical position #1 absolute (P) */ const char *TI_sc; /* sc / sc save current cursor position (P) */ const char *TI_ind; /* sf / ind scroll text up (P) */ const char *TI_ri; /* sr / ri scroll text down (P) */ const char *TI_sgr; /* sa / sgr define video attributes #1-#9 (PG9) */ const char *TI_hts; /* st / hts set a tab in every row, current columns */ const char *TI_wind; /* wi / wind current window is lines #1-#2 cols #3-#4 */ const char *TI_ht; /* ta / ht tab to next 8-space hardware tab stop */ const char *TI_tsl; /* ts / tsl move to status line */ const char *TI_uc; /* uc / uc underline char and move past it */ const char *TI_hu; /* hu / hu half a line up */ const char *TI_iprog; /* iP / iprog path name of program for initialization */ const char *TI_ka1; /* K1 / ka1 upper left of keypad */ const char *TI_ka3; /* K3 / ka3 upper right of keypad */ const char *TI_kb2; /* K2 / kb2 center of keypad */ const char *TI_kc1; /* K4 / kc1 lower left of keypad */ const char *TI_kc3; /* K5 / kc3 lower right of keypad */ const char *TI_mc5p; /* pO / mc5p turn on printer for #1 bytes */ const char *TI_rmp; /* rP / rmp like ip but when in insert mode */ const char *TI_acsc; /* ac / acsc graphics charset pairs, based on vt100 */ const char *TI_pln; /* pn / pln program label #1 to show string #2 */ const char *TI_kcbt; /* kB / kcbt back-tab key */ const char *TI_smxon; /* SX / smxon turn on xon/xoff handshaking */ const char *TI_rmxon; /* RX / rmxon turn off xon/xoff handshaking */ const char *TI_smam; /* SA / smam turn on automatic margins */ const char *TI_rmam; /* RA / rmam turn off automatic margins */ const char *TI_xonc; /* XN / xonc XON character */ const char *TI_xoffc; /* XF / xoffc XOFF character */ const char *TI_enacs; /* eA / enacs enable alternate char set */ const char *TI_smln; /* LO / smln turn on soft labels */ const char *TI_rmln; /* LF / rmln turn off soft labels */ const char *TI_kbeg; /* @1 / kbeg begin key */ const char *TI_kcan; /* @2 / kcan cancel key */ const char *TI_kclo; /* @3 / kclo close key */ const char *TI_kcmd; /* @4 / kcmd command key */ const char *TI_kcpy; /* @5 / kcpy copy key */ const char *TI_kcrt; /* @6 / kcrt create key */ const char *TI_kend; /* @7 / kend end key */ const char *TI_kent; /* @8 / kent enter/send key */ const char *TI_kext; /* @9 / kext exit key */ const char *TI_kfnd; /* @0 / kfnd find key */ const char *TI_khlp; /* %1 / khlp help key */ const char *TI_kmrk; /* %2 / kmrk mark key */ const char *TI_kmsg; /* %3 / kmsg message key */ const char *TI_kmov; /* %4 / kmov move key */ const char *TI_knxt; /* %5 / knxt next key */ const char *TI_kopn; /* %6 / kopn open key */ const char *TI_kopt; /* %7 / kopt options key */ const char *TI_kprv; /* %8 / kprv previous key */ const char *TI_kprt; /* %9 / kprt print key */ const char *TI_krdo; /* %0 / krdo redo key */ const char *TI_kref; /* &1 / kref reference key */ const char *TI_krfr; /* &2 / krfr refresh key */ const char *TI_krpl; /* &3 / krpl replace key */ const char *TI_krst; /* &4 / krst restart key */ const char *TI_kres; /* &5 / kres resume key */ const char *TI_ksav; /* &6 / ksav save key */ const char *TI_kspd; /* &7 / kspd suspend key */ const char *TI_kund; /* &8 / kund undo key */ const char *TI_kBEG; /* &9 / kBEG shifted begin key */ const char *TI_kCAN; /* &0 / kCAN shifted cancel key */ const char *TI_kCMD; /* *1 / kCMD shifted command key */ const char *TI_kCPY; /* *2 / kCPY shifted copy key */ const char *TI_kCRT; /* *3 / kCRT shifted create key */ const char *TI_kDC; /* *4 / kDC shifted delete-character key */ const char *TI_kDL; /* *5 / kDL shifted delete-line key */ const char *TI_kslt; /* *6 / kslt select key */ const char *TI_kEND; /* *7 / kEND shifted end key */ const char *TI_kEOL; /* *8 / kEOL shifted clear-to-end-of-line key */ const char *TI_kEXT; /* *9 / kEXT shifted exit key */ const char *TI_kFND; /* *0 / kFND shifted find key */ const char *TI_kHLP; /* #1 / kHLP shifted help key */ const char *TI_kHOM; /* #2 / kHOM shifted home key */ const char *TI_kIC; /* #3 / kIC shifted insert-character key */ const char *TI_kLFT; /* #4 / kLFT shifted left-arrow key */ const char *TI_kMSG; /* %a / kMSG shifted message key */ const char *TI_kMOV; /* %b / kMOV shifted move key */ const char *TI_kNXT; /* %c / kNXT shifted next key */ const char *TI_kOPT; /* %d / kOPT shifted options key */ const char *TI_kPRV; /* %e / kPRV shifted previous key */ const char *TI_kPRT; /* %f / kPRT shifted print key */ const char *TI_kRDO; /* %g / kRDO shifted redo key */ const char *TI_kRPL; /* %h / kRPL shifted replace key */ const char *TI_kRIT; /* %i / kRIT shifted right-arrow key */ const char *TI_kRES; /* %j / kRES shifted resume key */ const char *TI_kSAV; /* !1 / kSAV shifted save key */ const char *TI_kSPD; /* !2 / kSPD shifted suspend key */ const char *TI_kUND; /* !3 / kUND shifted undo key */ const char *TI_rfi; /* RF / rfi send next input char (for ptys) */ const char *TI_kf11; /* F1 / kf11 F11 function key */ const char *TI_kf12; /* F2 / kf12 F12 function key */ const char *TI_kf13; /* F3 / kf13 F13 function key */ const char *TI_kf14; /* F4 / kf14 F14 function key */ const char *TI_kf15; /* F5 / kf15 F15 function key */ const char *TI_kf16; /* F6 / kf16 F16 function key */ const char *TI_kf17; /* F7 / kf17 F17 function key */ const char *TI_kf18; /* F8 / kf18 F18 function key */ const char *TI_kf19; /* F9 / kf19 F19 function key */ const char *TI_kf20; /* FA / kf20 F20 function key */ const char *TI_kf21; /* FB / kf21 F21 function key */ const char *TI_kf22; /* FC / kf22 F22 function key */ const char *TI_kf23; /* FD / kf23 F23 function key */ const char *TI_kf24; /* FE / kf24 F24 function key */ const char *TI_kf25; /* FF / kf25 F25 function key */ const char *TI_kf26; /* FG / kf26 F26 function key */ const char *TI_kf27; /* FH / kf27 F27 function key */ const char *TI_kf28; /* FI / kf28 F28 function key */ const char *TI_kf29; /* FJ / kf29 F29 function key */ const char *TI_kf30; /* FK / kf30 F30 function key */ const char *TI_kf31; /* FL / kf31 F31 function key */ const char *TI_kf32; /* FM / kf32 F32 function key */ const char *TI_kf33; /* FN / kf33 F33 function key */ const char *TI_kf34; /* FO / kf34 F34 function key */ const char *TI_kf35; /* FP / kf35 F35 function key */ const char *TI_kf36; /* FQ / kf36 F36 function key */ const char *TI_kf37; /* FR / kf37 F37 function key */ const char *TI_kf38; /* FS / kf38 F38 function key */ const char *TI_kf39; /* FT / kf39 F39 function key */ const char *TI_kf40; /* FU / kf40 F40 function key */ const char *TI_kf41; /* FV / kf41 F41 function key */ const char *TI_kf42; /* FW / kf42 F42 function key */ const char *TI_kf43; /* FX / kf43 F43 function key */ const char *TI_kf44; /* FY / kf44 F44 function key */ const char *TI_kf45; /* FZ / kf45 F45 function key */ const char *TI_kf46; /* Fa / kf46 F46 function key */ const char *TI_kf47; /* Fb / kf47 F47 function key */ const char *TI_kf48; /* Fc / kf48 F48 function key */ const char *TI_kf49; /* Fd / kf49 F49 function key */ const char *TI_kf50; /* Fe / kf50 F50 function key */ const char *TI_kf51; /* Ff / kf51 F51 function key */ const char *TI_kf52; /* Fg / kf52 F52 function key */ const char *TI_kf53; /* Fh / kf53 F53 function key */ const char *TI_kf54; /* Fi / kf54 F54 function key */ const char *TI_kf55; /* Fj / kf55 F55 function key */ const char *TI_kf56; /* Fk / kf56 F56 function key */ const char *TI_kf57; /* Fl / kf57 F57 function key */ const char *TI_kf58; /* Fm / kf58 F58 function key */ const char *TI_kf59; /* Fn / kf59 F59 function key */ const char *TI_kf60; /* Fo / kf60 F60 function key */ const char *TI_kf61; /* Fp / kf61 F61 function key */ const char *TI_kf62; /* Fq / kf62 F62 function key */ const char *TI_kf63; /* Fr / kf63 F63 function key */ const char *TI_el1; /* cb / el1 Clear to beginning of line */ const char *TI_mgc; /* MC / mgc clear right and left soft margins */ const char *TI_smgl; /* ML / smgl set left soft margin at current column */ const char *TI_smgr; /* MR / smgr set right soft margin at current column */ const char *TI_fln; /* Lf / fln label format */ const char *TI_sclk; /* SC / sclk set clock, #1 hrs #2 mins #3 secs */ const char *TI_dclk; /* DK / dclk display clock at (#1,#2) */ const char *TI_rmclk; /* RC / rmclk remove clock */ const char *TI_cwin; /* CW / cwin define a window #1 from #2,#3 to #4,#5 */ const char *TI_wingo; /* WG / wingo go to window #1 */ const char *TI_hup; /* HU / hup hang-up phone */ const char *TI_dial; /* DI / dial dial number #1 */ const char *TI_qdial; /* QD / qdial dial number #1 without checking */ const char *TI_tone; /* TO / tone select touch tone dialing */ const char *TI_pulse; /* PU / pulse select pulse dialing */ const char *TI_hook; /* fh / hook flash switch hook */ const char *TI_pause; /* PA / pause pause for 2-3 seconds */ const char *TI_wait; /* WA / wait wait for dial-tone */ const char *TI_u0; /* u0 / u0 User string #0 */ const char *TI_u1; /* u1 / u1 User string #1 */ const char *TI_u2; /* u2 / u2 User string #2 */ const char *TI_u3; /* u3 / u3 User string #3 */ const char *TI_u4; /* u4 / u4 User string #4 */ const char *TI_u5; /* u5 / u5 User string #5 */ const char *TI_u6; /* u6 / u6 User string #6 */ const char *TI_u7; /* u7 / u7 User string #7 */ const char *TI_u8; /* u8 / u8 User string #8 */ const char *TI_u9; /* u9 / u9 User string #9 */ const char *TI_op; /* op / op Set default pair to its original value */ const char *TI_oc; /* oc / oc Set all color pairs to the original ones */ const char *TI_initc; /* Ic / initc initialize color #1 to (#2,#3,#4) */ const char *TI_initp; /* Ip / initp Initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7) */ const char *TI_scp; /* sp / scp Set current color pair to #1 */ const char *TI_setf; /* Sf / setf Set foreground color #1 */ const char *TI_setb; /* Sb / setb Set background color #1 */ const char *TI_cpi; /* ZA / cpi Change number of characters per inch */ const char *TI_lpi; /* ZB / lpi Change number of lines per inch */ const char *TI_chr; /* ZC / chr Change horizontal resolution */ const char *TI_cvr; /* ZD / cvr Change vertical resolution */ const char *TI_defc; /* ZE / defc Define a character */ const char *TI_swidm; /* ZF / swidm Enter double-wide mode */ const char *TI_sdrfq; /* ZG / sdrfq Enter draft-quality mode */ const char *TI_sitm; /* ZH / sitm Enter italic mode */ const char *TI_slm; /* ZI / slm Start leftward carriage motion */ const char *TI_smicm; /* ZJ / smicm Start micro-motion mode */ const char *TI_snlq; /* ZK / snlq Enter NLQ mode */ const char *TI_snrmq; /* ZL / snrmq Enter normal-quality mode */ const char *TI_sshm; /* ZM / sshm Enter shadow-print mode */ const char *TI_ssubm; /* ZN / ssubm Enter subscript mode */ const char *TI_ssupm; /* ZO / ssupm Enter superscript mode */ const char *TI_sum; /* ZP / sum Start upward carriage motion */ const char *TI_rwidm; /* ZQ / rwidm End double-wide mode */ const char *TI_ritm; /* ZR / ritm End italic mode */ const char *TI_rlm; /* ZS / rlm End left-motion mode */ const char *TI_rmicm; /* ZT / rmicm End micro-motion mode */ const char *TI_rshm; /* ZU / rshm End shadow-print mode */ const char *TI_rsubm; /* ZV / rsubm End subscript mode */ const char *TI_rsupm; /* ZW / rsupm End superscript mode */ const char *TI_rum; /* ZX / rum End reverse character motion */ const char *TI_mhpa; /* ZY / mhpa Like column_address in micro mode */ const char *TI_mcud1; /* ZZ / mcud1 Like cursor_down in micro mode */ const char *TI_mcub1; /* Za / mcub1 Like cursor_left in micro mode */ const char *TI_mcuf1; /* Zb / mcuf1 Like cursor_right in micro mode */ const char *TI_mvpa; /* Zc / mvpa Like row_address in micro mode */ const char *TI_mcuu1; /* Zd / mcuu1 Like cursor_up in micro mode */ const char *TI_porder; /* Ze / porder Match software bits to print-head pins */ const char *TI_mcud; /* Zf / mcud Like parm_down_cursor in micro mode */ const char *TI_mcub; /* Zg / mcub Like parm_left_cursor in micro mode */ const char *TI_mcuf; /* Zh / mcuf Like parm_right_cursor in micro mode */ const char *TI_mcuu; /* Zi / mcuu Like parm_up_cursor in micro mode */ const char *TI_scs; /* Zj / scs Select character set */ const char *TI_smgb; /* Zk / smgb Set bottom margin at current line */ const char *TI_smgbp; /* Zl / smgbp Set bottom margin at line #1 or #2 lines from bottom */ const char *TI_smglp; /* Zm / smglp Set left (right) margin at column #1 (#2) */ const char *TI_smgrp; /* Zn / smgrp Set right margin at column #1 */ const char *TI_smgt; /* Zo / smgt Set top margin at current line */ const char *TI_smgtp; /* Zp / smgtp Set top (bottom) margin at row #1 (#2) */ const char *TI_sbim; /* Zq / sbim Start printing bit image graphics */ const char *TI_scsd; /* Zr / scsd Start character set definition */ const char *TI_rbim; /* Zs / rbim Stop printing bit image graphics */ const char *TI_rcsd; /* Zt / rcsd End definition of character set */ const char *TI_subcs; /* Zu / subcs List of subscriptable characters */ const char *TI_supcs; /* Zv / supcs List of superscriptable characters */ const char *TI_docr; /* Zw / docr Printing any of these characters causes CR */ const char *TI_zerom; /* Zx / zerom No motion for subsequent character */ const char *TI_csnm; /* Zy / csnm List of character set names */ const char *TI_kmous; /* Km / kmous Mouse event has occurred */ const char *TI_minfo; /* Mi / minfo Mouse status information */ const char *TI_reqmp; /* RQ / reqmp Request mouse position */ const char *TI_getm; /* Gm / getm Curses should get button events */ const char *TI_setaf; /* AF / setaf Set foreground color using ANSI escape */ const char *TI_setab; /* AB / setab Set background color using ANSI escape */ const char *TI_pfxl; /* xl / pfxl Program function key #1 to type string #2 and show string #3 */ const char *TI_devt; /* dv / devt Indicate language/codeset support */ const char *TI_csin; /* ci / csin Init sequence for multiple codesets */ const char *TI_s0ds; /* s0 / s0ds Shift to code set 0 (EUC set 0, ASCII) */ const char *TI_s1ds; /* s1 / s1ds Shift to code set 1 */ const char *TI_s2ds; /* s2 / s2ds Shift to code set 2 */ const char *TI_s3ds; /* s3 / s3ds Shift to code set 3 */ const char *TI_smglr; /* ML / smglr Set both left and right margins to #1, #2 */ const char *TI_smgtb; /* MT / smgtb Sets both top and bottom margins to #1, #2 */ const char *TI_birep; /* Xy / birep Repeat bit image cell #1 #2 times */ const char *TI_binel; /* Zz / binel Move to next row of the bit image */ const char *TI_bicr; /* Yv / bicr Move to beginning of same row */ const char *TI_colornm; /* Yw / colornm Give name for color #1 */ const char *TI_defbi; /* Yx / defbi Define rectangualar bit image region */ const char *TI_endbi; /* Yy / endbi End a bit-image region */ const char *TI_setcolor; /* Yz / setcolor Change to ribbon color #1 */ const char *TI_slines; /* YZ / slines Set page length to #1 lines */ const char *TI_dispc; /* S1 / dispc Display PC character */ const char *TI_smpch; /* S2 / smpch Enter PC character display mode */ const char *TI_rmpch; /* S3 / rmpch Exit PC character display mode */ const char *TI_smsc; /* S4 / smsc Enter PC scancode mode */ const char *TI_rmsc; /* S5 / rmsc Exit PC scancode mode */ const char *TI_pctrm; /* S6 / pctrm PC terminal options */ const char *TI_scesc; /* S7 / scesc Escape for scancode emulation */ const char *TI_scesa; /* S8 / scesa Alternate escape for scancode emulation */ const char *TI_ehhlm; /* Xh / ehhlm Enter horizontal highlight mode */ const char *TI_elhlm; /* Xl / elhlm Enter left highlight mode */ const char *TI_elohlm; /* Xo / elohlm Enter low highlight mode */ const char *TI_erhlm; /* Xr / erhlm Enter right highlight mode */ const char *TI_ethlm; /* Xt / ethlm Enter top highlight mode */ const char *TI_evhlm; /* Xv / evhlm Enter vertical highlight mode */ const char *TI_sgr1; /* sA / sgr1 Define second set of video attributes #1-#6 */ const char *TI_slength; /* sL / slength YI Set page length to #1 hundredth of an inch */ const char *TI_OTi2; /* i2 / OTi2 secondary initialization string */ const char *TI_OTrs; /* rs / OTrs terminal reset string */ int TI_OTug; /* ug / OTug number of blanks left by ul */ int TI_OTbs; /* bs / OTbs uses ^H to move left */ int TI_OTns; /* ns / OTns crt cannot scroll */ int TI_OTnc; /* nc / OTnc no way to go to start of line */ int TI_OTdC; /* dC / OTdC pad needed for CR */ int TI_OTdN; /* dN / OTdN pad needed for LF */ const char *TI_OTnl; /* nl / OTnl use to move down */ const char *TI_OTbc; /* bc / OTbc move left, if not ^H */ int TI_OTMT; /* MT / OTMT has meta key */ int TI_OTNL; /* NL / OTNL move down with \n */ int TI_OTdB; /* dB / OTdB padding required for ^H */ int TI_OTdT; /* dT / OTdT padding required for ^I */ int TI_OTkn; /* kn / OTkn count of function keys */ const char *TI_OTko; /* ko / OTko list of self-mapped keycaps */ const char *TI_OTma; /* ma / OTma map arrow keys rogue(1) motion keys */ int TI_OTpt; /* pt / OTpt has 8-const char tabs invoked with ^I */ int TI_OTxr; /* xr / OTxr return clears the line */ const char *TI_OTG2; /* G2 / OTG2 single upper left */ const char *TI_OTG3; /* G3 / OTG3 single lower left */ const char *TI_OTG1; /* G1 / OTG1 single upper right */ const char *TI_OTG4; /* G4 / OTG4 single lower right */ const char *TI_OTGR; /* GR / OTGR tee pointing right */ const char *TI_OTGL; /* GL / OTGL tee pointing left */ const char *TI_OTGU; /* GU / OTGU tee pointing up */ const char *TI_OTGD; /* GD / OTGD tee pointing down */ const char *TI_OTGH; /* GH / OTGH single horizontal line */ const char *TI_OTGV; /* GV / OTGV single vertical line */ const char *TI_OTGC; /* GC / OTGC single intersection */ const char *TI_meml; /* ml / meml memory lock above */ const char *TI_memu; /* mu / memu memory unlock */ const char *TI_box1; /* bx / box1 box characters primary set */ /* non termcap/terminfo terminal info (generated by epic) */ char TI_normal[256]; const char *TI_sgrstrs[TERM_SGR_MAXVAL]; const char *TI_forecolors[16]; const char *TI_backcolors[16]; int TI_meta_mode; /* int TI_need_redraw ; */ }; #define term_has(x) (termfeatures & (x)) #define capstr(x) (current_term->TI_sgrstrs[(TERM_SGR_ ## x)-1]) #define outcap(x) (tputs_x(capstr(x))) #ifndef TERM_DEBUG #define tputs_x(s) (tputs(s, 0, putchar_x)) #else int tputs_x(char *); #endif #define IFV(x) if (get_int_var((x ## _VIDEO_VAR))) #define term_underline_on() IFV(UNDERLINE) outcap(UNDL_ON) #define term_underline_off() IFV(UNDERLINE) outcap(UNDL_OFF) #define term_standout_on() IFV(INVERSE) outcap(REV_ON) #define term_standout_off() IFV(INVERSE) outcap(REV_OFF) #define term_blink_on() IFV(BLINK) outcap(BLINK_ON) #define term_blink_off() IFV(BLINK) outcap(BLINK_OFF) #define term_bold_on() IFV(BOLD) outcap(BOLD_ON) #define term_bold_off() IFV(BOLD) outcap(BOLD_OFF) #define term_altcharset_on() if (get_int_var(ALT_CHARSET_VAR)) \ outcap(ALTCHAR_ON) #define term_altcharset_off() if (get_int_var(ALT_CHARSET_VAR)) \ outcap(ALTCHAR_OFF) #define term_set_foreground(x) tputs_x(current_term->TI_forecolors[(x) & 0x0f]) #define term_set_background(x) tputs_x(current_term->TI_backcolors[(x) & 0x0f]) #define term_set_attribs(f,b) tputs_x(term_getsgr(TERM_SGR_COLORS,(f),(b))) #define term_putgchar(x) tputs_x(term_getsgr(TERM_SGR_GCHAR,(x),0)) #define term_clear_screen() term_clrscr() #define term_move_cursor(c, r) term_gotoxy((c),(r)) #define term_cr() tputs_x(current_term->TI_cr) #define term_newline() tputs_x(current_term->TI_nel) #define term_cursor_left() term_left(1) #define term_cursor_right() term_right(1) #define term_clear_to_eol() term_clreol() #define term_all_off() tputs_x(current_term->TI_normal); RETSIGTYPE term_cont (int); void term_beep (void); int term_echo (int); int term_init (void); int term_resize (void); void term_pause (char, char *); void term_putchar (unsigned char); void term_scroll (int, int, int); void term_insert (unsigned char); void term_delete (int); void term_repeat (unsigned char, int); void term_right (int); void term_left (int); void term_clreol (void); void term_clrscr (void); void term_gotoxy (int, int); void term_reset (void); int term_eight_bit (void); void set_term_eight_bit (int); void set_meta_8bit (const void *); const char * term_getsgr (int, int, int); const char * get_term_capability (const char *, int, int); #endif /* _TERM_H_ */ epic4-2.10.2.orig/include/translat.h0000644000000000000000000000064307707324325014065 0ustar /* * Global stuff for translation tables. * * Tomten, tomten@solace.hsh.se / tomten@lysator.liu.se * * @(#)$Id: translat.h,v 1.3 2003/07/22 21:12:53 jnelson Exp $ */ #ifndef __translat_h_ # define __translat_h_ extern void set_translation (const void *); extern int translation; extern void translate_from_server (unsigned char *); extern void translate_to_server (unsigned char *); #endif /* __translat_h_ */ epic4-2.10.2.orig/KNOWNBUGS0000644000000000000000000000412112171115773011730 0ustar EPIC4 Projects, Bugs, and other Errata: KNOWN ERRATA (eg, bugs, or unresolved requests): ------------------------------------------------ * Roll back the /set new_server_lastlog_level changes from epic5. * /window commands disappear to /lastlog because they are LEVEL_NONE. doh [See http://www.epicsol.org/PROJECTS for things to come in the future] [See http://www.epicsol.org/CHANGELOG for things that changed in the past] THE CHANGELOG SINCE THE LAST RELEASE: ------------------------------------- * New version of /load hold_mode (implements /set hold_interval) * Fix crash with $write(w text) * Fix the build on systems without intmax_t/strtoimax(). * Add /on signal (pegasus) * Fix /set indent if /set continued_line contains ^C stuff (pegasus) * Patch from larne to fix build on interix * sig.inc should be created in the include directory. (rb larne) * Fix build on systems where CFLAGS doesn't get set (larne) * More changes for larne's cross-building project. * Move "term.h" out of the way so we can #include (mv'd to termx.h) * This makes it possible to avoid empty decls for tparm() * Which is supposed to fix the build for larne on who-only-knows-what. * Rename tparm() to my_tparm(). * Do a make depend since i changed the name of a header file. ugh. * Change the name of (struct term) to (struct my_term) for freebsd sake. ugh. * Resolve build conflicts between x/open curses and ncurses. ugh. * Fix brain-o -- AC_MSG_RESULT is not the same as AC_DEFINE, dummy. * Add $regcomp_cs() from epic5 as a special favor to blackjac. * EPIC4-2.10 was released here (Ineluctable) (Commit 769) * Signal fix from epic5 for SIG_IGN/SIG_DFL (ie, SIGPIPE) causing segafults * EPIC5-2.10.1 released here (Commit 771) * When saving /bind's, surround the sequence in double quotes (caf) * Apparently USERIP is 340 instead of 307 these days (rb jm) * Fix an important memory leak (rb |Rain|) * Work around Harzilein's irc bouncer with a mangled 004 numeric * Sort the supported rfc1459 protocol commands (caf) * Add status expando %G, to show the 005 NETWORK value (caf) * EPIC5-2.10.2 released here (Commit 776) epic4-2.10.2.orig/Makefile.in0000644000000000000000000001360210766624364012512 0ustar # IRC II was originally written by Michael Sandrof # Copyright 1991 Michael Sandrof # Copyright 1993 Matthew Green # Copyright 1998 EPIC Software Labs # # This software uses your normal, default targets. It should not be any # more difficult than anything else to install. # # Most useful targets: # make - Compiles ircII and wserv4 # make install - Installs ircII and wserv4 and the standard script # library to the normal places # make clean - Remove everything created by compiling # make distclean - make clean + remove autoconf generated stuff # # Other interesting targets: # make wserv - Compile just wserv # make installwserv - Installs just wserv # make installepic - Installs just the epic binary # make installscript - Installs just the standard script library # CC = @CC@ DEFS = @DEFS@ LIBS = @LIBS@ # Compiler/Linker flags -- These flags are passed to both the compiler # and the linker. Common flags include: # -g Include debugging info in the binary. # -O Compiler should do some basic optimizations. # -Wall For GCC compilers, the -Wall flag turns on lots of additional # warning checks. You can safely ignore any warnings about # "NULL format", as those uses are intentional. CFLAGS = @CFLAGS@ # Compiler flags -- These flags are passed only to the compiler. # Common flags include: # -ansi These two flags turn on "ansi" or "standard" mode on some # -std1 vendor compilers. This flag is required for the Digital # Alpha 'cc' compiler, and may be required for other compilers # that don't allow ansi C extensions without it. GCC does # not require this flag, though EPIC will compile with it. ANSIFLAGS = # Linker flags -- These flags are passed only to the linker. # Common flags include: # -s Strip all debugging information from the resulting binary. # -static Generate a binary that does not use shared libraries LDFLAGS = @LDFLAGS@ # # These are automatically generated by 'configure'. You really ought to # get in the habit of specifying these to 'configure' rather than changing # them here. ;-) # # Note that some things have changed! This summarizes the changes: # # Script library old: /usr/local/lib/irc/script # new: /usr/local/share/epic/script # Help files old: /usr/local/lib/irc/help # new: /usr/local/share/epic/help # Wserv location old: /usr/local/bin/wserv # new: /usr/local/libexec/wserv # IP = @program_prefix@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libexecdir = @libexecdir@ sharedir = @datadir@ mandir = @mandir@ epic = @epic@ epic_exe = $(bindir)/$(epic) wserv_exe = $(libexecdir)/wserv4 epicdir = $(sharedir)/$(epic) ############ You ought not change anything below this line ################### RM = rm -f CP = cp MV = mv INSTALL_PROGRAM = @srcdir@/bsdinstall -c -m 755 INSTALL_DATA = @srcdir@/bsdinstall -c -m 644 VERSION = @VERSION@ SHELL = /bin/sh MAKE2 = $(MAKE) $(MFLAGS) MFLAGS ='CC=$(CC)' \ 'ANSIFLAGS=$(ANSIFLAGS)' \ 'CFLAGS=$(CFLAGS)' \ 'DEFS=$(DEFS)' \ 'INSTALL_WSERV=$(wserv_exe)' \ 'IRCLIB=$(epicdir)' \ 'LDFLAGS=$(LDFLAGS)' \ 'LIBS=$(LIBS)' \ 'RM=$(RM)' all everything: epic wserv4 install installeverything: all installbin installscript installman installbin: installepic installwserv VPATH=@srcdir@ # # Main irc binary # epic: source/Makefile Makefile @cd source; $(MAKE2) all EPIC = $(epic_exe)-$(VERSION) EPIC_OLD = $(epic_exe).old EPIC_LINK = $(epic_exe) installepic installirc: epic installdirs test if ./my_test \( ! -f $(IP)$(EPIC) \) \ -o source/epic -nt $(IP)$(EPIC); then \ $(INSTALL_PROGRAM) source/epic $(IP)$(EPIC); \ if ./my_test -f $(IP)$(EPIC_OLD); then \ $(RM) $(IP)$(EPIC_OLD); \ fi; \ if ./my_test -f $(IP)$(EPIC_LINK); then \ $(MV) $(IP)$(EPIC_LINK) $(IP)$(EPIC_OLD); \ fi; \ $(RM) $(IP)$(EPIC_LINK); \ ln -s $(epic)-$(VERSION) $(IP)$(EPIC_LINK); \ fi # # wserv # wserv4: source/wserv.c source/gailib.c source/Makefile @cd source; $(MAKE2) wserv4 WSERV = $(wserv_exe) installwserv: wserv4 installdirs test if ./my_test \( \! -f $(IP)$(WSERV) \) -o \ source/wserv4 -nt $(IP)$(WSERV); then \ $(INSTALL_PROGRAM) source/wserv4 $(IP)$(WSERV); \ fi # # Script library # scriptdir = $(epicdir)/script installscript: installdirs test -@( \ if ./my_test -f $(IP)$(scriptdir)/local; then \ if ./my_test -f script/local; then \ $(MV) @srcdir@/script/local \ @srcdir@/script/local.orig; \ fi; \ fi; \ ) for i in @srcdir@/script/*; \ do \ if ./my_test -f $$i; then \ if ./my_test -x $$i; then \ chmod a-x $$i; \ fi; \ target=$(IP)$(scriptdir)/`basename $$i`; \ if ./my_test -f $$target; then \ if ./my_test $$i -nt $$target; then \ $(INSTALL_DATA) $$i $$target; \ fi; \ elif ./my_test -f $$target.gz; then \ if ./my_test $$i -nt $$target.gz; then \ $(INSTALL_DATA) $$i $$target; \ gzip -f $$target; \ fi; \ else \ $(INSTALL_DATA) $$i $$target; \ if ./my_test -f $(IP)$(scriptdir)/gzip-scripts; then \ gzip -f $$target; \ fi; \ fi; \ fi; \ done helpdir = $(epicdir)/help installhelp: installdirs if ./my_test -d help ; then \ (cd @srcdir@/help; tar cf - .) | (cd $(IP)$(helpdir); tar xf -) ; \ else \ echo No help files to install. ; \ fi installman: installdirs $(INSTALL_DATA) @srcdir@/doc/epic.1 $(IP)$(mandir)/man1/$(epic).1 installdirs: umask 022; \ @srcdir@/mkinstalldirs $(IP)$(epicdir) $(IP)$(scriptdir) \ $(IP)$(helpdir) $(IP)$(bindir) $(IP)$(libexecdir) \ $(IP)$(mandir)/man1 test.o: @srcdir@/test.c $(CC) -c @srcdir@/test.c test: test.o $(CC) test.o -o my_test clean: @-if test -f source/Makefile; then cd source; $(MAKE2) clean; fi $(RM) test.o my_test distclean cleandir realclean: clean $(RM) Makefile source/Makefile include/sig.inc config.status config.cache config.log include/defs.h source/info.c.sh depend: (cd source;make depend) # This is the end of the file. epic4-2.10.2.orig/source/0000755000000000000000000000000012200242556011723 5ustar epic4-2.10.2.orig/source/window.c0000644000000000000000000044211110767364266013424 0ustar /* $EPIC: window.c,v 1.101 2008/03/17 03:42:46 jnelson Exp $ */ /* * window.c: Handles the organzation of the logical viewports (``windows'') * for irc. This includes keeping track of what windows are open, where they * are, and what is on them. * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1997, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* Sigh */ #define __need_putchar_x__ #include "irc.h" #include "screen.h" #include "window.h" #include "vars.h" #include "server.h" #include "list.h" #include "termx.h" #include "names.h" #include "ircaux.h" #include "input.h" #include "status.h" #include "output.h" #include "log.h" #include "hook.h" #include "parse.h" #include "commands.h" #include "exec.h" #include "functions.h" static const char *onoff[] = { "OFF", "ON" }; /* Resize relatively or absolutely? */ #define RESIZE_REL 1 #define RESIZE_ABS 2 /* used by the update flag to determine what needs updating */ #define REDRAW_DISPLAY 1 << 0 #define UPDATE_STATUS 1 << 1 #define REDRAW_STATUS 1 << 2 /* * The current window. This replaces the old notion of "curr_scr_win" * which had the arbitrary restriction that you could not easily operate * on a window that was not on the current screen, and switching between * screens (or to a hidden window) was impossible. We no longer have any * concept of "current screen", opting instead to use "last_input_screen" * for handling input events, and "current_window" for everything else. * current_window is set when you do an input event, so all those places * that presumed curr_scr_win still work by referencing current_window. */ Window *current_window = NULL; /* * All of the hidden windows. These windows are not on any screen, and * therefore are not visible. */ Window *invisible_list = (Window *) 0; /* * This is used to note who the currently processed message was from. * Since each window has (through /window add) the ability to "grab" all * of the output from a given nickname, we store the nickname here and then * refer to it when anything is outputted. */ const char *who_from = (char *) 0; /* * This is the lastlog level that any output should be sent out at. This * determines what window output ultimately ends up in. */ int who_level = LOG_CRAP; /* * This is set to 1 if output is to be dispatched normally. This is set to * 0 if all output is to be suppressed (such as when the system wants to add * and alias and doesnt want to blab to the user, or when you use ^ to * suppress the output of a command.) */ unsigned window_display = 1; /* * Each time a window is made the current window, it grabs this value and * increments it. We use this value to track "current window"-ness in * various contexts. */ unsigned current_window_priority = 1; static void remove_from_invisible_list (Window *); static void swap_window (Window *, Window *); static Window *get_next_window (Window *); static Window *get_previous_window (Window *); static void revamp_window_levels (Window *); static void clear_window (Window *); static void resize_window_display (Window *); static Window *window_next (Window *, char **); static Window *window_previous (Window *, char **); static void set_screens_current_window (Screen *, Window *); static void remove_window_from_screen (Window *window, int hide); static Window *window_discon (Window *window, char **args); static void window_scrollback_start (Window *window); static void window_scrollback_end (Window *window); static void window_scrollback_backward (Window *window); static void window_scrollback_forward (Window *window); static void window_scrollback_backwards_lines (Window *window, int); static void window_scrollback_forwards_lines (Window *window, int); static void window_scrollback_to_string (Window *window, regex_t *str); static void window_scrollforward_to_string (Window *window, regex_t *str); int change_line (Window *window, const unsigned char *str); int add_to_display (Window *window, const unsigned char *str); static Display *new_display_line (Display *prev, Window *w); static int count_fixed_windows (Screen *s); /* * * * * * * * * * * CONSTRUCTOR AND DESTRUCTOR * * * * * * * * * * * */ /* * new_window: This creates a new window on the screen. It does so by either * splitting the current window, or if it can't do that, it splits the * largest window. The new window is added to the window list and made the * current window */ Window *new_window (Screen *screen) { Window * new_w; Window * tmp = NULL; unsigned new_refnum = 1; int i; if (dumb_mode && current_window) return NULL; new_w = (Window *) new_malloc(sizeof(Window)); tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->refnum == new_refnum) { new_refnum++; tmp = NULL; } } new_w->refnum = new_refnum; new_w->name = NULL; if (current_window) new_w->server = current_window->server; else new_w->server = NOSERV; new_w->last_server = NOSERV; new_w->priority = -1; /* Filled in later */ new_w->top = 0; /* Filled in later */ new_w->bottom = 0; /* Filled in later */ new_w->cursor = -1; /* Force a clear-screen */ new_w->noscrollcursor = -1; new_w->absolute_size = 0; new_w->old_size = 1; /* Filled in later */ new_w->update = 0; new_w->miscflags = 0; new_w->beep_always = 0; new_w->change_line = -1; new_w->scroll = 1; new_w->skip = 0; new_w->swappable = 1; new_w->scrolladj = 1; new_w->notify_level = real_notify_level(); if (!current_window) /* First window ever */ new_w->window_level = LOG_ALL; else new_w->window_level = LOG_NONE; new_w->prompt = NULL; /* Filled in later */ for (i = 0; i < 3; i++) { new_w->status.line[i].raw = NULL; new_w->status.line[i].format = NULL; new_w->status.line[i].count = 0; new_w->status.line[i].result = NULL; } new_w->status.double_status = 0; new_w->status.special = NULL; rebuild_a_status(new_w); new_w->top_of_scrollback = NULL; /* Filled in later */ new_w->display_ip = NULL; /* Filled in later */ new_w->display_buffer_size = 0; new_w->display_buffer_max = get_int_var(SCROLLBACK_VAR); new_w->display_size = 1; /* Filled in later */ new_w->display_counter = 1; new_w->scrolling_top_of_display = NULL; /* Filled in later */ new_w->scrolling_distance_from_display_ip = -1; /* Filled in later */ new_w->holding_top_of_display = NULL; /* Filled in later */ new_w->holding_distance_from_display_ip = -1; /* Filled in later */ new_w->scrollback_top_of_display = NULL; /* Filled in later */ new_w->scrollback_distance_from_display_ip = -1; /* Filled in later */ new_w->hold_interval = 10; new_w->hold_slider = get_int_var(HOLD_SLIDER_VAR); new_w->waiting_channel = NULL; new_w->bind_channel = NULL; new_w->query_nick = NULL; new_w->nicks = NULL; new_w->lastlog_oldest = NULL; new_w->lastlog_newest = NULL; new_w->lastlog_level = real_lastlog_level(); new_w->lastlog_size = 0; new_w->lastlog_max = get_int_var(LASTLOG_VAR); new_w->log = 0; new_w->logfile = NULL; new_w->log_fp = NULL; new_w->screen = screen; new_w->next = new_w->prev = NULL; new_w->deceased = 0; /* Initialize the scrollback */ new_w->top_of_scrollback = new_display_line(NULL, new_w); new_w->top_of_scrollback->line = NULL; new_w->top_of_scrollback->next = NULL; new_w->display_buffer_size = 1; new_w->display_ip = new_w->top_of_scrollback; new_w->scrolling_top_of_display = new_w->top_of_scrollback; new_w->old_size = 1; if (screen) { /* * Add_to_window_list sets the location and size of the window */ if (add_to_window_list(screen, new_w)) set_screens_current_window(screen, new_w); else { new_free((char **)&new_w); return NULL; } } else add_to_invisible_list(new_w); resize_window_display(new_w); /* * Offer it to the user. I dont know if this will break stuff * or not. */ do_hook(WINDOW_CREATE_LIST, "%d", new_w->refnum); return (new_w); } /* * delete_window: There are two important aspects to deleting a window. * The first aspect is window management. We must release the window * from its screen (or from the invisible list) so that it is not possible * for the user to reference the window in any way. We also want to * re-apportion the window's visible area to other windows on the screen. * The second aspect is purging the window's private data. Ideally, we * want these things to take place in this order. */ void delete_window (Window *window) { char buffer[BIG_BUFFER_SIZE + 1]; int oldref; int i; int invisible = 0; int fixed_wins; int fixed; if (!window) window = current_window; if (!window->screen) invisible = 1; if (window->screen) fixed_wins = count_fixed_windows(window->screen); else fixed_wins = 0; if (window->absolute_size && window->skip) fixed = 1; else fixed = 0; /* * If this is a hidden window and the client is not going down, * you cannot kill this window if: * * 1) This is a fixed window and it is the only window. * 2) This is the only non-fixed window (unless a swap can occur) */ if (dead == 0 && window->screen) { if ((fixed && window->screen->visible_windows == 1) || (!fixed && window->screen->visible_windows - fixed_wins <= 1 && !invisible_list)) { say("You can't kill the last window!"); return; } } /* Let the script have a stab at this first. */ do_hook(WINDOW_BEFOREKILL_LIST, "%d", window->refnum); /* * Mark this window as deceased. This is important later. */ window->deceased = 1; /* * If the client is exiting and this is the last window on the * screen, we need to do some extra cleanup on the screen that * otherwise we would not dare to perform. We also want to do some * extra sanity checking to make sure nothing bad has happened * elsewhere. */ if ((dead == 1) && window->screen && (window->screen->visible_windows == 1)) { if (window->screen->window_list != window || window->next != NULL || (window->screen->current_window && window->screen->current_window != window)) { panic("My screen says there is only one " "window on it, and I don't agree."); } else { window->deceased = 1; window->screen->window_list = NULL; window->screen->visible_windows = 0; window->screen->current_window = NULL; window->screen = NULL; if (current_window == window) current_window = NULL; } /* * This 'goto' saves me from making the next 75 lines part * of a big (ultimately unnecesary) 'else' clause, requiring * me to indent it yet again and break up the lines and make * it less readable. Don't bug me about this. */ goto delete_window_contents; } /* Move this window's channels anywhere else. */ /* * Ugh. We've already marked the window as deceased, so it * officially no longer exists; on top of this, 'swap_window' * is a sequence point, so channels must be capable of syncing * up before that. The ref checks will fail if there are any * channels on this window, because the window is dead, and so * we need to move the channels away before the sequence point. * I hope this explanation makes sense. ;-) */ reassign_window_channels(window->refnum); /* * At this point, we know there must be one of three cases: * 1) The window is an invisible window * 2) The window is on a screen with other windows. * 3) The window is last window on screen, with an invisible window. * * We handle each of these three cases seperately. If any other * situation arises, we panic, because that means I forgot something * and that *is* a bug. */ if (invisible) remove_from_invisible_list(window); else if (fixed || window->screen->visible_windows > fixed_wins + 1) remove_window_from_screen(window, 0); else if (invisible_list) { window->swappable = 1; swap_window(window, NULL); } else { yell("I don't know how to kill window [%d]", window->refnum); return; } /* * This is done for the sake of invisible windows; but it is a safe * sanity check and can be done for any window, visible or invisible. * Basically, we have to be sure that we find some way to make sure * that the 'current_window' pointer is not pointing at what we are * about to delete (or else the client will crash.) */ if (window == current_window) { if (window == last_input_screen->current_window) { if (window->screen != last_input_screen) panic("I am not on that screen"); else make_window_current(last_input_screen->window_list); } else make_window_current(NULL); } if (window == current_window) panic("window == current_window -- this is wrong."); /* * OK! Now we have completely unlinked this window from whatever * window chain it was on before, be it a screen, or be it the * invisible window list. The screens have been updated, and the * only place this window exists is in our 'window' pointer. We * can now safely go about the business of eliminating what it is * pointing to. */ delete_window_contents: /* Save a copy of the refnum for /on window_kill later. */ if (window->name) strlcpy(buffer, window->name, sizeof buffer); else strlcpy(buffer, ltoa(window->refnum), sizeof buffer); oldref = window->refnum; /* * Clean up after the window's internal data. */ /* Status bars... */ for (i = 0; i < 3; i++) { new_free(&window->status.line[i].raw); new_free(&window->status.line[i].format); new_free(&window->status.line[i].result); window->status.double_status = 0; new_free(&window->status.special); } /* Various things... */ new_free(&window->query_nick); new_free(&window->waiting_channel); new_free(&window->bind_channel); new_free(&window->logfile); new_free(&window->name); /* The logical display */ { Display *next; while (window->top_of_scrollback) { next = window->top_of_scrollback->next; new_free(&window->top_of_scrollback->line); new_free((char **)&window->top_of_scrollback); window->display_buffer_size--; window->top_of_scrollback = next; } window->display_ip = NULL; if (window->display_buffer_size != 0) panic("display_buffer_size is %d, should be 0", window->display_buffer_size); } /* The lastlog... */ while (window->lastlog_size) remove_from_lastlog(window); /* The nick list... */ { WNickList *next; while (window->nicks) { next = window->nicks->next; new_free(&window->nicks->nick); new_free((char **)&window->nicks); window->nicks = next; } } /* * Nuke the window, check server connections, and re-adjust window * levels for whoever is left. Don't check the levels if we are * going down, as its a wasted point. */ #if 1 {Window *owd = window; new_free((char **)&owd);} #else new_free((char **)&window); #endif if (dead == 0) window_check_servers(); do_hook(WINDOW_KILL_LIST, "%d %s", oldref, buffer); } /* * This should only ever be called by irc_exit(). DONT CALL THIS ELSEWHERE! */ void delete_all_windows (void) { Window *win; for (win = NULL; traverse_all_windows(&win); win = NULL) delete_window(win); } /* * * * * * * * * * * ITERATE OVER WINDOWS * * * * * * * * * * * * * * * */ /* * traverse_all_windows: Based on the old idea by phone that there should * be a way to iterate the window list without having to keep a static * data member in the function. So now this is "thread safe". * * To initialize, *ptr should be NULL. The function will return 1 each time * *ptr is set to the next valid window. When the function returns 0, then * you have iterated all windows. */ int traverse_all_windows (Window **ptr) { /* * If this is the first time through... */ if (!*ptr) { Screen *screen = screen_list; while (screen && (!screen->alive || !screen->window_list)) screen = screen->next; if (!screen && !invisible_list) return 0; else if (!screen) *ptr = invisible_list; else *ptr = screen->window_list; } /* * As long as there is another window on this screen, keep going. */ else if ((*ptr)->next) *ptr = (*ptr)->next; /* * If there are no more windows on this screen, but we do belong to * a screen (eg, we're not invisible), try the next screen */ else if ((*ptr)->screen) { /* * Skip any dead screens */ Screen *ns = (*ptr)->screen->next; while (ns && (!ns->alive || !ns->window_list)) ns = ns->next; /* * If there are no other screens, then if there is a list * of hidden windows, try that. Otherwise we're done. */ if (!ns && !invisible_list) return 0; else if (!ns) *ptr = invisible_list; else *ptr = ns->window_list; } /* * Otherwise there are no other windows, and we're not on a screen * (eg, we're hidden), so we're all done here. */ else return 0; /* * If we get here, we're in business! */ return 1; } /* * * * * * * * * * * * * * * * WINDOW LISTS * * * * * * * * * * * * * * * */ /* * Handle the client's list of invisible windows. */ static void remove_from_invisible_list (Window *window) { Window *w; /* Purely a sanity check */ for (w = invisible_list; w && w != window; w = w->next) ; if (!w) panic("This window is _not_ invisible"); /* * Unlink it from the list */ if (window->prev) window->prev->next = window->next; else invisible_list = window->next; if (window->next) window->next->prev = window->prev; } void add_to_invisible_list (Window *window) { /* * Because this blows away window->next, it is implicitly * assumed that you have already removed the window from * its screen. */ if ((window->next = invisible_list) != NULL) invisible_list->prev = window; invisible_list = window; window->prev = (Window *) 0; if (window->screen) window->columns = window->screen->co; else window->columns = current_term->TI_cols; /* Whatever */ window->screen = (Screen *) 0; } /* * add_to_window_list: This inserts the given window into the visible window * list (and thus adds it to the displayed windows on the screen). The * window is added by splitting the current window. If the current window is * too small, the next largest window is used. The added window is returned * as the function value or null is returned if the window couldn't be added */ Window *add_to_window_list (Screen *screen, Window *new_w) { Window *biggest = (Window *) 0, *tmp; if (screen == NULL) panic("Cannot add window [%d] to NULL screen.", new_w->refnum); screen->visible_windows++; new_w->screen = screen; new_w->miscflags &= ~WINDOW_NOTIFIED; /* * If this is the first window to go on the screen */ if (!screen->current_window) { screen->window_list_end = screen->window_list = new_w; if (dumb_mode) { new_w->display_size = 24; set_screens_current_window(screen, new_w); return new_w; } recalculate_windows(screen); } /* * This is not the first window on this screen. */ else { /* split current window, or find a better window to split */ if ((screen->current_window->display_size < 4) || get_int_var(ALWAYS_SPLIT_BIGGEST_VAR)) { int size = 0; for (tmp = screen->window_list; tmp; tmp = tmp->next) { if (tmp->absolute_size) continue; if (tmp->display_size > size) { size = tmp->display_size; biggest = tmp; } } if (!biggest /* || size < 4 */) { say("Not enough room for another window!"); screen->visible_windows--; return NULL; } } else biggest = screen->current_window; if ((new_w->prev = biggest->prev) != NULL) new_w->prev->next = new_w; else screen->window_list = new_w; new_w->next = biggest; biggest->prev = new_w; biggest->display_size /= 2; new_w->display_size = biggest->display_size; recalculate_windows(screen); } return (new_w); } /* * remove_window_from_screen: this removes the given window from the list of * visible windows. It closes up the hole created by the windows abnsense in * a nice way. The window passed to this function *must* be visible. * * If 'hide' is 1, then the window is added to the invisible list before * the current window is reset -- this avoids a possible panic in the * /on switch_windows thrown there. If 'hide' is 0, then the window is * just unlinked and we assume the caller will gc it. */ static void remove_window_from_screen (Window *window, int hide) { Screen *s; if (!((s = window->screen))) panic("This window is not on a screen"); /* * We used to go to greath lengths to figure out how to fill * in the space vacated by this window. Now we dont sweat that. * we just blow away the window and then recalculate the entire * screen. */ if (window->prev) window->prev->next = window->next; else s->window_list = window->next; if (window->next) window->next->prev = window->prev; else s->window_list_end = window->prev; if (!--s->visible_windows) return; if (hide) add_to_invisible_list(window); if (s->current_window == window) set_screens_current_window(s, NULL); if (s->last_window_refnum == window->refnum) s->last_window_refnum = s->current_window->refnum; if (s->current_window == window) make_window_current(last_input_screen->window_list); else make_window_current(NULL); recalculate_windows(s); } /* * * * * * * * * * * * SIZE AND LOCATION PRIMITIVES * * * * * * * * * * * */ /* * recalculate_window_positions: This runs through the window list and * re-adjusts the top and bottom fields of the windows according to their * current positions in the window list. This doesn't change any sizes of * the windows */ void recalculate_window_positions (Screen *screen) { Window *tmp; int top; if (!screen) return; /* Window is hidden. Dont bother */ top = 0; for (tmp = screen->window_list; tmp; tmp = tmp->next) { tmp->top = top; tmp->bottom = top + tmp->display_size; top += tmp->display_size + 1 + tmp->status.double_status; window_body_needs_redraw(tmp); window_statusbar_needs_redraw(tmp); } } /* * swap_window: This swaps the given window with the current window. The * window passed must be invisible. Swapping retains the positions of both * windows in their respective window lists, and retains the dimensions of * the windows as well */ static void swap_window (Window *v_window, Window *window) { int check_hidden = 1; int recalculate_everything = 0; /* * v_window -- window to be swapped out * window -- window to be swapped in */ /* Find any invisible window to swap in. Prefer swappable ones */ if (!window) { for (window = invisible_list; window; window = window->next) if (window->swappable) break; } if (!window && invisible_list) { check_hidden = 0; window = invisible_list; } if (!window) { say("The window to be swapped in does not exist."); return; } if (window->screen || !v_window->screen) { say("You can only SWAP a hidden window with a visible window."); return; } if (!v_window->swappable) { if (v_window->name) say("Window %s is not swappable", v_window->name); else say("Window %d is not swappable", v_window->refnum); return; } if (check_hidden && !window->swappable) { if (window->name) say("Window %s is not swappable", window->name); else say("Window %d is not swappable", window->refnum); return; } /* * Put v_window on invisible list */ v_window->screen->last_window_refnum = v_window->refnum; /* * Take window off invisible list */ remove_from_invisible_list(window); /* * Give the window to be swapped in the same geometry as the window * to be swapped out, mark it as being visible, give it its screen, * and if the window being swapped out is curr_win, then the window * to be swapped in will be curr_win. */ window->top = v_window->top; window->display_size = v_window->display_size + v_window->status.double_status - window->status.double_status; window->bottom = window->top + window->display_size; window->screen = v_window->screen; if (window->display_size < 0) { window->display_size = 0; recalculate_everything = 1; } if (v_window->screen->current_window == v_window) { v_window->screen->current_window = window; window->priority = current_window_priority++; } /* * Put the window to be swapped into the screen list */ if ((window->prev = v_window->prev)) window->prev->next = window; else window->screen->window_list = window; if ((window->next = v_window->next)) window->next->prev = window; else window->screen->window_list_end = window; /* * Hide the window to be swapped out */ if (!v_window->deceased) add_to_invisible_list(v_window); if (recalculate_everything) recalculate_windows(window->screen); recalculate_window_cursor_and_display_ip(window); resize_window_display(window); /* * And recalculate the window's positions. */ window_body_needs_redraw(window); window_statusbar_needs_redraw(window); window->miscflags &= ~WINDOW_NOTIFIED; /* * Transfer current_window if the current window is being swapped out */ if (v_window == current_window) make_window_current(window); } /* * move_window: This moves a window offset positions in the window list. This * means, of course, that the window will move on the screen as well */ static void move_window (Window *window, int offset) { Window *tmp, *last; int win_pos, pos; if (offset == 0) return; last = (Window *) 0; if (!window->screen) return; /* Whatever */ for (win_pos = 0, tmp = window->screen->window_list; tmp; tmp = tmp->next, win_pos++) { if (window == tmp) break; last = tmp; } if (!tmp) return; if (!last) window->screen->window_list = tmp->next; else last->next = tmp->next; if (tmp->next) tmp->next->prev = last; else window->screen->window_list_end = last; win_pos = (offset + win_pos) % window->screen->visible_windows; if (win_pos < 0) win_pos = window->screen->visible_windows + win_pos; last = NULL; for (pos = 0, tmp = window->screen->window_list; pos != win_pos; tmp = tmp->next, pos++) last = tmp; if (!last) window->screen->window_list = window; else last->next = window; if (tmp) tmp->prev = window; else window->screen->window_list_end = window; window->prev = last; window->next = tmp; recalculate_window_positions(window->screen); } /* * move_window_to: This moves a given window to the Nth absolute position * on the screen. All the other windows move accordingly. */ static void move_window_to (Window *window, int offset) { Window *w; Screen *s; int i; if (offset <= 0) return; if (!(s = window->screen)) return; /* Whatever */ if (s->visible_windows == 1) return; /* Whatever */ if (offset > s->visible_windows) offset = s->visible_windows; /* Unlink the window from the screen */ if (window->prev) window->prev->next = window->next; else s->window_list = window->next; if (window->next) window->next->prev = window->prev; else s->window_list_end = window->prev; /* Now figure out where it goes */ for (w = s->window_list, i = 1; i < offset; i++) w = w->next; /* Now relink it where it belongs */ if (w) { if (w->prev) { w->prev->next = window; window->prev = w->prev; } else { s->window_list = window; window->prev = NULL; } } else { s->window_list_end->next = window; window->prev = s->window_list_end; s->window_list_end = window; } window->next = w; set_screens_current_window(s, window); make_window_current(window); recalculate_window_positions(s); } /* * resize_window: if 'how' is RESIZE_REL, then this will increase or decrease * the size of the given window by offset lines (positive offset increases, * negative decreases). If 'how' is RESIZE_ABS, then this will set the * absolute size of the given window. * Obviously, with a fixed terminal size, this means that some other window * is going to have to change size as well. Normally, this is the next * window in the window list (the window below the one being changed) unless * the window is the last in the window list, then the previous window is * changed as well */ static void resize_window (int how, Window *window, int offset) { Window *other; int after, window_size, other_size; if (!window) window = current_window; if (!window->screen) { say("You cannot change the size of hidden windows!"); return; } if (how == RESIZE_ABS) { offset -= window->display_size; how = RESIZE_REL; } after = 1; other = window; do { if (other->next) other = other->next; else { other = window->screen->window_list; after = 0; } if (other == window) { say("Can't change the size of this window!"); return; } if (other->absolute_size) continue; } while (other->display_size < offset); window_size = window->display_size + offset; other_size = other->display_size - offset; if ((window_size < 0) || (other_size < 0)) { say("Not enough room to resize this window!"); return; } window->display_size = window_size; other->display_size = other_size; recalculate_windows(window->screen); } /* * resize_display: After determining that the window has changed sizes, this * goes through and adjusts the top of the display. If the window grew, then * this will *back up* the top of the display (yes, this is the right thing * to do!), and if the window shrank, then it will move forward the top of * the display. We dont worry too much about the economy of redrawing. * If a window is resized, it gets redrawn. */ void resize_window_display (Window *window) { int cnt = 0, i; Display *tmp; if (dumb_mode) return; /* * Find out how much the window has changed by */ cnt = window->display_size - window->old_size; tmp = window->scrolling_top_of_display; /* * If it got bigger, move the scrolling_top_of_display back. */ if (cnt > 0) { /* * If "SCROLLADJUST" is off, then do not push back the top of * display to reveal what has previously scrolled off (for * ircII compatability */ if (window->scrolladj) { for (i = 0; i < cnt; i++) { if (!tmp || !tmp->prev) break; tmp = tmp->prev; } } } /* * If it got smaller, then move the scrolling_top_of_display up */ else if (cnt < 0) { /* Use any whitespace we may have lying around */ cnt += (window->old_size - window->scrolling_distance_from_display_ip); for (i = 0; i > cnt; i--) { if (tmp == window->display_ip) break; tmp = tmp->next; } } window->scrolling_top_of_display = tmp; recalculate_window_cursor_and_display_ip(window); /* * Mark the window for redraw and store the new window size. */ window_body_needs_redraw(window); window_statusbar_needs_redraw(window); window->old_size = window->display_size; return; } /* * * * * * * * * * * * WINDOW UPDATING AND RESIZING * * * * * * * * * */ /* * THese three functions are the one and only functions that are authorized * to be used to declare that something needs to be updated on the screen. */ /* * statusbar_needs_update */ void window_statusbar_needs_update (Window *w) { w->update |= UPDATE_STATUS; } /* * statusbar_needs_redraw */ void window_statusbar_needs_redraw (Window *w) { w->update |= REDRAW_STATUS; } /* * window_body_needs_redraw */ void window_body_needs_redraw (Window *w) { w->cursor = -1; } /* * redraw_all_windows: This basically clears and redraws the entire display * portion of the screen. All windows and status lines are draws. This does * nothing for the input line of the screen. Only visible windows are drawn */ void redraw_all_windows (void) { Window *tmp = NULL; if (dumb_mode) return; while (traverse_all_windows(&tmp)) { window_body_needs_redraw(tmp); window_statusbar_needs_redraw(tmp); } } /* * update_all_status: This performs a logical "update_window_status" on * every window for the current screen. */ void update_all_status (void) { Window *window; window = NULL; while (traverse_all_windows(&window)) window_statusbar_needs_update(window); } /* * update_all_windows: This goes through each visible window and draws the * necessary portions according the the update field of the window. */ void update_all_windows (void) { Window *tmp = NULL; static int recursion = 0; static int do_input_too = 0; static int restart; if (recursion) { restart = 1; return; } recursion++; while (traverse_all_windows(&tmp)) { if (restart) { restart = 0; tmp = NULL; continue; } /* * This should always be done, even for hidden windows * ... i think. */ if (tmp->display_size != tmp->old_size) resize_window_display(tmp); /* Never try to update/redraw an invisible window */ if (!tmp->screen) continue; if (tmp->cursor == -1 || (tmp->scroll && tmp->cursor < tmp->scrolling_distance_from_display_ip && tmp->cursor < tmp->display_size)) repaint_window_body(tmp); if (tmp->update & REDRAW_STATUS) { if (!make_status(tmp, 1)) tmp->update &= ~REDRAW_STATUS; do_input_too = 1; } else if (tmp->update & UPDATE_STATUS) { if (!make_status(tmp, 0)) tmp->update &= ~UPDATE_STATUS; do_input_too = 1; } } if (do_input_too) { do_input_too = 0; update_input(UPDATE_JUST_CURSOR); } tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->cursor > tmp->display_size) panic("uaw: window [%d]'s cursor [%d] is off the display [%d]", tmp->refnum, tmp->cursor, tmp->display_size); } recursion--; } /****************************************************************************/ /* * Rebalance_windows: this is called when you want all the windows to be * rebalanced, except for those who have a set size. */ void rebalance_windows (Screen *screen) { Window *tmp; int each, extra; int window_resized = 0, window_count = 0; if (dumb_mode) return; /* * Two passes -- first figure out how much we need to balance, * and how many windows there are to balance */ for (tmp = screen->window_list; tmp; tmp = tmp->next) { if (tmp->absolute_size) continue; window_resized += tmp->display_size; window_count++; } if (window_count == 0) { yell("All the windows on this screen are fixed!"); return; } each = window_resized / window_count; extra = window_resized % window_count; /* * And then go through and fix everybody */ for (tmp = screen->window_list; tmp; tmp = tmp->next) { if (tmp->absolute_size) ; else { tmp->display_size = each; if (extra) tmp->display_size++, extra--; } } recalculate_window_positions(screen); } /* * recalculate_windows: this is called when the terminal size changes (as * when an xterm window size is changed). It recalculates the sized and * positions of all the windows. The net change in space is distributed * proportionally across the windows as closely as possible. */ void recalculate_windows (Screen *screen) { int old_li = 1; int excess_li = 0; Window *tmp; int window_count = 0; int window_resized = 0; int offset; if (dumb_mode) return; /* * If its a new window, just set it and be done with it. */ if (!screen->current_window) { screen->window_list->top = 0; screen->window_list->display_size = screen->li - 2; screen->window_list->bottom = screen->li - 2; old_li = screen->li; return; } /* * Expanding the screen takes two passes. In the first pass, * We figure out how many windows will be resized. If none can * be rebalanced, we add the whole shebang to the last one. */ for (tmp = screen->window_list; tmp; tmp = tmp->next) { old_li += tmp->display_size + tmp->status.double_status + 1; if (tmp->absolute_size && (window_count || tmp->next)) continue; window_resized += tmp->display_size; window_count++; } excess_li = screen->li - old_li; for (tmp = screen->window_list; tmp; tmp = tmp->next) { if (tmp->absolute_size && tmp->next) ; else { /* * The number of lines this window gets is: * The number of lines available for resizing times * the percentage of the resizeable screen the window * covers. */ if (tmp->next && window_resized) offset = (tmp->display_size * excess_li) / window_resized; else offset = excess_li; tmp->display_size += offset; if (tmp->display_size < 0) tmp->display_size = 1; excess_li -= offset; resize_window_display(tmp); recalculate_window_cursor_and_display_ip(tmp); } } recalculate_window_positions(screen); } /* * * * * * * * LOCATION AND COMPOSITION OF WINDOWS ON SCREEN * * * * * * */ /* * goto_window: This will switch the current window to the N'th window * from the top of the screen. The "which" has nothing to do with the * window's refnum, only its location on the screen. */ static void goto_window (Screen *s, int which) { Window *tmp; int i; if (!s || which == 0) return; if ((which < 0) || (which > s->visible_windows)) { say("GOTO: Illegal value"); return; } tmp = s->window_list; for (i = 1; i < which; i++) tmp = tmp->next; set_screens_current_window(s, tmp); make_window_current(tmp); } /* * hide_window: sets the given window to invisible and recalculates remaing * windows to fill the entire screen */ void hide_window (Window *window) { if (!window->screen) { if (window->name) say("Window %s is already hidden", window->name); else say("Window %d is already hidden", window->refnum); return; } if (!window->swappable) { if (window->name) say("Window %s can't be hidden", window->name); else say("Window %d can't be hidden", window->refnum); return; } if (window->screen->visible_windows - count_fixed_windows(window->screen) <= 1) { say("You can't hide the last window."); return; } if (window->screen) remove_window_from_screen(window, 1); } /* * swap_last_window: This swaps the current window with the last window * that was hidden. * This is a keybinding. */ void swap_last_window (char dumb, char *dumber) { if (!invisible_list || !current_window->screen) return; swap_window(current_window, invisible_list); message_from((char *) 0, LOG_CRAP); update_all_windows(); } /* * next_window: This switches the current window to the next visible window * This is a keybinding. */ void next_window (char dumb, char *dumber) { Window *w; if (!last_input_screen) return; if (last_input_screen->visible_windows == 1) return; w = get_next_window(last_input_screen->current_window); make_window_current(w); /* XXX This is dangerous -- 'make_window_current' might nuke 'w'! */ set_screens_current_window(last_input_screen, w); update_all_windows(); } /* * swap_next_window: This swaps the current window with the next hidden * window. * This is a keybinding. */ void swap_next_window (char dumb, char *dumber) { window_next(current_window, NULL); update_all_windows(); } /* * previous_window: This switches the current window to the previous visible * window * This is a keybinding */ void previous_window (char dumb, char *dumber) { Window *w; if (!last_input_screen) return; if (last_input_screen->visible_windows == 1) return; w = get_previous_window(last_input_screen->current_window); make_window_current(w); /* XXX This is dangerous -- 'make_window_current' might nuke 'w'! */ set_screens_current_window(last_input_screen, w); update_all_windows(); } /* * swap_previous_window: This swaps the current window with the next * hidden window. * This is a keybinding */ void swap_previous_window (char dumb, char *dumber) { window_previous(current_window, NULL); update_all_windows(); } /* show_window: This makes the given window visible. */ static void show_window (Window *window) { if (!window->swappable) { if (window->name) say("Window %s can't be made visible", window->name); else say("Window %d can't be made visible", window->refnum); return; } if (!window->screen) { remove_from_invisible_list(window); if (!(window->screen = current_window->screen)) window->screen = last_input_screen; /* What the hey */ if (!add_to_window_list(window->screen, window)) { /* Ooops. this is an error. ;-) */ add_to_invisible_list(window); return; } } make_window_current(window); /* XXX This is dangerous -- 'make_window_current' might nuke 'w'! */ set_screens_current_window(window->screen, window); return; } /* * * * * * * * * * * * * GETTING WINDOWS AND WINDOW INFORMATION * * * * */ /* * get_window_by_desc: Given either a refnum or a name, find that window */ Window *get_window_by_desc (const char *stuff) { Window *w = NULL; /* bleh */ /* while (*stuff == '#') stuff++; */ if ((w = get_window_by_name(stuff))) return w; if (is_number(stuff) && (w = get_window_by_refnum(my_atol(stuff)))) return w; return NULL; } /* * get_window_by_refnum: Given a reference number to a window, this returns a * pointer to that window if a window exists with that refnum, null is * returned otherwise. The "safe" way to reference a window is throught the * refnum, since a window might be delete behind your back and and Window * pointers might become invalid. */ Window *get_window_by_refnum (unsigned refnum) { Window *tmp = NULL; if (refnum == 0) return current_window; while (traverse_all_windows(&tmp)) { if (tmp->refnum == refnum) return tmp; } return NULL; } /* * get_window_by_name: returns a pointer to a window with a matching logical * name or null if no window matches */ Window *get_window_by_name (const char *name) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->name && (my_stricmp(tmp->name, name) == 0)) return (tmp); } return NULL; } /* * DON'T EVEN THINK OF CALLING THIS FUNCTION IF YOU KNOW WHAT IS GOOD * FOR YOU! Well, if you do feel like calling it, you better make sure * to make a copy of it immediately, because the ltoa() return value will * soon point to someone else's number... ;-) */ char * get_refnum_by_window (const Window *w) { return ltoa(w->refnum); } int get_winref_by_servref (int servref) { Window *tmp = NULL; Window *best = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server != servref && tmp->last_server != servref) continue; if (best == NULL || best->priority < tmp->priority) best = tmp; } if (best) return best->refnum; else return -1; } /* * get_next_window: This overly complicated function attempts to find the * next non "skippable" window. The reason for the complication is that it * needs to be able to deal with wrapping over to the top of the screen, * if the next window is at the bottom, or isnt selectable, YGTI. */ static Window *get_next_window (Window *w) { Window *last = w; Window *new_w = w; if (!w || !w->screen) last = new_w = w = current_window; do { if (new_w->next) new_w = new_w->next; else new_w = w->screen->window_list; } while (new_w && new_w->skip && new_w != last); return new_w; } /* * get_previous_window: this returns the previous *visible* window in the * window list. This automatically wraps to the last window in the window * list */ static Window *get_previous_window (Window *w) { Window *last = w; Window *new_w = w; if (!w || !w->screen) last = new_w = w = current_window; do { if (new_w->prev) new_w = new_w->prev; else new_w = w->screen->window_list_end; } while (new_w->skip && new_w != last); return new_w; } /* * get_visible_by_refnum: Returns 1 if the specified window is visible. */ int is_window_visible (char *arg) { Window *win; if ((win = get_window_by_desc(arg))) { if (win->screen) return 1; else return 0; } return -1; } /* * XXXX i have no idea if this belongs here. */ char * get_status_by_refnum (unsigned refnum, int line) { Window *the_window; if ((the_window = get_window_by_refnum(refnum))) { if (line > the_window->status.double_status) return NULL; return denormalize_string(the_window->status.line[line].result); } else return NULL; } /* * * * * * * * * * * * * INPUT PROMPT * * * * * * * * * * * * * * */ /* * set_prompt_by_refnum: changes the prompt for the given window. A window * prompt will be used as the target in place of the query user or current * channel if it is set */ void set_prompt_by_refnum (unsigned refnum, char *prompt) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; malloc_strcpy(&tmp->prompt, prompt); update_input(UPDATE_JUST_CURSOR); } /* get_prompt_by_refnum: returns the prompt for the given window refnum */ char *get_prompt_by_refnum (unsigned refnum) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; return tmp->prompt ? tmp->prompt : empty_string; } /* * * * * * * * * * * * * * * TARGETS AND QUERIES * * * * * * * * * * * */ /* * get_target_by_refnum: returns the target for the window with the given * refnum (or for the current window). The target is either the query nick * or current channel for the window */ const char *get_target_by_refnum (unsigned refnum) { Window *tmp; const char * cc; if (!(tmp = get_window_by_refnum(refnum))) if (!(tmp = last_input_screen->current_window)) return NULL; if (tmp->query_nick) return tmp->query_nick; if ((cc = get_echannel_by_refnum(refnum))) return cc; return NULL; } /* query_nick: Returns the query nick for the current channel */ const char *query_nick (void) { return current_window->query_nick; } /* * * * * * * * * * * * * * CHANNELS * * * * * * * * * * * * * * * * * */ /* get_echannel_by_refnum: returns the current channel for window refnum */ const char *get_echannel_by_refnum (unsigned refnum) { Window *tmp; if ((tmp = get_window_by_refnum(refnum)) == (Window *) 0) panic("get_echannel_by_refnum: invalid window [%d]", refnum); return window_current_channel(tmp->refnum, tmp->server); } int get_winref_by_bound_channel (const char *channel, int server) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server != server) continue; if (tmp->bind_channel && !my_stricmp(tmp->bind_channel, channel)) return tmp->refnum; } return -1; } const char * get_bound_channel_by_refnum (unsigned refnum) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) return NULL; return tmp->bind_channel; } void unbind_channel (const char *channel, int server) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server == server && tmp->bind_channel && !my_stricmp(tmp->bind_channel, channel)) { new_free(&tmp->bind_channel); tmp->bind_channel = NULL; return; } } } int is_window_waiting_for_channel (unsigned refnum, const char *chan) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) return 0; if (chan == NULL) { if (tmp->waiting_channel) return 1; else return 0; } if (tmp->waiting_channel && !my_stricmp(chan, tmp->waiting_channel)) return 1; return 0; } void move_waiting_channel (unsigned oldref, unsigned newref) { Window *oldw, *neww; if (!(oldw = get_window_by_refnum(oldref))) panic("move_waiting_channel: Old Window [%d] doesn't exist", oldref); if (!(neww = get_window_by_refnum(newref))) panic("move_waiting_channel: New Window [%d] doesn't exist", newref); if (oldw->server != neww->server) panic("move_waiting_channel: window [%d:%d] and [%d:%d] " "are on different servers.", oldref, get_window_server(oldref), newref, get_window_server(newref)); if (oldw->waiting_channel) { neww->waiting_channel = oldw->waiting_channel; oldw->waiting_channel = NULL; } } /* * This is called whenever you're not going to reconnect and * destroy_server_channels() is called. */ void destroy_waiting_channels (int server) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server != server) continue; new_free(&tmp->waiting_channel); } } /* * * * * * * * * * * * * * * * * * SERVERS * * * * * * * * * * * * * */ /* * get_window_server: returns the server index for the window with the given * refnum */ int get_window_server (unsigned int refnum) { Window *tmp; if ((tmp = get_window_by_refnum(refnum)) == (Window *) 0) tmp = current_window; return (tmp->server); } /* * get_window_oldserver: returns the last server the window was connected to. */ int get_window_oldserver (unsigned refnum) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; return tmp->last_server; } /* * Changes any windows that are currently using "old_server" to instead * use "new_server". This is only ever called by connect_to_new_server. */ void change_window_server (int old_server, int new_server) { Window *tmp = NULL; /* * Only do this if we're moving servers. */ if (old_server != new_server) { /* Move any active windows first... */ while (traverse_all_windows(&tmp)) { if (tmp->server != old_server) continue; tmp->server = new_server; #if 0 /* * Unless we are disconnecting, deleting * current_channel and waiting_channel is not * our responsibility. But if we are disconnecting * then if we don't do it, nobody can. */ if (new_server == NOSERV) window_discon(tmp, NULL); /* XXXh */ #endif } } /* * Always try to reclaim any lost windows lying around. */ tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server != NOSERV) continue; if (tmp->last_server != old_server) continue; tmp->server = new_server; tmp->last_server = NOSERV; } if (old_server == primary_server) primary_server = new_server; window_check_servers(); } /* * windows_connected_to_server: This returns the number of windows that * are actively connected to a server. This is used by /window server */ static int windows_connected_to_server (int server) { Window *tmp = NULL; int count = 0; while (traverse_all_windows(&tmp)) { if (tmp->server == server) count++; } return count; } /* * window_check_servers: this checks the validity of the open servers vs the * current window list. Every open server must have at least one window * associated with it. If a window is associated with a server that's no * longer open, that window's server is set to the primary server. If an * open server has no assicatiate windows, that server is closed. If the * primary server is no more, a new primary server is picked from the open * servers */ void window_check_servers (void) { Window *tmp; int cnt, max, i, connected; int prime = NOSERV; connected_to_server = 0; max = server_list_size(); for (i = 0; i < max; i++) { connected = is_server_open(i); cnt = 0; tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server == i) { /* * Generally, closed server connections have * their window's moved to new servers * gracefully. In this case, something * really died. We just make this window * not connected to any server and save the * last server so connect_to_new_server can * glum this window up next time. */ if (!connected) { tmp->last_server = i; tmp->server = NOSERV; } else { prime = tmp->server; cnt++; } } } if (cnt) connected_to_server++; else if (connected) { set_server_save_channels(i, 0); close_server(i, "No windows for this server"); } } if (dead) return; if (!is_server_open(primary_server)) { tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server == primary_server) tmp->server = prime; } primary_server = prime; } update_all_status(); cursor_to_input(); } /* * This is a debugging function that is used to determine the referential * integrity of all of the channels to all of the windows. The basic notion * is that it is a bug if any of the following conditions exist: * * 1) There exists some window W, such that its named current channel E * does not exist. * 2) There exists some window W, such that its named current channel E * is not connected to window W. * 3) There exists some channel E, such that it is not connected to any * window. (repairable) * 4) There exists some channel E, such that its connected window W is * not connected to the same server as E. * 5) There exists some channel E, such that its connected window W * does not exist. * 6) There exists some channel E, connected to window W, such that W * has no current channel. (repairable) * 7) There exists some channel E, such that it's server is not open and * its "saved" option is not asserted. */ void window_check_channels (void) { /* Tests #3 through #5 are done in names.c */ channel_check_windows(); } /* * * * * * * * * * LEVELS * * * * * * * * * */ /* * set_level_by_refnum: This sets the window level given a refnum. It * revamps the windows levels as well using revamp_window_levels() */ void set_level_by_refnum (unsigned refnum, int level) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; tmp->window_level = level; revamp_window_levels(tmp); } /* * revamp_window_levels: Given a level setting for the current window, this * makes sure that that level setting is unused by any other window. Thus * only one window in the system can be set to a given level. This only * revamps levels for windows with servers matching the given window * it also makes sure that only one window has the level `DCC', as this is * not dependant on a server. */ static void revamp_window_levels (Window *window) { Window *tmp = NULL; int got_dcc; got_dcc = (LOG_DCC & window->window_level) ? 1 : 0; while (traverse_all_windows(&tmp)) { if (tmp == window) continue; if (LOG_DCC & tmp->window_level) { if (got_dcc) tmp->window_level &= ~LOG_DCC; got_dcc = 1; } if (window->server == tmp->server) tmp->window_level ^= (tmp->window_level & window->window_level); } } /* * message_to: This allows you to specify a window (by refnum) as a * destination for messages. Used by EXEC routines quite nicely */ void message_to (int refnum) { to_window = (refnum != -1) ? get_window_by_refnum((unsigned)refnum) : NULL; } /* * save_message_from: this is used to save (for later restoration) the * who_from variable. This is needed when a function (do_hook) is about * to call another function (parse_line) it knows will change who_from. * The values are saved on the stack so it will be recursive-safe. * * NO CHEATING when you call this function to get the value of who_from! ;-) */ void save_message_from (const char **saved_who_from, int *saved_who_level) { *saved_who_from = who_from; *saved_who_level = who_level; } /* restore_message_from: restores a previously saved who_from variable */ void restore_message_from (const char *saved_who_from, int saved_who_level) { who_from = saved_who_from; who_level = saved_who_level; } /* * message_from: With this you can set the who_from variable and the * who_level variable, used by the display routines to decide which * window messages should go to. */ void message_from (const char *who, int level) { #ifdef NO_CHEATING malloc_strcpy(&who_from, who); #else who_from = who; #endif set_lastlog_msg_level(level); who_level = level; } /* * message_from_level: Like set_lastlog_msg_level, except for message_from. * this is needed by XECHO, because we could want to output things in more * than one level. */ int message_from_level (int level) { int temp; temp = who_level; who_level = level; return temp; } /* * * * * * * * * * * CLEARING WINDOWS * * * * * * * * * * */ static void clear_window (Window *window) { if (dumb_mode) return; window->scrolling_top_of_display = window->display_ip; if (window->miscflags & WINDOW_NOTIFIED) window->miscflags &= ~WINDOW_NOTIFIED; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_redraw(window); } void clear_all_windows (int visible, int hidden, int unhold) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (visible && !hidden && !tmp->screen) continue; if (!visible && hidden && tmp->screen) continue; clear_window(tmp); } } /* * clear_window_by_refnum: just like clear_window(), but it uses a refnum. If * the refnum is invalid, the current window is cleared. */ void clear_window_by_refnum (unsigned refnum, int unhold) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; clear_window(tmp); } static void unclear_window (Window *window) { int i; if (dumb_mode) return; window->scrolling_top_of_display = window->display_ip; for (i = 0; i < window->display_size; i++) { if (window->scrolling_top_of_display == window->top_of_scrollback) break; window->scrolling_top_of_display = window->scrolling_top_of_display->prev; } recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_redraw(window); } void unclear_all_windows (int visible, int hidden, int unhold) { Window *tmp = NULL; while (traverse_all_windows(&tmp)) { if (visible && !hidden && !tmp->screen) continue; if (!visible && hidden && tmp->screen) continue; unclear_window(tmp); } } void unclear_window_by_refnum (unsigned refnum, int unhold) { Window *tmp; if (!(tmp = get_window_by_refnum(refnum))) tmp = current_window; unclear_window(tmp); } /* * This returns 1 if 'w' is holding something. This means the * window has output that has never been displayed ("held"). * For compatability with ircII, we "unhold" windows that are * "holding", but we do the check before running a command and * do the unhold after running it. This is confusing, but it's * the way ircII has always done it, so there you have it. */ int window_is_holding (Window *w) { if (w->holding_distance_from_display_ip > w->display_size) return 1; else return 0; } /* * After running a command (from the SEND_LINE keybinding), if the window * had output that was never displayed ("holding"), then display the next * screenfull of output. Unholding should only be done on windows that * were holding *before* the command is run in SEND_LINE. */ int unhold_a_window (Window *w) { int slider, i; if (!w->holding_top_of_display) return 0; /* ok, whatever */ slider = (w->hold_slider * w->display_size) / 100; for (i = 0; i < slider; i++) { if (w->holding_top_of_display == w->display_ip) break; w->holding_top_of_display = w->holding_top_of_display->next; } recalculate_window_cursor_and_display_ip(w); window_body_needs_redraw(w); window_statusbar_needs_update(w); return 0; } /* * * * * * * * * * * * * * * SCROLLING * * * * * * * * * * * * * * */ /* * set_scroll_lines: called by /SET SCROLL_LINES to check the scroll lines * value */ void set_scroll_lines (const void *stuff) { int size = *(const int *)stuff; if (size == 0) { say("You cannot turn SCROLL off. Gripe at me."); return; } else if (size > current_window->display_size) { say("Maximum lines that may be scrolled is %d", current_window->display_size); set_int_var(SCROLL_LINES_VAR, current_window->display_size); } } /* * * * * * * * * UNSORTED * * * * * * * */ /* * set_continued_line: checks the value of CONTINUED_LINE for validity, * altering it if its no good */ void set_continued_line (const void *stuff) { const char *value = (const char *)stuff; if (value && (strlen(value) > (size_t)(current_term->TI_cols / 2))) { char *chg = LOCAL_COPY(value); chg[current_term->TI_cols / 2] = 0; set_string_var(CONTINUED_LINE_VAR, chg); } } /* current_refnum: returns the reference number for the current window */ unsigned current_refnum (void) { return current_window->refnum; } int number_of_windows_on_screen (Window *w) { return w->screen->visible_windows; } /* * set_lastlog_size: sets up a lastlog buffer of size given. If the lastlog * has gotten larger than it was before, all previous lastlog entry remain. * If it get smaller, some are deleted from the end. */ void set_scrollback_size (const void *stuff) { int size = *(const int *)stuff; Window *window = NULL; while (traverse_all_windows(&window)) { if (size < window->display_size * 2) window->display_buffer_max = window->display_size * 2; else window->display_buffer_max = size; } } /* * is_window_name_unique: checks the given name vs the names of all the * windows and returns true if the given name is unique, false otherwise */ static int is_window_name_unique (char *name) { Window *tmp = NULL; if (name) { while (traverse_all_windows(&tmp)) { if (tmp->name && (my_stricmp(tmp->name, name) == 0)) return (0); } } return (1); } char *get_nicklist_by_window (Window *win) { WNickList *nick = win->nicks; char *stuff = NULL; size_t stuffclue = 0; for (; nick; nick = nick->next) malloc_strcat_wordlist_c(&stuff, space, nick->nick, &stuffclue); if (!stuff) return malloc_strdup(empty_string); else return stuff; } #define WIN_FORM "%-4s %*.*s %*.*s %*.*s %-9.9s %-10.10s %s%s" static void list_a_window (Window *window, int len) { int cnw = get_int_var(CHANNEL_NAME_WIDTH_VAR); const char *chan = get_echannel_by_refnum(window->refnum); if (cnw == 0) cnw = 12; /* Whatever */ say(WIN_FORM, ltoa(window->refnum), 12, 12, get_server_nickname(window->server), len, len, window->name ? window->name : "", cnw, cnw, chan ? chan : "", window->query_nick ? window->query_nick : "", get_server_itsname(window->server), bits_to_lastlog_level(window->window_level), window->screen ? empty_string : " Hidden"); } int get_geom_by_winref (const char *desc, int *co, int *li) { Window *win = get_window_by_desc(desc); if (!win || !win->screen) return -1; *co = win->screen->co; *li = win->screen->li; return 0; } /* below is stuff used for parsing of WINDOW command */ /* * get_window: this parses out any window (visible or not) and returns a * pointer to it */ static Window *get_window (const char *name, char **args) { char *arg; Window *win; if ((arg = next_arg(*args, args))) { if ((win = get_window_by_desc(arg))) return win; say("%s: No such window: %s", name, arg); } else say("%s: Please specify a window refnum or name", name); return NULL; } /* * get_invisible_window: parses out an invisible window by reference number. * Returns the pointer to the window, or null. The args can also be "LAST" * indicating the top of the invisible window list (and thus the last window * made invisible) */ static Window *get_invisible_window (const char *name, char **args) { char *arg; Window *tmp; if ((arg = next_arg(*args, args)) != NULL) { if (my_strnicmp(arg, "LAST", strlen(arg)) == 0) { if (invisible_list == (Window *) 0) say("%s: There are no hidden windows", name); return (invisible_list); } if ((tmp = get_window(name, &arg)) != NULL) { if (!tmp->screen) { return (tmp); } else { if (tmp->name) say("%s: Window %s is not hidden!", name, tmp->name); else say("%s: Window %d is not hidden!", name, tmp->refnum); } } } else say("%s: Please specify a window refnum or LAST", name); return ((Window *) 0); } /* get_number: parses out an integer number and returns it */ static int get_number (const char *name, char **args) { char *arg; if ((arg = next_arg(*args, args)) != NULL) return (my_atol(arg)); else say("%s: You must specify the number of lines", name); return 0; } /* * get_boolean: parses either ON, OFF, or TOGGLE and sets the var * accordingly. Returns 0 if all went well, -1 if a bogus or missing value * was specified */ static int get_boolean (const char *name, char **args, int *var) { char *arg; int newval; newval = *var; if (!(arg = next_arg(*args, args)) || do_boolean(arg, &newval)) { say("Value for %s must be ON, OFF, or TOGGLE", name); return (-1); } /* The say() MUST BE DONE BEFORE THE ASSIGNMENT! */ say("Window %s is %s", name, onoff[newval]); *var = newval; return (0); } /* * /WINDOW ADD nick<,nick> * Adds a list of one or more nicknames to the current list of usupred * targets for the current window. These are matched up with the nick * argument for message_from(). */ static Window *window_add (Window *window, char **args) { char *ptr; WNickList *new_w; char *arg = next_arg(*args, args); if (!arg) say("ADD: Add nicknames to be redirected to this window"); else while (arg) { if ((ptr = strchr(arg, ','))) *ptr++ = 0; if (!find_in_list((List **)&window->nicks, arg, !USE_WILDCARDS)) { say("Added %s to window name list", arg); new_w = (WNickList *)new_malloc(sizeof(WNickList)); new_w->nick = malloc_strdup(arg); add_to_list((List **)&(window->nicks), (List *)new_w); } else say("%s already on window name list", arg); arg = ptr; } return window; } /* * /WINDOW BACK * Changes the current window pointer to the window that was most previously * the current window. If that window is now hidden, then it is swapped with * the current window. */ static Window *window_back (Window *window, char **args) { Window *tmp; tmp = get_window_by_refnum(last_input_screen->last_window_refnum); if (!tmp) tmp = last_input_screen->window_list; make_window_current(tmp); /* XXX This is dangerous, 'make_window_current' might nuke 'tmp' */ if (tmp->screen) set_screens_current_window(tmp->screen, tmp); else { swap_window(window, tmp); message_from((char *) 0, LOG_CRAP); } return window; } /* * /WINDOW BALANCE * Causes all of the windows on the current screen to be adjusted so that * the largest window on the screen is no more than one line larger than * the smallest window on the screen. */ static Window *window_balance (Window *window, char **args) { if (window->screen) rebalance_windows(window->screen); else yell("Cannot balance invisible windows!"); return window; } /* * /WINDOW BEEP_ALWAYS ON|OFF * Indicates that when this window is HIDDEN (sorry, thats not what it seems * like it should do, but that is what it does), beeps to this window should * not be suppressed like they normally are for hidden windows. In all cases, * the current window is notified when a beep occurs if this window is hidden. */ static Window *window_beep_always (Window *window, char **args) { if (get_boolean("BEEP_ALWAYS", args, &window->beep_always)) return NULL; return window; } /* * /WINDOW BIND <#channel> * Indicates that the window should be "bound" to the specified channel. * "binding" a channel to a window means that the channel will always * belong to this window, no matter what. For example, if a channel is * bound to a window, you can do a /join #channel in any window, and it * will always "join" in this window. This is especially useful when * you are disconnected from a server, because when you reconnect, the client * often loses track of which channel went to which window. Binding your * channels gives the client a hint where channels belong. * * You can rebind a channel to a new window, even after it has already * been bound elsewhere. */ static Window *window_bind (Window *window, char **args) { char *arg; Window *w = NULL; const char *chan; if ((arg = next_arg(*args, args))) { if (!is_channel(arg)) { say("BIND: %s is not a valid channel name", arg); return NULL; } /* * If its already bound, no point in continuing. */ if (window->bind_channel && !my_stricmp(window->bind_channel, arg)) { say("Window is already bound to channel %s", arg); return window; } /* * If the window is bound to something else, let the user * know about that. */ if (window->bind_channel) { say("Unbinding channel %s from this window", window->bind_channel); window->bind_channel = NULL; } /* * You must either bind the current channel to a window, or * you must be binding to a window without a current channel */ chan = get_echannel_by_refnum(window->refnum); if (chan) { if (!my_stricmp(chan, arg)) malloc_strcpy(&window->bind_channel, arg); else say("You may only /WINDOW BIND the current channel for this window"); return window; } /* * So we know this window doesnt have a current channel. * So we have to find the window where it IS the current * channel (if it is at all) */ while (traverse_all_windows(&w)) { /* * If we have found a window where this channel * is the current channel, then we make it so that * it is the current channel here. * Also, move_channel_to_window transfer cancels the * channels' bound status on the old window. */ chan = get_echannel_by_refnum(w->refnum); if (chan && !my_stricmp(chan, arg) && w->server == window->server) { move_channel_to_window(arg, window->server, w->refnum, window->refnum); } } /* * Now we mark this channel as being bound here. * and as being our current channel. */ malloc_strcpy(&window->bind_channel, arg); say("Window is bound to channel %s", arg); if (im_on_channel(arg, window->server)) { move_channel_to_window(arg, window->server, 0, window->refnum); say("Current channel for window now %s", arg); } } else if ((arg = window->bind_channel)) say("Window is bound to channel %s", arg); else say("Window is not bound to any channel"); return window; } /* * /WINDOW CHANNEL <#channel> * Directs the client to make a specified channel the current channel for * the window -- it will JOIN the channel if you are not already on it. * If the channel you wish to activate is bound to a different window, you * will be notified. If you are already on the channel in another window, * then the channel's window will be switched. If you do not specify a * channel, or if you specify the channel "0", then the window will drop its * connection to whatever channel it is in. You can only join a channel if * that channel is not bound to a different window. */ static Window *window_channel (Window *window, char **args) { char *sarg, *arg, *arg2 = NULL, *arg3 = NULL; Window *w = NULL; const char *carg; const char *chan; /* Fix by Jason Brand, Nov 6, 2000 */ if (window->server == NOSERV) { say("This window is not connected to a server."); return NULL; } if ((sarg = new_next_arg(*args, args))) { if (!(carg = next_arg(sarg, &sarg))) { say("Huh?"); return window; } if (!my_strnicmp(carg, "-i", 2)) { if (!(carg = get_server_invite_channel(window->server))) { say("You have not been invited to a channel!"); return window; } } if (!is_channel(carg)) { say("CHANNEL: %s is not a valid channel name", carg); return NULL; } /* * We do some chicanery here. :/ * For some complicated reasons, new_next_arg skips over * backslashed quotation marks. Usually what happens down * the line is that the backslash eventually gets unescaped. * Well, not here. So we have to do this manually. This is * a quick, and nasty hack, but i will re-assess the * situation later and improve what is being done here. */ arg = malloc_strcat_ues(&arg2, carg, empty_string); sarg = malloc_strcat_ues(&arg3, sarg, empty_string); while (traverse_all_windows(&w)) { if (w == window || w->server != window->server) continue; /* Not us! */ if (w->bind_channel && !my_stricmp(arg, w->bind_channel)) { say("Channel %s is already bound elsewhere", arg); new_free(&arg2); new_free(&arg3); return window; } chan = get_echannel_by_refnum(w->refnum); if (chan && !my_stricmp(arg, chan)) move_channel_to_window(arg, w->server, w->refnum, window->refnum); } message_from(arg, LOG_CRAP); if (im_on_channel(arg, window->server)) { move_channel_to_window(arg, window->server, 0, window->refnum); say("You are now talking to channel %s", check_channel_type(arg)); } #if 0 /* What to do here? */ else if (arg[0] == '0' && arg[1] == 0) set_channel_by_refnum(window->refnum, NULL); #endif else { /* * This needs to be done first in case anyone has any weird * ideas about doing a /wait in the /on send_to_server. */ malloc_strcpy(&window->waiting_channel, arg); if (sarg) send_to_aserver(window->server,"JOIN %s %s", arg, sarg); else send_to_aserver(window->server,"JOIN %s", arg); } new_free(&arg2); new_free(&arg3); } message_from(NULL, LOG_CRAP); return window; } /* WINDOW CLEAR -- should be obvious, right? */ static Window *window_clear (Window *window, char **args) { clear_window(window); return window; } /* * /WINDOW CREATE * This directs the client to open up a new physical screen and create a * new window in it. This feature depends on the external "wserv" utility * and requires a multi-processing system, since it actually runs the new * screen in a seperate process. Please note that the external screen is * not actually controlled by the client, but rather by "wserv" which acts * as a pass-through filter on behalf of the client. * * Since the external screen is outside the client's process, it is not really * possible for the client to know when the external screen is resized, or * what that new size would be. For this reason, you should not resize any * screen when you have external screens open. If you do, the client will * surely become confused and the output will probably be garbled. You can * restore some sanity by making sure that ALL external screens have the same * geometry, and then redrawing each screen. */ static Window *window_create (Window *window, char **args) { #ifdef WINDOW_CREATE Window *tmp; if ((tmp = (Window *)create_additional_screen())) window = tmp; else #endif say("Cannot create new screen!"); return window; } /* * /WINDOW DELETE * This directs the client to close the current external physical screen * and to re-parent any windows onto other screens. You are not allowed * to delete the "main" window because that window belongs to the process * group of the client itself. */ static Window *window_delete (Window *window, char **args) { #ifdef WINDOW_CREATE kill_screen(window->screen); #endif return current_window; } /* * /WINDOW DESCRIBE * Directs the client to tell you a bit about the current window. * This is the 'default' argument to the /window command. */ static Window *window_describe (Window *window, char **args) { const char *chan; if (window->name) say("Window %s (%u)", window->name, window->refnum); else say("Window %u", window->refnum); say("\tServer: %d - %s", window->server, get_server_name(window->server)); say("\tScreen: %p", window->screen); say("\tGeometry Info: [%d %d %d %d %d %d %d %d]", window->top, window->bottom, 0, window->display_size, window->cursor, window->scrolling_distance_from_display_ip, window->holding_distance_from_display_ip, window->scrollback_distance_from_display_ip); say("\tCO, LI are [%d %d]", current_term->TI_cols, current_term->TI_lines); chan = get_echannel_by_refnum(window->refnum); say("\tCurrent channel: %s", chan ? chan : ""); if (window->waiting_channel) say("\tWaiting channel: %s", window->waiting_channel); if (window->bind_channel) say("\tBound channel: %s", window->bind_channel); say("\tQuery User: %s", window->query_nick ? window->query_nick : ""); say("\tPrompt: %s", window->prompt ? window->prompt : ""); say("\tSecond status line is %s", onoff[window->status.double_status]); say("\tLogging is %s", onoff[window->log]); if (window->logfile) say("\tLogfile is %s", window->logfile); else say("\tNo logfile given"); say("\tNotification is %s", onoff[window->miscflags & WINDOW_NOTIFY]); say("\tHold mode is %s", onoff[window->holding_top_of_display ? 1 : 0]); say("\tWindow level is %s", bits_to_lastlog_level(window->window_level)); say("\tLastlog level is %s", bits_to_lastlog_level(window->lastlog_level)); say("\tNotify level is %s", bits_to_lastlog_level(window->notify_level)); if (window->nicks) { WNickList *tmp; say("\tName list:"); for (tmp = window->nicks; tmp; tmp = tmp->next) say("\t %s", tmp->nick); } return window; } /* * /WINDOW DISCON * This disassociates a window with all servers. */ static Window *window_discon (Window *window, char **args) { reassign_window_channels(window->refnum); new_free(&window->bind_channel); new_free(&window->waiting_channel); window->last_server = window->server; window->server = NOSERV; /* XXX This shouldn't be set here. */ window_check_servers(); return window; } /* * /WINDOW DOUBLE ON|OFF * This directs the client to enable or disable the supplimentary status bar. * When the "double status bar" is enabled, the status formats are taken from * /set STATUS_FORMAT1 or STATUS_FORMAT2. When it is disabled, the format is * taken from /set STATUS_FORMAT. */ static Window *window_double (Window *window, char **args) { int current = window->status.double_status; if (get_boolean("DOUBLE", args, &window->status.double_status)) return NULL; window->display_size += current - window->status.double_status; if (window->display_size < 0) { window->display_size = 0; if (window->screen) recalculate_windows(window->screen); } recalculate_window_positions(window->screen); return window; } /* * WINDOW ECHO * * Text must either be surrounded with double-quotes (")'s or it is assumed * to terminate at the end of the argument list. This sends the given text * to the current window. */ static Window *window_echo (Window *window, char **args) { const char *to_echo; Window *old_to_window; if (**args == '"') to_echo = new_next_arg(*args, args); else to_echo = *args, *args = NULL; /* Calling add_to_window() directly is a hack. */ old_to_window = to_window; to_window = window; add_to_screen(to_echo); to_window = old_to_window; return window; } /* * /WINDOW FIXED (ON|OFF) * * When this is ON, then this window will never be used as the implicit * partner for a window resize. That is to say, if you /window grow another * window, this window will not be considered for the corresponding shrink. * You may /window grow a fixed window, but if you do not have other nonfixed * windows, the grow will fail. */ static Window *window_fixed (Window *window, char **args) { if (get_boolean("FIXED", args, &window->absolute_size)) return NULL; return window; } /* * /WINDOW FLUSH * * Does the window part of the /flush command. */ static Window *window_flush (Window *window, char **args) { flush_scrollback_after(window); return window; } /* * /WINDOW GOTO refnum * This switches the current window selection to the window as specified * by the numbered refnum. */ static Window *window_goto (Window *window, char **args) { goto_window(window->screen, get_number("GOTO", args)); from_server = get_window_server(0); return current_window; } /* * /WINDOW GROW lines * This directs the client to expand the specified window by the specified * number of lines. The number of lines should be a positive integer, and * the window's growth must not cause another window to be smaller than * the minimum of 3 lines. */ static Window *window_grow (Window *window, char **args) { resize_window(RESIZE_REL, window, get_number("GROW", args)); return window; } /* * /WINDOW HIDE * This directs the client to remove the specified window from the current * (visible) screen and place the window on the client's invisible list. * A hidden window has no "screen", and so can not be seen, and does not * have a size. It can be unhidden onto any screen. */ static Window *window_hide (Window *window, char **args) { hide_window(window); return current_window; } /* * /WINDOW HIDE_OTHERS * This directs the client to place *all* windows on the current screen, * except for the current window, onto the invisible list. */ static Window *window_hide_others (Window *window, char **args) { Window *tmp, *next; if (window->screen) tmp = window->screen->window_list; else tmp = invisible_list; while (tmp) { next = tmp->next; if (tmp != window) hide_window(tmp); tmp = next; } return window; } /* * /WINDOW HOLD_INTERVAL * This determines how frequently the status bar should update the "HELD" * value when you are in holding mode. The default is 10, so that your * status bar isn't constantly flickering every time a new line comes in. * But if you want better responsiveness, this is the place to change it. */ static Window *window_hold_interval (Window *window, char **args) { char *arg = next_arg(*args, args); if (arg) { int size = my_atol(arg); if (size <= 0) { say("Hold interval must be a positive value!"); return window; } window->hold_interval = size; } say("Window hold interval notification is %d", window->hold_interval); return window; } /* * /WINDOW HOLD_MODE * This arranges for the window to "hold" any output bound for it once * a full page of output has been completed. Setting the global value of * HOLD_MODE is truly bogus and should be changed. XXXX */ static Window *window_hold_mode (Window *window, char **args) { int hold_mode; int slider; int i; if (window->holding_top_of_display) hold_mode = 1; else hold_mode = 0; if (get_boolean("HOLD_MODE", args, &hold_mode)) return NULL; if (hold_mode && !window->holding_top_of_display) { window->holding_top_of_display = window->scrolling_top_of_display; slider = (window->hold_slider * window->display_size) / 100; for (i = 0; i < slider; i++) { if (window->holding_top_of_display == window->display_ip) break; window->holding_top_of_display = window->holding_top_of_display->next; } recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } if (!hold_mode && window->holding_top_of_display) { window->holding_top_of_display = NULL; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } return window; } /* * /WINDOW HOLD_SLIDER * This determines how far up the hold pointer should move when you hit * the return key (unhold action) */ static Window *window_hold_slider (Window *window, char **args) { char *arg = next_arg(*args, args); if (arg) { int size = my_atol(arg); if (size < 0 || size > 100) { say("Hold slider must be 0 to 100!"); return window; } window->hold_slider = size; } say("Window hold slider is %d", window->hold_slider); return window; } /* * /WINDOW KILL * This arranges for the current window to be destroyed. Once a window * is killed, it cannot be recovered. Because every server must have at * least one window "connected" to it, if you kill the last window for a * server, the client will drop your connection to that server automatically. */ static Window *window_kill (Window *window, char **args) { delete_window(window); return current_window; } /* * /WINDOW KILL_OTHERS * This arranges for all windows on the current screen, other than the * current window to be destroyed. Obviously, the current window will be * the only window left on the screen. Connections to servers other than * the server for the current window will be implicitly closed. */ static Window *window_kill_others (Window *window, char **args) { Window *tmp, *next; if (window->screen) tmp = window->screen->window_list; else tmp = invisible_list; while (tmp) { next = tmp->next; if (tmp != window) delete_window(tmp); tmp = next; } return window; } /* * /WINDOW KILLSWAP * This arranges for the current window to be replaced by the last window * to be hidden, and also destroys the current window. */ static Window *window_killswap (Window *window, char **args) { if (invisible_list) { swap_window(window, invisible_list); delete_window(window); } else say("There are no hidden windows!"); return current_window; } /* * /WINDOW LAST * This changes the current window focus to the window that was most recently * the current window *but only if that window is still visible*. If the * window is no longer visible (having been HIDDEN), then the next window * following the current window will be made the current window. */ static Window *window_last (Window *window, char **args) { set_screens_current_window(window->screen, NULL); return current_window; } /* * /WINDOW LASTLOG * This changes the size of the window's lastlog buffer. The default value * for a window's lastlog is the value of /set LASTLOG, but each window may * be independantly tweaked with this command. */ static Window *window_lastlog (Window *window, char **args) { char *arg = next_arg(*args, args); if (arg) { int size = my_atol(arg); if (window->lastlog_size > size) { int i, diff; diff = window->lastlog_size - size; for (i = 0; i < diff; i++) remove_from_lastlog(window); } window->lastlog_max = size; } say("Lastlog size is %d", window->lastlog_max); return window; } /* * /WINDOW LASTLOG_LEVEL * This changes the types of lines that will be placed into this window's * lastlog. It is useful to note that the window's lastlog will contain * a subset (possibly a complete subset) of the lines that have appeared * in the window. This setting allows you to control which lines are * "thrown away" by the window. */ static Window *window_lastlog_level (Window *window, char **args) { char *arg = next_arg(*args, args);; if (arg) window->lastlog_level = parse_lastlog_level(arg); say("Lastlog level is %s", bits_to_lastlog_level(window->lastlog_level)); return window; } /* * /WINDOW LEVEL * This changes the types of output that will appear in the specified window. * Note that for the given set of windows connected to a server, each level * may only appear once in that set. When you add a level to a given window, * then it will be removed from whatever window currently holds it. The * exception to this is the "DCC" level, which may only be set to one window * for the entire client. */ static Window *window_level (Window *window, char **args) { char *arg; int add = 0; int newlevel = 0; if ((arg = next_arg(*args, args))) { if (*arg == '+') add = 1, arg++; else if (*arg == '-') add = -1, arg++; newlevel = parse_lastlog_level(arg); if (add == 1) window->window_level |= newlevel; else if (add == 0) window->window_level = newlevel; else if (add == -1) window->window_level &= ~newlevel; revamp_window_levels(window); } say("Window level is %s", bits_to_lastlog_level(window->window_level)); return window; } /* * /WINDOW LIST * This lists all of the windows known to the client, and a breif summary * of their current state. */ static Window *window_list (Window *window, char **args) { Window *tmp = NULL; int len = 6; int cnw = get_int_var(CHANNEL_NAME_WIDTH_VAR); if (cnw == 0) cnw = 12; /* Whatever */ tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->name && (strlen(tmp->name) > (size_t)len)) len = strlen(tmp->name); } say(WIN_FORM, "Ref", 12, 12, "Nick", len, len, "Name", cnw, cnw, "Channel", "Query", "Server", "Level", empty_string); tmp = NULL; while (traverse_all_windows(&tmp)) list_a_window(tmp, len); return window; } /* * /WINDOW LOG ON|OFF * This sets the current state of the logfile for the given window. When the * logfile is on, then any lines that appear on the window are written to the * logfile 'as-is'. The name of the logfile can be controlled with * /WINDOW LOGFILE. The default logfile name is . */ static Window *window_log (Window *window, char **args) { char *logfile; int add_ext = 1; char buffer[BIG_BUFFER_SIZE + 1]; if (get_boolean("LOG", args, &window->log)) return NULL; if ((logfile = window->logfile)) add_ext = 0; else if (!(logfile = get_string_var(LOGFILE_VAR))) logfile = empty_string; strlcpy(buffer, logfile, sizeof buffer); if (add_ext) { const char *title = empty_string; strlcat(buffer, ".", sizeof buffer); if ((title = get_echannel_by_refnum(window->refnum))) strlcat(buffer, title, sizeof buffer); else if ((title = window->query_nick)) strlcat(buffer, title, sizeof buffer); else { strlcat(buffer, "Window_", sizeof buffer); strlcat(buffer, ltoa(window->refnum), sizeof buffer); } } do_log(window->log, buffer, &window->log_fp); if (!window->log_fp) window->log = 0; return window; } /* * /WINDOW LOGFILE * This sets the current value of the log filename for the given window. * When you activate the log (with /WINDOW LOG ON), then any output to the * window also be written to the filename specified. */ static Window *window_logfile (Window *window, char **args) { char *arg = next_arg(*args, args); if (arg) { malloc_strcpy(&window->logfile, arg); say("Window LOGFILE set to %s", arg); } else if (window->logfile) say("Window LOGFILE is %s", window->logfile); else say("Window LOGFILE is not set."); return window; } static Window *window_move (Window *window, char **args) { move_window(window, get_number("MOVE", args)); return window; } static Window *window_move_to (Window *window, char **args) { move_window_to(window, get_number("MOVE", args)); return window; } static Window *window_name (Window *window, char **args) { char *arg; if ((arg = new_next_arg(*args, args))) { /* /window name - unsets the window name */ if (!strcmp(arg, "-")) new_free(&window->name); /* /window name to existing name -- ignore this. */ else if (window->name && (my_stricmp(window->name, arg) == 0)) return window; else if (is_window_name_unique(arg)) { malloc_strcpy(&window->name, arg); window_statusbar_needs_update(window); } else say("%s is not unique!", arg); } else say("You must specify a name for the window!"); return window; } static Window *window_new (Window *window, char **args) { Window *tmp; if ((tmp = new_window(window->screen))) window = tmp; make_window_current(window); /* XXX This is dangerous -- 'make_window_current' might nuke 'window' */ return window; } static Window *window_new_hide (Window *window, char **args) { new_window(NULL); return window; } static Window *window_next (Window *window, char **args) { Window *tmp; Window *next = NULL; Window *smallest = NULL; smallest = window; for (tmp = invisible_list; tmp; tmp = tmp->next) { if (!tmp->swappable) continue; if (tmp->refnum < smallest->refnum) smallest = tmp; if ((tmp->refnum > window->refnum) && (!next || (tmp->refnum < next->refnum))) next = tmp; } if (!next) next = smallest; if (next == NULL || next == window) { say("There are no hidden windows"); return NULL; } swap_window(window, next); message_from((char *) 0, LOG_CRAP); return current_window; } static Window *window_noserv (Window *window, char **args) { /* This is just like /window discon but last_server is set to NOSERV */ reassign_window_channels(window->refnum); new_free(&window->bind_channel); new_free(&window->waiting_channel); window->last_server = NOSERV; window->server = NOSERV; /* XXX This shouldn't be set here. */ window_check_servers(); return window; } static Window *window_notify (Window *window, char **args) { window->miscflags ^= WINDOW_NOTIFY; say("Notification when hidden set to %s", window->miscflags & WINDOW_NOTIFY ? on : off); return window; } static Window *window_notify_list (Window *window, char **args) { window->miscflags ^= WINDOW_NOTIFIED; say("Notify list status set to %s", window->miscflags & WINDOW_NOTIFIED ? on : off); return window; } static Window *window_notify_level (Window *window, char **args) { char *arg; if ((arg = next_arg(*args, args))) window->notify_level = parse_lastlog_level(arg); say("Window notify level is %s", bits_to_lastlog_level(window->notify_level)); return window; } static Window *window_number (Window *window, char **args) { Window *tmp; char *arg; int i; if ((arg = next_arg(*args, args))) { if (window_current_channel(window->refnum, window->server)) { say("You cannot change the number of a window with a channel"); return window; } if ((i = my_atol(arg)) > 0) { if ((tmp = get_window_by_refnum(i))) tmp->refnum = window->refnum; window->refnum = i; } else say("Window number must be greater than 0"); } else say("Window number missing"); return window; } /* * /WINDOW POP * This changes the current window focus to the most recently /WINDOW PUSHed * window that still exists. If the window is hidden, then it will be made * visible. Any windows that are found along the way that have been since * KILLed will be ignored. */ static Window *window_pop (Window *window, char **args) { int refnum; WindowStack *tmp; Window *win = NULL; while (window->screen->window_stack) { refnum = window->screen->window_stack->refnum; tmp = window->screen->window_stack->next; new_free((char **)&window->screen->window_stack); window->screen->window_stack = tmp; win = get_window_by_refnum(refnum); if (!win) continue; if (win->screen) set_screens_current_window(win->screen, win); else show_window(win); } if (!window->screen->window_stack && !win) say("The window stack is empty!"); return win; } static Window *window_previous (Window *window, char **args) { Window *tmp; Window *previous = NULL, *largest; largest = window; for (tmp = invisible_list; tmp; tmp = tmp->next) { if (!tmp->swappable) continue; if (tmp->refnum > largest->refnum) largest = tmp; if ((tmp->refnum < window->refnum) && (!previous || tmp->refnum > previous->refnum)) previous = tmp; } if (!previous) previous = largest; if (previous == NULL || previous == window) { say("There are no hidden windows to swap in"); return NULL; } swap_window(window, previous); message_from((char *) 0, LOG_CRAP); return current_window; } static Window *window_prompt (Window *window, char **args) { char *arg; if ((arg = next_arg(*args, args))) { malloc_strcpy(&window->prompt, arg); window_statusbar_needs_update(window); } else say("You must specify a prompt for the window!"); return window; } static Window *window_push (Window *window, char **args) { WindowStack *new_ws; new_ws = (WindowStack *) new_malloc(sizeof(WindowStack)); new_ws->refnum = window->refnum; new_ws->next = window->screen->window_stack; window->screen->window_stack = new_ws; return window; } Window *window_query (Window *window, char **args) { WNickList *tmp; const char *nick; char *a; Window *sw; /* * Nuke the old query list */ if ((nick = window->query_nick)) { say("Ending conversation with %s", window->query_nick); window_statusbar_needs_update(window); a = LOCAL_COPY(nick); while (a && *a) { nick = next_in_comma_list(a, &a); if ((tmp = (WNickList *)remove_from_list( (List **)&window->nicks, nick))) { new_free(&tmp->nick); new_free((char **)&tmp); } } new_free(&window->query_nick); } if ((nick = new_next_arg(*args, args))) { if (!strcmp(nick, ".")) { if (!(nick = get_server_sent_nick(window->server))) say("You have not messaged anyone yet"); } else if (!strcmp(nick, ",")) { if (!(nick = get_server_recv_nick(window->server))) say("You have not recieved a message yet"); } else if (!strcmp(nick, "*") && !(nick = get_echannel_by_refnum(0))) { say("You are not on a channel"); } else if (*nick == '%') { if (is_valid_process(nick) == -1) nick = NULL; } if (!nick) return window; /* * Create the new query list * Ugh. Make sure this goes to the RIGHT WINDOW! */ sw = to_window; to_window = window; say("Starting conversation with %s", nick); to_window = sw; malloc_strcpy(&window->query_nick, nick); window_statusbar_needs_update(window); a = LOCAL_COPY(nick); while (a && *a) { nick = next_in_comma_list(a, &a); tmp = (WNickList *)new_malloc(sizeof(WNickList)); tmp->nick = malloc_strdup(nick); add_to_list((List **)&window->nicks, (List *)tmp); } } return window; } /* * /WINDOW REBIND <#channel> * The channel will be "bound" to this window unconditionally. This is * the same as /window bind, except that <#channel> does not need to be * the current channel of this window. It may be bound elsewhere, for * example. This function will handle all of that for you. This function * will not fail unless you goof up the argument. * * Note: This operation is intentionally silent -- Please do not add a * whole bunch of says and yells in here. The primary purpose of this * function is to be used in things like /on connect where all the output * just gets in the way and gives the user no useful information. */ static Window *window_rebind (Window *window, char **args) { char *arg; Window *w = NULL; if (!(arg = next_arg(*args, args))) { say("REBIND: requires a channel argument"); return NULL; } if (!is_channel(arg)) { say("REBIND: %s is not a valid channel name", arg); return NULL; } /* * If its already bound, just accept it and stop here. */ if (window->bind_channel && !my_stricmp(window->bind_channel, arg)) return window; /* * Unbind whatever is currently bound to the window... */ if (window->bind_channel) new_free(&window->bind_channel); /* * Go a-hunting to see if any other window claims this channel. * If they do, forcibly take it from them. */ while (traverse_all_windows(&w)) { /* * If we have found a window where this channel * is the current channel, then we make it so that * it is the current channel here. This informs * the channel that it now belongs to us. * This also unbinds it from the old window. */ const char *chan = get_echannel_by_refnum(w->refnum); if (chan && !my_stricmp(arg, chan) && w->server == window->server) move_channel_to_window(arg, w->server, w->refnum, window->refnum); } /* * Now lay claim to the channel as belonging to us. * and as being our current channel. Tell ourselves * (and the user) that we own this channel now. */ malloc_strcpy(&window->bind_channel, arg); if (im_on_channel(arg, window->server)) move_channel_to_window(arg, window->server, 0, window->refnum); return window; } /* * /WINDOW REJOIN <#channel>[,<#channel>] * Here's the plan: * * For each channel, assuming from_server: * - If we are already on the channel: * - If the current window is connected to from_server: * -> Move the channel to the current window. * - If the current window is NOT connected to from_server: * -> Do nothing. * - If we are NOT already on the channel: * - If there is a window that looks like it owns this channel: * -> Join the channel in that window. * - If there is NOT a window that looks like it owns this channel: * - If the current window is connected to from_server: * -> Join the channel in the current window * - If the current window is NOT connected to from_server: * -> Find a window connected to from_server and join channel there. * -endif * * /WINDOW REJOIN is a terminal verb: it always slurps up all of the rest * of the command as it's arguments and returns NULL and you cannot do any * more operations after it is finished. * * If this function looks insane, it's because I wrote it after a long * day of coding in java, and so I am, in fact, commitable right now. */ Window *window_rejoin (Window *window, char **args) { char * channels; const char * chan; char * keys = NULL; char * newchan = NULL; /* First off, we have to be connected to join */ if (from_server == NOSERV || !is_server_registered(from_server)) { say("You are not connected to a server."); return window; } /* And the user must want to join something */ /* Get the channels, and the keys. */ if (!(channels = new_next_arg(*args, args))) { say("REJOIN: Must provide a channel argument"); return window; } keys = new_next_arg(*args, args); /* Iterate over each channel name in the list. */ while (*channels && (chan = next_in_comma_list(channels, &channels))) { /* Handle /join -i, which joins last invited channel */ if (!my_strnicmp(chan, "-i", 2)) { if (!(chan = get_server_invite_channel(window->server))) { say("You have not been invited to a channel!"); continue; } } /* Handle /join 0, which parts all current channels */ if (!strcmp(chan, "0")) { send_to_server("JOIN 0"); continue; } /* Sanity check the channel for the user */ if (!is_channel(chan)) { say("CHANNEL: %s is not a valid channel name", chan); continue; } /* * Now comes all the fun! THere are a whole bunch of * cases we could deal with right now -- see the comment * block above the function for the particulars, but * basically if we are ON the channel, we want to move it * to the current window for the user. This lets /join * act like /window channel. But if we are NOT on the * channel, then we want to find if there is any window * that thinks it owns it -- this lets the user do a /join * in /on connect, and have everything go to the right window. * If nobody owns the channel, then we take it. If we can't * take it (wrong server) then we find somebody else to take * it. If we can't find somebody else, then we're screwed. */ /* If we're on the channel... */ if (im_on_channel(chan, from_server)) { /* And i'm on the right server, grab the channel */ if (window->server == from_server) { Window *other; other = get_window_by_refnum(get_channel_winref(chan, from_server)); move_channel_to_window(chan, from_server, other->refnum, window->refnum); say("You are now talking to channel %s", check_channel_type(chan)); } /* Otherwise, Do not move the channel */ } /* I am NOT on the channel. */ else { Window *owner = NULL; Window *w = NULL; Window *anybody = NULL; /* Go hunt for the owner. */ while (traverse_all_windows(&w)) { if (w->server != from_server) continue; if (w->bind_channel && !my_stricmp(w->bind_channel, chan)) { owner = w; break; } if (w->waiting_channel && !my_stricmp(w->waiting_channel, chan)) { owner = w; break; } /* Take anybody on this server... */ if (anybody == NULL) anybody = w; } /* If there is no owner, then we get first crack. */ if (!owner && window->server == from_server) owner = window; /* If there is still no owner, take anybody. */ if (!owner && anybody) owner = anybody; /* If there is still no owner, we messed up. */ if (!owner) panic("There are no windows for this server, " "and there should be."); malloc_strcpy(&owner->waiting_channel, chan); malloc_strcat_wordlist(&newchan, ",", chan); } } if (newchan) { if (keys) send_to_server("JOIN %s %s", newchan, keys); else send_to_server("JOIN %s", newchan); new_free(&newchan); } message_from(NULL, LOG_CRAP); return window; } static Window *window_refnum (Window *window, char **args) { Window *tmp; if ((tmp = get_window("REFNUM", args))) { window = tmp; make_window_current(tmp); /* XXX This is dangerous -- 'make_window_current' might nuke 'tmp' */ if (tmp->screen) { set_screens_current_window(tmp->screen, tmp); window = tmp; } } else window = NULL; return window; } static Window *window_refnum_or_swap (Window *window, char **args) { Window *tmp; if (!(tmp = get_window("REFNUM_OR_SWAP", args))) return NULL; if (tmp->screen) { make_window_current(tmp); /* XXX This is dangerous -- 'make_window_current' might nuke 'tmp' */ set_screens_current_window(tmp->screen, tmp); } else swap_window(window, tmp); return tmp; } static Window *window_refresh (Window *window, char **args) { update_all_status(); update_all_windows(); return window; } static Window *window_remove (Window *window, char **args) { char *arg; if ((arg = next_arg(*args, args))) { char *ptr; WNickList *new_nl; while (arg) { if ((ptr = strchr(arg, ',')) != NULL) *ptr++ = 0; if ((new_nl = (WNickList *)remove_from_list((List **)&(window->nicks), arg))) { say("Removed %s from window name list", new_nl->nick); new_free(&new_nl->nick); new_free((char **)&new_nl); } else say("%s is not on the list for this window!", arg); arg = ptr; } } else say("REMOVE: Do something! Geez!"); return window; } /* This is a NO-OP now -- every window is a scratch window */ static Window *window_scratch (Window *window, char **args) { int scratch = 0; if (get_boolean("SCRATCH", args, &scratch)) return NULL; return window; } /* XXX - Need to come back and fix this... */ Window *window_scroll (Window *window, char **args) { int scroll = 0; if (get_boolean("SCROLL", args, &scroll)) return NULL; #if 0 if (!(window->scroll = scroll)) { while (window->display_buffer_size < window->display_size) add_to_display(window, empty_string); window->noscrollcursor = 0; unclear_window(window); } #endif return window; } static Window *window_scrolladj (Window *window, char **args) { if (get_boolean("SCROLLADJ", args, &window->scrolladj)) return NULL; return window; } static Window *window_scrollback (Window *window, char **args) { int val; if (args && *args && **args) { val = get_number("SCROLLBACK", args); if (val < window->display_size * 2) window->display_buffer_max = window->display_size * 2; else window->display_buffer_max = val; } say("Window scrollback size set to %d", window->display_buffer_max); return window; } static Window *window_scroll_backward (Window *window, char **args) { int val; if (args && *args && **args) { val = get_number("SCROLL_BACKWARD", args); if (val == 0) window_scrollback_backward(window); else window_scrollback_backwards_lines(window, val); } else window_scrollback_backward(window); return window; } static Window *window_scroll_end (Window *window, char **args) { window_scrollback_end(window); return window; } static Window *window_scroll_forward (Window *window, char **args) { int val; if (args && *args && **args) { val = get_number("SCROLL_FORWARD", args); if (val == 0) window_scrollback_forward(window); else window_scrollback_forwards_lines(window, val); } else window_scrollback_forward(window); return window; } static Window *window_scroll_start (Window *window, char **args) { window_scrollback_start(window); return window; } regex_t *last_regex = NULL; static int new_search_term (const char *arg) { int errcode; if (last_regex) regfree(last_regex); else last_regex = new_malloc(sizeof(*last_regex)); errcode = regcomp(last_regex, arg, REG_EXTENDED | REG_ICASE | REG_NOSUB); if (errcode != 0) { char errstr[1024]; regerror(errcode, last_regex, errstr, sizeof(errstr)); say("The regex [%s] isn't acceptable because [%s]", arg, errstr); return -1; } return 0; } static Window *window_search_back (Window *window, char **args) { char *arg; if ((arg = new_next_arg(*args, args))) { if (new_search_term(arg)) return window; } if (last_regex) window_scrollback_to_string(window, last_regex); else say("Need to know what to search for"); return window; } static Window *window_search_forward (Window *window, char **args) { char *arg; if ((arg = new_next_arg(*args, args))) { if (new_search_term(arg)) return window; } if (last_regex) window_scrollforward_to_string(window, last_regex); else say("Need to know what to search for"); return window; } static Window *window_skip (Window *window, char **args) { if (get_boolean("SKIP", args, &window->skip)) return NULL; return window; } Window *window_server (Window *window, char **args) { char * arg; int newconn; if ((arg = next_arg(*args, args))) { int i = find_server_refnum(arg, NULL); if (windows_connected_to_server(window->server) > 1) { clear_reconnect_counts(); /* ?? */ newconn = 1; } else newconn = 0; if (!connect_to_new_server(i, window->server, 1)) { /* * First find a new home for all our channels. * This is a must since we're moving to a * different server, and we don't want the channels * on one server to point to a window on another * server. */ reassign_window_channels(window->refnum); /* * Associate ourselves with the new server. */ window->server = i; window->last_server = NOSERV; /* * Set the window's lastlog level that is * in /set new_server_lastlog_level */ set_level_by_refnum(window->refnum, new_server_lastlog_level); /* * And blow away any old channel information * which we surely cannot use now. */ new_free(&window->bind_channel); new_free(&window->waiting_channel); } /* * Now make sure everything seems coherent. * If we were the last window attached to that server, * then window_check_servers() will close up that server * for us and garbage collect any channels lying around. */ window_check_servers(); } else say("SERVER: You must specify a server"); return window; } static Window *window_show (Window *window, char **args) { Window *tmp; if ((tmp = get_window("SHOW", args))) { show_window(tmp); window = current_window; } return window; } static Window *window_show_all (Window *window, char **args) { while (invisible_list) show_window(invisible_list); return window; } static Window *window_shrink (Window *window, char **args) { resize_window(RESIZE_REL, window, -get_number("SHRINK", args)); return window; } static Window *window_size (Window *window, char **args) { char * ptr = *args; int number; number = parse_number(args); if (ptr == *args) say("Window size is %d", window->display_size); else resize_window(RESIZE_ABS, window, number); return window; } /* * This lists the windows that are on the stack, cleaning up any * bogus entries on the way. */ static Window *window_stack (Window *window, char **args) { WindowStack *last, *tmp, *crap; Window *win = NULL; size_t len = 4; while (traverse_all_windows(&win)) { if (win->name && (strlen(win->name) > len)) len = strlen(win->name); } say("Window stack:"); last = NULL; tmp = window->screen->window_stack; while (tmp) { if ((win = get_window_by_refnum(tmp->refnum)) != NULL) { list_a_window(win, len); last = tmp; tmp = tmp->next; } else { crap = tmp->next; new_free((char **)&tmp); if (last) last->next = crap; else window->screen->window_stack = crap; tmp = crap; } } return window; } static Window *window_status_format (Window *window, char **args) { char *arg; arg = new_next_arg(*args, args); malloc_strcpy(&window->status.line[0].raw, arg); window_statusbar_needs_redraw(window); rebuild_a_status(window); return window; } static Window *window_status_format1 (Window *window, char **args) { char *arg; arg = new_next_arg(*args, args); malloc_strcpy(&window->status.line[1].raw, arg); window_statusbar_needs_redraw(window); rebuild_a_status(window); return window; } static Window *window_status_format2 (Window *window, char **args) { char *arg; arg = new_next_arg(*args, args); malloc_strcpy(&window->status.line[2].raw, arg); window_statusbar_needs_redraw(window); rebuild_a_status(window); return window; } static Window *window_status_special (Window *window, char **args) { char *arg; arg = new_next_arg(*args, args); malloc_strcpy(&window->status.special, arg); window_statusbar_needs_redraw(window); return window; } static Window *window_swap (Window *window, char **args) { Window *tmp; if ((tmp = get_invisible_window("SWAP", args))) swap_window(window, tmp); return current_window; } static Window *window_swappable (Window *window, char **args) { if (get_boolean("SWAPPABLE", args, &window->swappable)) return NULL; window_statusbar_needs_update(window); return window; } static Window *window_unbind (Window *window, char **args) { char *arg; if ((arg = next_arg(*args, args))) { if (get_winref_by_bound_channel(arg, window->server) > 0) { say("Channel %s is no longer bound", arg); unbind_channel(arg, from_server); } else say("Channel %s is not bound", arg); } else { say("Channel %s is no longer bound", window->bind_channel); new_free(&window->bind_channel); } return window; } typedef Window *(*window_func) (Window *, char **args); typedef struct window_ops_T { const char *command; window_func func; } window_ops; static const window_ops options [] = { { "ADD", window_add }, { "BACK", window_back }, { "BALANCE", window_balance }, { "BEEP_ALWAYS", window_beep_always }, { "BIND", window_bind }, { "CHANNEL", window_channel }, { "CLEAR", window_clear }, { "CREATE", window_create }, { "DELETE", window_delete }, { "DESCRIBE", window_describe }, /* * */ { "DISCON", window_discon }, { "DOUBLE", window_double }, { "ECHO", window_echo }, { "FIXED", window_fixed }, { "FLUSH", window_flush }, { "GOTO", window_goto }, { "GROW", window_grow }, { "HIDE", window_hide }, { "HIDE_OTHERS", window_hide_others }, { "HOLD_INTERVAL", window_hold_interval }, { "HOLD_MODE", window_hold_mode }, { "HOLD_SLIDER", window_hold_slider }, { "KILL", window_kill }, { "KILL_OTHERS", window_kill_others }, { "KILLSWAP", window_killswap }, { "LAST", window_last }, { "LASTLOG", window_lastlog }, { "LASTLOG_LEVEL", window_lastlog_level }, { "LEVEL", window_level }, { "LIST", window_list }, { "LOG", window_log }, { "LOGFILE", window_logfile }, { "MOVE", window_move }, { "MOVE_TO", window_move_to }, { "NAME", window_name }, { "NEW", window_new }, { "NEW_HIDE", window_new_hide }, /* * */ { "NEXT", window_next }, { "NOSERV", window_noserv }, { "NOTIFIED", window_notify_list }, { "NOTIFY", window_notify }, { "NOTIFY_LEVEL", window_notify_level }, { "NUMBER", window_number }, { "POP", window_pop }, { "PREVIOUS", window_previous }, { "PROMPT", window_prompt }, { "PUSH", window_push }, { "QUERY", window_query }, { "REBIND", window_rebind }, { "REFNUM", window_refnum }, { "REFNUM_OR_SWAP", window_refnum_or_swap }, { "REFRESH", window_refresh }, { "REJOIN", window_rejoin }, { "REMOVE", window_remove }, { "SCRATCH", window_scratch }, { "SCROLL", window_scroll }, { "SCROLLADJ", window_scrolladj }, { "SCROLLBACK", window_scrollback }, /* * */ { "SCROLL_BACKWARD", window_scroll_backward }, { "SCROLL_END", window_scroll_end }, { "SCROLL_FORWARD", window_scroll_forward }, { "SCROLL_START", window_scroll_start }, { "SEARCH_BACK", window_search_back }, { "SEARCH_FORWARD", window_search_forward }, { "SERVER", window_server }, { "SHOW", window_show }, { "SHOW_ALL", window_show_all }, /* * */ { "SHRINK", window_shrink }, { "SIZE", window_size }, { "SKIP", window_skip }, { "STACK", window_stack }, { "STATUS_FORMAT", window_status_format }, { "STATUS_FORMAT1", window_status_format1 }, { "STATUS_FORMAT2", window_status_format2 }, { "STATUS_SPECIAL", window_status_special }, { "SWAP", window_swap }, { "SWAPPABLE", window_swappable }, { "UNBIND", window_unbind }, { NULL, NULL } }; BUILT_IN_COMMAND(windowcmd) { char *arg; int nargs = 0; Window *window; int old_status_update; int winref; old_status_update = permit_status_update(0); message_from(NULL, LOG_CURRENT); window = current_window; while ((arg = next_arg(args, &args))) { int i; int len = strlen(arg); if (*arg == '-' || *arg == '/') /* Ignore - or / */ arg++, len--; for (i = 0; options[i].func ; i++) { if (!my_strnicmp(arg, options[i].command, len)) { winref = window ? (int)window->refnum : -1; window = options[i].func(window, &args); nargs++; if (!window) args = NULL; do_hook(WINDOW_COMMAND_LIST, "%d %d", winref, window ? (int)window->refnum : -1); break; } } if (!options[i].func) { Window *s_window; if ((s_window = get_window_by_desc(arg))) { nargs++; window = s_window; } else yell("WINDOW: Invalid option: [%s]", arg); } } if (!nargs) window_describe(current_window, NULL); permit_status_update(old_status_update); message_from(NULL, LOG_CRAP); window_check_channels(); update_all_windows(); } /********************** SCROLLBACK BUFFER MAINTAINANCE **********************/ /* * XXXX Dont you DARE touch this XXXX * * Most of the time, a delete_display_line() is followed somewhat * immediately by a new_display_line(). So most of the time we just * cache that one item and re-use it. That saves us thousands of * malloc()s. In the cases where its not, then we just do things the * normal way. */ static Display *recycle = NULL; static size_t display_line_count = 1; void delete_display_line (Display *stuff) { if (recycle == stuff) panic("recycle == stuff is bogus"); if (recycle) { new_free((char **)&recycle->line); new_free((char **)&recycle); } recycle = stuff; #if 0 new_free(&stuff->line); #endif *(stuff->line) = 0; } /* * CAUTION: The return value of this function may or may not have 'line' * set to NULL. Therefore, you MUST call malloc_strcpy() to initialize * the 'line' field. You will cause memory leaks if you fail to do this! * By not free()ing line, we save a free()/malloc() if the new original line * had enough space to hold the new line. We let malloc_strcpy() do the * dirty work there. */ static Display *new_display_line (Display *prev, Window *w) { Display *stuff; if (recycle) { stuff = recycle; recycle = NULL; } else { stuff = (Display *)new_malloc(sizeof(Display)); stuff->line = NULL; } #if 0 stuff->line = NULL; #endif stuff->count = w->display_counter++; stuff->prev = prev; stuff->next = NULL; return stuff; } /* * This function adds an item to the window's scrollback. If the item * should be displayed on the screen, then 1 is returned. If the item is * not to be displayed, then 0 is returned. This function handles all * the hold_mode stuff. */ int add_to_scrollback (Window *window, const unsigned char *str) { /* * If this is a scratch window, do that somewhere else */ if (window->change_line != -1) return change_line(window, str); return add_to_display(window, str); } int add_to_display (Window *window, const unsigned char *str) { int scroll; int i; /* Add to the display list */ window->display_ip->next = new_display_line(window->display_ip, window); malloc_strcpy(&window->display_ip->line, str); window->display_ip = window->display_ip->next; window->display_buffer_size++; /* Adjust the top of screen values */ window->scrolling_distance_from_display_ip++; if (window->scrollback_top_of_display) window->scrollback_distance_from_display_ip++; if (window->holding_top_of_display) window->holding_distance_from_display_ip++; /* Check to see what happens in hold mode */ if (window->holding_top_of_display) { size_t lines_held; lines_held = window->holding_distance_from_display_ip - window->display_size; if (lines_held > 0) window_statusbar_needs_update(window); } /* Check to see what happens in scrollback mode */ if (window->scrollback_top_of_display) { size_t lines_held; lines_held = window->scrollback_distance_from_display_ip - window->display_size; if (lines_held > 0) window_statusbar_needs_update(window); } /* Logically scroll the normal top of display pointer */ while (window->scrolling_distance_from_display_ip > window->display_size) { if ((scroll = get_int_var(SCROLL_LINES_VAR)) <= 0) scroll = 1; for (i = 0; i < scroll; i++) { window->scrolling_top_of_display = window->scrolling_top_of_display->next; window->scrolling_distance_from_display_ip--; } } return 1; } int trim_scrollback (Window *window) { /* Do not trim the scrollback if we are in scrollback mode */ if (window->scrollback_top_of_display) return 0; /* Do not trim the scrollback if we are holding stuff. */ if (window->holding_distance_from_display_ip > window->display_size) return 0; /* * Before outputting the line, we snip back the top of the * display buffer. (The fact that we do this only when we get * to here is what keeps whats currently on the window always * active -- once we get out of hold mode or scrollback mode, then * we truncate the display buffer at that point.) */ while (window->display_buffer_size > window->display_buffer_max) { Display *next = window->top_of_scrollback->next; delete_display_line(window->top_of_scrollback); window->top_of_scrollback = next; window->display_buffer_size--; } /* Ok. Go ahead and print it */ return 1; } int flush_scrollback_after (Window *window) { Display *curr_line, *next_line; int count; if (!(curr_line = window->holding_top_of_display)) { say("/WINDOW FLUSH doesn't do anything unless you're in hold mode"); return 0; } for (count = 1; count < window->display_size; count++) { if (curr_line == window->display_ip) return 0; curr_line = curr_line->next; } next_line = curr_line->next; curr_line->next = window->display_ip; window->display_ip->prev = curr_line; curr_line = next_line; while (curr_line != window->display_ip) { next_line = curr_line->next; delete_display_line(curr_line); window->display_buffer_size--; curr_line = next_line; } window->scrolling_top_of_display = window->holding_top_of_display; recalculate_window_cursor_and_display_ip(window); return 1; } /* * * * * * * * * * * Scrollback functionality * * * * * * * * * * */ static void window_scrollback_start (Window *window) { if (window->display_buffer_size <= window->display_size) { term_beep(); return; } window->scrollback_top_of_display = window->top_of_scrollback; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } /* * Cancel out scrollback and holding stuff so you're left pointing at the * "standard" place. Doesn't turn hold mode off, obviously. */ static void window_scrollback_end (Window *window) { if (window->scrollback_top_of_display) window->scrollback_top_of_display = NULL; if (window->holding_top_of_display) window->holding_top_of_display = window->display_ip; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } /* * Scroll backwards from the last scrollback point, the last hold point, * or the standard place. */ static void window_scrollback_backwards_lines (Window *window, int lines) { Display *new_top; int new_lines; if (window->scrollback_top_of_display == window->top_of_scrollback) { term_beep(); return; } if (window->scrollback_top_of_display == NULL) { if (window->holding_distance_from_display_ip > window->scrolling_distance_from_display_ip) window->scrollback_top_of_display = window->holding_top_of_display; else window->scrollback_top_of_display = window->scrolling_top_of_display; } new_top = window->scrollback_top_of_display; for (new_lines = 0; new_lines < lines; new_lines++) { if (new_top == window->top_of_scrollback) break; new_top = new_top->prev; } window->scrollback_top_of_display = new_top; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } /* * Scroll the scrollback (or hold mode) forward. */ static void window_scrollback_forwards_lines (Window *window, int lines) { Display *new_top; int unholding; int new_lines = 0; if (window->scrollback_top_of_display) { new_top = window->scrollback_top_of_display; unholding = 0; } else if (window->holding_top_of_display) { new_top = window->holding_top_of_display; unholding = 1; } else { term_beep(); return; } for (new_lines = 0; new_lines < lines; new_lines++) { if (new_top == window->display_ip) break; new_top = new_top->next; } if (!unholding) window->scrollback_top_of_display = new_top; else window->holding_top_of_display = new_top; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); } static void window_scrollback_to_string (Window *window, regex_t *preg) { Display *new_top; if (window->scrollback_top_of_display) new_top = window->scrollback_top_of_display; else if (window->holding_distance_from_display_ip > window->scrolling_distance_from_display_ip) new_top = window->holding_top_of_display; else new_top = window->scrolling_top_of_display; while (new_top != window->top_of_scrollback) { /* Always move up a line before searching */ new_top = new_top->prev; if (regexec(preg, new_top->line, 0, NULL, 0) == 0) { window->scrollback_top_of_display = new_top; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); return; } } term_beep(); } static void window_scrollforward_to_string (Window *window, regex_t *preg) { Display *new_top; if (window->scrollback_top_of_display) new_top = window->scrollback_top_of_display; else if (window->holding_distance_from_display_ip > window->scrolling_distance_from_display_ip) new_top = window->holding_top_of_display; else new_top = window->scrolling_top_of_display; while (new_top->next != window->display_ip) { /* Always move up a line before searching */ new_top = new_top->next; if (regexec(preg, new_top->line, 0, NULL, 0) == 0) { window->scrollback_top_of_display = new_top; recalculate_window_cursor_and_display_ip(window); window_body_needs_redraw(window); window_statusbar_needs_update(window); return; } } term_beep(); } /* * * * * * * * */ static void window_scrollback_forward (Window *window) { int ratio = get_int_var(SCROLLBACK_RATIO_VAR); int lines; if (ratio < 1) ratio = 1; if (ratio > 100) ratio = 100; if ((lines = window->display_size * ratio / 100) < 1) lines = 1; window_scrollback_forwards_lines(window, lines); } static void window_scrollback_backward (Window *window) { int ratio = get_int_var(SCROLLBACK_RATIO_VAR); int lines; if (ratio < 1) ratio = 1; if (ratio > 100) ratio = 100; if ((lines = window->display_size * ratio / 100) < 1) lines = 1; window_scrollback_backwards_lines(window, lines); } void scrollback_forwards (char dumb, char *dumber) { window_scrollback_forward(current_window); } void scrollback_backwards (char dumb, char *dumber) { window_scrollback_backward(current_window); } void scrollback_end (char dumb, char *dumber) { window_scrollback_end(current_window); } void scrollback_start (char dumb, char *dumber) { window_scrollback_start(current_window); } /* HOLD MODE STUFF */ void unstop_all_windows (char dumb, char *dumber) { Window *tmp = NULL; char my_off[4]; char * ptr; while (traverse_all_windows(&tmp)) { strcpy(my_off, "OFF"); ptr = my_off; window_hold_mode(tmp, (char **)&ptr); } update_all_windows(); } /* toggle_stop_screen: the BIND function TOGGLE_STOP_SCREEN */ void toggle_stop_screen (char unused, char *not_used) { char toggle[7], *p = toggle; strlcpy(toggle, "TOGGLE", sizeof toggle); window_hold_mode(current_window, (char **)&p); update_all_windows(); } /**************************************************************************/ /* * Miscelaneous -- these probably belong somewhere else, but until then, * theyre here. */ /* * The "Window Cursor" tells the output routines where the next line of * output to this window should go. "Window Top" is offset of the window's * first line on the physical screen. So by adding "Window Top" to "Window * Cursor", we know where to put the next line. * * However, as a special idiom, if "Window Cursor" is equal to the "Window * Display Size", it points at the status bar; this is a special case which * is always to be interpreted in one of two ways: * * "Window Scrollback Point" is not set: Scroll window before output * "Window Scrollback Point" is set: Do not do any on output. * * In all cases where "Window Cursor" is less than "Window Display Size", * output will occur. * * This function also recalculates "Window Distance From Top Of Display To * the Insertion Point" which is used to decide whether to do output * supression in hold mode and other places. */ void recalculate_window_cursor_and_display_ip (Window *window) { Display *tmp; window->cursor = 0; window->display_buffer_size = 0; window->scrolling_distance_from_display_ip = -1; window->holding_distance_from_display_ip = -1; window->scrollback_distance_from_display_ip = -1; window->display_counter = 1; /* Recount and resequence the scrollback */ for (tmp = window->top_of_scrollback;; tmp = tmp->next) { window->display_buffer_size++; tmp->count = window->display_counter++; if (tmp == window->display_ip) break; } /* Calculate the distances to the bottom of scrollback */ if (window->holding_top_of_display) window->holding_distance_from_display_ip = window->display_ip->count - window->holding_top_of_display->count; if (window->scrollback_top_of_display) window->scrollback_distance_from_display_ip = window->display_ip->count - window->scrollback_top_of_display->count; window->scrolling_distance_from_display_ip = window->display_ip->count - window->scrolling_top_of_display->count; /* Auto-detect when scrollback should be turned off */ if (window->scrollback_distance_from_display_ip <= window->holding_distance_from_display_ip || window->scrollback_distance_from_display_ip <= window->scrolling_distance_from_display_ip) { window->scrollback_top_of_display = NULL; window->scrollback_distance_from_display_ip = -1; } /* Figure out where the cursor is */ if (window->holding_distance_from_display_ip >= window->display_size) window->cursor = window->display_size; else if (window->scrolling_distance_from_display_ip >= window->display_size) window->cursor = window->display_size; else window->cursor = window->scrolling_distance_from_display_ip; } /* * This is used to set the current_window for the given screen. It handles * last_window_refnum and making sure the window's status bar is updated * (for the STATUS_WINDOW thing), and arranging for the windows to be updated. * Its a bad idea to directly assign screen->current_window! */ static void set_screens_current_window (Screen *screen, Window *window) { if (!window) { window = get_window_by_refnum(screen->last_window_refnum); /* Cant use a window that is now on a different screen */ /* Check check a window that doesnt exist, too! */ if (window && window->screen != screen) window = NULL; } if (!window) window = screen->window_list; if (window->deceased) panic("This window is dead."); if (window->screen != screen) panic("The window is not on that screen."); if (!screen) panic("Cannot set the invisible screen's current window."); if (screen->current_window != window) { if (screen->current_window) { window_statusbar_needs_update(screen->current_window); screen->last_window_refnum = screen->current_window->refnum; } screen->current_window = window; window_statusbar_needs_update(screen->current_window); } if (current_window != window) make_window_current(window); window->priority = current_window_priority++; #if 0 /* Can we get away with not doing this? */ update_all_windows(); #endif } void make_window_current_by_refnum (int refnum) { Window *new_win; if (refnum == -1) return; if ((new_win = get_window_by_refnum(refnum))) make_window_current(new_win); else say("Window [%d] doesnt exist any more. Punting.", refnum); } /* * This is used to make the specified window the current window. This * is preferable to directly doing the assign, because it can deal with * finding a current window if the old one has gone away. */ void make_window_current (Window *window) { Window *old_current_window = current_window; int old_screen, old_window; int new_screen, new_winref; if (!window) current_window = last_input_screen->current_window; else if (current_window != window) current_window = window; if (current_window == NULL) current_window = last_input_screen->window_list; if (current_window == NULL) panic("make_window_current(NULL) -- can't find another window"); if (current_window->deceased) panic("This window is dead and cannot be made current"); if (current_window == old_current_window) return; if (!old_current_window) old_screen = old_window = -1; else if (!old_current_window->screen) old_screen = -1, old_window = old_current_window->refnum; else old_screen = old_current_window->screen->screennum, old_window = old_current_window->refnum; new_winref = current_window->refnum; if (!current_window->screen) new_screen = -1; else new_screen = current_window->screen->screennum; do_hook(SWITCH_WINDOWS_LIST, "%d %d %d %d", old_screen, old_window, new_screen, new_winref); } /**************************************************************************/ /* * This puts the given string into a scratch window. It ALWAYS suppresses * any further action (by returning a FAIL, so rite() is not called). */ int change_line (Window *window, const unsigned char *str) { Display *my_line; int cnt; int chg_line; chg_line = window->change_line; window->change_line = -1; /* Must have been asked to change a line */ if (chg_line == -1) panic("This is not a scratch window."); /* Outputting to a 0 size window is a no-op. */ if (window->display_size == 0) return 0; /* Must be within the bounds of the size of the window */ if (chg_line >= window->display_size) panic("change_line is too big."); /* Make sure that the line exists that we want to change */ while (window->scrolling_distance_from_display_ip <= chg_line) add_to_display(window, empty_string); /* Now find the line we want to change */ my_line = window->scrolling_top_of_display; if (my_line == window->display_ip) panic("Can't change line [%d] -- doesn't exist", chg_line); for (cnt = 0; cnt < chg_line; cnt++) { my_line = my_line->next; if (my_line == window->display_ip) panic("Can't change line [%d] -- doesn't exist", chg_line); } /* * Now change the line, move the logical cursor, and then let * the caller (window_disp) output the new line. */ malloc_strcpy(&my_line->line, str); window->cursor = chg_line; return 1; /* Express a success */ } void check_window_cursor (Window *window) { #if 0 if (window->scroll && window->cursor < window->display_size && window->cursor < window->scrolling_distance_from_display_ip) { recalculate_window_cursor_and_display_ip(window); } /* XXX This is a hack that covers up a bug elsewhere. */ if (window->hold_mode == 0 && window->autohold == 0 && window->distance_from_display_ip > window->display_size) { window_scrollback_end(window); #if 0 yell("Unheld this window for you -- let #epic on efnet know!"); #endif } #endif } /* Used by function_windowctl */ /* * $windowctl(REFNUMS) * $windowctl(REFNUM window-desc) * $windowctl(MAX) * $windowctl(GET 0 [LIST]) * $windowctl(SET 0 [ITEM] [VALUE]) * * [LIST] and [ITEM] are one of the following: * REFNUM Unique integer that identifies one window * NAME A name given to the window by user * SERVER The server this window sends msgs to * LAST_SERVER If disconnected, the last server connected. * PRIORITY The "current window" priority on this server. * VISIBLE Whether this window is on a screen or not * TOP * BOTTOM * CURSOR * NOSCROLLCURSOR * ABSOLUTE_SIZE * SCROLL * CHANGE_LINE * OLD_SIZE * UPDATE * MISCFLAGS * BEEP_ALWAYS * NOTIFY_LEVEL * WINDOW_LEVEL * SKIP * COLUMNS * PROMPT * STATUS_FORMAT * STATUS_FORMAT1 * STATUS_FORMAT2 * DISPLAY_BUFFER_SIZE * DISPLAY_BUFFER_MAX * DISPLAY_SIZE * HOLD_MODE * AUTOHOLD * LINES_HELD * HOLD_INTERVAL * LAST_LINES_HELD * DISTANCE_FROM_DISPLAY_IP * WAITING_CHANNEL * BIND_CHANNEL * QUERY_NICK * NICKLIST * LASTLOG_LEVEL * LASTLOG_SIZE * LASTLOG_MAX * LOGGING * LOGFILE * DECEASED */ char *windowctl (char *input) { int refnum, len; char *listc; char *ret = NULL; Window *w; GET_STR_ARG(listc, input); len = strlen(listc); if (!my_strnicmp(listc, "REFNUM", len)) { char *windesc; GET_STR_ARG(windesc, input); if (!(w = get_window_by_desc(windesc))) RETURN_EMPTY; RETURN_INT(w->refnum); } else if (!my_strnicmp(listc, "REFNUMS", len)) { w = NULL; while (traverse_all_windows(&w)) malloc_strcat_wordlist(&ret, space, ltoa(w->refnum)); RETURN_MSTR(ret); } else if (!my_strnicmp(listc, "NEW", len)) { } else if (!my_strnicmp(listc, "GET", len)) { GET_INT_ARG(refnum, input); if (!(w = get_window_by_refnum(refnum))) RETURN_EMPTY; GET_STR_ARG(listc, input); len = strlen(listc); if (!my_strnicmp(listc, "REFNUM", len)) { RETURN_INT(w->refnum); } else if (!my_strnicmp(listc, "NAME", len)) { RETURN_STR(w->name); } else if (!my_strnicmp(listc, "SERVER", len)) { RETURN_INT(w->server); } else if (!my_strnicmp(listc, "LAST_SERVER", len)) { RETURN_INT(w->last_server); } else if (!my_strnicmp(listc, "PRIORITY", len)) { RETURN_INT(w->priority); } else if (!my_strnicmp(listc, "VISIBLE", len)) { RETURN_INT(w->screen ? 1 : 0); } else if (!my_strnicmp(listc, "TOP", len)) { RETURN_INT(w->top); } else if (!my_strnicmp(listc, "BOTTOM", len)) { RETURN_INT(w->bottom); } else if (!my_strnicmp(listc, "CURSOR", len)) { RETURN_INT(w->cursor); } else if (!my_strnicmp(listc, "NOSCROLLCURSOR", len)) { RETURN_INT(w->noscrollcursor); } else if (!my_strnicmp(listc, "FIXED", len)) { RETURN_INT(w->absolute_size); } else if (!my_strnicmp(listc, "SCROLL", len)) { RETURN_INT(w->scroll); } else if (!my_strnicmp(listc, "CHANGE_LINE", len)) { RETURN_INT(w->change_line); } else if (!my_strnicmp(listc, "OLD_SIZE", len)) { RETURN_INT(w->old_size); } else if (!my_strnicmp(listc, "UPDATE", len)) { RETURN_INT(w->update); } else if (!my_strnicmp(listc, "MISCFLAGS", len)) { RETURN_INT(w->miscflags); } else if (!my_strnicmp(listc, "BEEP_ALWAYS", len)) { RETURN_INT(w->beep_always); } else if (!my_strnicmp(listc, "NOTIFY_LEVEL", len)) { RETURN_STR(bits_to_lastlog_level(w->notify_level)); } else if (!my_strnicmp(listc, "WINDOW_LEVEL", len)) { RETURN_STR(bits_to_lastlog_level(w->window_level)); } else if (!my_strnicmp(listc, "SKIP", len)) { RETURN_INT(w->skip); } else if (!my_strnicmp(listc, "COLUMNS", len)) { RETURN_INT(w->columns); } else if (!my_strnicmp(listc, "PROMPT", len)) { RETURN_STR(w->prompt); } else if (!my_strnicmp(listc, "DOUBLE", len)) { RETURN_INT(w->status.double_status); } else if (!my_strnicmp(listc, "STATUS_FORMAT", len)) { RETURN_STR(w->status.line[0].raw); } else if (!my_strnicmp(listc, "STATUS_FORMAT1", len)) { RETURN_STR(w->status.line[1].raw); } else if (!my_strnicmp(listc, "STATUS_FORMAT2", len)) { RETURN_STR(w->status.line[2].raw); } else if (!my_strnicmp(listc, "STATUS_LINE", len)) { RETURN_STR(w->status.line[0].result); } else if (!my_strnicmp(listc, "STATUS_LINE1", len)) { RETURN_STR(w->status.line[1].result); } else if (!my_strnicmp(listc, "STATUS_LINE2", len)) { RETURN_STR(w->status.line[2].result); } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_SIZE", len)) { RETURN_INT(w->display_buffer_size); } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_MAX", len)) { RETURN_INT(w->display_buffer_max); } else if (!my_strnicmp(listc, "SCROLLING_DISTANCE", len)) { RETURN_INT(w->scrolling_distance_from_display_ip); } else if (!my_strnicmp(listc, "HOLDING_DISTANCE", len)) { RETURN_INT(w->holding_distance_from_display_ip); } else if (!my_strnicmp(listc, "SCROLLBACK_DISTANCE", len)) { RETURN_INT(w->scrollback_distance_from_display_ip); } else if (!my_strnicmp(listc, "DISPLAY_COUNTER", len)) { RETURN_INT(w->display_counter); } else if (!my_strnicmp(listc, "HOLD_SLIDER", len)) { RETURN_INT(w->hold_slider); } else if (!my_strnicmp(listc, "HOLD_INTERVAL", len)) { RETURN_INT(w->hold_interval); } else if (!my_strnicmp(listc, "LAST_LINES_HELD", len)) { RETURN_INT(w->last_lines_held); } else if (!my_strnicmp(listc, "WAITING_CHANNEL", len)) { RETURN_STR(w->waiting_channel); } else if (!my_strnicmp(listc, "BIND_CHANNEL", len)) { RETURN_STR(w->bind_channel); } else if (!my_strnicmp(listc, "CHANNELS", len)) { RETURN_MSTR(window_all_channels(w->refnum, w->server)); } else if (!my_strnicmp(listc, "QUERY_NICK", len)) { RETURN_STR(w->query_nick); } else if (!my_strnicmp(listc, "NICKLIST", len)) { RETURN_MSTR(get_nicklist_by_window(w)); } else if (!my_strnicmp(listc, "LASTLOG_LEVEL", len)) { RETURN_STR(bits_to_lastlog_level(w->lastlog_level)); } else if (!my_strnicmp(listc, "LASTLOG_SIZE", len)) { RETURN_INT(w->lastlog_size); } else if (!my_strnicmp(listc, "LASTLOG_MAX", len)) { RETURN_INT(w->lastlog_max); } else if (!my_strnicmp(listc, "LOGGING", len)) { RETURN_INT(w->log); } else if (!my_strnicmp(listc, "LOGFILE", len)) { RETURN_STR(w->logfile); } else if (!my_strnicmp(listc, "SWAPPABLE", len)) { RETURN_INT(w->swappable); } else if (!my_strnicmp(listc, "SCROLLADJ", len)) { RETURN_INT(w->swappable); } else if (!my_strnicmp(listc, "DECEASED", len)) { RETURN_INT(w->deceased); } } else if (!my_strnicmp(listc, "SET", len)) { GET_INT_ARG(refnum, input); if (!(w = get_window_by_refnum(refnum))) RETURN_EMPTY; GET_STR_ARG(listc, input); len = strlen(listc); #if 0 if (!my_strnicmp(listc, "REFNUM", len)) { } else if (!my_strnicmp(listc, "NAME", len)) { } else if (!my_strnicmp(listc, "SERVER", len)) { } else if (!my_strnicmp(listc, "LAST_SERVER", len)) { } else if (!my_strnicmp(listc, "PRIORITY", len)) { } else if (!my_strnicmp(listc, "TOP", len)) { } else if (!my_strnicmp(listc, "BOTTOM", len)) { } else if (!my_strnicmp(listc, "CURSOR", len)) { } else if (!my_strnicmp(listc, "NOSCROLLCURSOR", len)) { } else if (!my_strnicmp(listc, "FIXED", len)) { } else if (!my_strnicmp(listc, "SCROLL", len)) { } else if (!my_strnicmp(listc, "CHANGE_LINE", len)) { } else if (!my_strnicmp(listc, "OLD_SIZE", len)) { } else if (!my_strnicmp(listc, "UPDATE", len)) { } else if (!my_strnicmp(listc, "MISCFLAGS", len)) { } else if (!my_strnicmp(listc, "BEEP_ALWAYS", len)) { } else if (!my_strnicmp(listc, "NOTIFY_LEVEL", len)) { } else if (!my_strnicmp(listc, "WINDOW_LEVEL", len)) { } else if (!my_strnicmp(listc, "SKIP", len)) { } else if (!my_strnicmp(listc, "COLUMNS", len)) { } else if (!my_strnicmp(listc, "PROMPT", len)) { } else if (!my_strnicmp(listc, "STATUS_FORMAT", len)) { } else if (!my_strnicmp(listc, "STATUS_FORMAT1", len)) { } else if (!my_strnicmp(listc, "STATUS_FORMAT2", len)) { } else if (!my_strnicmp(listc, "STATUS_LINE", len)) { } else if (!my_strnicmp(listc, "STATUS_LINE1", len)) { } else if (!my_strnicmp(listc, "STATUS_LINE2", len)) { } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_SIZE", len)) { } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_MAX", len)) { } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_SIZE", len)) { } else if (!my_strnicmp(listc, "DISPLAY_BUFFER_MAX", len)) { } else if (!my_strnicmp(listc, "SCROLLING_DISTANCE", len)) { } else if (!my_strnicmp(listc, "HOLDING_DISTANCE", len)) { } else if (!my_strnicmp(listc, "SCROLLBACK_DISTANCE", len)) { } else if (!my_strnicmp(listc, "DISPLAY_COUNTER", len)) { } else if (!my_strnicmp(listc, "HOLD_SLIDER", len)) { } else if (!my_strnicmp(listc, "HOLD_INTERVAL", len)) { } else if (!my_strnicmp(listc, "LAST_LINES_HELD", len)) { } else if (!my_strnicmp(listc, "WAITING_CHANNEL", len)) { } else if (!my_strnicmp(listc, "BIND_CHANNEL", len)) { } else if (!my_strnicmp(listc, "QUERY_NICK", len)) { } else if (!my_strnicmp(listc, "NICKLIST", len)) { } else if (!my_strnicmp(listc, "LASTLOG_LEVEL", len)) { } else if (!my_strnicmp(listc, "LASTLOG_SIZE", len)) { } else if (!my_strnicmp(listc, "LASTLOG_MAX", len)) { } else if (!my_strnicmp(listc, "LOGGING", len)) { } else if (!my_strnicmp(listc, "LOGFILE", len)) { } else if (!my_strnicmp(listc, "SWAPPABLE", len)) { } else if (!my_strnicmp(listc, "SCROLLADJ", len)) { } else if (!my_strnicmp(listc, "DECEASED", len)) { } #endif } else RETURN_EMPTY; update_all_status(); update_all_windows(); RETURN_EMPTY; } static int count_fixed_windows (Screen *s) { int count = 0; Window *w; for (w = s->window_list; w; w = w->next) if (w->absolute_size && w->skip) count++; return count; } epic4-2.10.2.orig/source/hook.c0000644000000000000000000011705110755674317013055 0ustar /* $EPIC: hook.c,v 1.27 2008/02/16 23:59:11 jnelson Exp $ */ /* * hook.c: Does those naughty hook functions. * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1993, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "hook.h" #include "ircaux.h" #include "alias.h" #include "window.h" #include "output.h" #include "commands.h" #include "if.h" #include "stack.h" /* * The various ON levels: SILENT means the DISPLAY will be OFF and it will * suppress the default action of the event, QUIET means the display will be * OFF but the default action will still take place, NORMAL means you will be * notified when an action takes place and the default action still occurs, * NOISY means you are notified when an action occur plus you see the action * in the display and the default actions still occurs */ typedef enum NoiseEnum { UNKNOWN = 0, SILENT, QUIET, NORMAL, NOISY } Noise; static const char *noise_level[] = { "UNKNOWN", "SILENT", "QUIET", "NORMAL", "NOISY" }; #define HF_NORECURSE 0x0001 /* Hook: The structure of the entries of the hook functions lists */ typedef struct hook_stru { struct hook_stru *next; char *nick; /* /on type NICK stuff */ char *stuff; /* /on type nick STUFF */ int not; /* /on type ^nick stuff */ Noise noisy; /* /on [^-+]type nick stuff */ int sernum; /* /on #type NUM nick stuff */ /* Default sernum is 0. */ int global; /* set if loaded from `global' */ int flexible; /* on type 'NICK' stuff */ char *filename; /* Where it was loaded */ } Hook; /* * NumericList: a special list type to dynamically handle numeric hook * requests */ typedef struct numericlist_stru { struct numericlist_stru *next; int numeric; char name[4]; Hook *list; char *filename; } NumericList; NumericList *numeric_list = NULL; /* A list of all the hook functions available */ struct { const char *name; /* The name of the hook type */ Hook *list; /* The list of events for type */ int params; /* Number of parameters expected */ int mark; /* Hook type is currently active */ unsigned flags; /* Anything else needed */ } hook_functions[] = { { "ACTION", (Hook *) 0, 3, 0, 0 }, { "CHANNEL_NICK", (Hook *) 0, 3, 0, 0 }, { "CHANNEL_SIGNOFF", (Hook *) 0, 3, 0, 0 }, { "CHANNEL_SYNC", (Hook *) 0, 3, 0, 0 }, { "CONNECT", (Hook *) 0, 2, 0, 0 }, { "CTCP", (Hook *) 0, 4, 0, 0 }, { "CTCP_REPLY", (Hook *) 0, 4, 0, 0 }, { "CTCP_REQUEST", (Hook *) 0, 4, 0, 0 }, { "DCC_ACTIVITY", (Hook *) 0, 1, 0, 0 }, { "DCC_CHAT", (Hook *) 0, 2, 0, 0 }, { "DCC_CONNECT", (Hook *) 0, 2, 0, 0 }, { "DCC_LIST", (Hook *) 0, 8, 0, 0 }, { "DCC_LOST", (Hook *) 0, 2, 0, 0 }, { "DCC_OFFER", (Hook *) 0, 2, 0, 0 }, { "DCC_RAW", (Hook *) 0, 3, 0, 0 }, { "DCC_REQUEST", (Hook *) 0, 4, 0, 0 }, { "DISCONNECT", (Hook *) 0, 1, 0, 0 }, { "ENCRYPTED_NOTICE", (Hook *) 0, 3, 0, 0 }, { "ENCRYPTED_PRIVMSG", (Hook *) 0, 3, 0, 0 }, { "ERROR", (Hook *) 0, 1, 0, 0 }, { "EXEC", (Hook *) 0, 2, 0, 0 }, { "EXEC_ERRORS", (Hook *) 0, 2, 0, 0 }, { "EXEC_EXIT", (Hook *) 0, 3, 0, 0 }, { "EXEC_PROMPT", (Hook *) 0, 2, 0, 0 }, { "EXIT", (Hook *) 0, 1, 0, 0 }, { "FLOOD", (Hook *) 0, 3, 0, 0 }, { "GENERAL_NOTICE", (Hook *) 0, 3, 0, 0 }, { "GENERAL_PRIVMSG", (Hook *) 0, 3, 0, 0 }, { "HELP", (Hook *) 0, 2, 0, 0 }, { "HOOK", (Hook *) 0, 1, 0, 0 }, { "IDLE", (Hook *) 0, 1, 0, 0 }, { "INPUT", (Hook *) 0, 1, 0, HF_NORECURSE }, { "INVITE", (Hook *) 0, 3, 0, 0 }, { "JOIN", (Hook *) 0, 4, 0, 0 }, { "KICK", (Hook *) 0, 3, 0, 0 }, { "KILL", (Hook *) 0, 5, 0, 0 }, { "LEAVE", (Hook *) 0, 2, 0, 0 }, { "LIST", (Hook *) 0, 3, 0, 0 }, { "MAIL", (Hook *) 0, 2, 0, 0 }, { "MODE", (Hook *) 0, 3, 0, 0 }, { "MODE_STRIPPED", (Hook *) 0, 3, 0, 0 }, { "MSG", (Hook *) 0, 2, 0, 0 }, { "MSG_GROUP", (Hook *) 0, 3, 0, 0 }, { "NAMES", (Hook *) 0, 2, 0, 0 }, { "NICKNAME", (Hook *) 0, 2, 0, 0 }, { "NOTE", (Hook *) 0, 3, 0, 0 }, { "NOTICE", (Hook *) 0, 2, 0, 0 }, { "NOTIFY_SIGNOFF", (Hook *) 0, 1, 0, 0 }, { "NOTIFY_SIGNON", (Hook *) 0, 2, 0, 0 }, { "ODD_SERVER_STUFF", (Hook *) 0, 3, 0, 0 }, { "OPER_NOTICE", (Hook *) 0, 2, 0, 0 }, { "PONG", (Hook *) 0, 2, 0, 0 }, { "PUBLIC", (Hook *) 0, 3, 0, 0 }, { "PUBLIC_MSG", (Hook *) 0, 3, 0, 0 }, { "PUBLIC_NOTICE", (Hook *) 0, 3, 0, 0 }, { "PUBLIC_OTHER", (Hook *) 0, 3, 0, 0 }, { "RAW_IRC", (Hook *) 0, 1, 0, 0 }, { "REDIRECT", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_ACTION", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_CTCP", (Hook *) 0, 3, 0, HF_NORECURSE }, { "SEND_DCC_CHAT", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_MSG", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_NOTICE", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_PUBLIC", (Hook *) 0, 2, 0, HF_NORECURSE }, { "SEND_TO_SERVER", (Hook *) 0, 3, 0, HF_NORECURSE }, { "SERVER_ESTABLISHED", (Hook *) 0, 2, 0, 0 }, { "SERVER_LOST", (Hook *) 0, 2, 0, 0 }, { "SERVER_NOTICE", (Hook *) 0, 1, 0, 0 }, { "SET", (Hook *) 0, 2, 0, 0 }, { "SIGNAL", (Hook *) 0, 1, 0, 0 }, { "SIGNOFF", (Hook *) 0, 1, 0, 0 }, { "SILENCE", (Hook *) 0, 2, 0, 0 }, { "SSL_SERVER_CERT", (Hook *) 0, 3, 0, 0 }, { "STATUS_UPDATE", (Hook *) 0, 3, 0, 0 }, { "SWITCH_CHANNELS", (Hook *) 0, 3, 0, 0 }, { "SWITCH_WINDOWS", (Hook *) 0, 4, 0, 0 }, { "TIMER", (Hook *) 0, 1, 0, 0 }, { "TOPIC", (Hook *) 0, 2, 0, 0 }, { "UNLOAD", (Hook *) 0, 1, 0, 0 }, { "WALL", (Hook *) 0, 2, 0, 0 }, { "WALLOP", (Hook *) 0, 3, 0, 0 }, { "WHO", (Hook *) 0, 6, 0, 0 }, { "WIDELIST", (Hook *) 0, 1, 0, 0 }, { "WINDOW", (Hook *) 0, 2, 0, HF_NORECURSE }, { "WINDOW_COMMAND", (Hook *) 0, 1, 0, 0 }, { "WINDOW_CREATE", (Hook *) 0, 1, 0, 0 }, { "WINDOW_BEFOREKILL", (Hook *) 0, 1, 0, 0 }, { "WINDOW_KILL", (Hook *) 0, 2, 0, 0 }, { "YELL", (Hook *) 0, 1, 0, 0 }, }; static void add_to_list (Hook **list, Hook *item); static Hook * remove_from_list (Hook **list, char *item, int sernum); static void add_numeric_list (NumericList *item); static NumericList *find_numeric_list (int numeric); static NumericList *remove_numeric_list (int numeric); /* * This converts a user-specified string of unknown composition and * returns a string that contains at minimum "params" number of words * in it. For any words that are forcibly added on, the last word will * be a * (so it can match any number of words), and any previous words * will be a % (so it forces the correct number of words to be caught.) */ static char * fill_it_out (char *str, int params) { char buffer[BIG_BUFFER_SIZE + 1]; char *arg, *ptr; int i = 0; ptr = LOCAL_COPY(str); *buffer = 0; while ((arg = next_arg(ptr, &ptr)) != NULL) { if (*buffer) strlcat(buffer, " ", sizeof buffer); strlcat(buffer, arg, sizeof buffer); if (++i == params) break; } for (; i < params; i++) strlcat(buffer, (i < params-1) ? " %" : " *", sizeof buffer); if (*ptr) { strlcat(buffer, " ", sizeof buffer); strlcat(buffer, ptr, sizeof buffer); } return malloc_strdup(buffer); } /* * find_hook: returns the numerical value for a specified hook name */ static int find_hook (char *name, int *first) { int which = INVALID_HOOKNUM, i, cnt; size_t len; if (first) *first = -1; if (!name || !(len = strlen(name))) { say("You must specify an event type!"); return INVALID_HOOKNUM; } upper(name); for (cnt = 0, i = 0; i < NUMBER_OF_LISTS; i++) { if (!strncmp(name, hook_functions[i].name, len)) { if (first && *first == -1) *first = i; if (strlen(hook_functions[i].name) == len) { cnt = 1; which = i; break; } else { cnt++; which = i; } } else if (cnt) break; } if (cnt == 0) { if (is_number(name)) { which = atol(name); if ((which < 0) || (which > 999)) { say("Numerics must be between 001 and 999"); return INVALID_HOOKNUM; } which = -which; } else { say("No such ON function: %s", name); return INVALID_HOOKNUM; } } else if (cnt > 1) { say("Ambiguous ON function: %s", name); return INVALID_HOOKNUM; } return which; } /* * * * * ADDING A HOOK * * * * * */ /* * This adds a numeric hook to the numeric hook list. The composition of that * list is a linked list of "numeric holders" which simply indicate the * numeric of that list, and a pointer to the actual list itself. The actual * list itself is just a linked list of events sorted by serial number, then * by "nick". */ static void add_numeric_hook (int numeric, char *nick, char *stuff, int noisy, int not, int sernum, int flexible) { NumericList *entry; Hook *new_h; if (!(entry = find_numeric_list(numeric))) { entry = (NumericList *) new_malloc(sizeof(NumericList)); entry->numeric = numeric; snprintf(entry->name, sizeof(entry->name), "%3.3u", numeric); entry->next = NULL; entry->list = NULL; add_numeric_list(entry); } if (!(new_h = remove_from_list(&entry->list, nick, sernum))) { new_h = (Hook *)new_malloc(sizeof(Hook)); new_h->nick = NULL; new_h->stuff = NULL; new_h->filename = NULL; } malloc_strcpy(&new_h->nick, nick); malloc_strcpy(&new_h->stuff, stuff); new_h->noisy = noisy; new_h->not = not; new_h->sernum = sernum; new_h->flexible = flexible; new_h->global = loading_global; malloc_strcpy(&new_h->filename, current_package()); new_h->next = NULL; upper(new_h->nick); add_to_list(&entry->list, new_h); } /* * add_hook: Given an index into the hook_functions array, this adds a new * entry to the list as specified by the rest of the parameters. The new * entry is added in alphabetical order (by nick). */ static void add_hook (int which, char *nick, char *stuff, int noisy, int not, int sernum, int flexible) { Hook *new_h; if (which < 0) { add_numeric_hook(-which, nick, stuff, noisy, not, sernum, flexible); return; } if (!(new_h = remove_from_list(&hook_functions[which].list, nick, sernum))) { new_h = (Hook *)new_malloc(sizeof(Hook)); new_h->nick = NULL; new_h->stuff = NULL; new_h->filename = NULL; } malloc_strcpy(&new_h->nick, nick); malloc_strcpy(&new_h->stuff, stuff); new_h->noisy = noisy; new_h->not = not; new_h->sernum = sernum; new_h->flexible = flexible; new_h->global = loading_global; malloc_strcpy(&new_h->filename, current_package()); new_h->next = NULL; upper(new_h->nick); add_to_list(&hook_functions[which].list, new_h); } /* * * * * * REMOVING A HOOK * * * * * * * */ static void remove_numeric_hook (int numeric, char *nick, int sernum, int quiet) { NumericList *hook; Hook *tmp, *next; if ((hook = find_numeric_list(numeric))) { if (nick) { if ((tmp = remove_from_list(&hook->list, nick, sernum))) { if (!quiet) { say("%c%s%c removed from %d list", (tmp->flexible?'\'':'"'), nick, (tmp->flexible?'\'':'"'), numeric); } new_free(&(tmp->nick)); new_free(&(tmp->stuff)); new_free(&(tmp->filename)); new_free((char **)&tmp); if (!hook->list) { if ((hook = remove_numeric_list(numeric))) new_free((char **)&hook); } return; } } else { remove_numeric_list(numeric); for (tmp = hook->list; tmp; tmp = next) { next = tmp->next; tmp->not = 1; new_free(&(tmp->nick)); new_free(&(tmp->stuff)); new_free(&(tmp->filename)); new_free((char **)&tmp); } hook->list = (Hook *) 0; new_free((char **)&hook); if (!quiet) say("The %d list is empty", numeric); return; } } if (quiet) return; if (nick) say("\"%s\" is not on the %d list", nick, numeric); else say("The %d list is empty", numeric); } static void remove_hook (int which, char *nick, int sernum, int quiet) { Hook *tmp, *next; if (which < 0) { remove_numeric_hook(-which, nick, sernum, quiet); return; } if (nick) { if ((tmp = remove_from_list(&hook_functions[which].list, nick, sernum))) { if (!quiet) say("%c%s%c removed from %s list", (tmp->flexible?'\'':'"'), nick, (tmp->flexible?'\'':'"'), hook_functions[which].name); new_free(&(tmp->nick)); new_free(&(tmp->stuff)); new_free(&(tmp->filename)); tmp->next = NULL; new_free((char **)&tmp); /* XXX why? */ } else if (!quiet) say("\"%s\" is not on the %s list", nick, hook_functions[which].name); } else { Hook *prev = NULL; Hook *top = NULL; top = hook_functions[which].list; for (tmp = top; tmp; tmp = next) { next = tmp->next; /* * If given a non-zero sernum, then we clean out * only those hooks that are at that level. */ if (sernum && tmp->sernum != sernum) { prev = tmp; continue; } if (prev) prev->next = tmp->next; else top = tmp->next; tmp->not = 1; new_free(&(tmp->nick)); new_free(&(tmp->stuff)); new_free(&(tmp->filename)); tmp->next = NULL; new_free((char **)&tmp); } hook_functions[which].list = top; if (!quiet) { if (sernum) say("The %s <%d> list is empty", hook_functions[which].name, sernum); else say("The %s list is empty", hook_functions[which].name); } } } /* Used to bulk-erase all of the currently scheduled ONs */ void flush_on_hooks (void) { int x; int old_display = window_display; window_display = 0; for (x = 1; x < 999; x++) remove_numeric_hook(x, NULL, x, 1); for (x = 0; x < NUMBER_OF_LISTS; x++) remove_hook(x, NULL, 0, 1); window_display = old_display; } void unload_on_hooks (char *filename) { int x; NumericList *tmp; Hook *list, *next; int old_display = window_display; window_display = 0; for (x = 1; x < 999; x++) { if ((tmp = find_numeric_list(x))) { for (list = tmp->list; list; list = next) { next = list->next; if (!strcmp(list->filename, filename)) remove_numeric_hook(x, list->nick, list->sernum, 1); } } } for (x = 0; x < NUMBER_OF_LISTS; x++) { for (list = hook_functions[x].list; list; list = next) { next = list->next; if (!strcmp(list->filename, filename)) remove_hook(x, list->nick, list->sernum, 1); } } window_display = old_display; } /* * * * * * SHOWING A HOOK * * * * * * */ /* show_hook shows a single hook */ static void show_hook (Hook *list, const char *name) { say("[%s] On %s from %c%s%c do %s [%s] <%d>", list->filename[0] ? list->filename : "*", name, (list->flexible?'\'':'"'), list->nick, (list->flexible?'\'':'"'), (list->not ? "nothing" : list->stuff), noise_level[list->noisy], list->sernum); } /* * show_numeric_list: If numeric is 0, then all numeric lists are displayed. * If numeric is non-zero, then that particular list is displayed. The total * number of entries displayed is returned */ static int show_numeric_list (int numeric) { NumericList *tmp; Hook *list; char buf[4]; int cnt = 0; if (numeric) { snprintf(buf, sizeof buf, "%3.3u", numeric); if ((tmp = find_numeric_list(numeric))) { for (list = tmp->list; list; list = list->next, cnt++) show_hook(list, tmp->name); } } else { for (tmp = numeric_list; tmp; tmp = tmp->next) { for (list = tmp->list; list; list = list->next, cnt++) show_hook(list, tmp->name); } } return (cnt); } /* * show_list: Displays the contents of the list specified by the index into * the hook_functions array. This function returns the number of entries in * the list displayed */ static int show_list (int which) { Hook *list; int cnt = 0; /* Less garbage when issueing /on without args. (lynx) */ for (list = hook_functions[which].list; list; list = list->next, cnt++) show_hook(list, hook_functions[which].name); return (cnt); } /* * * * * * * * EXECUTING A HOOK * * * * * * */ #define NO_ACTION_TAKEN -1 #define SUPPRESS_DEFAULT 0 #define DONT_SUPPRESS_DEFAULT 1 #define RESULT_PENDING 2 /* * do_hook: This is what gets called whenever a MSG, INVITES, WALL, (you get * the idea) occurs. The nick is looked up in the appropriate list. If a * match is found, the stuff field from that entry in the list is treated as * if it were a command. First it gets expanded as though it were an alias * (with the args parameter used as the arguments to the alias). After it * gets expanded, it gets parsed as a command. This will return as its value * the value of the noisy field of the found entry, or -1 if not found. */ /* huh-huh.. this sucks.. im going to re-write it so that it works */ int do_hook (int which, const char *format, ...) { Hook *tmp, **list; char buffer [BIG_BUFFER_SIZE * 10 + 1]; const char *name = (char *) 0; int retval = DONT_SUPPRESS_DEFAULT; unsigned display = window_display; int i; Hook *hook_array [2048]; int hook_num = 0; /* * Figure out where the hooks are for the event type were asserting */ /* Numeric list */ if (which < 0) { NumericList *hook; if ((hook = find_numeric_list(-which))) { name = hook->name; list = &hook->list; } else list = (Hook **) 0; } /* Named list */ else { /* * If we're already executing the type, and we're * specifically not supposed to allow recursion, then * dont allow recursion. ;-) */ if (hook_functions[which].mark && (hook_functions[which].flags & HF_NORECURSE)) list = (Hook **) 0; else { list = &(hook_functions[which].list); name = hook_functions[which].name; } } /* * No hooks to look at? No problem. Drop out. */ if (!list) return NO_ACTION_TAKEN; /* * Press the buffer using the specified format string and args * We do this here so that we dont waste time doing the vsnprintf * if we're not going to do any matching. So for types where the * user has no hooks, its a cheapie call. */ if (format) { va_list args; va_start (args, format); vsnprintf(buffer, BIG_BUFFER_SIZE * 10, format, args); va_end(args); } else panic("do_hook: format is NULL"); /* * Mark the event as being executed. This is used to suppress * unwanted recursion in some /on's. */ if (which >= 0) hook_functions[which].mark++; /* not attached, so dont "fix" it */ { int currser = 0, oldser = INT_MIN, currmatch = 0, oldmatch = 0; Hook * bestmatch = (Hook *) 0; /* * Walk the list of hooks for this event */ for (tmp = *list; tmp; tmp = tmp->next) { char * tmpnick = (char *) 0; int sa; /* * save the current serial number */ currser = tmp->sernum; /* * Is this a different serial number than the * last hook? If it is, then we save the previous * serial number's best hook to the hook_array. */ if (currser != oldser) { /* * This would happen if the list is out * of order. This probably should not be * fatal, but it is probably irrecoverable. * It needs to be trapped and fixed. */ if (currser < oldser) panic("currser [%d] is less than oldser [%d]", currser, oldser); oldser = currser; currmatch = oldmatch = 0; if (bestmatch) hook_array[hook_num++] = bestmatch; bestmatch = (Hook *) 0; } /* * If this is a flexible hook, expand the nick stuff */ if (tmp->flexible) /* * XXX Something ought to be done here * with current_window, but ick, how? */ tmpnick = expand_alias(tmp->nick, empty_string, &sa, NULL); else tmpnick = tmp->nick; /* * Check to see if the pattern matches the text */ currmatch = wild_match(tmpnick, buffer); /* * If it is the "best match" so far, then we mark * its "value" and save a pointer to it. */ if (currmatch > oldmatch) { oldmatch = currmatch; bestmatch = tmp; } /* * Clean up after flexible hooks */ if (tmp->flexible) new_free(&tmpnick); } /* * Ok. we've walked the list. If the last hook had a best * match, use that one too. =) */ if (bestmatch) hook_array[hook_num++] = bestmatch; } /* * Now we walk the list of collected hook events that are to be run */ for (i = 0; i < hook_num; i++) { const char * saved_who_from; int saved_who_level; char * name_copy; char * stuff_copy; char * result = NULL; int noise, old; /* * This should never happen. */ if (!(tmp = hook_array[i])) panic("hook_array[%d] is null", i); /* * Check to see if this hook is supposed to supress the * default action for the event. */ if (tmp->noisy == SILENT && tmp->sernum == 0) retval = SUPPRESS_DEFAULT; else if (tmp->noisy == UNKNOWN && tmp->sernum == 0) retval = RESULT_PENDING; /* * If this is a negated event, or there isnt anything to be * executed, then we dont bother. Just go on to the next one */ if (tmp->not || !tmp->stuff || !*tmp->stuff) continue; name_copy = LOCAL_COPY(name); stuff_copy = LOCAL_COPY(tmp->stuff); noise = tmp->noisy; /* * If this is a NORMAL or NOISY hook, then we tell the user * that we're going to execute the hook. */ if (tmp->noisy > QUIET) say("%s activated by %c%s%c", name, tmp->flexible ? '\'' : '"', buffer, tmp->flexible ? '\'' : '"'); /* * YOU CAN'T TOUCH ``tmp'' AFTER THIS POINT */ /* * Save some information that may be reset in the * execution, turn off the display if the user specified. */ save_message_from(&saved_who_from, &saved_who_level); if (noise < NOISY) window_display = 0; old = system_exception; if (retval == RESULT_PENDING) { result = call_lambda_function(name_copy, stuff_copy, buffer); if (result && atol(result)) retval = SUPPRESS_DEFAULT; else retval = DONT_SUPPRESS_DEFAULT; new_free(&result); } else { /* * Ok. Go and run the code. It is imperitive to note * that "tmp" may be deleted by the code executed here, * so it is absolutely forbidden to reference "tmp" * after this point. */ will_catch_return_exceptions++; parse_line(name_copy, stuff_copy, buffer, 0, 0); will_catch_return_exceptions--; return_exception = 0; } /* * Clean up the stuff that may have been mangled by the * execution. */ system_exception = old; window_display = display; restore_message_from(saved_who_from, saved_who_level); } /* * Mark the event as not currently being done here. */ if (which >= 0) hook_functions[which].mark--; /* * And return the user-specified suppression level */ return retval; } /* * shook: the SHOOK command -- this probably doesnt belong here, * and shook is probably a stupid name. It simply asserts a fake * hook event for a given type. Fraught with peril! */ BUILT_IN_COMMAND(shookcmd) { int which; char *arg = next_arg(args, &args); if ((which = find_hook(arg, NULL)) == INVALID_HOOKNUM) return; else do_hook(which, "%s", args); } /* * * * * * SCHEDULING AN EVENT * * * * * * * */ /* * The ON command: * Format: /ON [#][+-^]TYPE ['] [SERNUM] NICK ['] [{] STUFF [}] * * The "ON" command mainly takes three arguments. The first argument * is the "type" of callback that you want to schedule. This is either * a three digit number, of it is one of the strings so enumerated at the * top of this file in hook_list. The second argument is the "nick" or * "pattern" that is to be used to match against future events. If the * "nick" matches the text that is later passed to do_hook() with the given * "type", then the commands in "stuff" will be executed. * * If "nick" is enclosed in single quotes ('), then it is a "flexible" * pattern, and will be expanded before it is matched against the text * in do_hook. Otherwise, the string so specified is "static", and is * used as-is in do_hook(). * * Within each type, there are at least 65,535 different "serial numbers", * (there actually are MAX_INT of them, but by convention, only 16 bit * serial numbers are used, from -32,768 to 32,767) which may be used to * schedule any number of events at the given serial number. * * Each time an assertion occurs for a given "type", at most one of the * scheduled events is executed for each of the distinct serial numbers that * are in use for that event. The event to be executed is the one at a * given serial number that "best" matches the text passed to do_hook(). * While in theory, up to MAX_INT events could be executed for a given single * assertion, in practice, a hard limit of 2048 events per assertion is * enforced. * * The runtime behavior of the event being scheduled can be modified by * specifying a character at the beginning of the "type" argument. If you * want to schedule an event at a serial number, then the first character * must be a hash (#). The argument immediately FOLLOWING the "type" * argument, and immediately PRECEEDING the "nick" argument must be an * integer number, and is used for the serial number for this event. * * The "verbosity" of the event may also be modified by specifying at most * one of the following characters: * A caret (^) is the SILENT level, and indicates that the event is to * be executed with no output (window_display is turned off), * and the "default action" (whatever that is) for the event is * to be suppressed. The default action is actually only * suppressed if the SILENT level is specified for serial number * zero. This is the most common level used for overriding the * output of most /on's. * A minus (-) is the QUIET level, and is the same as the SILENT level, * except that the default action (whatever that is) is not to * be suppressed. * No character is the "normal" case, and is the same as the "minus" * level, with the addition that the client will inform you that * the event was executed. This is useful for debugging. * A plus (+) is the same as the "normal" (no character specified), * except that the output is not suppressed (window_display is * not changed.) */ BUILT_IN_COMMAND(oncmd) { char *func, *nick, *serial = NULL; Noise noisy = NORMAL; int not = 0, sernum = 0, rem = 0, which = INVALID_HOOKNUM; int flex = 0; char type; int first; /* * Get the type of event to be scheduled */ if ((func = next_arg(args, &args)) != NULL) { /* * Check to see if this has a serial number. */ if (*func == '#') { if (!(serial = next_arg(args, &args))) { say("No serial number specified"); return; } sernum = atol(serial); func++; } /* * Get the verbosity level, if any. */ switch (*func) { case '?': noisy = UNKNOWN; func++; break; case '-': noisy = QUIET; func++; break; case '^': noisy = SILENT; func++; break; case '+': noisy = NOISY; func++; break; default: noisy = NORMAL; break; } /* * Check to see if the event type is valid */ if ((which = find_hook(func, &first)) == INVALID_HOOKNUM) { /* * Ok. So either the user specified an invalid type * or they specified an ambiguous type. Either way, * we're not going to be going anywhere. So we have * free reign to mangle 'args' at this point. */ int len; /* * If first is -1, then it was an unknown type. * An error has already been output, just return here */ if (first == -1) return; /* * Otherwise, its an ambiguous type. If they were * trying to register the hook, then they've already * gotten the error message, just return; */ if (new_new_next_arg_count(args, &args, &type, 1)) return; /* * Ok. So they probably want a listing. */ len = strlen(func); while (!my_strnicmp(func, hook_functions[first].name, len)) { if (!show_list(first)) say("The %s list is empty.", hook_functions[first].name); first++; } return; } /* * If sernum is 0 and serial is "+" or "-" get a serial * number for the event type in question */ if (sernum == 0 && serial != NULL) { if (!strcmp(serial, "+")) sernum = hook_find_free_serial(1, 0, which); else if (!strcmp(serial, "-")) sernum = hook_find_free_serial(-1, 0, which); } /* * Check to see if this is a removal event or if this * is a negated event. */ switch (*args) { case '-': rem = 1; args++; break; case '^': not = 1; args++; break; } /* * Grab the "nick" */ if ((nick = new_new_next_arg_count(args, &args, &type, 1))) { char *exp; /* * Pad it to the appropriate number of args */ if (which < 0) nick = fill_it_out(nick, 1); else nick = fill_it_out(nick, hook_functions[which].params); /* * If nick is empty, something is very wrong. */ if (!*nick) { say("No expression specified"); new_free(&nick); return; } /* * If we're doing a removal, do the deed. */ if (rem) { remove_hook(which, nick, sernum, 0); new_free(&nick); return; } /* * Take a note if its flexible or not. */ if (type == '\'') flex = 1; else flex = 0; /* * If this is a negative event, then we dont want * to take any action for it. */ if (not) args = empty_string; /* * Slurp up any whitespace after the nick */ while (my_isspace(*args)) args++; /* * Then slurp up the body ("text") */ if (*args == '{') /* } */ { if (!(exp = next_expr(&args, '{'))) /* } */ { say("Unmatched brace in ON"); new_free(&nick); return; } } else exp = args; /* * Schedule the event */ add_hook(which, nick, exp, noisy, not, sernum, flex); /* * Tell the user that we're done. */ if (which < 0) say("On %3.3u from %c%s%c do %s [%s] <%d>", -which, type, nick, type, (not ? "nothing" : exp), noise_level[noisy], sernum); else say("On %s from %c%s%c do %s [%s] <%d>", hook_functions[which].name, type, nick, type, (not ? "nothing" : exp), noise_level[noisy], sernum); /* * Clean up after the nick */ new_free(&nick); } /* * No "nick" argument was specified. That means the user * either is deleting all of the events of a type, or it * wants to list all the events of a type. */ else { /* * if its a removal, do the deed */ if (rem) { remove_hook(which, (char *) 0, sernum, 0); return; } /* * The help files say that an "/on 0" shows all * of the numeric ONs. Since the ACTION hook is * number 0, we have to check to see if the first * character of "func" is a zero or not. If it is, * we output all of the numeric functions. */ if (*func == '0') { if (!show_numeric_list(0)) say("All numeric ON lists are empty."); } else if (which < 0) { if (!show_numeric_list(-which)) say("The %3.3u list is empty.", -which); } else if (!show_list(which)) say("The %s list is empty.", hook_functions[which].name); } } /* * No "Type" argument was specified. That means the user wants to * list all of the ONs currently scheduled. */ else { int total = 0; say("ON listings:"); /* * Show the named events */ for (which = 0; which < NUMBER_OF_LISTS; which++) total += show_list(which); /* * Show the numeric events */ total += show_numeric_list(0); if (!total) say("All ON lists are empty."); } } /* * * * * * * * * * SAVING A HOOK * * * * * * * * * * */ static void write_hook (FILE *fp, Hook *hook, const char *name) { const char *stuff = (char *) 0; char flexi = '"'; if (hook->flexible) flexi = '\''; switch (hook->noisy) { case SILENT: stuff = "^"; break; case QUIET: stuff = "-"; break; case NORMAL: stuff = empty_string; break; case NOISY: stuff = "+"; break; case UNKNOWN: stuff = "?"; break; } if (hook->sernum) fprintf(fp, "ON #%s%s %d", stuff, name, hook->sernum); else fprintf(fp, "ON %s%s", stuff, name); fprintf(fp, " %c%s%c {%s}\n", flexi, hook->nick, flexi, hook->stuff); } /* * save_hooks: for use by the SAVE command to write the hooks to a file so it * can be interpreted by the LOAD command */ void save_hooks (FILE *fp, int do_all) { Hook *list; NumericList *numeric; int which; for (which = 0; which < NUMBER_OF_LISTS; which++) { for (list = hook_functions[which].list; list; list = list->next) if (!list->global || do_all) write_hook(fp,list, hook_functions[which].name); } for (numeric = numeric_list; numeric; numeric = numeric->next) { for (list = numeric->list; list; list = list->next) if (!list->global) write_hook(fp, list, numeric->name); } } /* * * * * * * * * * STACKING A HOOK * * * * * * * * */ typedef struct onstacklist { int which; Hook *list; struct onstacklist *next; } OnStack; static OnStack * on_stack = NULL; void do_stack_on (int type, char *args) { int which; Hook *list; NumericList *nhook = NULL, *nptr; if (!on_stack && (type == STACK_POP || type == STACK_LIST)) { say("ON stack is empty!"); return; } if (!args || !*args) { say("Missing event type for STACK ON"); return; } if ((which = find_hook(args, NULL)) == INVALID_HOOKNUM) return; /* Error message already outputted */ if (which < 0) { if ((nhook = find_numeric_list(-which))) list = nhook->list; else list = NULL; } else list = hook_functions[which].list; if (type == STACK_PUSH) { OnStack *new_os; new_os = (OnStack *) new_malloc(sizeof(OnStack)); new_os->which = which; new_os->list = list; new_os->next = on_stack; on_stack = new_os; if (which < 0) { if (nhook && numeric_list) remove_numeric_list(-which); } else hook_functions[which].list = NULL; return; } else if (type == STACK_POP) { OnStack *p, *tmp = (OnStack *) 0; for (p = on_stack; p; tmp = p, p = p->next) { if (p->which == which) { if (p == on_stack) on_stack = p->next; else tmp->next = p->next; break; } } if (!p) { say("No %s on the stack", args); return; } if ((which < 0 && nhook) || (which >= 0 && hook_functions[which].list)) remove_hook(which, NULL, 0, 1); /* free hooks */ if (which < 0) { /* look -- do we have any hooks already for this numeric? */ if (!(nptr = find_numeric_list(-which))) { if (p->list) /* not just a placeholder? */ { /* No. make a new list and put the stack on it */ nptr = (NumericList *) new_malloc(sizeof(NumericList)); nptr->list = p->list; nptr->next = NULL; nptr->numeric = -which; snprintf(nptr->name, sizeof(nptr->name), "%3.3u", -which); add_numeric_list(nptr); } } else { remove_hook(which, NULL, 0, 1); nptr->list = p->list; } } else hook_functions[which].list = p->list; new_free((char **)&p); return; } else if (type == STACK_LIST) { int slevel = 0; OnStack *osptr; for (osptr = on_stack; osptr; osptr = osptr->next) { if (osptr->which == which) { Hook *hptr; slevel++; say("Level %d stack", slevel); for (hptr = osptr->list; hptr; hptr = hptr->next) show_hook(hptr, args); } } if (!slevel) say("The STACK ON %s list is empty", args); return; } say("Unknown STACK ON type ??"); } /* List manips especially for on's. */ static void add_to_list (Hook **list, Hook *item) { Hook *tmp, *last = NULL; for (tmp = *list; tmp; last = tmp, tmp = tmp->next) { if (tmp->sernum < item->sernum) continue; else if ((tmp->sernum == item->sernum) && (my_stricmp(tmp->nick, item->nick) < 0)) continue; else break; } if (last) { item->next = last->next; last->next = item; } else { item->next = *list; *list = item; } } static Hook *remove_from_list (Hook **list, char *item, int sernum) { Hook *tmp, *last = NULL; for (tmp = *list; tmp; last = tmp, tmp = tmp->next) { if (tmp->sernum == sernum && !my_stricmp(tmp->nick, item)) { if (last) last->next = tmp->next; else *list = tmp->next; return tmp; } } return NULL; } static void add_numeric_list (NumericList *item) { NumericList *tmp, *last = NULL; for (tmp = numeric_list; tmp; last = tmp, tmp = tmp->next) { if (tmp->numeric > item->numeric) break; } if (last) { last->next = item; item->next = tmp; } else { item->next = numeric_list; numeric_list = item; } } static NumericList *find_numeric_list (int numeric) { NumericList *tmp, *last = NULL; for (tmp = numeric_list; tmp; last = tmp, tmp = tmp->next) { if (tmp->numeric == numeric) return tmp; } return NULL; } static NumericList *remove_numeric_list (int numeric) { NumericList *tmp, *last = NULL; for (tmp = numeric_list; tmp; last = tmp, tmp = tmp->next) { if (tmp->numeric == numeric) break; } if (last) last->next = tmp->next; else numeric_list = numeric_list->next; return tmp; } /* this function traverses all the hooks for all the events in the system * trying to find a free serial number (one that is unused by any hook on * any event) in the direction given (either -1 or +1 for - and +) starting * at the given point. */ int hook_find_free_serial(int dir, int from, int which) { int ser; Hook *hp; NumericList *nlp; int wc; if (from == 0) from = dir; /* We iterate through the specified (or all) lists looking for a serial * number that isn't in use. If we make it through all of our loops * without breaking out of them, we have found an unused number */ for (ser = from; (dir > 0 ? ser <= 32767 : ser >= -32767); ser += dir) { if (which != INVALID_HOOKNUM) { /* a list was specified */ if (which < 0) { if ((nlp = find_numeric_list(-which)) != NULL) hp = nlp->list; else /* the numeric list doesn't exist. this must be unique */ return ser; } else hp = hook_functions[which].list; while (hp != NULL) { if (hp->sernum == ser) break; hp = hp->next; } if (hp == NULL) break; } else { /* no list was specified. start digging */ hp = NULL; for (wc = 0; wc < NUMBER_OF_LISTS; wc++) { for (hp = hook_functions[wc].list; hp != NULL; hp = hp->next) if (hp->sernum == ser) break; if (hp != NULL) break; } if (hp != NULL) continue; /* found a used one.. */ hp = NULL; for (nlp = numeric_list; nlp != NULL; nlp = nlp->next) { for (hp = nlp->list; hp != NULL; hp = hp->next) if (hp->sernum == ser) continue; } if (hp == NULL) break; /* found an unused one */ } } return ser; } epic4-2.10.2.orig/source/logfiles.c0000644000000000000000000005360110226237441013703 0ustar /* $EPIC: logfiles.c,v 1.24 2005/04/10 14:58:41 jnelson Exp $ */ /* * logfiles.c - General purpose log files * * Copyright © 2002 EPIC Software Labs * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "log.h" #include "vars.h" #include "output.h" #include "ircaux.h" #include "alias.h" #include "list.h" #include "server.h" #include "window.h" #include "functions.h" #define MAX_TARGETS 32 #define LOG_TARGETS 0 #define LOG_WINDOWS 1 #define LOG_SERVERS 2 static const char *onoff[] = { "OFF", "ON" }; static const char *logtype[] = { "TARGETS", "WINDOWS", "SERVERS" }; struct Logfile { struct Logfile *next; int refnum; char * name; char * filename; FILE * log; int servref; int type; WNickList *targets; int refnums[MAX_TARGETS]; int level; char * rewrite; int mangler; char * mangle_desc; int active; time_t activity; }; typedef struct Logfile Logfile; Logfile *logfiles = NULL; int logref = 0; static Logfile * new_logfile (void) { Logfile *log; int i; log = (Logfile *)new_malloc(sizeof(Logfile)); log->next = logfiles; log->refnum = ++logref; log->name = malloc_sprintf(NULL, "%d", log->refnum); log->filename = NULL; log->log = NULL; log->servref = from_server; log->type = LOG_TARGETS; log->targets = NULL; for (i = 0; i < MAX_TARGETS; i++) log->refnums[i] = -1; log->level = LOG_ALL; log->rewrite = NULL; log->mangler = 0; log->mangle_desc = NULL; log->active = 0; time(&log->activity); logfiles = log; return log; } static void delete_logfile (Logfile *log) { Logfile *prev; WNickList *next; if (log == logfiles) logfiles = log->next; else { for (prev = logfiles; prev; prev = prev->next) if (prev->next == log) break; prev->next = log->next; } new_free(&log->name); if (log->active) do_log(0, log->filename, &log->log); new_free(&log->filename); while (log->targets) { next = log->targets->next; new_free(&log->targets->nick); new_free((char **)&log->targets); log->targets = next; } new_free(&log->rewrite); new_free(&log->mangle_desc); } static Logfile * get_log_by_desc (const char *desc) { Logfile *log; if (is_number(desc)) { int number = atol(desc); for (log = logfiles; log; log = log->next) if (log->refnum == number) return log; } else { for (log = logfiles; log; log = log->next) if (!my_stricmp(log->name, desc)) return log; } return NULL; } static int is_logfile_name_unique (const char *desc) { Logfile *log; for (log = logfiles; log; log = log->next) if (!my_stricmp(log->name, desc)) return 0; return 1; } static void clean_log_targets (Logfile *log) { int i; WNickList *next; for (i = 0; i < MAX_TARGETS; i++) log->refnums[i] = -1; while (log->targets) { next = log->targets->next; new_free(&log->targets->nick); new_free((char **)&log->targets); log->targets = next; } } static char *logfile_get_targets (Logfile *log) { WNickList *tmp; char *nicks = NULL; int i; if (log->type == LOG_TARGETS) { for (tmp = log->targets; tmp; tmp = tmp->next) malloc_strcat_wordlist(&nicks, ",", tmp->nick); } else if (log->type == LOG_SERVERS || log->type == LOG_WINDOWS) { for (i = 0; i < MAX_TARGETS; i++) if (log->refnums[i] != -1) malloc_strcat_wordlist(&nicks, ",", ltoa(log->refnums[i])); } return nicks; } /************************************************************************/ typedef Logfile *(*logfile_func) (Logfile *, char **); static Logfile *logfile_activity (Logfile *log, char **args); static Logfile *logfile_add (Logfile *log, char **args); static Logfile *logfile_describe (Logfile *log, char **args); static Logfile *logfile_filename (Logfile *log, char **args); static Logfile *logfile_kill (Logfile *log, char **args); static Logfile *logfile_list (Logfile *log, char **args); static Logfile *logfile_mangle (Logfile *log, char **args); static Logfile *logfile_name (Logfile *log, char **args); static Logfile *logfile_new (Logfile *log, char **args); static Logfile *logfile_off (Logfile *log, char **args); static Logfile *logfile_on (Logfile *log, char **args); static Logfile *logfile_refnum (Logfile *log, char **args); static Logfile *logfile_remove (Logfile *log, char **args); static Logfile *logfile_rewrite (Logfile *log, char **args); static Logfile *logfile_type (Logfile *log, char **args); static Logfile * logfile_activity (Logfile *log, char **args) { if (!log) { say("ACTIVITY: You need to specify a logfile first"); return NULL; } time(&log->activity); return log; } static Logfile * logfile_add (Logfile *log, char **args) { char *ptr; WNickList *new_w; char *arg = next_arg(*args, args); int i; if (!log) { say("ADD: You need to specify a logfile first"); return NULL; } if (!arg) say("ADD: Add nicknames/channels to be logged to this file"); else while (arg) { if ((ptr = strchr(arg, ','))) *ptr++ = 0; if (log->type == LOG_TARGETS) { if (!find_in_list((List **)&log->targets, arg, !USE_WILDCARDS)) { say("Added %s to log name list", arg); new_w = (WNickList *)new_malloc(sizeof(WNickList)); new_w->nick = malloc_strdup(arg); add_to_list((List **)&(log->targets), (List *)new_w); } else say("%s already on log name list", arg); } else if (log->type == LOG_SERVERS || log->type == LOG_WINDOWS) { int refnum = my_atol(arg); for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == refnum) { say("%s already on log refnum list", arg); break; } } for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == -1) { say("Added %d to log name list", refnum); log->refnums[i] = refnum; break; } } if (i >= MAX_TARGETS) say("Could not add %d to log name list!", refnum); } arg = ptr; } return log; } static Logfile * logfile_describe (Logfile *log, char **args) { char *targets = NULL; if (!log) { say("DESCRIBE: You need to specify a logfile first"); return NULL; } targets = logfile_get_targets(log); say(" Logfile refnum %d is %s", log->refnum, onoff[log->active]); say("\t Logical name: %s", log->name); say("\t Filename: %s", log->filename ? log->filename : ""); say("\t Type: %s", logtype[log->type]); say("\t Server: %d", log->servref); say("\tTarget/Refnum: %s", targets ? targets : ""); say("\t Level: %s", bits_to_lastlog_level(log->level)); say("\t Rewrite Rule: %s", log->rewrite ? log->rewrite : ""); say("\t Mangle rules: %s", log->mangle_desc ? log->mangle_desc : ""); new_free(&targets); return log; } static Logfile * logfile_filename (Logfile *log, char **args) { char * arg = next_arg(*args, args); if (!log) { say("FILENAME: You need to specify a logfile first"); return NULL; } if (!arg) { if (log->filename) say("Log %s is attached to %s", log->name, log->filename); else say("Log %s does not have a filename", log->name); return log; } if (log->active) logfile_off(log, NULL); malloc_strcpy(&log->filename, arg); if (log->active) logfile_on(log, NULL); return log; } static Logfile * logfile_kill (Logfile *log, char **args) { if (!log) { say("KILL: You need to specify a logfile first"); return NULL; } delete_logfile(log); return NULL; } static Logfile * logfile_level (Logfile *log, char **args) { char *arg = new_next_arg(*args, args); if (!log) { say("LEVEL: You need to specify a logfile first"); return NULL; } log->level = parse_lastlog_level(arg); return log; } static Logfile * logfile_list (Logfile *log, char **args) { Logfile *l; char *targets = NULL; say("Logfiles:"); for (l = logfiles; l; l = l->next) { targets = logfile_get_targets(l); say("Log %2d [%s] logging %s is %s, file %s server %d targets %s", l->refnum, l->name, logtype[l->type], onoff[l->active], l->filename ? l->filename : "", l->servref, targets ? targets : ""); new_free(&targets); } return log; } static Logfile * logfile_mangle (Logfile *log, char **args) { char * arg = next_arg(*args, args); if (!log) { say("MANGLE: You need to specify a logfile first"); return NULL; } if (!arg) say("MANGLE: This logfile mangles %s", log->mangle_desc); else { new_free(&log->mangle_desc); log->mangler = parse_mangle(arg, log->mangler, &log->mangle_desc); say("MANGLE: Now mangling %s", log->mangle_desc); } return log; } static Logfile * logfile_name (Logfile *log, char **args) { char *arg; if (!log) { say("NAME: You need to specify a logfile first"); return NULL; } if (!(arg = next_arg(*args, args))) say("You must specify a name for the logfile!"); else { /* /log name - unsets the window name */ if (!strcmp(arg, "-")) new_free(&log->name); /* /log name to existing name -- ignore this. */ else if (log->name && (my_stricmp(log->name, arg) == 0)) return log; else if (is_logfile_name_unique(arg)) malloc_strcpy(&log->name, arg); else say("%s is not unique!", arg); } return log; } static Logfile * logfile_new (Logfile *log, char **args) { return new_logfile(); } static Logfile * logfile_off (Logfile *log, char **args) { if (!log) { say("OFF: You need to specify a logfile first"); return NULL; } if (!log->filename) { say("OFF: You need to specify a filename for this log first"); return log; } time(&log->activity); do_log(0, log->filename, &log->log); log->active = 0; return log; } static Logfile * logfile_on (Logfile *log, char **args) { if (!log) { say("ON: You need to specify a logfile first"); return NULL; } if (!log->filename) { say("ON: You need to specify a filename for this log first"); return log; } time(&log->activity); do_log(1, log->filename, &log->log); log->active = 1; return log; } static Logfile * logfile_refnum (Logfile *log, char **args) { char *arg = next_arg(*args, args); log = get_log_by_desc(arg); return log; } static Logfile * logfile_remove (Logfile *log, char **args) { char *arg = next_arg(*args, args); char *ptr; WNickList *new_nl; int i; if (!log) { say("REMOVE: You need to specify a logfile first"); return NULL; } if (!arg) say("Remove: Remove nicknames/channels logged to this file"); else while (arg) { if ((ptr = strchr(arg, ',')) != NULL) *ptr++ = 0; if (log->type == LOG_TARGETS) { if ((new_nl = (WNickList *)remove_from_list((List **)&(log->targets), arg))) { say("Removed %s from log target list", new_nl->nick); new_free(&new_nl->nick); new_free((char **)&new_nl); } else say("%s is not on the list for this log!", arg); } else if (log->type == LOG_SERVERS || log->type == LOG_WINDOWS) { int refnum = my_atol(ptr); for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == refnum) { say("Removed %d to log refnum list", refnum); log->refnums[i] = -1; break; } } if (i >= MAX_TARGETS) say("%s is not on the refnum list for this log!", arg); } arg = ptr; } return log; } static Logfile * logfile_rewrite (Logfile *log, char **args) { char *arg = new_next_arg(*args, args); if (!log) { say("REWRITE: You need to specify a logfile first"); return NULL; } malloc_strcpy(&log->rewrite, arg); return log; } static Logfile * logfile_server (Logfile *log, char **args) { char *arg = new_next_arg(*args, args); if (!log) { say("SERVER: You need to specify a logfile first"); return NULL; } if (!is_number(arg)) say("SERVER: The log's server needs to be a number"); else log->servref = parse_server_index(arg, 1); return log; } static Logfile * logfile_type (Logfile *log, char **args) { char *arg = new_next_arg(*args, args); if (!log) { say("TYPE: You need to specify a logfile first"); return NULL; } clean_log_targets(log); if (!my_strnicmp(arg, "SERVER", 1)) log->type = LOG_SERVERS; else if (!my_strnicmp(arg, "WINDOW", 1)) log->type = LOG_WINDOWS; else if (!my_strnicmp(arg, "TARGET", 1)) log->type = LOG_TARGETS; else say("TYPE: Unknown type of log"); return log; } typedef struct logfile_ops_T { const char * command; logfile_func func; } logfile_ops; static const logfile_ops options [] = { { "ACTIVITY", logfile_activity }, { "ADD", logfile_add }, { "DESCRIBE", logfile_describe }, { "FILENAME", logfile_filename }, { "KILL", logfile_kill }, { "LEVEL", logfile_level }, { "LIST", logfile_list }, { "MANGLE", logfile_mangle }, { "NAME", logfile_name }, { "NEW", logfile_new }, { "OFF", logfile_off }, { "ON", logfile_on }, { "REFNUM", logfile_refnum }, { "REMOVE", logfile_remove }, { "REWRITE", logfile_rewrite }, { "SERVER", logfile_server }, { "TYPE", logfile_type }, { NULL, NULL } }; BUILT_IN_COMMAND(logcmd) { char *arg; int nargs = 0; Logfile *log = NULL; while ((arg = next_arg(args, &args))) { int i; int len = strlen(arg); if (*arg == '-' || *arg == '/') /* Ignore - or / */ arg++, len--; for (i = 0; options[i].func ; i++) { if (!my_strnicmp(arg, options[i].command, len)) { log = options[i].func(log, &args); nargs++; break; } } if (!options[i].func) { Logfile *s_log; if ((s_log = get_log_by_desc(arg))) { nargs++; log = s_log; } else yell("LOG: Invalid option: [%s]", arg); } } if (!nargs) logfile_list(NULL, NULL); } /****************************************************************************/ void add_to_logs (long winref, int servref, const char *target, int level, const char *orig_str) { Logfile *log; int i; for (log = logfiles; log; log = log->next) { if (log->type == LOG_WINDOWS) { for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == winref) { if (log->level && (log->level & level) == 0) continue; time(&log->activity); add_to_log(log->log, winref, orig_str, log->mangler, log->rewrite); } } } if (log->type == LOG_SERVERS) { for (i = 0; i < MAX_TARGETS; i++) { if (log->refnums[i] == servref) { if (log->level && (log->level & level) == 0) continue; time(&log->activity); add_to_log(log->log, winref, orig_str, log->mangler, log->rewrite); } } } else if (log->type == LOG_TARGETS) { if (log->servref != NOSERV && (log->servref != servref)) continue; if (log->level && (log->level & level) == 0) continue; if (log->targets && !target) continue; if (target && !find_in_list((List **)&log->targets, target, USE_WILDCARDS)) continue; /* OK! We want to log it now! */ time(&log->activity); add_to_log(log->log, winref, orig_str, log->mangler, log->rewrite); } } } /*****************************************************************************/ /* Used by function_logctl */ /* * $logctl(REFNUMS [ACTIVE|INACTIVE|ALL]) * $logctl(REFNUM log-desc) * $logctl(ADD log-desc [target]) * $logctl(DELETE log-desc [target]) * $logctl(GET [LIST] * $logctl(SET [ITEM] [VALUE]) * $logctl(MATCH [pattern]) * $logctl(PMATCH [pattern]) * * [LIST] and [ITEM] are one of the following * REFNUM The refnum for the log (GET only) * NAME The logical name for the log * FILENAME The filename this log writes to * SERVER The server this log associates with (-1 for any) * TARGETS All of the targets for this log * LEVEL The Lastlog Level for this log * REWRITE The rewrite rule for this log * MANGLE The mangle rule for this log * STATUS 1 if log is on, 0 if log is off. * TYPE Either "TARGET", "WINDOW", or "SERVER" */ char *logctl (char *input) { char *refstr; char *listc; int val; Logfile *log; GET_STR_ARG(listc, input); if (!my_strnicmp(listc, "REFNUMS", 7)) { char * retval = NULL; int active; GET_STR_ARG(refstr, input); if (!my_stricmp(refstr, "ACTIVE")) active = 1; else if (!my_stricmp(refstr, "INACTIVE")) active = 0; else if (!my_stricmp(refstr, "ALL")) active = -1; else RETURN_EMPTY; for (log = logfiles; log; log = log->next) { if (active != -1 && active != log->active) continue; malloc_strcat_word(&retval, space, ltoa(log->refnum)); } RETURN_MSTR(retval); } else if (!my_strnicmp(listc, "REFNUM", 6)) { GET_STR_ARG(refstr, input); if (!(log = get_log_by_desc(refstr))) RETURN_EMPTY; RETURN_INT(log->refnum); } else if (!my_strnicmp(listc, "ADD", 2)) { GET_STR_ARG(refstr, input); if (!(log = get_log_by_desc(refstr))) RETURN_EMPTY; logfile_add(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "DELETE", 2)) { GET_STR_ARG(refstr, input); if (!(log = get_log_by_desc(refstr))) RETURN_EMPTY; logfile_remove(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "GET", 2)) { GET_STR_ARG(refstr, input); if (!(log = get_log_by_desc(refstr))) RETURN_EMPTY; GET_STR_ARG(listc, input); if (!my_strnicmp(listc, "REFNUM", 1)) { RETURN_INT(log->refnum); } else if (!my_strnicmp(listc, "NAME", 3)) { RETURN_STR(log->name); } else if (!my_strnicmp(listc, "FILENAME", 3)) { RETURN_STR(log->filename); } else if (!my_strnicmp(listc, "SERVER", 3)) { RETURN_INT(log->servref); } else if (!my_strnicmp(listc, "TARGETS", 3)) { char *ret = logfile_get_targets(log); RETURN_MSTR(ret); } else if (!my_strnicmp(listc, "LEVEL", 3)) { char *ret = bits_to_lastlog_level(log->level); RETURN_STR(ret); } else if (!my_strnicmp(listc, "REWRITE", 3)) { RETURN_STR(log->rewrite); } else if (!my_strnicmp(listc, "MANGLE", 3)) { RETURN_STR(log->mangle_desc); } else if (!my_strnicmp(listc, "STATUS", 3)) { RETURN_INT(log->active); } else if (!my_strnicmp(listc, "TYPE", 3)) { RETURN_STR(logtype[log->type]); } else if (!my_strnicmp(listc, "ACTIVITY", 1)) { RETURN_INT(log->activity); } } else if (!my_strnicmp(listc, "SET", 1)) { GET_STR_ARG(refstr, input); if (!(log = get_log_by_desc(refstr))) RETURN_EMPTY; GET_STR_ARG(listc, input); if (!my_strnicmp(listc, "NAME", 3)) { logfile_name(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "FILENAME", 3)) { logfile_filename(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "SERVER", 3)) { logfile_server(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "TARGETS", 3)) { clean_log_targets(log); logfile_add(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "LEVEL", 3)) { logfile_level(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "REWRITE", 3)) { logfile_rewrite(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "MANGLE", 3)) { logfile_mangle(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "STATUS", 3)) { GET_INT_ARG(val, input); if (val) logfile_on(log, &input); else logfile_off(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "TYPE", 3)) { logfile_type(log, &input); RETURN_INT(1); } else if (!my_strnicmp(listc, "ACTIVITY", 1)) { logfile_activity(log, &input); RETURN_INT(1); } } else if (!my_strnicmp(listc, "MATCH", 1)) { RETURN_EMPTY; /* Not implemented for now. */ } else if (!my_strnicmp(listc, "PMATCH", 1)) { RETURN_EMPTY; /* Not implemented for now. */ } else RETURN_EMPTY; RETURN_EMPTY; } epic4-2.10.2.orig/source/ignore.c0000644000000000000000000011106110224006550013346 0ustar /* $EPIC: ignore.c,v 1.15 2005/04/03 15:36:08 jnelson Exp $ */ /* * ignore.c: handles the ingore command for irc * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1995, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Here's the plan... * * IGNORE THEORY: There are times when we want to single out a particular * person, server, or channel for special handling. The process of * identifying another target on irc for special handling (see below), * and the descriptions and dispositions of what you want epic to do when * that target sends you a message, is known as "IGNORING" them. Any * particular message may be subject to one or more "IGNORE" rules. * * Each Ignore rule may either "pass" (do nothing) on a message or terminate * the disposition of a message. There are three dispositions available: * * 1) Suppressive ignore (IGNORE_SUPPRESS) - A message from this person * shall be discarded and shall not generate any direct output. * 2) Exceptive ignore (IGNORE_DONT) - A message from this person shall be * considered important enough to be exempt from all other ignore rules. * Ignores of this type are "exceptions" to ignores of other types. * 3) Highlight ignore (IGNORE_HIGH) - A message from this person shall not * only be exempt from all other ignore rules, but EPIC's default output * shall be embellished to indicate to the user that a person of import * has sent a message. * * Each Ignore type has (currently) many "levels" through which all messages * are sorted: * MSGS PRIVMSGs sent to you * PUBLIC PRIVMSGs sent to a channel you are on * WALLS PRIVMSGs not covered by MSGS or PUBLIC * WALLOPS WALLOPs messages sent to anybody. * INVITES INVITEs sent to you * NOTICES NOTICEs sent to anybody * NOTES "NOTE" notices sent to you. * CTCPS CTCP requests or CTCP replies sent to anybody * TOPICS TOPIC changes by anybody * NICKS NICK changes by anybody * JOINS JOINs to any channel by anybody * PARTS PARTs from any channel by anybody * CRAP QUITs, MODEs, KICKs and PONGs. * * In addition, the user can use these shorthand level descriptions: * ALL All of the above. * * Further in addition, the user can set ancilliary data which have the * following descriptions: * REASON "arg" Set the ignore's reason to the double-quoted * word argument after REASON * TIMEOUT number Automatically cancel the ignore after "number" * seconds from now. * * Each message that can be ignored fits into one of the above categories. * For each Ignore item, for each level, the three dispotions are mutually * exclusive of each other. If you add MSGS to your suppressive ignores, * it is implied that MSGS will be removed from Exceptive and Highlight * ignores. * * It is not necessary for each ignore to have a disposition for each level. * If an ignore does not declare a disposition for a level, it "passes" on * that message and further ignore rules will be checked. */ #include "irc.h" #include "ignore.h" #include "ircaux.h" #include "list.h" #include "vars.h" #include "output.h" #include "parse.h" #include "timer.h" #include "functions.h" #include "window.h" #define IGNORE_REMOVE -1 #define IGNORE_SUPPRESS 0 #define IGNORE_DONT 1 #define IGNORE_HIGH 2 /* * Ignore: the ignore list structure, consists of the nickname, and the type * of ignorance which is to take place */ typedef struct IgnoreStru { struct IgnoreStru *next; char *nick; /* What is being ignored */ int refnum; /* The refnum for internal use */ int type; /* Suppressive ignores */ int dont; /* Exceptional ignores */ int high; /* Highlight ignores */ int counter; /* How many times it has triggered */ Timeval creation; /* When it was created */ Timeval last_used; /* When it was last ``triggered'' */ Timeval expiration; /* When this ignore expires */ char *reason; } Ignore; /* ignored_nicks: pointer to the head of the ignore list */ static Ignore *ignored_nicks = NULL; static int global_ignore_refnum = 0; static void expire_ignores (void); static const char * get_ignore_types (Ignore *item, int); static int change_ignore_mask_by_desc (const char *, int *, int *, int *, char **, Timeval *); static int ignore_change (Ignore *, int, void *); static int ignore_list (Ignore *, int, void *); static int foreach_ignore (const char *, int, int (*)(Ignore *, int, void *), int, void *); static int remove_ignore (const char *); /*****************************************************************************/ static Ignore *new_ignore (const char *new_nick) { Ignore *item; item = (Ignore *) new_malloc(sizeof(Ignore)); item->nick = malloc_strdup(new_nick); upper(item->nick); item->reason = NULL; item->refnum = ++global_ignore_refnum; item->type = 0; item->dont = 0; item->high = 0; item->counter = 0; get_time(&item->creation); item->last_used.tv_sec = 0; item->last_used.tv_usec = 0; item->expiration.tv_sec = 0; item->expiration.tv_usec = 0; add_to_list((List **)&ignored_nicks, (List *)item); return item; } /* * get_ignore_by_refnum: When all you have is a refnum, all the world's * a linked list... * * Arguments: * 'refnum' -- The refnum of an ignore allegedly in use * * Return Value: * If 'refnum' is actually in use, that Ignore item is returned, * otherwise NULL is returned. */ static Ignore *get_ignore_by_refnum (int refnum) { Ignore *item; for (item = ignored_nicks; item; item = item->next) if (item->refnum == refnum) return item; return NULL; } /****************************************************************************/ /* * do_expire_ignores: TIMER callback for when ignores should be reaped * * Arguments: * 'ignored' -- Not used. * * Return Value: * No return value */ int do_expire_ignores (void *ignored) { expire_ignores(); return 0; } /* * expire_ignores: find and destroy any timers which have reached the end * of their useful lifetime. * * Arguments: * No arguments * * Return Value: * No return value */ static void expire_ignores (void) { Ignore *item, *next; Timeval right_now; if (!ignored_nicks) return; get_time(&right_now); for (item = ignored_nicks; item; item = next) { next = item->next; if (item->expiration.tv_sec != 0 && time_diff(right_now, item->expiration) < 0) remove_ignore(item->nick); } } /* * remove_ignore: Delete one or more Ignore items by description. * * Arguments: * 'nick' - A string containing either the exact value of an Ignore item * (ie, a nick!user@host, server name, or channel name), or * a wildcard pattern that matches one or more values of Ignore * items. If it is an exact value, that ignore item is deleted. * If it is a wildcard pattern, then all ignore items that are * matched by the pattern are deleted. * * Return value: * This function returns the number of ignore items deleted. * * Notes: * This function may delete more than one item! * * This function tells the user what the changes are. If you do not want * the output to occur, set window_display to 0 before calling. */ static int remove_ignore (const char *nick) { Ignore *item; char new_nick[IRCD_BUFFER_SIZE + 1]; int count = 0; char *mnick, *user, *host; if (is_number(nick)) { Ignore *last; int refnum = my_atol(nick); for (last = NULL, item = ignored_nicks; item; item = item->next) { if (item->refnum == refnum) { if (last) last->next = item->next; else ignored_nicks = item->next; say("%s removed from ignorance list (ignore refnum %d)", item->nick, item->refnum); new_free(&(item->nick)); new_free(&(item->reason)); new_free((char **)&item); return 1; } last = item; } say("Ignore refnum [%d] is not in use!", refnum); return 0; } if (figure_out_address(nick, &mnick, &user, &host)) strlcpy(new_nick, nick, IRCD_BUFFER_SIZE); else snprintf(new_nick, IRCD_BUFFER_SIZE, "%s!%s@%s", mnick, user, host); /* * Look for an exact match first. */ if ((item = (Ignore *) list_lookup((List **)&ignored_nicks, new_nick, !USE_WILDCARDS, REMOVE_FROM_LIST))) { say("%s removed from ignorance list (ignore refnum %d)", item->nick, item->refnum); new_free(&(item->nick)); new_free(&(item->reason)); new_free((char **)&item); count++; } /* * Otherwise clear everything that matches. */ else while ((item = (Ignore *)list_lookup((List **)&ignored_nicks, nick, USE_WILDCARDS, REMOVE_FROM_LIST))) { say("%s removed from ignorance list (ignore refnum %d)", item->nick, item->refnum); new_free(&(item->nick)); new_free(&(item->reason)); new_free((char **)&item); count++; } if (!count) say("%s is not in the ignorance list!", new_nick); return count; } /***************************************************************************/ /* * get_ignore_types: Summarize the effects of an Ignore rule. * * Arguments: * 'item' - The Ignore item whose dispositions shall be summarized * * Return value: * This function returns a static, temporary string that contains a summary * of the effects of the Ignore rule 'item'. This string will be destroyed * the next time someone calls this function so if you want to keep it, you * must make a copy of it. You must not try to write to the string. */ #define HANDLE_TYPE(x,y) \ if ((item->dont & IGNORE_ ## x) == IGNORE_ ## x) \ { \ if ((y) == 1) \ strlcat_c(buffer, " DONT-" #x, sizeof buffer, &clue); \ else if ((y) == 2) \ strlcat_c(buffer, " ^" #x, sizeof buffer, &clue); \ } \ else if ((item->type & IGNORE_ ## x) == IGNORE_ ## x) \ { \ if ((y) == 1) \ strlcat_c(buffer, " " #x, sizeof buffer, &clue); \ else if ((y) == 2) \ strlcat_c(buffer, " /" #x, sizeof buffer, &clue); \ } \ else if ((item->high & IGNORE_ ## x) == IGNORE_ ## x) \ { \ if ((y) == 1) \ strlopencat_c(buffer, sizeof buffer, &clue, space, \ high, #x, high, NULL); \ else if ((y) == 2) \ strlcat_c(buffer, " +" #x, sizeof buffer, &clue); \ } static const char * get_ignore_types (Ignore *item, int output_type) { static char buffer[BIG_BUFFER_SIZE + 1]; char *high = highlight_char; size_t clue; char *retval; clue = 0; *buffer = 0; HANDLE_TYPE(ALL, output_type) else { HANDLE_TYPE(MSGS, output_type) HANDLE_TYPE(PUBLIC, output_type) HANDLE_TYPE(WALLS, output_type) HANDLE_TYPE(WALLOPS, output_type) HANDLE_TYPE(INVITES, output_type) HANDLE_TYPE(NOTICES, output_type) HANDLE_TYPE(NOTES, output_type) HANDLE_TYPE(CTCPS, output_type) HANDLE_TYPE(TOPICS, output_type) HANDLE_TYPE(NICKS, output_type) HANDLE_TYPE(JOINS, output_type) HANDLE_TYPE(PARTS, output_type) HANDLE_TYPE(CRAP, output_type) } retval = buffer; while (isspace(*retval)) retval++; return retval; /* Eh! */ } /* * change_ignore_mask_by_desc: Change ignore mask and ancilliary data in * the manner provided by a user description ignore-dispensation list. * * Arguments: * 'type' - A comma-and-space separated list of ignore levels along with * dispensations for the list. For each level and dispensation * included, the following variables will be changed: * 'do_mask' - Suppressive ignores * 'dont_mask' - Exceptional ignores * 'high_mask' - Highlight ignores * 'reason' - The reason the ignore was created. May be NULL. * Expects an argument. If argument not provided or argument * is a hyphen ("-"), the reason is unset. * 'expire' - The time the ignore shall expire. May be NULL. * Expects an argument. If argument not provided or argument * is a hyphen ("-"), the timeout is unset. * * Return value: * The value 0 is returned. * * Notes: * The following dispositions are supported: * - Remove from all disposition types * ! Change to an exceptional ignore * ^ Same as ! * + Change to a highlight ignore * / Change to a suppressive ignore * Same as / * * The supported s are defined at the top of this file in the * "IGNORE THEORY" documentation. */ static int change_ignore_mask_by_desc (const char *type, int *do_mask, int *dont_mask, int *high_mask, char **reason, Timeval *expire) { char *l1, *l2; int len; int *mask = NULL, *del1, *del2, *del3; char * copy; int bit; copy = LOCAL_COPY(type); while ((l1 = new_next_arg(copy, ©))) { while (*l1 && (l2 = next_in_comma_list(l1, &l1))) { switch (*l2) { case '-': l2++; mask = NULL; del1 = do_mask; del2 = dont_mask; del3 = high_mask; break; case '!': case '^': l2++; mask = dont_mask; del1 = do_mask; del2 = high_mask; del3 = NULL; break; case '+': l2++; mask = high_mask; del1 = do_mask; del2 = dont_mask; del3 = NULL; break; case '/': default: mask = do_mask; del1 = dont_mask; del2 = high_mask; del3 = NULL; break; } if (!(len = strlen(l2))) continue; if (!my_strnicmp(l2, "NONE", len)) { mask = NULL; del1 = do_mask; del2 = dont_mask; del3 = high_mask; bit = IGNORE_ALL; } else if (!my_strnicmp(l2, "ALL", len)) bit = IGNORE_ALL; else if (!my_strnicmp(l2, "MSGS", len)) bit = IGNORE_MSGS; else if (!my_strnicmp(l2, "PUBLIC", len)) bit = IGNORE_PUBLIC; else if (!my_strnicmp(l2, "WALLS", len)) bit = IGNORE_WALLS; else if (!my_strnicmp(l2, "WALLOPS", len)) bit = IGNORE_WALLOPS; else if (!my_strnicmp(l2, "INVITES", len)) bit = IGNORE_INVITES; else if (!my_strnicmp(l2, "NOTICES", len)) bit = IGNORE_NOTICES; else if (!my_strnicmp(l2, "NOTES", len)) bit = IGNORE_NOTES; else if (!my_strnicmp(l2, "CTCPS", len)) bit = IGNORE_CTCPS; else if (!my_strnicmp(l2, "TOPICS", len)) bit = IGNORE_TOPICS; else if (!my_strnicmp(l2, "NICKS", len)) bit = IGNORE_NICKS; else if (!my_strnicmp(l2, "JOINS", len)) bit = IGNORE_JOINS; else if (!my_strnicmp(l2, "PARTS", len)) bit = IGNORE_PARTS; else if (!my_strnicmp(l2, "CRAP", len)) bit = IGNORE_CRAP; else if (!my_strnicmp(l2, "REASON", len)) { char *the_reason; the_reason = new_next_arg(copy, ©); if (reason) { if (!mask || !the_reason || !*the_reason || !strcmp(the_reason, "-")) new_free(reason); else malloc_strcpy(reason, the_reason); } continue; } else if (!my_strnicmp(l2, "TIMEOUT", len)) { char *the_timeout; the_timeout = new_next_arg(copy, ©); if (expire) { if (!mask || !the_timeout || !*the_timeout || !strcmp(the_timeout, "-")) { expire->tv_sec = 0; expire->tv_usec = 0; } else if (is_real_number(the_timeout)) { double seconds; Timeval right_now, interval; seconds = atof(the_timeout); interval = double_to_timeval(seconds); get_time(&right_now); *expire = time_add(right_now, interval); add_timer(0, empty_string, seconds, 1, do_expire_ignores, NULL, NULL, -1); } } continue; } else { say("You must specify one of the following:"); say("\tALL MSGS PUBLIC WALLS WALLOPS INVITES " "NOTICES NOTES CTCPS TOPICS NICKS JOINS " "PARTS CRAP NONE REASON \"\""); continue; } if (mask) *mask |= bit; if (del1) *del1 &= ~bit; if (del2) *del2 &= ~bit; if (del3) *del3 &= ~bit; } } return 0; } /*****************************************************************************/ /* * ignore_change: Change the types of things being ignored for an * Ignore item. * * Arguments: * 'item' - A particular Ignore item to be operated upon. * 'type' - Ignored -- should be 1 * 'data' - A pointer to a string containing ignore type changes. * * Return value: * This function returns 0. * * Notes: * This function tells the user what the changes are. If you do not want * the output to occur, set window_display to 0 before calling. */ static int ignore_change (Ignore *item, int type, void *data) { char *changes; changes = (char *)data; change_ignore_mask_by_desc(changes, &item->type, &item->dont, &item->high, &item->reason, &item->expiration); /* * Tell the user the new state of the ignore. * Garbage collect this ignore if it is clear. * remove_ignore() does the output for us here. */ if ((item->type & IGNORE_ALL) == IGNORE_NONE && (item->high & IGNORE_ALL) == IGNORE_NONE && (item->dont & IGNORE_ALL) == IGNORE_NONE) { remove_ignore(item->nick); return 0; } if (item->reason) say("Now ignoring %s from %s (refnum %d) because %s", get_ignore_types(item, 1), item->nick, item->refnum, item->reason); else say("Now ignoring %s from %s (refnum %d)", get_ignore_types(item, 1), item->nick, item->refnum); return 0; } /* * ignore_list: Tell the user about a particular ignore item. * * Arguments: * 'item' - A particular Ignore item to be described. * 'type' - This value is ignored. Pass the value 1. * 'data' - This value is ignored. Pass a pointer to an integer. * * Return value: * This function returns 0. */ static int ignore_list (Ignore *item, int type, void *data) { int expiring = 0; double time_to_expire = 0; Timeval right_now; if (item->expiration.tv_sec != 0) { get_time(&right_now); time_to_expire = time_diff(right_now, item->expiration); expiring = 1; } if (item->reason) { if (!expiring) { say("[%d] %s:\t%s (%s)", item->refnum, item->nick, get_ignore_types(item, 1), item->reason); } else { say("[%d] %s:\t%s (%s) (%f seconds left)", item->refnum, item->nick, get_ignore_types(item, 1), item->reason, time_to_expire); } } else { if (!expiring) { say("[%d] %s:\t%s", item->refnum, item->nick, get_ignore_types(item, 1)); } else { say("[%d] %s:\t%s (%f seconds left)", item->refnum, item->nick, get_ignore_types(item, 1), time_to_expire); } } return 0; } /***************************************************************************/ /* * foreach_ignore: call a function to manipulate one or more ignore items. * * Arguments: * 'nicklist' - A comma-and-space separated list of nicknames, channels, * and targets, each of which will be operated on. * 'create' - If 1, items in 'nicklist' which do not exist will be created * on demand. Otherwise they will be skipped with an error. * 'callback' - For each (Ignore) item represented by targets in 'nicklist', * this function will be called passing in the (Ignore) item, * and the two following data items: * 'data1' - An integer value to be passed to the callback function. * The usual mean is 1 to set a value and 0 to unset a value * 'data2' - A pointer to payload data which shall be passed to the * callback value. This is usually a pointer to an integer * or a character string. * * Return value: * This function returns 0. * * Notes: * This function allows you to easily perform the same operation on one or * more ignore items as requested by the user. * If a target in "nicklist" is not currently being ignored, and 'create' is * true, a new entry for that target will be created, and the new item will * be passed to the callback. This is a preferred way to create new ignore * items. */ static int foreach_ignore (const char *nicklist, int create, int (*callback) (Ignore *, int, void *), int data1, void *data2) { char *copy, *arg, *nick; Ignore *item; char * mnick; char * user; char * host; char new_nick[IRCD_BUFFER_SIZE + 1]; if (nicklist == NULL) { for (item = ignored_nicks; item; item = item->next) callback(item, data1, data2); return 0; } /* * Walk over 'nicklist', which separates each target with spaces * or with commas, ie: * /ignore "hop hop2" ALL * /ignore hop,hop2 ALL */ copy = LOCAL_COPY(nicklist); while ((arg = new_next_arg(copy, ©))) { while (*arg && (nick = next_in_comma_list(arg, &arg))) { if (is_number(nick)) { int refnum = my_atol(nick); for (item = ignored_nicks; item; item = item->next) if (item->refnum == refnum) break; if (!item) { say("Ignore refnum [%d] is not in use!", refnum); continue; } } else { /* * If possible, fill out the address. If it cannot * be figured out, just use what we were given. */ if (figure_out_address(nick, &mnick, &user, &host)) strlcpy(new_nick, nick, sizeof new_nick); else snprintf(new_nick, sizeof new_nick, "%s!%s@%s", mnick, user, host); /* * Create a new ignore item if this one does not exist. */ if ((item = (Ignore *)find_in_list((List **)&ignored_nicks, new_nick, 0)) == NULL) { if (create == 0) { say("%s is not being ignored!", new_nick); continue; } item = new_ignore(new_nick); } } callback(item, data1, data2); } } return 0; } /**************************************************************************/ /* * ignore: The /IGNORE command * * Arguments: * 'args' - The command line arguments to /IGNORE. * * Return value: * None * * Notes: * /IGNORE * List all ignore items * /IGNORE * List one or more particular ignore item by giving the target or * refnum; separate multiple items by commas or spaces. Surround * the list with double quotes if it contains spaces. * /IGNORE * Change one or more particular ignore items, assigning the given * levels to the given dispositions. The target list may be separated * with spaces or commas. Surround the target list with double quotes * if it contains spaces. The level dispositions may be separated with * spaces or commas. It is not necessary to surround the level * dispositions with double quotes. * * Where: * := ["] | * [ ]* ["] * := [][!@] * := * * := | * := * := [!|^] Set exclusionary ignore * | - Remove level from all types * | + Set highlight ignore * | [/|] Set suppressive ignore * := MSGS | PUBLIC | WALLS | WALLOPS | INVITES | * NOTICES | NOTES | CTCPS | TOPICS | NICKS | * JOINS | PARTS | CRAP | NONE | ALL | * REASON "" | TIMEOUT "" * * Examples: * /IGNORE #EPIC +ALL (Highlight all messages to epic) * /IGNORE #EPIC -ALL (Delete ignore item for epic) * /IGNORE #EPIC NONE (Same thing as -ALL) * /IGNORE (List all ignores) * /IGNORE 1 NONE (Remove ignore refnum 1) * /IGNORE 2,3 NONE (Remove ignore refnums 2 and 3) * /IGNORE "2 3" NONE (Same thing) */ BUILT_IN_COMMAND(ignore) { char *nick; nick = new_next_arg(args, &args); if (nick && !is_string_empty(args)) foreach_ignore(nick, 1, ignore_change, 1, args); else { say("Ignorance List:"); foreach_ignore(nick, 0, ignore_list, 0, NULL); } } /**************************** INTERNAL API ********************************/ /* * get_ignores_by_pattern: Forward or reverse matching of ignore patterns * with a list of patterns. The built in $igmask() * and $rigmask() functions. * * Arguments: * 'patterns' - A space separated list of patterns to use in forward * or reverse matching the Ignore items. * 'covered' - If 0, do forward matching ($igmask()), * if 1, do reverse matching ($rigmask()). * * Return value: * The return value is a MALLOCED word list containing all of the ignore * wildcard masks covering or covered by the 'patterns' * * Notes: * "Forward" matching means treating each ignore pattern as a literal * string and the user's input as a wildcard pattern. All ignore * patterns which are matched by the input are returned. * "Reverse" matching means treating each ignore pattern as wildcard * patterns and the user's input as a literal string. All ignore * patterns which match the input are returned. * Forward matching asks the question -- "Which ignore patterns contain * this text in them?" * Reverse matching asks the question -- "If this was the nick!user@host, * which ignore patterns apply to that target?" */ char *get_ignores_by_pattern (char *patterns, int covered) { Ignore *tmp; char *pattern; char *retval = NULL; size_t clue = 0; while ((pattern = new_next_arg(patterns, &patterns))) { for (tmp = ignored_nicks; tmp; tmp = tmp->next) { if (covered ? wild_match(tmp->nick, pattern) : wild_match(pattern, tmp->nick)) malloc_strcat_word_c(&retval, space, tmp->nick, &clue); } } return retval ? retval : malloc_strdup(empty_string); } /* * get_ignore_types_by_pattern: The $igtype() built in function * * Arguments: * 'pattern' - A single ignore pattern or refnum. * * Return value: * The targets being ignored by the ignore item, suitable for displaying * to the user. */ const char *get_ignore_types_by_pattern (char *pattern) { Ignore *tmp; int number = -1; if (is_number(pattern)) if ((number = my_atol(pattern)) < 0) number = -1; for (tmp = ignored_nicks; tmp; tmp = tmp->next) { if (!my_stricmp(tmp->nick, pattern)) return get_ignore_types(tmp, 1); if (number > -1 && tmp->refnum == number) return get_ignore_types(tmp, 1); } return empty_string; } /* * get_ignore_patterns_by_type: The $rigtype() built in function * * Arguments: * 'ctype' - A comma-and-space separated list of ignore level descriptions * * Return value: * A MALLOCED string containing a word list of all of the targets * (nick!user@host or #channels) ignoring at least the levels * described by the argument. */ char *get_ignore_patterns_by_type (char *ctype) { Ignore *tmp; int do_mask = 0, dont_mask = 0, high_mask = 0; char *result = NULL; size_t clue = 0; /* * Convert the user's input into something we can use. * If the user doesnt specify anything useful, then we * just punt right here. */ change_ignore_mask_by_desc(ctype, &do_mask, &dont_mask, &high_mask, NULL, NULL); if (do_mask == 0 && dont_mask == 0 && high_mask == 0) return malloc_strdup(empty_string); for (tmp = ignored_nicks; tmp; tmp = tmp->next) { /* * change_ignore_mask_by_desc is supposed to ensure that * each bit is set only once in 'do_mask', 'dont_mask', * and 'high_mask', and we already know this is the case * for the Ignores. So we check each of the three ignore * types, and if this ignore has all of the levels set in * all of the right places, it's ok. It could have more * levels than what the user asked for, but it can't have * levels with different dispositions. */ if ((tmp->dont & dont_mask) != dont_mask) continue; if ((tmp->type & do_mask) != do_mask) continue; if ((tmp->high & high_mask) != high_mask) continue; /* Add it to the fray */ malloc_strcat_word_c(&result, space, tmp->nick, &clue); } return result; } /* * Here's the plan: * * $ignorectl(REFNUMS) * $ignorectl(REFNUM ) * $ignorectl(ADD [level-desc]) * $ignorectl(CHANGE [level-desc]) * $ignorectl(DELETE ) * $ignorectl(PATTERN ) * $ignorectl(RPATTERN ) * $ignorectl(WITH_TYPES ) * $ignorectl(GET [LIST]) * $ignorectl(SET [ITEM] [VALUE]) * * [LIST] and [ITEM] are one of the following * NICK The pattern being ignored. Changing this is dangerous. * LEVELS A parsable summary of what is being ignored * TYPE An integer representing the suppressive ignores * DONT An integer representing the exceptional ignores * HIGH An integer representing the highlight ignores * EXPIRATION The time the ignore will expire * REASON The reason why we're ignoring this pattern. */ char * ignorectl (char *input) { char * refstr; char * listc; Ignore *i; int len; int owd; GET_STR_ARG(listc, input); len = strlen(listc); if (!my_strnicmp(listc, "REFNUM", len)) { if ((i = (Ignore *)find_in_list((List **)&ignored_nicks, input, 0)) == NULL) RETURN_EMPTY; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "REFNUMS", len)) { char * retval = NULL; size_t clue = 0; for (i = ignored_nicks; i; i = i->next) malloc_strcat_word_c(&retval, space, ltoa(i->refnum), &clue); RETURN_MSTR(retval); } else if (!my_strnicmp(listc, "ADD", len)) { char * pattern; GET_STR_ARG(pattern, input); owd = window_display; window_display = 0; i = new_ignore(pattern); ignore_change(i, 1, input); window_display = owd; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "CHANGE", len)) { int refnum; GET_STR_ARG(refstr, input); if (!is_number(refstr)) RETURN_EMPTY; refnum = my_atol(refstr); if (!(i = get_ignore_by_refnum(refnum))) RETURN_EMPTY; owd = window_display; window_display = 0; ignore_change(i, 1, input); window_display = owd; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "DELETE", len)) { RETURN_INT(remove_ignore(input)); } else if (!my_strnicmp(listc, "PATTERN", len)) { RETURN_MSTR(get_ignores_by_pattern(input, 0)); } else if (!my_strnicmp(listc, "RPATTERN", len)) { RETURN_MSTR(get_ignores_by_pattern(input, 1)); } else if (!my_strnicmp(listc, "WITH_TYPES", len)) { RETURN_MSTR(get_ignore_patterns_by_type(input)); } else if (!my_strnicmp(listc, "GET", len)) { int refnum; GET_STR_ARG(refstr, input); if (!is_number(refstr)) RETURN_EMPTY; refnum = my_atol(refstr); if (!(i = get_ignore_by_refnum(refnum))) RETURN_EMPTY; GET_STR_ARG(listc, input); len = strlen(listc); if (!my_strnicmp(listc, "NICK", len)) { RETURN_STR(i->nick); } else if (!my_strnicmp(listc, "LEVELS", len)) { RETURN_STR(get_ignore_types(i, 2)); } else if (!my_strnicmp(listc, "SUPPRESS", len)) { RETURN_INT(i->type); } else if (!my_strnicmp(listc, "EXCEPT", len)) { RETURN_INT(i->dont); } else if (!my_strnicmp(listc, "HIGHLIGHT", len)) { RETURN_INT(i->high); } else if (!my_strnicmp(listc, "EXPIRATION", len)) { char *ptr = NULL; return malloc_sprintf(&ptr, "%ld %ld", (long) i->expiration.tv_sec, (long) i->expiration.tv_usec); } else if (!my_strnicmp(listc, "REASON", len)) { RETURN_STR(i->reason); } else if (!my_strnicmp(listc, "COUNTER", len)) { RETURN_INT(i->counter); } else if (!my_strnicmp(listc, "CREATION", len)) { char *ptr = NULL; return malloc_sprintf(&ptr, "%ld %ld", (long) i->creation.tv_sec, (long) i->creation.tv_usec); } else if (!my_strnicmp(listc, "LAST_USED", len)) { char *ptr = NULL; return malloc_sprintf(&ptr, "%ld %ld", (long) i->last_used.tv_sec, (long) i->last_used.tv_usec); } } else if (!my_strnicmp(listc, "SET", len)) { int refnum; GET_STR_ARG(refstr, input); if (!is_number(refstr)) RETURN_EMPTY; refnum = my_atol(refstr); if (!(i = get_ignore_by_refnum(refnum))) RETURN_EMPTY; GET_STR_ARG(listc, input); len = strlen(listc); if (!my_strnicmp(listc, "NICK", len)) { malloc_strcpy(&i->nick, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "LEVELS", len)) { i->type = i->dont = i->high = 0; ignore_change(i, 1, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "SUPPRESS", len)) { GET_INT_ARG(i->type, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "EXCEPT", len)) { GET_INT_ARG(i->dont, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "HIGHLIGHT", len)) { GET_INT_ARG(i->high, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "EXPIRATION", len)) { Timeval to; GET_INT_ARG(to.tv_sec, input); GET_INT_ARG(to.tv_usec, input); i->expiration = to; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "REASON", len)) { if (is_string_empty(input)) new_free(&i->reason); else malloc_strcpy(&i->reason, input); RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "CREATION", len)) { Timeval to; GET_INT_ARG(to.tv_sec, input); GET_INT_ARG(to.tv_usec, input); i->creation = to; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "LAST_USED", len)) { Timeval to; GET_INT_ARG(to.tv_sec, input); GET_INT_ARG(to.tv_usec, input); i->last_used = to; RETURN_INT(i->refnum); } else if (!my_strnicmp(listc, "COUNTER", len)) { GET_INT_ARG(i->counter, input); RETURN_INT(i->refnum); } } /* We get here if something is not implemented. */ RETURN_EMPTY; } /***************************** BACK END *************************************/ /* * check_ignore -- replaces the old double_ignore * Why did i change the name? * * double_ignore isnt really applicable any more becuase it doesnt * do two ignore lookups, it only does one. * * This function doesnt look anything like the old double_ignore * * This function works for the new *!*@* patterns stored by * ignore instead of the old nick and userhost patterns. * (jfn may 1995) */ int check_ignore (const char *nick, const char *uh, int type) { return check_ignore_channel(nick, uh, NULL, type); } /* * "check_ignore_channel" is kind of a bad name for this function, but * i was not inspired with a better name. This function is simply the * old 'check_ignore', only it has an additional check for a channel target. */ int check_ignore_channel (const char *nick, const char *uh, const char *channel, int type) { char nuh[IRCD_BUFFER_SIZE]; Ignore *tmp; int count = 0; int bestimatch = 0; Ignore *i_match = NULL; int bestcmatch = 0; Ignore *c_match = NULL; if (!ignored_nicks) return NOT_IGNORED; snprintf(nuh, IRCD_BUFFER_SIZE - 1, "%s!%s", nick ? nick : star, uh ? uh : star); for (tmp = ignored_nicks; tmp; tmp = tmp->next) { /* * Always check for exact matches first... */ if (!strcmp(tmp->nick, nuh)) { i_match = tmp; break; } /* * Then check for wildcard matches... */ count = wild_match(tmp->nick, nuh); if (count > bestimatch) { bestimatch = count; i_match = tmp; } /* * Then check for channels... */ if (channel) { count = wild_match(tmp->nick, channel); if (count > bestcmatch) { bestcmatch = count; c_match = tmp; } } } /* * We've found something... Always prefer a nickuserhost match * over a channel match, and always prefer an exact match over * a wildcard match... */ if (i_match) { tmp = i_match; if (tmp->dont & type) { tmp->counter++; get_time(&tmp->last_used); return NOT_IGNORED; } if (tmp->type & type) { tmp->counter++; get_time(&tmp->last_used); return IGNORED; } if (tmp->high & type) { tmp->counter++; get_time(&tmp->last_used); return HIGHLIGHTED; } } /* * If the nickuserhost match did not say anything about the level * that we are interested in, then try a channel ignore next. */ else if (c_match) { tmp = c_match; if (tmp->dont & type) { tmp->counter++; get_time(&tmp->last_used); return NOT_IGNORED; } if (tmp->type & type) { tmp->counter++; get_time(&tmp->last_used); return IGNORED; } if (tmp->high & type) { tmp->counter++; get_time(&tmp->last_used); return HIGHLIGHTED; } } /* * Otherwise i guess we dont ignore them. */ return NOT_IGNORED; } epic4-2.10.2.orig/source/glob.c0000644000000000000000000004547507707324326013045 0ustar /* $EPIC: glob.c,v 1.10 2003/07/22 21:12:54 jnelson Exp $ */ #include "config.h" #if defined(NEED_GLOB) /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* from: static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; */ /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * * The [!...] convention to negate a range is supported (SysV, Posix, ksh). * * Optional extra services, controlled by flags not defined by POSIX: * * GLOB_QUOTE: * Escaping convention: \ inhibits any special meaning the following * character might have (except \ at end of string is retained). * GLOB_MAGCHAR: * Set in gl_flags if pattern contained a globbing character. * GLOB_NOMAGIC: * Same as GLOB_NOCHECK, but it will only append pattern if it did * not contain any magic characters. [Used in csh style globbing] * GLOB_ALTDIRFUNC: * Use alternately specified directory access functions. * GLOB_TILDE: * expand ~user/foo to the /home/dir/of/user/foo * GLOB_BRACE: * expand {1,2}{a,b} to 1a 1b 2a 2b * GLOB_INSENSITIVE: * Globbing occurs without regard to case of the letters. * gl_matchc: * Number of matches in the current invocation of glob. */ #include #include #include #include #include #include "glob.h" #include #include #include #include #include #include "irc.h" #ifndef MAXPATHLEN # ifndef PATHSIZE # define MAXPATHLEN 1024 # else # define MAXPATHLEN PATHSIZE # endif #endif #undef EOS #define DOLLAR '$' #define DOT '.' #define EOS '\0' #define LBRACKET '[' #define NOT '!' #define QUESTION '?' #define QUOTE '\\' #define RANGE '-' #define RBRACKET ']' #define SEP '/' #define STAR '*' #define TILDE '~' #define UNDERSCORE '_' #define LBRACE '{' #define RBRACE '}' #define SLASH '/' #define COMMA ',' #define M_QUOTE 0x8000 #define M_PROTECT 0x4000 #define M_ANYCASE 0x2000 /* EPIC ADD */ #define M_MASK 0xffff #define M_ASCII 0x00ff #ifdef Char #undef Char #endif typedef unsigned short Char; #define CHAR(c) ((Char)((c)&M_ASCII)) #define META(c) ((Char)((c)|M_QUOTE)) #define M_ALL META('*') #define M_END META(']') #define M_NOT META('!') #define M_ONE META('?') #define M_RNG META('-') #define M_SET META('[') #define ismeta(c) (((c)&M_QUOTE) != 0) static int compare (const void *, const void *); static void g_Ctoc (const Char *, char *); static int g_lstat (Char *, Stat *, glob_t *); static DIR * g_opendir (Char *, glob_t *); static ssize_t g_strchr (const Char *, int); static int g_stat (Char *, Stat *, glob_t *); static int glob0 (const Char *, glob_t *); static int glob1 (Char *, glob_t *); static int glob2 (Char *, Char *, Char *, glob_t *); static int glob3 (Char *, Char *, Char *, Char *, glob_t *); static int globextend (const Char *, glob_t *); static const Char * globtilde (const Char *, Char *, glob_t *); static int globexp1 (const Char *, glob_t *); static int globexp2 (const Char *, const Char *, glob_t *, int *); static int globmatch (Char *, Char *, Char *, int); int bsd_glob ( const char *pattern, int flags, int (*errfunc) (const char *, int), glob_t *pglob ) { const u_char *patnext; int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; patnext = (const u_char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN; if (flags & GLOB_QUOTE) { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != EOS) { if (c == QUOTE) { if ((c = *patnext++) == EOS) { c = QUOTE; --patnext; } *bufnext++ = c | M_PROTECT; } else *bufnext++ = c; } } else while (bufnext < bufend && (c = *patnext++) != EOS) *bufnext++ = c; *bufnext = EOS; if (flags & GLOB_BRACE) return globexp1(patbuf, pglob); else return glob0(patbuf, pglob); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1 ( const Char *pattern, glob_t *pglob ) { const Char* ptr = pattern; int rv; ssize_t span; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob); while ((span = g_strchr(ptr, LBRACE)) >= 0) { ptr += span; if (!globexp2(ptr, pattern, pglob, &rv)) return rv; } return glob0(pattern, pglob); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2 ( const Char *ptr, const Char *pattern, glob_t *pglob, int *rv ) { int i; Char *lm, *ls; const Char *pe, *pm, *pl; Char patbuf[MAXPATHLEN + 1]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) continue; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe; pe++) { if (*pe == LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) continue; if (*pe == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pe = pm; } } else if (*pe == LBRACE) i++; else if (*pe == RBRACE) { if (i == 0) break; i--; } } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) { *rv = glob0(patbuf, pglob); return 0; } for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { case LBRACKET: /* Ignore everything between [] */ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) continue; if (*pm == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pm = pl; } break; case LBRACE: i++; break; case RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case COMMA: if (i && *pm == COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) continue; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != EOS;) continue; /* Expand the current pattern */ *rv = globexp1(patbuf, pglob); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } } *rv = 0; return 0; } /* * expand tilde from the passwd file. */ static const Char *globtilde ( const Char *pattern, Char *patbuf, glob_t *pglob ) { struct passwd *pwd; char *h; const Char *p; Char *b; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* Copy up to the end of the string or / */ for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH; *h++ = *p++) continue; *h = EOS; if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ if ((h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char *)patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; *h; *b++ = *h++) continue; /* Append the rest of the pattern */ while ((*b++ = *p++) != EOS) continue; return patbuf; } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0 ( const Char *pattern, glob_t *pglob ) { const Char * qpatnext; int c; int err; int oldpathc; Char * bufnext; Char patbuf[MAXPATHLEN+1]; qpatnext = globtilde(pattern, patbuf, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) < 0) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* * collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; if ((err = glob1(patbuf, pglob)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc && ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) return(globextend(pattern, pglob)); else if (!(pglob->gl_flags & GLOB_NOSORT)) { if (pglob->gl_pathv) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } return(0); } static int compare ( const void *p, const void *q ) { return (strcmp(*(const char * const *)p, *(const char * const *)q)); } static int glob1 ( Char *pattern, glob_t *pglob ) { Char pathbuf[MAXPATHLEN+1]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf, pattern, pglob)); } /* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2 ( Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob ) { Stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) /* End of pattern? */ { *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) #ifdef S_ISLNK /* bummer for unixware */ || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)) #endif )) { *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return(globextend(pathbuf, pglob)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; *q++ = *p++; } if (!anymeta) /* No expansion, do next segment. */ { pathend = q; pattern = p; while (*pattern == SEP) *pathend++ = *pattern++; } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathend, pattern, p, pglob)); } /* NOTREACHED */ } static int glob3 ( Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern, glob_t *pglob ) { register struct dirent *dp; DIR *dirp; int err; char buf[MAXPATHLEN]; /* * The readdirfunc declaration can't be prototyped, because it is * assigned, below, to two functions which are prototyped in glob.h * and dirent.h as taking pointers to differently typed opaque * structures. */ struct dirent *(*readdirfunc)(DIR *); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { g_Ctoc(pathbuf, buf); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) return (GLOB_ABEND); } return(0); } err = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir; else readdirfunc = readdir; while ((dp = (*readdirfunc)(dirp))) { register u_char *sc; register Char *dc; int nocase = 0; /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; for (sc = (u_char *) dp->d_name, dc = pathend; (*dc++ = *sc++) != EOS;) continue; if (pglob->gl_flags & GLOB_INSENSITIVE) nocase = 1; if (!globmatch(pathend, pattern, restpattern, nocase)) { *pathend = EOS; continue; } err = glob2(pathbuf, --dc, restpattern, pglob); if (err) break; } if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); return(err); } /* * Extend the gl_pathv member of a glob_t structure to accomodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int globextend ( const Char *path, glob_t *pglob ) { register char **pathv; register int i; unsigned newsize; char *copy; const Char *p; newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); pathv = pglob->gl_pathv ? (char **)realloc((char *)pglob->gl_pathv, newsize) : (char **)malloc(newsize); if (pathv == NULL) return(GLOB_NOSPACE); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; for (i = pglob->gl_offs; --i >= 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; for (p = path; *p++;) continue; if ((copy = malloc(p - path)) != NULL) { g_Ctoc(path, copy); pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; return(copy == NULL ? GLOB_NOSPACE : 0); } /* * pattern matching function for filenames. Each occurrence of the * * pattern causes a recursion level. */ static int globmatch ( register Char *name, register Char *pat, register Char *patend, int nocase ) { int ok, negate_range; Char c, k; while (pat < patend) { c = *pat++; switch (c & M_MASK) { case M_ALL: if (pat == patend) return(1); do if (globmatch(name, pat, patend, nocase)) return(1); while (*name++ != EOS); return(0); case M_ONE: if (*name++ == EOS) return(0); break; case M_SET: ok = 0; if ((k = *name++) == EOS) return(0); if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++pat; while (((c = *pat++) & M_MASK) != M_END) { if ((*pat & M_MASK) == M_RNG) { if (c <= k && k <= pat[1]) ok = 1; pat += 2; } else if (c == k) ok = 1; } if (ok == negate_range) return(0); break; default: { if (nocase) { if (toupper((int)CHAR(*name)) != toupper((int)CHAR(c))) return 0; } else { if (*name != c) return 0; } name++; break; } } } if (*name == EOS) return 1; return 0; } /* Free allocated data belonging to a glob_t structure. */ void bsd_globfree ( glob_t *pglob ) { register int i; register char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) free(*pp); free(pglob->gl_pathv); } } static DIR *g_opendir ( register Char *str, glob_t *pglob ) { char buf[MAXPATHLEN]; if (!*str) strlcpy(buf, ".", sizeof buf); else g_Ctoc(str, buf); if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_opendir)(buf)); return(opendir(buf)); } static int g_lstat ( register Char *fn, Stat *sb, glob_t *pglob ) { char buf[MAXPATHLEN]; g_Ctoc(fn, buf); if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return(lstat(buf, sb)); } static int g_stat ( register Char *fn, Stat *sb, glob_t *pglob ) { char buf[MAXPATHLEN]; g_Ctoc(fn, buf); if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_stat)(buf, sb)); return(stat(buf, sb)); } static ssize_t g_strchr ( const Char *str, int ch ) { const Char *start = str; do { if (*str == ch) return str - start; } while (*str++); return -1; } static void g_Ctoc ( register const Char *str, char *buf ) { register char *dc; for (dc = buf; (*dc++ = *str++) != EOS;) continue; } #endif epic4-2.10.2.orig/source/newio.c0000644000000000000000000003171210030457623013216 0ustar /* $EPIC: newio.c,v 1.20 2004/03/25 04:26:59 jnelson Exp $ */ /* * newio.c: This is some handy stuff to deal with file descriptors in a way * much like stdio's FILE pointers * * IMPORTANT NOTE: If you use the routines here-in, you shouldn't switch to * using normal reads() on the descriptors cause that will cause bad things * to happen. If using any of these routines, use them all * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1997, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "ircaux.h" #include "output.h" #include "newio.h" #include "ssl.h" #include #ifdef HAVE_SYS_FILIO_H #include #endif #ifdef HAVE_STROPTS_H #include /* XXXX nonportable */ #endif #ifdef HAVE_SYS_STROPTS_H #include /* XXXX nonportable */ #endif #if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) # define IO_ARRAYLEN sysconf(_SC_OPEN_MAX) #else # if defined(FD_SETSIZE) # define IO_ARRAYLEN FD_SETSIZE # else # define IO_ARRAYLEN NFDBITS # endif #endif #define MAX_SEGMENTS 16 typedef struct myio_struct { char *buffer; size_t buffer_size; unsigned read_pos, write_pos; int segments; int error; #if 0 void (*read_callback) (int fd, int numbytes, char *data); char * (*write_callback) (int fd); int strategy; #endif } MyIO; static MyIO **io_rec = NULL; int dgets_errno = 0; /* * Get_pending_bytes: What do you think it does? */ size_t get_pending_bytes (int fd) { if (fd >= 0 && io_rec[fd] && io_rec[fd]->buffer) return strlen(io_rec[fd]->buffer); return 0; } static void init_io (void) { static int first = 1; if (first) { int c, max_fd = IO_ARRAYLEN; io_rec = (MyIO **)new_malloc(sizeof(MyIO *) * max_fd); for (c = 0; c < max_fd; c++) io_rec[c] = (MyIO *) 0; first = 0; } } /* * dgets() is used by: * dcc.c for DCC CHAT (buffer = 1) * dcc.c for DCC RAW (buffer = 0) * exec.c for handling inbound data from execd processes (buffer = 0) * screen.c for reading in from a created screen (buffer = 0) * screen.c for reading stdin when process is in dumb mode. (buffer = 1) * server.c for reading in lines from server (buffer = 1) * server.c for the /flush command (buffer = 0) */ /* * All new dgets -- no more trap doors! * * There are at least four ways to look at this function. * The most important variable is 'buffer', which determines if * we force line buffering. If it is on, then we will sit on any * incomplete lines until they get a newline. This is the default * behavior for server connections, because they *must* be line * delineated. However, when are getting input from an untrusted * source (eg, dcc chat, /exec'd process), we cannot assume that every * line will be newline delinated. So in those cases, 'buffer' is 0, * and we force a flush on whatever we can slurp, without waiting for * a newline. * * Return values: * * -1 -- The file descriptor is dead. Either an EOF occured, or a * read() error occured, or the buffer for the filedesc filled * up, or some other non-recoverable error occured. * 0 -- If the data read in from the file descriptor did not form a * complete line, then zero is always returned. This should be * considered a stopping condition. Do not call dgets() again * after it returns 0, because unless more data is avaiable on * the fd, it will return -1, which you would misinterpret as an * error condition. * If "buffer" is 0, then whatever we have available will be * returned in "str". * If "buffer" is not 0, then we will retain whatever we have * available, waiting for the newline to occur perhaps next time. * >0 -- If a full, newline terminated line was available, the length * of the line is returned. */ ssize_t dgets (int des, char *buf, size_t buflen, int buffer, void *ssl_aux) { ssize_t cnt = 0; int c = 0; /* gcc can die. */ MyIO *ioe; if (!io_rec) init_io(); if (buflen == 0) { yell("***XXX*** Buffer for des [%d] is zero-length! ***XXX***", des); dgets_errno = ENOMEM; /* Cough */ return -1; } ioe = io_rec[des]; if (ioe == NULL) { ioe = io_rec[des] = (MyIO *)new_malloc(sizeof(MyIO)); ioe->buffer_size = IO_BUFFER_SIZE; ioe->buffer = (char *)new_malloc(ioe->buffer_size + 2); ioe->read_pos = ioe->write_pos = 0; ioe->segments = 0; ioe->error = 0; } if (ioe->read_pos == ioe->write_pos) { ioe->read_pos = ioe->write_pos = 0; ioe->buffer[0] = 0; ioe->segments = 0; } if (!strchr(ioe->buffer + ioe->read_pos, '\n')) { if (ioe->read_pos) { ov_strcpy(ioe->buffer, ioe->buffer + ioe->read_pos); ioe->read_pos = 0; ioe->write_pos = strlen(ioe->buffer); ioe->segments = 1; } /* * Dont try to read into a full buffer. */ if (ioe->write_pos >= ioe->buffer_size) { yell("***XXX*** Buffer for des [%d] is filled! ***XXX***", des); dgets_errno = ENOMEM; /* Cough */ return -1; } if (ssl_aux) { #ifndef HAVE_SSL panic("Attempt to call SSL_read on non-ssl client"); #else /* Better safe than sorry... */ c = SSL_read((SSL *)ssl_aux, ioe->buffer + ioe->write_pos, ioe->buffer_size - ioe->write_pos - 1); #endif } else { /* Better safe than sorry... */ c = read(des, ioe->buffer + ioe->write_pos, ioe->buffer_size - ioe->write_pos - 1); } if (x_debug & DEBUG_INBOUND) yell("FD [%d], did [%d]", des, c); if (c <= 0) { *buf = 0; dgets_errno = (c == 0) ? -1 : errno; return -1; } ioe->buffer[ioe->write_pos + c] = 0; ioe->write_pos += c; ioe->segments++; } dgets_errno = 0; /* * If the caller wants us to force line buffering, and if there * is no complete line, just stop right here. */ if (buffer && !strchr(ioe->buffer + ioe->read_pos, '\n')) { if (ioe->segments > MAX_SEGMENTS) { yell("***XXX*** Too many read()s on des [%d] without a newline! ***XXX***", des); *buf = 0; dgets_errno = ECONNABORTED; return -1; } return 0; } /* * Slurp up the data that is available into 'buf'. */ while (ioe->read_pos < ioe->write_pos) { if (((buf[cnt] = ioe->buffer[ioe->read_pos++])) == '\n') break; cnt++; } /* If the line is too long, truncate it. */ /* * Before anyone whines about this, a lot of code in epic * silently assumes that incoming lines from the server don't * exceed 510 bytes. Until we "fix" all of those cases, it is * better to truncate excessively long lines than to let them * overflow buffers! */ if (cnt > (ssize_t)(buflen - 1)) { if (x_debug & DEBUG_INBOUND) yell("FD [%d], Too long (did [%d], max [%d])", des, cnt, buflen); /* Remember that 'buf' must be 'buflen + 1' bytes big! */ if (buf[cnt] == '\n') buf[buflen - 1] = '\n'; cnt = buflen - 1; } /* * Terminate it */ buf[cnt + 1] = 0; /* * If we end in a newline, then all is well. * Otherwise, we're unbuffered, tell the caller. * The caller then would need to do a strlen() to get * the amount of data. */ if (buf[cnt] == '\n') return cnt; else return 0; } /* * new_select: works just like select(), execpt I trimmed out the excess * parameters I didn't need. */ int new_select (fd_set *rd, fd_set *wd, Timeval *timeout) { static int polls = 0; Timeval thetimeout; Timeval *newtimeout = &thetimeout; int i, set = 0; fd_set new_f; if (timeout) { thetimeout = *timeout; if (timeout->tv_sec == 0 && timeout->tv_usec == 0) { if (polls++ > 10000) panic("Stuck in a polling loop. Help!"); } else polls = 0; } else newtimeout = NULL; if (!io_rec) panic("new_select called before io_rec was initialized"); FD_ZERO(&new_f); for (i = 0; i <= global_max_fd; i++) { /* * Check to see if there is a complete line sitting in the * fd's buffer. If there is, then we just tag this fd as * being ready. No sweat. Don't mark the fd ready if the * caller didn't ask about the fd, because that leads to * a busy-loop. */ if (io_rec[i]) { if (io_rec[i]->read_pos < io_rec[i]->write_pos && FD_ISSET(i, rd) && strchr(io_rec[i]->buffer + io_rec[i]->read_pos, '\n')) { FD_SET(i, &new_f); set++; } } } /* * Only do the expensive select() call if there are no lines waiting * in any fd's buffer. This allows us to quickly dump the entire * contents of an ircd packet without doing expensive select() calls * inbetween each line. */ if (set) { *rd = new_f; return set; } else return select(global_max_fd + 1, rd, wd, NULL, newtimeout); } /* * Register a filedesc for readable events * Set up its input buffer */ int new_open (int des) { if (des < 0) return des; /* Invalid */ if (!io_rec) init_io(); if (!FD_ISSET(des, &readables)) FD_SET(des, &readables); if (FD_ISSET(des, &writables)) FD_CLR(des, &writables); if (FD_ISSET(des, &held_readables)) FD_CLR(des, &held_readables); if (FD_ISSET(des, &held_writables)) FD_CLR(des, &held_writables); /* * Keep track of the highest fd in use. */ if (des > global_max_fd) global_max_fd = des; return des; } /* * Register a filedesc for readable events * Set up its input buffer */ int new_open_for_writing (int des) { if (des < 0) return des; /* Invalid */ if (!io_rec) init_io(); if (!FD_ISSET(des, &writables)) FD_SET(des, &writables); if (!FD_ISSET(des, &held_writables)) FD_SET(des, &held_writables); /* * Keep track of the highest fd in use. */ if (des > global_max_fd) global_max_fd = des; return des; } /* * This isn't really new, but what the hey.. * * Remove the fd from the select fd sets so * that it won't bother us until we unhold it. * * Note that this is meant to be a read/write * hold and that this only operates on read * sets because that's all the client uses. */ int new_hold_fd (int des) { if (0 <= des && des <= global_max_fd && FD_ISSET(des, &readables)) { FD_SET(des, &held_readables); FD_CLR(des, &readables); } return des; } /* * Add the fd again. */ int new_unhold_fd (int des) { if (0 <= des && des <= global_max_fd && FD_ISSET(des, &held_readables)) { FD_SET(des, &readables); FD_CLR(des, &held_readables); } return des; } /* * Unregister a filedesc for readable events * and close it down and free its input buffer */ int new_close (int des) { if (des < 0) return -1; if (FD_ISSET(des, &readables)) FD_CLR(des, &readables); if (FD_ISSET(des, &writables)) FD_CLR(des, &writables); if (FD_ISSET(des, &held_readables)) FD_CLR(des, &held_readables); if (FD_ISSET(des, &held_writables)) FD_CLR(des, &held_writables); if (io_rec) { if (io_rec[des]) new_free(&io_rec[des]->buffer); new_free((char **)&(io_rec[des])); } close(des); /* * If we're closing the highest fd in use, then we * want to adjust global_max_fd downward to the next highest fd. */ while ( global_max_fd >= 0 && !FD_ISSET(global_max_fd, &readables) && !FD_ISSET(global_max_fd, &held_readables)) global_max_fd--; return -1; } /* set's socket options */ void set_socket_options (int s) { int opt = 1; int optlen = sizeof(opt); #ifndef NO_STRUCT_LINGER struct linger lin; lin.l_onoff = lin.l_linger = 0; setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&lin, optlen); #endif setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, optlen); opt = 1; setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, optlen); #if notyet /* This is waiting for nonblock-aware code */ info = fcntl(fd, F_GETFL, 0); info |= O_NONBLOCK; fcntl(fd, F_SETFL, info); #endif } epic4-2.10.2.orig/source/flood.c0000644000000000000000000002010007734137773013207 0ustar /* $EPIC: flood.c,v 1.15 2003/09/23 21:49:47 jnelson Exp $ */ /* * flood.c: handle channel flooding. * * Copyright (c) 1990-1992 Tomi Ollila * Copyright © 1997, 2003 EPIC Software Labs * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * This attempts to give you some protection from flooding. Basically, it keeps * track of how far apart (timewise) messages come in from different people. * If a single nickname sends more than 3 messages in a row in under a * second, this is considered flooding. It then activates the ON FLOOD with * the nickname and type (appropriate for use with IGNORE). */ #include "irc.h" #include "flood.h" #include "hook.h" #include "ignore.h" #include "ircaux.h" #include "output.h" #include "server.h" #include "vars.h" #include "functions.h" #include "lastlog.h" #include "window.h" static const char *ignore_types[NUMBER_OF_FLOODS] = { "CRAP", "CTCPS", "INVITES", "JOINS", "MSGS", "NICKS", "NOTES", "NOTICES", "PUBLIC", "TOPICS", "WALLOPS", "WALLS" }; typedef struct flood_stru { char *nuh; char *channel; int server; FloodType type; long cnt; Timeval start; int floods; } Flooding; static Flooding *flood = (Flooding *) 0; int users = 0; /* * If flood_maskuser is 0, proceed normally. If 2, keep * track of the @host only. If 1, keep track of the U@H * only if it begins with an alphanum, and use the @host * otherwise. */ static const char * normalize_nuh (const char *nuh) { int maskuser = get_int_var(FLOOD_MASKUSER_VAR); if (maskuser == 0) { } else if (!nuh) { } else if (maskuser == 1 && isalnum(*nuh)) { } else { char *nnuh = strrchr(nuh, '@'); nuh = nnuh ? nnuh : nuh; } return nuh; } /* * check_flooding: This checks for message flooding of the type specified for * the given nickname. This is described above. This will return 0 if no * flooding took place, or flooding is not being monitored from a certain * person. It will return 1 if flooding is being check for someone and an ON * FLOOD is activated. */ int new_check_flooding (const char *nick, const char *nuh, const char *chan, const char *line, FloodType type) { static int pos = 0; int i, numusers, server, retval = 0; Timeval right_now; double diff; Flooding *tmp; /* * Figure out how many people we want to track */ numusers = get_int_var(FLOOD_USERS_VAR); /* * If the number of users has changed, then resize the info array */ if (users != numusers) { i = users; for (i--; i >= numusers; i--) { new_free(&(flood[i].nuh)); new_free(&(flood[i].channel)); } RESIZE(flood, Flooding, numusers); for (i++; i < numusers; i++) { flood[i].nuh = NULL; flood[i].channel = NULL; flood[i].server = NOSERV; flood[i].type = -1; flood[i].cnt = 0; get_time(&(flood[i].start)); flood[i].floods = 0; } users = numusers; if (users) pos %= users; } /* * Following 0 people turns off flood checking entirely. */ if (numusers == 0) { if (flood) new_free((char **)&flood); users = 0; return 0; } if (nuh && *nuh) nuh = normalize_nuh(nuh); else return 0; /* * What server are we using? */ server = (from_server == NOSERV) ? primary_server : from_server; /* * Look in the flooding array. * Find an entry that matches us: * It must be the same flooding type and server. * It must be for the same nickname * If we're for a channel, it must also be for a channel * and it must be for our channel * else if we're not for a channel, it must also not be for * a channel. */ for (i = 0; i < users; i++) { /* * Do some inexpensive tests first */ if (type != flood[i].type) continue; if (server != flood[i].server) continue; if (!flood[i].nuh) continue; /* * Must be for the person we're looking for */ if (my_stricmp(nuh, flood[i].nuh)) continue; /* * Must be for a channel if we're for a channel */ if (!!flood[i].channel != !!chan) continue; /* * Must be for the channel we're looking for. */ if (chan && my_stricmp(chan, flood[i].channel)) continue; /* * We have a winner! */ break; } get_time(&right_now); /* * We didnt find anybody. */ if (i == users) { /* * pos points at the next insertion point in the array. */ int old_pos = pos; do { pos = (0 < pos ? pos : users) - 1; } while (0 < --flood[pos].floods && pos != old_pos); tmp = flood + pos; malloc_strcpy(&tmp->nuh, nuh); if (chan) malloc_strcpy(&tmp->channel, chan); else new_free(&tmp->channel); tmp->server = server; tmp->type = type; tmp->cnt = 0; tmp->start = right_now; pos = (0 < old_pos ? old_pos : users) - 1; return 0; } else tmp = flood + i; /* * Has the person flooded too much? */ if (++tmp->cnt >= get_int_var(FLOOD_AFTER_VAR)) { float rate = get_int_var(FLOOD_RATE_VAR); rate /= get_int_var(FLOOD_RATE_PER_VAR); diff = time_diff(tmp->start, right_now); if ((diff == 0.0 || tmp->cnt / diff >= rate) && (retval = do_hook(FLOOD_LIST, "%s %s %s %s", nick, ignore_types[type], chan ? chan : "*", line))) { tmp->floods++; message_from(chan, LOG_CRAP); if (get_int_var(FLOOD_WARNING_VAR)) say("FLOOD: %ld %s detected from %s in %f seconds", tmp->cnt+1, ignore_types[type], nick, diff); message_from(NULL, LOG_CRAP); } else { /* * Not really flooding -- reset back to normal. */ tmp->cnt = 0; tmp->start = right_now; } } if (get_int_var(FLOOD_IGNORE_VAR)) return retval; else return 0; } int check_flooding (const char *nick, const char *nuh, FloodType type, const char *line) { return new_check_flooding(nick, nuh, NULL, line, type); } /* * Note: This will break whatever uses it when any of the arguments * contain a double quote. */ char * function_floodinfo (char *args) { const char *arg; char *ret = NULL; size_t clue = 0; Timeval right_now; int i; get_time(&right_now); while ((arg = new_next_arg(args, &args))) { if (!strspn(arg, "*?")) arg = normalize_nuh(arg); for (i = 0; i < users; i++) { if (flood[i].nuh && wild_match(arg, flood[i].nuh)) { malloc_strcat_wordlist_c(&ret, space, "\"", &clue); malloc_strcat_wordlist_c(&ret, empty_string, flood[i].nuh, &clue); malloc_strcat_wordlist_c(&ret, space, flood[i].channel ? flood[i].channel : star, &clue); malloc_strcat_wordlist_c(&ret, space, ignore_types[flood[i].type], &clue); malloc_strcat_wordlist_c(&ret, space, ltoa(flood[i].server), &clue); malloc_strcat_wordlist_c(&ret, space, ltoa(flood[i].cnt), &clue); malloc_strcat_wordlist_c(&ret, space, ftoa(time_diff(flood[i].start, right_now)), &clue); malloc_strcat_wordlist_c(&ret, empty_string, "\"", &clue); } } } RETURN_MSTR(ret); } epic4-2.10.2.orig/source/words.c0000644000000000000000000006450410144304404013232 0ustar /* $EPIC: words.c,v 1.20 2004/11/10 03:20:36 jnelson Exp $ */ /* * words.c -- right now it just holds the stuff i wrote to replace * that beastie arg_number(). Eventually, i may move all of the * word functions out of ircaux and into here. Now wouldnt that * be a beastie of a patch! Beastie! Beastie! * * Copyright © 1994, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "ircaux.h" #include "words.h" #include "output.h" /* * If "extended" is 1, then honor /xdebug extractw. * If "extended" is other than 1 but not zero, imply /xdebug extractw. */ #define CHECK_EXTENDED_SUPPORT \ if (extended == DWORD_YES && \ ((x_debug & DEBUG_EXTRACTW) == 0)) \ extended = DWORD_NEVER; \ else if (extended == DWORD_ALWAYS) \ extended = DWORD_YES; \ /* * search() looks for a character forward or backward from mark */ char * search_for (char *start, char **mark, char *chars, int how) { if (!mark || !*mark) *mark = start; if (how > 0) /* forward search */ { *mark = sindex(*mark, chars); how--; for (;(how > 0) && *mark && **mark;how--) *mark = sindex(*mark+1, chars); } else if (how == 0) return NULL; else /* how < 0 */ *mark = rsindex(*mark, start, chars, -how); return *mark; } /* * A "forward quote" is the first double quote we find that has a space * or the end of string after it; or the end of the string. */ static const char * find_forward_character (const char *input, const char *start, const char *whats) { int simple; char what; if (whats && whats[0] && whats[1] == 0) { simple = 1; what = whats[0]; } else { simple = 0; what = 255; } /* * An "extended word" is defined as: * * * := | | <" "> | <"\t"> | <"\n"> * :- <'"'> (from quotechar) * := ANY ASCII CHAR 0 .. 256 */ /* Make sure we are actually looking at a double-quote */ if ( (simple == 1 && *input != what) || (simple == 0 && strchr(whats, *input) == NULL) ) return NULL; /* * Make sure that the character before is the start of the * string or that it is a space. */ if (input > start && !isspace(input[-1])) return NULL; /* * Walk the string looking for a double quote. Yes, we do * really have to check for \'s, still, because the following * still is one word: * "one\" two" * Once we find a double quote, then it must be followed by * either the end of string (chr 0) or a space. If we find * that, return the position of the double-quote. */ for (input++; *input; input++) { if (input[0] == '\\' && input[1]) input++; else if ( (simple == 1 && input[0] == what) || (simple == 0 && strchr(whats, *input)) ) { if (input[1] == 0 || isspace(input[1])) return input; } } /* * If we get all the way to the end of the string w/o finding * a matching double-quote, return the position of the (chr 0), * which is a special meaning to the caller. */ return input; /* Bumped the end of string. doh! */ } /* * A "backward quote" is the first double quote we find, going backward, * that has a space or the start of string after it; or the start of * the string. */ static const char * find_backward_quote (const char *input, const char *start, const char *whats) { const char * saved_input = input; char what; int simple; if (whats && whats[0] && whats[1] == 0) { simple = 1; what = whats[0]; } else { simple = 0; what = 255; } /* * An "extended word" is defined as: * * * := | | <" "> | <"\t"> | <"\n"> * :- <'"'> (from quotechar) * := ANY ASCII CHAR 0 .. 256 */ /* Make sure we are actually looking at a double-quote */ if ( (simple == 1 && *input != what) || (simple == 0 && strchr(whats, *input) == NULL) ) return NULL; /* * Make sure that the character after is either the end of the * string, or that it is a space. */ if (input[1] && !isspace(input[1])) return NULL; /* * Walk the string looking for a double quote. Yes, we do * really have to check for \'s, still, because the following * still is one word: * "one\" two" * Once we find a double quote, then it must be followed by * either the end of string (chr 0) or a space. If we find * that, return the position of the double-quote. */ for (input--; input >= start; input--) { if ( (simple == 1 && *input == what && (input > start && input[-1] == '\\')) || (simple == 0 && strchr(whats, *input) && (input > start && input[-1] == '\\')) ) { input--; } else if ( (simple == 1 && input[0] == what) || (simple == 0 && strchr(whats, *input)) ) { if (input == start || isspace(input[-1])) return input; } else if (input == start) break; /* Stop right here */ } /* * If we get all the way to the start of the string w/o finding * a matching double-quote, then THIS IS NOT AN EXTENDED WORD! * We need to re-do this word entirely by starting over and looking * for a normal word. */ input = saved_input; while (input > start && !isspace(input[0])) input--; if (isspace(input[0])) input++; /* Just in case we've gone too far */ return input; /* Wherever we are is fine. */ } /* * 'move_to_prev_word': Move a "mark" from its current position to the * beginning of the "previous" word. * * Arguments: * 'str' - a pointer to a character pointer -- The initial value is the * "mark", and it will be changed upon return to the beginning * of the previous word. * 'start' - The start of the string that (*str) points to. * 'extended' - Whether double quoted words shall be supported * 'delims' - The types of double quoets to honor (if applicable) * * Return value: * If (*str) points to 'start' or is NULL (there is no previous word) * the return value is 0. * Otherwise, the return value is 1. * * Notes: * Regardless of whether 'start' is actually the start of the string that * '*str' points to, this function will treat it as such and will never go * backwards further than 'start'. * If (*str) points to the nul that terminates 'start', then (*str) shall * be set to the first character in the last word in 'start'. * If (*str) points to the first character in any word, then (*str) shall * be set to the first character in the full word BEFORE (*str). * If (*str) points to the middle of a string, then (*str) shall be set to * the first character IN THAT WORD (*str) points to. * If (*str) points to a space, then (*str) shall be set to the first * character in the word before the space. * A "word" always begins on the second character after the end of a word * because the first character after a word is a space (which is reserved * because we might want to change it to a nul). That means if there is * more than one space between words, the first space belongs to the "left" * word and all the rest of the spaces belong to the "right" word! * * XXX - The debugging printfs are ugly. */ static int move_to_prev_word (const char **str, const char *start, int extended, const char *delims) { char what; int simple; const char *pos; if (!str || *str <= start) return 0; /* Overhead -- work out if "" support will be cheap or expensive */ if (delims && delims[0] && delims[1] == 0) { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Simple processing"); simple = 1; what = delims[0]; } else { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Expensive processing"); simple = 0; what = 255; } /* Overhead -- work out if we're doing "" support or not. */ CHECK_EXTENDED_SUPPORT /* Start at the mark the user provided us */ pos = *str; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Starting at [%s] (in [%s])", pos, start); /* * XXX This is a hack, but what do i care? * If we are pointing at the start of a string, then * we want to go to the PREVIOUS word, so cheat by * stepping off the word. This means if you want the * last word, you need to point to the nul, not the last * character before the nul! */ if (pos > start && isspace(pos[-1])) pos--; /* * Skip over whitespace */ while (pos >= start && ((*pos == 0) || my_isspace(*pos))) pos--; /* * In the above 'mark1' case (the normal case), we would be pointing * at the last character in 'two'. If this were a double quoted word * then this would be a double quote of some sort, and this code * checks for that. If it finds a double quote, then it moves to the * "matching" double quote. */ if (pos > start && extended == DWORD_YES && ( (simple == 1 && *pos == what) || (simple == 0 && strchr(delims, *pos)) ) ) { const char * before; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Handling extended word."); if (!(before = find_backward_quote(pos, start, delims))) panic("find_backward returned NULL [2]"); if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Extended word begins at [%s] (of [%s])", before, start); /* * "Before" either points at a double quote or it points * at the start of the string. If it points at a double * quote, move back one position so it points at a space. */ if (before > start) before--; /* So our new mark is the space before the double quoted word */ pos = before; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: So the position before the extended word is [%s] (of [%s])", pos, start); } /* * If this is not a double quoted word, keep moving backwards until * we find a space -- so our new mark is the space before the start * of the word. */ else { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Handling simple word."); while (pos >= start && !my_isspace(*pos)) pos--; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: So the position before the simple word is [%s] (of [%s])", pos, start); } /* * If we hit the front of the string (*gulp*), set the return value * (*str) to the start of the string and just punt right here. */ if (pos <= start) { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: Ooops. we hit the start " "of the string. Stopping here."); *str = start; return 1; } /* * Slurp up spaces. */ else { while (*pos && isspace(*pos)) pos++; while (pos > start && isspace(pos[0]) && isspace(pos[-1])) pos--; } if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_prev_word: And after we're done, [%s] is " "the start of the previous word!", pos); *str = pos; return 1; } /* * 'move_to_next_word': Move a "mark" from its current position to the * beginning of the "next" word. * * Arguments: * 'str' - a pointer to a character pointer -- The initial value is the * "mark", and it will be changed upon return to the beginning * of the previous word. * 'start' - The start of the string that (*str) points to. * 'extended' - Whether double quoted words shall be supported * 'delims' - The types of double quoets to honor (if applicable) * * Return value: * If (*str) is NULL or points to the end of a string (there is no next * word) the return value is 0. * Otherwise, the return value is 1. * * Notes: * Regardless of whether 'start' is actually the start of the string that * '*str' points to, this function will treat it as such and will never go * backwards further than 'start'. * If (*str) points to the nul that terminates 'start', then (*str) shall * be set to the first character in the last word in 'start'. * If (*str) points to the first character in any word, then (*str) shall * be set to the first character in the full word BEFORE (*str). * If (*str) points to the middle of a string, then (*str) shall be set to * the first character IN THAT WORD (*str) points to. * If (*str) points to a space, then (*str) shall be set to the first * character in the word before the space. * A "word" always begins on the second character after the end of a word * because the first character after a word is a space (which is reserved * because we might want to change it to a nul). That means if there is * more than one space between words, the first space belongs to the "left" * word and all the rest of the spaces belong to the "right" word! * EXCEPT WHEN there are trailing spaces on a string and we are already in the * last word (there is not a next word). In that case, ths current word * claims all of the trailing spaces and (*str) is set to the trailing nul. * * XXX - The debugging printfs are ugly. */ static int move_to_next_word (const char **str, const char *start, int extended, const char *delims) { char what; int simple; #if 0 const char * mark2; #endif const char * pos; /* * If there is not a word, then just stop right here. */ if (!str || !*str || !**str) return 0; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(">>>> move_to_next_word: mark [%s], start [%s], " "extended [%d], delims [%s]", *str, start, extended, delims); /* * If "delims" has only one character, then we can do the double * quote support simply (by comapring characters), otherwise we have * to do it by calling strchr() for each character. Ick. */ if (delims && delims[0] && delims[1] == 0) { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: Simple processing"); simple = 1; what = delims[0]; } else { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: Expensive processing"); simple = 0; what = 255; } /* * Here we check to see if we even want to do extended word support. * The user can always have the option to turn it off. */ CHECK_EXTENDED_SUPPORT if (x_debug & DEBUG_EXTRACTW_DEBUG) { yell(".... move_to_next_word: Extended word support requested [%d]", extended == DWORD_YES); yell(".... move_to_next_word: Extended word support for simple case valid [%d]", simple == 1 && **str == what); yell(".... move_to_next_word: Extended word support for complex case valid [%d]", simple == 0 && strchr(delims, **str)); } /* Start at where the user asked, eh? */ pos = *str; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: starting at [%s]", pos); /* * Always skip leading spaces */ while (*pos && isspace(*pos)) pos++; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: after skipping spaces, [%s]", pos); /* * Now check to see if this is an extended word. If it is an * extended word, move to the "end" of the word, which is the * matching puncutation mark. */ if (extended == DWORD_YES && ( (simple == 1 && *pos == what) || (simple == 0 && strchr(delims, *pos)) ) ) { const char * after; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: handling extended word"); if (!(after = find_forward_character(pos, start, delims))) panic("find_forward returned NULL [1]"); if (*after) after++; pos = after; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: after extended word [%s]", pos); } /* * If this is not an extended word, just skip to the next space. */ else { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: handling simple word [%s]", pos); while (*pos && !my_isspace(*pos)) pos++; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(".... move_to_next_word: at next space: [%s]", pos); } #if 0 /* * 'pos' now points at the space just after the end of the word; * This space belongs to us, but any further spaces do not long * belong to us, unless there are no more words after us! So we * need to check this. */ /* -- Is the rest of a string just spaces? -- */ if (x_debug & DEBUG_EXTRACTW_DEBUG) yell("... move_to_next_word: looking for another word..."); mark2 = pos; while (*mark2 && my_isspace(*mark2)) mark2++; if (!*mark2) /* Only spaces after this. Ok. */ { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell("... move_to_next_word: didn't find one."); pos = mark2; } /* The start of the next word is after our space. */ else { if (x_debug & DEBUG_EXTRACTW_DEBUG) yell("... move_to_next_word: there's another word."); pos++; } #else if (*pos) pos++; #endif if (x_debug & DEBUG_EXTRACTW_DEBUG) yell("... move_to_next_word: next word starts with [%s]", pos); *str = pos; return 1; } /* * 'real_move_to_abs_word' -- Find the start of the 'word'th word in 'start'. * * Arguments: * 'start' - The string we will look into * 'mark' - A pointer to a (char *) where we will set the return value. * MAY BE NULL * 'word' - The number of the word we want to find * 'extended' - Whether or not to support double quoted words * 'quotes' - The types of double quotes we will support. * * Return value: * The return value is the beginning of the 'word'th word in 'start'. * This may include leading whitespace which you will need to trim if * you don't want surroundign whitespace. This may include trailing * whitespace if you ask for the last word and there is trailing whitespace. * * Notes: * 'mark' is not used as an input parameter. Upon return, it is set to * the return value. * The return value is suitable for passing to 'strext' if you wanted to * extract a string ending with the previous word! * Word numbering always counts from 0. */ const char * real_move_to_abs_word (const char *start, const char **mark, int word, int extended, const char *quotes) { const char * pointer = start; int counter = word; if (x_debug & DEBUG_EXTRACTW_DEBUG) yell(">>>> real_move_to_abs_word: start [%s], count [%d], extended [%d], quotes [%s]", start, word, extended, quotes); for (; counter > 0 && *pointer; counter--) move_to_next_word(&pointer, start, extended, quotes); if (x_debug & DEBUG_EXTRACTW_DEBUG) yell("<<<< real_move_to_abs_word: pointer [%s]", pointer); if (mark) *mark = pointer; return pointer; } /* * Return the number of words in 'str' as defined by 'real_move_to_abs_word' */ int count_words (const char *str, int extended, const char *quotes) { const char * pointer = str; int counter = 0; while (move_to_next_word(&pointer, str, extended, quotes)) counter++; return counter; } /* * Move a relative number of words from the present mark */ ssize_t move_word_rel (const char *start, const char **mark, int word, int extended, const char *quotes) { int counter = word; const char * pointer = *mark; const char * end = start + strlen(start); if (end == start) /* null string, return it */ return 0; if (counter > 0) { for (;counter > 0 && *pointer;counter--) move_to_next_word(&pointer, start, extended, quotes); } else if (counter == 0) pointer = *mark; else /* counter < 0 */ { for (; counter < 0 && pointer > start; counter++) move_to_prev_word(&pointer, start, extended, quotes); } if (mark) *mark = pointer; return pointer - start; } /* * extract2 is the word extractor that is used when its important to us * that 'firstword' get special treatment if it is negative (specifically, * that it refer to the "firstword"th word from the END). This is used * basically by the ${n}{-m} expandos and by function_rightw(). */ char * real_extract2 (const char *start, int firstword, int lastword, int extended) { const char * mark; const char * mark2; char * retval; /* * 'firstword == EOS' means we should return the last word * This is used for $~. Handle the whole shebang here. */ if (firstword == EOS) { /* Mark to the end of the string... */ mark = start + strlen(start); /* And move to the start of that word */ move_word_rel(start, &mark, -1, extended, "\""); return malloc_strdup(mark); } /* * 'firstword == SOS' means the user did $-. * The start of retval is start of string. */ else if (firstword == SOS) mark = start; /* * 'firstword is not negative' means user wants to start at * the th word. Move the mark to that position. * * If the mark does not exist (ie, $10- when there are not * 10 words), fail by returning the empty string. */ else if (firstword >= 0) { real_move_to_abs_word(start, &mark, firstword, extended, "\""); if (!*mark) return malloc_strdup(empty_string); } /* * 'firstword is negative' means user wants to start at the * th word from the end. Move the mark to that * position. This is used for $rightw() and stuff. */ else { mark = start + strlen(start); move_word_rel(start, &mark, firstword, extended, "\""); } /*****************************************************************/ /* * So now 'mark' points at the start of the string we want to * return; this should include the spaces that lead up to the word. * * Now we need to find the end of the string to return. */ /* * 'lastword is EOS' means the user did $-, so cheat by * just returning the mark */ if (lastword == EOS) return malloc_strdup(mark); /* * 'lastword is nonnegative' means the user did $-, * so we need to move to the start of the and go back * one position -- easy, eh? */ else if (lastword >= 0) real_move_to_abs_word(start, &mark2, lastword + 1, extended, "\""); /* * 'lastword is negative' means the user wants all but the last * words, so we move to the start of the th word from * the end, and go back one character! */ else { mark2 = start + strlen(start); move_word_rel(start, &mark2, lastword, extended, "\""); } /* * move back one position, because we are the start of the NEXT word. */ if (*mark2 && mark2 > start) mark2--; /* * If the end is before the string, then there is nothing * to extract (this is perfectly legal, btw) */ if (mark2 < mark) return malloc_strdup(empty_string); /* * XXX Backwards compatability requires that $ not * have any leading spaces. */ if (firstword == lastword) { while (mark && *mark && isspace(*mark)) mark++; } /* * This is kind of tricky, because the string we are * copying out of is const. So we cant just null off * the trailing character and malloc_strdup it. */ retval = strext(mark, mark2); /* * XXX Backwards compatability requires that $ not have * any trailing spaces, even if it is the last word. */ if (firstword == lastword) remove_trailing_spaces(retval, 0); return retval; } /* * extract is a simpler version of extract2, it is used when we dont * want special treatment of "firstword" if it is negative. This is * typically used by the word/list functions, which also dont care if * we strip out or leave in any whitespace, we just do what is the * fastest. */ char * real_extract (char *start, int firstword, int lastword, int extended) { /* * firstword and lastword must be zero. If they are not, * then they are assumed to be invalid However, please note * that taking word set (-1,3) is valid and contains the * words 0, 1, 2, 3. But word set (-1, -1) is an empty_string. */ const char * mark; const char * mark2; char * booya = NULL; CHECK_EXTENDED_SUPPORT /* * Before we do anything, we strip off leading and trailing * spaces. * * ITS OK TO TAKE OUT SPACES HERE, AS THE USER SHOULDNT EXPECT * THAT THE WORD FUNCTIONS WOULD RETAIN ANY SPACES. (That is * to say that since the word/list functions dont pay attention * to the whitespace anyhow, noone should have any problem with * those ops removing bothersome whitespace when needed.) */ while (*start && my_isspace(*start)) start++; remove_trailing_spaces(start, 0); if (firstword == EOS) { mark = start + strlen(start); move_word_rel(start, (const char **)&mark, -1, extended, "\""); } /* If the firstword is positive, move to that word */ else if (firstword >= 0) real_move_to_abs_word(start, (const char **)&mark, firstword, extended, "\""); /* Its negative. Hold off right now. */ else mark = start; /* * When we find the last word, we need to move to the * END of the word, so that word 3 to 3, would include * all of word 3, so we sindex to the space after the word */ /* EOS is a #define meaning "end of string" */ if (lastword == EOS) mark2 = start + strlen(start); else { if (lastword >= 0) real_move_to_abs_word(start, (const char **)&mark2, lastword+1, extended, "\""); else /* its negative -- thats not valid */ return malloc_strdup(empty_string); while (mark2 > start && my_isspace(mark2[-1])) mark2--; } /* * Ok.. now if we get to here, then lastword is positive, so * we sanity check firstword. */ if (firstword < 0) firstword = 0; if (firstword > lastword) /* this works even if fw was < 0 */ return malloc_strdup(empty_string); /* * If the end is before the string, then there is nothing * to extract (this is perfectly legal, btw) */ if (mark2 < mark) return malloc_strdup(empty_string); booya = strext(mark, mark2); return booya; } epic4-2.10.2.orig/source/expr2.c0000644000000000000000000017016410144304403013133 0ustar /* $EPIC: expr2.c,v 1.19 2004/11/10 03:20:35 jnelson Exp $ */ /* * Zsh: math.c,v 3.1.2.1 1997/06/01 06:13:15 hzoli Exp * math.c - mathematical expression evaluation * This file is based on 'math.c', which is part of zsh, the Z shell. * * Copyright (c) 1992-1997 Paul Falstad, All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright notice, * this list of conditions and the two following paragraphs. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * In no event shall Paul Falstad or the Zsh Development Group be liable * to any party for direct, indirect, special, incidental, or consequential * damages arising out of the use of this software and its documentation, * even if Paul Falstad and the Zsh Development Group have been advised of * the possibility of such damage. * * Paul Falstad and the Zsh Development Group specifically disclaim any * warranties, including, but not limited to, the implied warranties of * merchantability and fitness for a particular purpose. The software * provided hereunder is on an "as is" basis, and Paul Falstad and the * Zsh Development Group have no obligation to provide maintenance, * support, updates, enhancements, or modifications. * */ /* * Substantial modifications by Jeremy Nelson which are * Coypright 1998, 2003 EPIC Software Labs, All rights reserved. * * You may distribute this file under the same terms as the above, by * including the parties "Jeremy Nelson" and "EPIC Software Labs" to the * limitations of liability and the express disclaimer of all warranties. * This software is provided "AS IS". */ #include #define STACKSZ 80 #define TOKENCOUNT 80 #define MAGIC_TOKEN -14 /* * THIS IS THE "NEW NEW" MATH PARSER -- or shall I say, this is the * new math parser, second edition. */ /* * Question: Why is this math parser so much more hideous than the old one? * * Answer: The implementation looks very very complex, and to a certain * extent it is. However, do not be frightened by the malicious abuse of * macros and the over-use of inline functions. The design of this math * parser is not nearly as complex as its implementation. Maybe that is * due to my not being the world's best C programmer, and I probably wrote * this code too quickly. One of the most important design considerations * was that it should be possible to prove correctness, while maintaining * the possibility for general optimization. Those are conflicting goals * and this implementation tries to balance the two. */ /* * Question: Why should I use this math parser instead of the old one? * * Answer: Like the old math parser, this new math parser evaluates infix * notation expressions and returns the resulting value of the entire * expression. Unlike the old math parser, this new math parser correctly * obeys both operator precedence as well as associativity. It still can * do short-circuiting of &&, ||, and ?: operators. All operands start * off their life as text strings, but can be converted to and from other * data types (such as floating point, integer, and boolean). Type conversion * is automatic and efficient, and the results of every conversion is cached, * so the conversion is only done once, and only when it is actually needed. * This new math parser has a slew of new operators, as well as correct * implementations of some of the old operators. This new math parser also * handles both integer and floating point operations gracefully. */ /* * Question: Why is everything stored in a struct? * * Answer: All the information for each expression is stored in a struct. * This is done so that there are no global variables in use (they're all * collected making them easier to handle), and makes re-entrancy possible * since you don't have to worry about whether or not all of the state * information is accounted for (it's all on the stack). */ /* * Question: Why do you keep a 'symbol table' for each expression? * * By keeping a record of every direct symbol or derived symbol during * the entire lifetime of the expression, we can be assured that we have * a clean way to clean up after an expression (no memory leaks), and * permit a reference to any operator to persist for the entire lifetime * of the expression, without having to worry about who might be holding * a reference to an operand (tokens never change over their lifetime). * By refering to each token through an integer, rather than a pointer, * we can also prevent stale pointers, which can cause crashes. * * This also solves several more problems. There is never any concern over * whether or not a certain string is malloced(), or just who is responsible * for free()ing it. If you need a value to stay around as a temporary value * you can always tokenize() it and get a handle which you then use further. * The value will not go away until the entire expression has been parsed. */ /* * Question: Why don't you support pre-compiled expressions? * * Because this implementation does not create a compiled spanning tree * out of the expression before executing it, but rather tokenizes the * operands and reduces the operations based on prior operations. Perhaps * this might change in the future, but don't count on it. The lexer uses * the results of prior operations to support such things as short circuits * and changing that would be a big pain. */ typedef int TOKEN; typedef int BooL; /* * These flags tell us whether or not a given token has a useful value * of the given type. This is used to tell us when we need to do automatic * conversion, or whether the conversion was done before and we can just * grab the cached value. These flags are used by the "used" field, and * are cumulative. */ #define USED_NONE 0 #define USED_LVAL 1 << 0 #define USED_RAW 1 << 1 #define USED_EXPANDED 1 << 2 #define USED_INTEGER 1 << 3 #define USED_FLOAT 1 << 4 #define USED_BOOLEAN 1 << 5 /* * Theoretically, all these macros are independant because the return value of * INT*FUNC is typecasted back to INTTYPE. One caveat is that INT2STR * must return a malloc'd string. */ #ifdef HAVE_LONG_LONG typedef long long INTTYPE; #define FORMAT "%lld" #define STR2INT(x) ((INTTYPE)atoll(x)) #define INT2STR(x) (malloc_sprintf(NULL, FORMAT , (INTTYPE)(x))) #else typedef long INTTYPE; #define FORMAT "%ld" #define STR2INT(x) ((INTTYPE)atol(x)) #define INT2STR(x) (malloc_sprintf(NULL, FORMAT , (INTTYPE)(x))) #endif /* * This is a symbol table entry. */ typedef struct TOKEN_type { int used; /* Which fields contain useful info? */ char * lval; /* Cached unexpanded variable name */ char * raw_value; /* Cached unexpected string */ char * expanded_value; /* Cached full expanded string */ INTTYPE integer_value; /* Cached integer value */ double float_value; /* Cached floating point value */ short boolean_value; /* Cached boolean value */ } SYMBOL; #define __inline /* * This is an expression context */ typedef struct { /* POSITION AND STATE INFORMATION */ /* * This is the current position in the lexing. */ char *ptr; /* * When set, the expression is lexed, but nothing that may have a side * effect (function calls, assignments, etc) are actually performed. * Dummy values are instead substituted. */ int noeval; /* * When set, this means the next token may either be a prefix operator * or an operand. When clear, it means the next operator must be a * non-prefix operator. */ int operand; /* TOKEN TABLE */ /* * Each registered 'token' is given a TOKEN id. The idea is * that we want TOKEN to be an opaque type to be used to refer * to a token in a generic way, but in practice its just an integer * offset into a char ** table. We register all tokens sequentially, * so this just gets incremented when we want to register a new token. */ TOKEN token; /* * This is the list of operand (string) tokens we have extracted * so far from the expression. Offsets into this array are stored * into the parsing stack. */ SYMBOL tokens[TOKENCOUNT + 1]; /* OPERAND STACK */ /* * This is the operand shift stack. These are the operands that * are currently awaiting reduction. Note that rather than keeping * track of the lvals and rvals here, we simply keep track of offsets * to the 'tokens' table that actually stores all the relevant data. * Then we can just call the token-class functions to get that data. * This is more efficient because it allows us to recycle tokens * more reasonably without wasteful malloc-copies. */ TOKEN stack[STACKSZ + 1]; /* Current index to the operand stack */ int sp; /* This is the last token that was lexed. */ TOKEN mtok; /* This is set when an error happens */ int errflag; TOKEN last_token; const char *args; int *args_flag; } expr_info; /* * Useful macro to get at a specific token. * 'c' is the expression context, 'v' is the token handle. */ #define TOK(c, v) c->tokens[v] /* Forward function references */ __inline static TOKEN tokenize_raw (expr_info *c, char *t); static char * after_expando_special (expr_info *c); static char * alias_special_char (char **buffer, char *ptr, const char *args, char *quote_em, int *args_flag); /******************** EXPRESSION CONSTRUCTOR AND DESTRUCTOR ****************/ /* * Clean the expression context pointed to by 'c'. * This function must be called before you call mathparse(). */ static void setup_expr_info (expr_info *c) { int i; c->ptr = NULL; c->noeval = 0; c->operand = 1; c->token = 0; for (i = 0; i <= TOKENCOUNT; i++) { TOK(c, i).used = USED_NONE; TOK(c, i).lval = NULL; TOK(c, i).raw_value = NULL; TOK(c, i).expanded_value = NULL; TOK(c, i).integer_value = 0; TOK(c, i).float_value = 0; TOK(c, i).boolean_value = 0; } for (i = 0; i <= STACKSZ; i++) c->stack[i] = 0; c->sp = -1; c->mtok = 0; c->errflag = 0; c->last_token = 0; tokenize_raw(c, empty_string); /* Always token 0 */ } /* * Clean up the expression context pointed to by 'c'. * This function must be called after you call mathparse(). */ static void destroy_expr_info (expr_info *c) { int i; c->ptr = NULL; c->noeval = -1; c->operand = -1; for (i = 0; i < c->token; i++) { TOK(c, i).used = USED_NONE; new_free(&TOK(c, i).lval); new_free(&TOK(c, i).raw_value); new_free(&TOK(c, i).expanded_value); } c->token = -1; for (i = 0; i <= STACKSZ; i++) c->stack[i] = -1; c->sp = -1; c->mtok = -1; c->errflag = -1; c->last_token = -1; } /**************** TOKEN, PRECEDENCE, and ASSOCITIVITY TABLES ****************/ /* * LR = left-to-right associativity * RL = right-to-left associativity * BOOL = short-circuiting boolean */ #define LR 0 #define RL 1 #define BOOL 2 /* * These are all the token-types. Each of the operators is represented, * as is the generic operand type */ enum LEX { M_INPAR, NOT, COMP, PREMINUS, PREPLUS, UPLUS, UMINUS, STRLEN, WORDC, DEREF, POWER, MUL, DIV, MOD, PLUS, MINUS, STRCAT, SHLEFT, SHRIGHT, LES, LEQ, GRE, GEQ, MATCH, NOMATCH, DEQ, NEQ, AND, XOR, OR, DAND, DXOR, DOR, QUEST, COLON, EQ, PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ, ANDEQ, XOREQ, OREQ, SHLEFTEQ, SHRIGHTEQ, DANDEQ, DOREQ, DXOREQ, POWEREQ, STRCATEQ, STRPREEQ, SWAP, COMMA, POSTMINUS, POSTPLUS, ID, M_OUTPAR, ERROR, EOI, TOKCOUNT }; /* * Precedence table: Operators with a lower precedence VALUE have a higher * precedence. The theory behind infix notation (algebraic notation) is that * you have a sequence of operands seperated by (typically binary) operators. * The problem of precedence is that each operand is surrounded by two * operators, so it is ambiguous which operator the operand "binds" to. This * is resolved by "precedence rules" which state that given two operators, * which one is allowed to "reduce" (operate on) the operand. For a simple * explanation, take the expression (3+4*5). Now the middle operand is a * '4', but we dont know if it should be reduced via the plus, or via the * multiply. If we look up both operators in the prec table, we see that * multiply has the lower value -- therefore the 4 is reduced via the multiply * and then the result of the multiply is reduced by the addition. */ static int prec[TOKCOUNT] = { 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 2, 2, 0, 137, 156, 200 }; #define TOPPREC 21 /* * Associativity table: But precedence isnt enough. What happens when you * have two identical operations to determine between? Well, the easy way * is to say that the first operation is always done first. But some * operators dont work that way (like the assignment operator) and always * reduce the LAST (or rightmost) operation first. For example: * (3+4+5) ((4+3)+5) (7+5) (12) * (v1=v2=3) (v1=(v2=3)) (v1=3) (3) * So for each operator we need to specify how to determine the precedence * of the same operator against itself. This is called "associativity". * Left-to-right associativity means that the operations occur left-to-right, * or first-operator, first-reduced. Right-to-left associativity means * that the operations occur right-to-left, or last-operator, first-reduced. * * We have a special case of associativity called BOOL, which is just a * special type of left-to-right associtivity whereby the right hand side * of the operand is not automatically parsed. (not really, but its the * theory that counts.) */ static int assoc[TOKCOUNT] = { LR, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, LR, BOOL, BOOL, BOOL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, RL, LR, RL, RL, LR, LR, LR, LR }; /* ********************* CREATE NEW SYMBOLS AND TOKENS ********************/ /* Lvalues are stored via this routine */ __inline static TOKEN tokenize_lval (expr_info *c, const char *t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_LVAL; malloc_strcpy(&TOK(c, c->token).lval, t); return c->token++; } /* * This is where we store our rvalues, kind of. What we really store here * are all of the string operands from the original expression. Whenever * one of the original operands is parsed, it is converted to a string and * put in here and the index into the 'token' table is returned. Only the * operands of the original expression go here. All derived operands (the * result of operators) directly create "expanded" tokens. */ /* THIS FUNCTION MAKES A NEW COPY OF 'T'. YOU MUST DISPOSE OF 'T' YOURSELF */ __inline static TOKEN tokenize_raw (expr_info *c, char *t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_RAW; malloc_strcpy(&TOK(c, c->token).raw_value, t); return c->token++; } /* * This is where any rvalues are stored. The result of any operation that * yeilds a string creates an 'expanded' token. Tokens that begin life as * 'expanded' tokens never can be passed through expand_alias() again. This * protects against possible security holes in the client. */ __inline static TOKEN tokenize_expanded (expr_info *c, char *t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_EXPANDED; malloc_strcpy(&TOK(c, c->token).expanded_value, t); return c->token++; } /* * This creates an integer token. This is useful for quick operation on * complex mathematical expressions, where conversions to and from strings * is both expensive, and unnecesary. This type of token is created by * integer-only operations like &, |, ^, <<, >>. */ __inline static TOKEN tokenize_integer (expr_info *c, INTTYPE t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_INTEGER; TOK(c, c->token).integer_value = t; return c->token++; } /* * This creates a floating point token. This is useful for the same things * that integer tokens are, and this is the token generated by floating * point operations, such as +, -, *, /, %, **. */ __inline static TOKEN tokenize_float (expr_info *c, double t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_FLOAT; TOK(c, c->token).float_value = t; return c->token++; } /* * This creates a boolean token. This is useful for the same things as * integer tokens are. This token is generated by any sort of logic * operation, such as ==, !=, >, <, &&, ||. */ __inline static TOKEN tokenize_bool (expr_info *c, BooL t) { if (c->token >= TOKENCOUNT) { error("Too many tokens for this expression"); return -1; } TOK(c, c->token).used = USED_BOOLEAN; TOK(c, c->token).boolean_value = t; return c->token++; } /******************** RETRIEVE SYMBOLS FROM TOKEN HANDLES *******************/ /* * These functions permit you to get at the tokens in various ways. * There is a definite concept of each token being stored in several * different representations: "raw" format (as the user specified it * in the expression), "expanded" format (what the raw value looks like * after it is passed through expand_alias), "integer" format (what the * expanded value looks like after a call to atol()), "float" format, * (what the expanded value looks like after a call to atof()), and * "boolean" format (what the expanded value looks like after a call to * check_val()). Each of these types are created on demand; so that if * a token is never referenced in an integer context, the expensive * conversion to an integer is not performed. This is inteded to keep * the number of unnecesary conversions to an absolute minimum. * * YOU MUST NOT EVER -- EVER -- FREE THE RETURN VALUE FROM ANY OF THESE * FUNCTIONS! TO DO SO WILL CRASH THE CLIENT! YOU HAVE BEEN WARNED! */ /* * Get the "raw" value of the token. For tokens that have been created * via "tokenize", nothing has to be done since the raw value is already * present. However, for computed tokens (such as the result of a math * operation), the raw token may not actually exist, and so it must be * infered from whatever data is available. We use the value that has * the most information, starting with expanded string, to the boolean * value. */ __inline static const char * get_token_raw (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return c->args; /* XXX Probably wrong */ if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return get_token_raw(c, 0); /* The empty token */ } if (v == 0) return empty_string; if (c->noeval) return get_token_raw(c, 0); #if 0 panic("c->noeval is not valid here. [1]"); #endif if ((TOK(c, v).used & USED_RAW) == 0) { TOK(c, v).used |= USED_RAW; if (TOK(c, v).used & USED_EXPANDED) panic("Cannot convert EXPANDED token to RAW"); else if (TOK(c, v).used & USED_FLOAT) { TOK(c, v).raw_value = malloc_sprintf(NULL, "%f", TOK(c, v).float_value); canon_number(TOK(c, v).raw_value); } else if (TOK(c, v).used & USED_INTEGER) TOK(c, v).raw_value = INT2STR(TOK(c, v).integer_value); else if (TOK(c, v).used & USED_BOOLEAN) TOK(c, v).raw_value = malloc_sprintf(NULL, "%d", TOK(c, v).boolean_value); else if (TOK(c, v).used & USED_LVAL) { if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(">>> Expanding var name [%d]: [%s]", v, TOK(c, v).lval); TOK(c, v).raw_value = expand_alias(TOK(c, v).lval, c->args, c->args_flag, NULL); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(">>> Expanded var name [%d]: [%s] to [%s]", v, TOK(c, v).lval, TOK(c, v).raw_value); } else panic("Can't convert this token to raw format"); } return TOK(c, v).raw_value; } /* * This is kind of funky. This is used to get the "fully qualified" * lvalue for a given token. What that means is that this is not the * raw value of TOK(c, v).lval, but is rather TOK(c, v).raw, but if * and only if (TOK(c, v).used & USED_LVAL)! Otherwise, this returns * NULL and emits an error. */ __inline static const char * get_token_lval (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return c->args; /* XXX Probably wrong */ if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return NULL; /* No lvalue here! */ } if (v == 0) return NULL; /* Suppress the operation entirely */ else if (c->noeval) { return NULL; /* Suppress the operation entirely */ #if 0 return get_token_raw(c, 0); panic("c->noeval is not valid here. [0]"); #endif } else if (((TOK(c, v).used & USED_LVAL) == 0)) { error("Token [%d] is not an lvalue", v); return NULL; /* No lvalue here! */ } else return get_token_raw(c, v); } /* * Get the "expanded" representation of the token. The first time you * call this function, it gets the "raw" value, if there is one, and then * call expand_alias() to get the value. Of course, there is always a * "raw" value, as get_token_raw() can convert from anything. */ __inline static const char * get_token_expanded (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return c->args; if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return get_token_expanded(c, 0); /* The empty token */ } if (v == 0) return get_token_raw(c, 0); if (c->noeval) return get_token_raw(c, 0); #if 0 panic("c->noeval is not valid here. [2]"); #endif if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(">>> Getting token [%d] now.", v); if ((TOK(c, v).used & USED_EXPANDED) == 0) { char *myval; myval = LOCAL_COPY(get_token_raw(c, v)); TOK(c, v).used |= USED_EXPANDED; /* * If this token started off life as an lval, then the * "raw" value of this token will yeild the expanded form * of the lvalue, suitable for passing to alias_special_char. */ if (TOK(c, v).used & USED_LVAL) { char *buffer = NULL; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(">>> Looking up variable [%d]: [%s]", v, myval); alias_special_char(&buffer, myval, c->args, NULL, c->args_flag); if (!buffer) buffer = malloc_strdup(empty_string); TOK(c, v).expanded_value = buffer; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("<<< Expanded variable [%d] [%s] to: [%s]", v, myval, TOK(c, v).expanded_value); } /* * Otherwise, this token started off life as an rval * (such as a [...] string), and only needs to be expanded * with alias_special_char to yeild a useful value. */ else if (TOK(c, v).used & USED_RAW) { if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(">>> Expanding token [%d]: [%s]", v, myval); TOK(c, v).used |= USED_EXPANDED; TOK(c, v).expanded_value = expand_alias(myval, c->args, c->args_flag, NULL); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("<<< Expanded token [%d]: [%s] to: [%s]", v, myval, TOK(c, v).expanded_value); } else panic("Cannot convert from this token to EXPANDED"); } if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("<<< Token [%d] value is [%s].", v, TOK(c, v).expanded_value); return TOK(c, v).expanded_value; } /* * Get the integer representation of the token. The first time you call * this function, it calls atof() on the "raw" value, if there is one, * to get the result. */ __inline static INTTYPE get_token_integer (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return STR2INT(c->args); /* XXX Probably wrong */ if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return 0; /* The empty token */ } if ((TOK(c, v).used & USED_INTEGER) == 0) { const char * myval = get_token_expanded(c, v); TOK(c, v).used |= USED_INTEGER; TOK(c, v).integer_value = STR2INT(myval); } return TOK(c, v).integer_value; } /* * Get the floating point value representation of the token. */ __inline static double get_token_float (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return atof(c->args); /* XXX Probably wrong */ if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return 0.0; /* The empty token */ } if ((TOK(c, v).used & USED_FLOAT) == 0) { const char * myval = get_token_expanded(c, v); TOK(c, v).used |= USED_FLOAT; TOK(c, v).float_value = atof(myval); } return TOK(c, v).float_value; } /* * Get the boolean value of the token */ __inline static BooL get_token_boolean (expr_info *c, TOKEN v) { if (v == MAGIC_TOKEN) /* Magic token */ return check_val(c->args); /* XXX Probably wrong */ if (v < 0 || v >= c->token) { error("Token index [%d] is out of range", v); return 0; /* The empty token */ } if ((TOK(c, v).used & USED_BOOLEAN) == 0) { const char * myval = get_token_expanded(c, v); TOK(c, v).used |= USED_BOOLEAN; TOK(c, v).boolean_value = check_val(myval); } return TOK(c, v).boolean_value; } /* *********************** ADD TO OPERAND STACK **************************** */ /* * Adding (shifting) and Removing (reducing) operands from the stack is a * fairly straightforward process. The general way to add an token to * the stack is to pass in its TOKEN index. However, there are some times * when you want to shift a value that has not been tokenized. So you call * one of the other functions that will do this for you. */ __inline static TOKEN push_token (expr_info *c, TOKEN t) { if (c->sp == STACKSZ - 1) { error("Expressions may not have more than %d operands", STACKSZ); return -1; } else c->sp++; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Pushing token [%d] [%s]", t, get_token_expanded(c, t)); return ((c->stack[c->sp] = t)); } __inline static TOKEN push_string (expr_info *c, char *val) { return push_token(c, tokenize_expanded(c, val)); } __inline static TOKEN push_float (expr_info *c, double val) { return push_token(c, tokenize_float(c, val)); } __inline static TOKEN push_integer (expr_info *c, INTTYPE val) { return push_token(c, tokenize_integer(c, val)); } __inline static TOKEN push_boolean (expr_info *c, BooL val) { return push_token(c, tokenize_bool(c, val)); } __inline static TOKEN push_lval (expr_info *c, const char *val) { return push_token(c, tokenize_lval(c, val)); } /*********************** REMOVE FROM OPERAND STACK **************************/ __inline static TOKEN top (expr_info *c) { if (c->sp < 0) { error("No operands."); return -1; } else return c->stack[c->sp]; } __inline static TOKEN pop_token (expr_info *c) { if (c->sp < 0) { /* * Attempting to pop more operands than are available * Yeilds empty values. Thats probably the most reasonable * course of action. */ error("Cannot pop operand: no more operands"); return 0; } else return c->stack[c->sp--]; } __inline static double pop_integer (expr_info *c) { return get_token_integer(c, pop_token(c)); } __inline static double pop_float (expr_info *c) { return get_token_float(c, pop_token(c)); } __inline static const char * pop_expanded (expr_info *c) { return get_token_expanded(c, pop_token(c)); } __inline static BooL pop_boolean (expr_info *c) { return get_token_boolean(c, pop_token(c)); } __inline static void pop_2_tokens (expr_info *c, TOKEN *t1, TOKEN *t2) { *t2 = pop_token(c); *t1 = pop_token(c); } __inline static void pop_2_floats (expr_info *c, double *a, double *b) { *b = pop_float(c); *a = pop_float(c); } __inline static void pop_2_integers (expr_info *c, INTTYPE *a, INTTYPE *b) { *b = pop_integer(c); *a = pop_integer(c); } __inline static void pop_2_strings (expr_info *c, const char **s, const char **t) { *t = pop_expanded(c); *s = pop_expanded(c); } __inline static void pop_2_booleans (expr_info *c, BooL *a, BooL *b) { *b = pop_boolean(c); *a = pop_boolean(c); } __inline static void pop_3_tokens (expr_info *c, BooL *a, TOKEN *v, TOKEN *w) { TOKEN t1, t2, t3; t3 = pop_token(c); t2 = pop_token(c); t1 = pop_token(c); *a = get_token_boolean(c, t1); *v = t2; *w = t3; } /******************************* OPERATOR REDUCER **************************/ /* * This is the reducer. It takes the relevant arguments off the argument * stack and then performs the neccesary operation on them. */ static void reduce (expr_info *cx, int what) { double a, b; BooL c, d; INTTYPE i, j; const char *s, *t; TOKEN v, w; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Reducing last operation..."); if (cx->sp < 0) { error("An operator is missing a required operand"); return; } if (cx->errflag) return; /* Dont parse on an error */ /* Check to see if we are evaluating the expression at this point. */ #define CHECK_NOEVAL \ if (cx->noeval) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: Operation short-circuited"); \ push_token(cx, 0); \ break; \ } /* Perform an ordinary garden variety floating point binary operation. */ #define BINARY_FLOAT(floatop) \ { \ pop_2_floats(cx, &a, &b); \ CHECK_NOEVAL \ push_float(cx, (floatop)); \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (%f %f) -> %f", \ #floatop, a, b, floatop); \ break; \ } /* Perform an ordinary garden variety integer binary operation */ #define BINARY_INTEGER(intop) \ { \ pop_2_integers(cx, &i, &j); \ CHECK_NOEVAL \ push_integer(cx, (intop)); \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (" FORMAT " " FORMAT ") -> " FORMAT, \ #intop, i, j, intop); \ break; \ } /* Perform an ordinary garden variety boolean binary operation */ #define BINARY_BOOLEAN(boolop) \ { \ pop_2_booleans(cx, &c, &d); \ CHECK_NOEVAL \ push_boolean(cx, (boolop)); \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (%d %d) -> %d", \ #boolop, c, d, boolop); \ break; \ } /* Perform a floating point binary operation where the rhs must not be 0. */ #define BINARY_FLOAT_NOZERO(floatop) \ { \ pop_2_floats(cx, &a, &b); \ CHECK_NOEVAL \ if (b == 0.0) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (%f %f) -> []", \ #floatop, a, b); \ error("Division by zero"); \ push_token(cx, 0); \ } \ else \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (%f %f) -> %f", \ #floatop, a, b, floatop); \ push_float(cx, (floatop)); \ } \ break; \ } /* Perform a floating point binary operation where the rhs must not be 0. */ #define BINARY_INTEGER_NOZERO(intop) \ { \ pop_2_integers(cx, &i, &j); \ CHECK_NOEVAL \ if (j == 0) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (" FORMAT " " FORMAT ") -> []", \ #intop, i, j); \ error("Division by zero"); \ push_token(cx, 0); \ } \ else \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (" FORMAT " " FORMAT ") -> " FORMAT, \ #intop, i, j, intop); \ push_integer(cx, (intop)); \ } \ break; \ } /***************** ASSIGNMENT MACROS *******************/ /* Prep the lvalue and the rvalue for a future assignment. */ #define GET_LVAL_RVAL \ pop_2_tokens(cx, &v, &w); \ if (!(s = get_token_lval(cx, v))) \ { \ push_token(cx, 0); \ break; \ } /* Perform an ordinary integer operation, assigning the result to the lvalue */ #define IMPLIED_INTEGER(intop) \ { \ GET_LVAL_RVAL \ CHECK_NOEVAL \ i = get_token_integer(cx, v); \ j = get_token_integer(cx, w); \ \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (" FORMAT " " FORMAT ") -> " FORMAT, \ s, #intop, i, j, intop); \ \ w = tokenize_integer(cx, (intop)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ push_token(cx, w); \ break; \ } /* Perform an ordinary float operation, assigning the result to the lvalue */ #define IMPLIED_FLOAT(floatop) \ { \ GET_LVAL_RVAL \ CHECK_NOEVAL \ a = get_token_float(cx, v); \ b = get_token_float(cx, w); \ \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (%f %f) -> %f", \ s, #floatop, a, b, floatop); \ \ w = tokenize_float(cx, (floatop)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ push_token(cx, w); \ break; \ } /* Perform an ordinary boolean operation, assigning the result to the lvalue */ #define IMPLIED_BOOLEAN(boolop) \ { \ GET_LVAL_RVAL \ CHECK_NOEVAL \ c = get_token_boolean(cx, v); \ d = get_token_boolean(cx, w); \ \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (%d %d) -> %d", \ s, #boolop, c, d, boolop); \ \ w = tokenize_bool(cx, (boolop)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ push_token(cx, w); \ break; \ } /* * Perform a float operation, rvalue must not be zero, assigning the result * to the lvalue. */ #define IMPLIED_FLOAT_NOZERO(floatop) \ { \ GET_LVAL_RVAL \ CHECK_NOEVAL \ a = get_token_float(cx, v); \ b = get_token_float(cx, w); \ \ if (b == 0.0) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (%f %f) -> 0", \ s, #floatop, a, b); \ error("Division by zero"); \ add_var_alias(s, empty_string, 0); \ push_token(cx, 0); \ break; \ } \ \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (%f %f) -> %f", \ s, #floatop, a, b, floatop); \ \ w = tokenize_float(cx, (floatop)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ push_token(cx, w); \ break; \ } /* * Perform a float operation, rvalue must not be zero, assigning the result * to the lvalue. */ #define IMPLIED_INTEGER_NOZERO(intop) \ { \ GET_LVAL_RVAL \ CHECK_NOEVAL \ i = get_token_float(cx, v); \ j = get_token_float(cx, w); \ \ if (j == 0) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (" FORMAT " " FORMAT ") -> 0",\ s, #intop, i, j); \ error("Division by zero"); \ add_var_alias(s, empty_string, 0); \ push_token(cx, 0); \ break; \ } \ \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s = %s (" FORMAT " " FORMAT ") -> " FORMAT,\ s, #intop, i, j, intop); \ \ w = tokenize_float(cx, (intop)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ push_token(cx, w); \ break; \ } /* * Perform an auto(in|de)crement operation on the last operand, assigning * to it the value of 'x', but pushing the value of 'y' onto the stack. */ #define AUTO_UNARY(intop_assign, intop_result) \ { \ v = pop_token(cx); \ if (!(s = get_token_lval(cx, v))) \ { \ push_token(cx, 0); \ break; \ } \ CHECK_NOEVAL \ \ j = get_token_integer(cx, v); \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s (%s " FORMAT ") -> " FORMAT, \ #intop_result, s, j, (intop_result)); \ \ w = tokenize_integer(cx, (intop_assign)); \ t = get_token_expanded(cx, w); \ add_var_alias(s, t, 0); \ \ push_integer(cx, (intop_result)); \ break; \ } /* ****************** START HERE *********************/ #define dpushn(x1,x2,y1) \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ { \ yell("O: COMPARE"); \ yell("O: %s -> %d", #x2, (x2)); \ } \ push_boolean( x1 , y1 ); \ } #define COMPARE(x, y) \ { \ pop_2_strings(cx, &s, &t); \ CHECK_NOEVAL \ if (is_real_number(s) && is_real_number(t)) \ { \ a = atof(s), b = atof(t); \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s N(%f %f) -> %d", #x, a, b, (x)); \ if ((x)) dpushn(cx, x, 1) \ else dpushn(cx, x, 0) \ } \ else \ { \ if (x_debug & DEBUG_NEW_MATH_DEBUG) \ yell("O: %s S(%s %s) -> %d", #x, s, t, (y)); \ if ((y)) dpushn(cx, y, 1) \ else dpushn(cx, y, 0) \ } \ break; \ } /************** THE OPERATORS THEMSELVES ********************/ switch (what) { /* Simple unary prefix operators */ case NOT: c = pop_boolean(cx); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: !%d -> %d", c, !c); push_boolean(cx, !c); break; case COMP: i = pop_integer(cx); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell(": ~" FORMAT " -> " FORMAT, i, ~i); push_integer(cx, ~i); break; case UPLUS: a = pop_float(cx); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: +%f -> %f", a, a); push_float(cx, a); break; case UMINUS: a = pop_float(cx); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: -%f -> %f", a, -a); push_float(cx, -a); break; case STRLEN: s = pop_expanded(cx); CHECK_NOEVAL i = strlen(s); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: @(%s) -> " FORMAT, s, i); push_integer(cx, i); break; case WORDC: s = pop_expanded(cx); CHECK_NOEVAL i = count_words(s, DWORD_YES, "\""); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: #(%s) -> " FORMAT, s, i); push_integer(cx, i); break; case DEREF: { if (top(cx) == MAGIC_TOKEN) break; /* Dont do anything */ /* * We need to consume the operand, even if * we don't intend to use it; plus we need * to ensure this defeats auto-append. Ick. */ s = pop_expanded(cx); *cx->args_flag = 1; CHECK_NOEVAL push_lval(cx, s); break; } /* (pre|post)(in|de)crement operators. */ case PREPLUS: AUTO_UNARY(j + 1, j + 1) case PREMINUS: AUTO_UNARY(j - 1, j - 1) case POSTPLUS: AUTO_UNARY(j + 1, j) case POSTMINUS: AUTO_UNARY(j - 1, j) /* Simple binary operators */ case AND: BINARY_INTEGER(i & j) case XOR: BINARY_INTEGER(i ^ j) case OR: BINARY_INTEGER(i | j) case PLUS: BINARY_FLOAT(a + b) case MINUS: BINARY_FLOAT(a - b) case MUL: BINARY_FLOAT(a * b) case POWER: BINARY_FLOAT(pow(a, b)) case SHLEFT: BINARY_INTEGER(i << j) case SHRIGHT: BINARY_INTEGER(i >> j) case DIV: BINARY_FLOAT_NOZERO(a / b) case MOD: BINARY_INTEGER_NOZERO(i % j) case DAND: BINARY_BOOLEAN(c && d) case DOR: BINARY_BOOLEAN(c || d) case DXOR: BINARY_BOOLEAN((c && !d) || (!c && d)) case STRCAT: { char * myval; pop_2_strings(cx, &s, &t); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: (%s) ## (%s) -> %s%s", s, t, s, t); myval = malloc_strdup2(s, t); push_string(cx, myval); new_free(&myval); break; } /* Assignment operators */ case PLUSEQ: IMPLIED_FLOAT(a + b) case MINUSEQ: IMPLIED_FLOAT(a - b) case MULEQ: IMPLIED_FLOAT(a * b) case POWEREQ: IMPLIED_FLOAT(pow(a, b)) case DIVEQ: IMPLIED_FLOAT_NOZERO(a / b) case MODEQ: IMPLIED_INTEGER_NOZERO(i % j) case ANDEQ: IMPLIED_INTEGER(i & j) case XOREQ: IMPLIED_INTEGER(i ^ j) case OREQ: IMPLIED_INTEGER(i | j) case SHLEFTEQ: IMPLIED_INTEGER(i << j) case SHRIGHTEQ: IMPLIED_INTEGER(i >> j) case DANDEQ: IMPLIED_BOOLEAN(c && d) case DOREQ: IMPLIED_BOOLEAN(c || d) case DXOREQ: IMPLIED_BOOLEAN((c && !d) || (!c && d)) case STRCATEQ: { char * myval; GET_LVAL_RVAL CHECK_NOEVAL myval = malloc_strdup(get_token_expanded(cx, v)); t = get_token_expanded(cx, w); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s = (%s ## %s) -> %s%s", s, myval, t, myval, t); malloc_strcat(&myval, t); push_string(cx, myval); add_var_alias(s, myval, 0); new_free(&myval); break; } case STRPREEQ: { char * myval; GET_LVAL_RVAL CHECK_NOEVAL myval = malloc_strdup(get_token_expanded(cx, w)); t = get_token_expanded(cx, v); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s = (%s ## %s) -> %s%s", s, t, myval, t, myval); malloc_strcat(&myval, t); push_string(cx, myval); add_var_alias(s, myval, 0); new_free(&myval); break; } case EQ: { GET_LVAL_RVAL CHECK_NOEVAL t = get_token_expanded(cx, w); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s = (%s)", s, t); push_token(cx, w); add_var_alias(s, t, 0); break; } case SWAP: { const char *sval, *tval; pop_2_tokens(cx, &v, &w); CHECK_NOEVAL if (!(s = get_token_lval(cx, v))) { push_token(cx, 0); break; } if (!(t = get_token_lval(cx, w))) { push_token(cx, 0); break; } sval = get_token_expanded(cx, v); tval = get_token_expanded(cx, w); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s <=> %s", s, t); add_var_alias(s, tval, 0); add_var_alias(t, sval, 0); push_token(cx, w); break; } /* Comparison operators */ case DEQ: { pop_2_strings(cx, &s, &t); CHECK_NOEVAL c = my_stricmp(s, t) ? 0 : 1; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s == %s -> %d", s, t, c); push_boolean(cx, c); break; } case NEQ: { pop_2_strings(cx, &s, &t); CHECK_NOEVAL c = my_stricmp(s, t) ? 1 : 0; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s != %s -> %d", s, t, c); push_boolean(cx, c); break; } case MATCH: { pop_2_strings(cx, &s, &t); CHECK_NOEVAL c = wild_match(t, s) ? 1 : 0; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s =~ %s -> %d", s, t, c); push_boolean(cx, c); break; } case NOMATCH: { pop_2_strings(cx, &s, &t); CHECK_NOEVAL c = wild_match(t, s) ? 0 : 1; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s !~ %s -> %d", s, t, c); push_boolean(cx, c); break; } case LES: COMPARE(a < b, my_stricmp(s, t) < 0) case LEQ: COMPARE(a <= b, my_stricmp(s, t) <= 0) case GRE: COMPARE(a > b, my_stricmp(s, t) > 0) case GEQ: COMPARE(a >= b, my_stricmp(s, t) >= 0) /* Miscelaneous operators */ case QUEST: { pop_3_tokens(cx, &c, &v, &w); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) { yell("O: %d ? %s : %s -> %s", c, get_token_expanded(cx, v), get_token_expanded(cx, w), (c ? get_token_expanded(cx, v) : get_token_expanded(cx, w))); } push_token(cx, c ? v : w); break; } case COLON: break; case COMMA: { pop_2_tokens(cx, &v, &w); CHECK_NOEVAL if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("O: %s , %s -> %s", get_token_expanded(cx, v), get_token_expanded(cx, w), get_token_expanded(cx, w)); push_token(cx, w); break; } default: error("Unknown operator or out of operators"); return; } } /**************************** EXPRESSION LEXER ******************************/ static int dummy = 1; static int lexerr (expr_info *c, const char *format, ...) { char buffer[BIG_BUFFER_SIZE + 1]; va_list a; va_start(a, format); vsnprintf(buffer, BIG_BUFFER_SIZE, format, a); va_end(a); error("%s", buffer); c->errflag = 1; return EOI; } /* * 'operand' is state information that tells us about what the next token * is expected to be. When a binary operator is lexed, then the next token * is expected to be either a unary operator or an operand. So in this * case 'operand' is set to 1. When an operand is lexed, then the next token * is expected to be a binary operator, so 'operand' is set to 0. */ static __inline int check_implied_arg (expr_info *c) { if (c->operand == 2) { push_token(c, MAGIC_TOKEN); /* XXXX Bleh */ c->operand = 0; *c->args_flag = 1; return 0; } return c->operand; } static __inline TOKEN operator (expr_info *c, const char *x, int y, TOKEN z) { check_implied_arg(c); if (c->operand) return lexerr(c, "A binary operator (%s) was found " "where an operand was expected", x); c->ptr += y; c->operand = 1; return z; } static __inline TOKEN unary (expr_info *c, const char *x, int y, TOKEN z) { if (!c->operand) return lexerr(c, "A unary operator (%s) was found where " "a binary operator was expected", x); c->ptr += y; c->operand = dummy; return z; } /* * This finds and extracts the next token in the expression */ static int zzlex (expr_info *c) { char *start = c->ptr; #define OPERATOR(x, y, z) return operator(c, x, y, z); #define UNARY(x, y, z) return unary(c, x, y, z); dummy = 1; if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Parsing next token from: [%s]", c->ptr); for (;;) { switch (*(c->ptr++)) { case '(': c->operand = 1; return M_INPAR; case ')': /* * If we get a close paren and the lexer is expecting * an operand, then obviously thats a syntax error. * But we gently just insert the empty value as the * rhs for the last operand and hope it all works out. */ if (check_implied_arg(c)) push_token(c, 0); c->operand = 0; return M_OUTPAR; case '+': { /* * Note: In general, any operand that depends on * whether it is a unary or binary operator based * upon the context is required to call the func * 'check_implied_arg' to solidify the context. * That is because some operators are ambiguous, * And if you see (# + 4), it can only be determined * on the fly how to lex that. */ check_implied_arg(c); if (*c->ptr == '+' && (c->operand || !isalnum(*c->ptr))) { c->ptr++; return c->operand ? PREPLUS : POSTPLUS; } else if (*c->ptr == '=') OPERATOR("+=", 1, PLUSEQ) else if (c->operand) UNARY("+", 0, UPLUS) else OPERATOR("+", 0, PLUS) } case '-': { check_implied_arg(c); if (*c->ptr == '-' && (c->operand || !isalnum(*c->ptr))) { c->ptr++; return (c->operand) ? PREMINUS : POSTMINUS; } else if (*c->ptr == '=') OPERATOR("-=", 1, MINUSEQ) else if (c->operand) UNARY("-", 0, UMINUS) else OPERATOR("-", 0, MINUS) } case '*': { if (*c->ptr == '*') { c->ptr++; if (*c->ptr == '=') OPERATOR("**=", 1, POWEREQ) else OPERATOR("**", 0, POWER) } else if (*c->ptr == '=') OPERATOR("*=", 1, MULEQ) else if (c->operand) { dummy = 2; UNARY("*", 0, DEREF) } else OPERATOR("*", 0, MUL) } case '/': { if (*c->ptr == '=') OPERATOR("/=", 1, DIVEQ) else OPERATOR("/", 0, DIV) } case '%': { if (*c->ptr == '=') OPERATOR("%=", 1, MODEQ) else OPERATOR("%", 0, MOD) } case '!': { if (*c->ptr == '=') OPERATOR("!=", 1, NEQ) else if (*c->ptr == '~') OPERATOR("!~", 1, NOMATCH) else UNARY("!", 0, NOT) } case '~': UNARY("~", 0, COMP) case '&': { if (*c->ptr == '&') { c->ptr++; if (*c->ptr == '=') OPERATOR("&&=", 1, DANDEQ) else OPERATOR("&&", 0, DAND) } else if (*c->ptr == '=') OPERATOR("&=", 1, ANDEQ) else OPERATOR("&", 0, AND) } case '|': { if (*c->ptr == '|') { c->ptr++; if (*c->ptr == '=') OPERATOR("||=", 1, DOREQ) else OPERATOR("||", 0, DOR) } else if (*c->ptr == '=') OPERATOR("|=", 1, OREQ) else OPERATOR("|", 0, OR) } case '^': { if (*c->ptr == '^') { c->ptr++; if (*c->ptr == '=') OPERATOR("^^=", 1, DXOREQ) else OPERATOR("^^", 0, DXOR) } else if (*c->ptr == '=') OPERATOR("^=", 1, XOREQ) else OPERATOR("^", 0, XOR) } case '#': { check_implied_arg(c); if (*c->ptr == '#') { c->ptr++; if (*c->ptr == '=') OPERATOR("##=", 1, STRCATEQ) else OPERATOR("##", 0, STRCAT) } else if (*c->ptr == '=') OPERATOR("#=", 1, STRCATEQ) else if (*c->ptr == '~') OPERATOR("#~", 1, STRPREEQ) else if (c->operand) { dummy = 2; UNARY("#", 0, WORDC) } else OPERATOR("#", 0, STRCAT) } case '@': dummy = 2; UNARY("@", 0, STRLEN) case '<': { if (*c->ptr == '<') { c->ptr++; if (*c->ptr == '=') OPERATOR("<<=", 1, SHLEFTEQ) else OPERATOR("<<", 0, SHLEFT) } else if (*c->ptr == '=') { c->ptr++; if (*c->ptr == '>') OPERATOR("<=>", 1, SWAP) else OPERATOR("<=", 0, LEQ) } else OPERATOR("<", 0, LES) } case '>': { if (*c->ptr == '>') { c->ptr++; if (*c->ptr == '=') OPERATOR(">>=", 1, SHRIGHTEQ) else OPERATOR(">>", 0, SHRIGHT) } else if (*c->ptr == '=') OPERATOR(">=", 1, GEQ) else OPERATOR(">", 0, GRE) } case '=': if (*c->ptr == '=') OPERATOR("==", 1, DEQ) else if (*c->ptr == '~') OPERATOR("=~", 1, MATCH) else OPERATOR("=", 0, EQ) case '?': check_implied_arg(c); c->operand = 1; return QUEST; case ':': /* * I dont want to hear anything from you anti-goto * bigots out there. ;-) If you can't figure out * what this does, you ought to give up programming. * And a big old :p to everyone who insisted that * i support this horrid hack. */ if (c->operand) goto handle_expando; c->operand = 1; return COLON; case ',': /* Same song, second verse. */ if (c->operand) goto handle_expando; c->operand = 1; return COMMA; case '\0': check_implied_arg(c); c->operand = 1; c->ptr--; return EOI; /* * The {...} operator is really a hack that is left over * from the old math parser. The support for it here is * a hack. The entire thing is a hack. */ case '{': { char *p = c->ptr; char oc = 0; ssize_t span; if (!c->operand) return lexerr(c, "Misplaced { token"); if ((span = MatchingBracket(p, '{', '}')) >= 0) { c->ptr = p + span; oc = *c->ptr; *c->ptr = 0; } else c->ptr = empty_string; c->last_token = 0; if (!c->noeval) { char * result; result = call_lambda_function(NULL, p, c->args); c->last_token = tokenize_expanded(c, result); new_free(&result); } if (oc) *c->ptr++ = oc; c->operand = 0; return ID; } /******************** OPERAND TYPES **********************/ /* * This is an UNEXPANDED-STRING operand type. * Extract everything inside the [...]'s, and then * tokenize that as a "raw" token. It will be expanded * on an as-needed basis. * * If we are in the no-eval section of a short-circuit, * then we throw away this token entirely. */ case '[': { char *p = c->ptr; char oc = 0; ssize_t span; if (!c->operand) return lexerr(c, "Misplaced [ token"); if ((span = MatchingBracket(p, '[', ']')) >= 0) { c->ptr = p + span; oc = *c->ptr; *c->ptr = 0; } else c->ptr = empty_string; if (c->noeval) c->last_token = 0; else c->last_token = tokenize_raw(c, p); if (oc) *c->ptr++ = oc; c->operand = 0; return ID; } /* The "space" characters. */ case 9: case 10: case 11: case 12: case 13: case ' ': start++; break; /* * This is a NUMBER operand type. This may seem unusual, * but we actually tokenize the string representation of * the number as an "expanded" token type. Why do we do * this? Because in the most common case, the user is * doing something like: * * @ var = 0 * * Now we already have the "0" in string format (natch), * and we will never actually reference the 0 as a number * per se -- all assignments are done on strings, so we * need the string anyhow. So when we lex a number in the * expression, we tokenize it as an 'expanded string' and * then if we ever have to actually use the number in any * particular context, it will be converted as-needed. */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { char *end; char endc; c->operand = 0; c->ptr--; strtod(c->ptr, &end); endc = *end; *end = 0; if (c->noeval) c->last_token = 0; else c->last_token = tokenize_expanded(c, c->ptr); *end = endc; c->ptr = end; return ID; } /* * Handle those weirdo $-values */ case '$': continue; /* * This is an LVAL operand type. This also may seem * unusual, but lval's may contain $'s, which need to * be expanded. They may contain function calls, which * must only be expanded *once*. When we lex out an lval * (such as "var" in "@ var = 5"), we tokenize the lval * as an unexpanded lval. Then, if we ever actually need * to reference the proper variable name, we will get the * "raw" value, which will be the lval after passed through * expand_alias(). If we want to get the *value of the * variable $lval), then we will get the "expanded" value, * which will use the "raw" value to do the variable name * lookup. See? It's really pretty straightforward. The * reason we do all this is to make sure that the expansion * of the variable name happens *at most once*, and that if * the variable is not actually referenced, then the expansion * isn't done at all. */ default: handle_expando: { char *end; char endc; c->operand = 0; c->ptr--; if ((end = after_expando_special(c))) { endc = *end; *end = 0; /* * If we are in the short-circuit of a noeval, * then we throw the token away. */ if (c->noeval) c->last_token = 0; else c->last_token = tokenize_lval(c, start); *end = endc; c->ptr = end; } else { c->last_token = 0; /* Empty token */ c->ptr = empty_string; } if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("After token: [%s]", c->ptr); return ID; } } } } /******************************* STATE MACHINE *****************************/ /* * mathparse -- this is the state machine that actually parses the * expression. The parsing is done through a shift-reduce mechanism, * and all the precedence levels lower than 'pc' are evaluated. */ static void mathparse (expr_info *c, int pc) { int otok, onoeval; /* * Drop out of parsing if an error has occured */ if (c->errflag) return; /* * Get the next token in the expression */ c->mtok = zzlex(c); /* * For as long as the next operator indicates a shift operation... */ while (prec[c->mtok] <= pc) { /* Drop out if an error has occured */ if (c->errflag) return; /* * Figure out what to do with this token that needs * to be shifted. */ switch (c->mtok) { /* * This is any kind of an indentifier. There are several * that we handle: * * VARIABLE REFERENCE ie, "foo" in "@ foo = 2" * NUMBER ie, "2" in "@ foo = 2" * UNEXPANDED STRING ie, "[boo]" in "@ foo = [boo]" * * The actual determination of which type is done in the lexer. * We just get a token id for the resulting identifier. * Getting the value is done on an as-needed basis. */ case ID: if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Parsed identifier token [%s]", get_token_expanded(c, c->last_token)); /* * The lexer sets the last token to * 0 if noeval is set. This saves us * from having to tokenize a string * that we expressly will not use. */ push_token(c, c->last_token); break; /* * An open-parenthesis indicates that we should * recursively evaluate the inside of the paren-set. */ case M_INPAR: { if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Parsed open paren"); mathparse(c, TOPPREC); /* * Of course if the expression ends without * a matching rparen, then we whine about it. */ if (c->mtok != M_OUTPAR) { if (!c->errflag) error("')' expected"); return; } break; } /* * A question mark requires that we check for short * circuiting. We check the lhs, and if it is true, * then we evaluate the lhs of the colon. If it is * false then we just parse the lhs of the colon and * evaluate the rhs of the colon. */ case QUEST: { BooL u = pop_boolean(c); push_boolean(c, u); if (!u) c->noeval++; mathparse(c, prec[QUEST] - 1); if (!u) c->noeval--; else c->noeval++; mathparse(c, prec[QUEST]); if (u) c->noeval--; reduce(c, QUEST); continue; } /* * All other operators handle normally */ default: { /* Save state */ otok = c->mtok; onoeval = c->noeval; /* * Check for short circuiting. */ if (assoc[otok] == BOOL) { if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Parsed short circuit operator"); switch (otok) { case DAND: case DANDEQ: { BooL u = pop_boolean(c); push_boolean(c, u); if (!u) c->noeval++; break; } case DOR: case DOREQ: { BooL u = pop_boolean(c); push_boolean(c, u); if (u) c->noeval++; break; } } } if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Parsed operator of type [%d]", otok); /* * Parse the right hand side through * recursion if we're doing things R->L. */ mathparse(c, prec[otok] - (assoc[otok] != RL)); /* * Then reduce this operation. */ c->noeval = onoeval; reduce(c, otok); continue; } } /* * Grab the next token */ c->mtok = zzlex(c); } } /******************************** HARNASS **********************************/ /* * This is the new math parser. It sets up an execution context, which * contains sundry information like all the extracted tokens, intermediate * tokens, shifted tokens, and the like. The expression context is passed * around from function to function, each function is totaly independant * of state information stored in global variables. Therefore, this math * parser is re-entrant safe. */ static char * matheval (char *s, const char *args, int *args_flag) { expr_info context; char * ret = NULL; /* Sanity check */ if (!s || !*s) return malloc_strdup(empty_string); /* Create new state */ setup_expr_info(&context); context.ptr = s; context.args = args; context.args_flag = args_flag; /* Actually do the parsing */ mathparse(&context, TOPPREC); /* Check for error */ if (context.errflag) { ret = malloc_strdup(empty_string); goto cleanup; } /* Check for leftover operands */ if (context.sp) error("The expression has too many operands"); if (x_debug & DEBUG_NEW_MATH_DEBUG) { int i; yell("Terms left: %d", context.sp); for (i = 0; i <= context.sp; i++) yell("Term [%d]: [%s]", i, get_token_expanded(&context, context.stack[i])); } /* Get the return value, if requested */ ret = malloc_strdup(get_token_expanded(&context, pop_token(&context))); cleanup: /* Clean up and restore order */ destroy_expr_info(&context); if (x_debug & DEBUG_NEW_MATH_DEBUG) yell("Returning [%s]", ret); /* Return the result */ return ret; } /******************************* SUPPORT *************************************/ /* * after_expando_special: This is a special version of after_expando that * can handle parsing out lvalues in expressions. Due to the eclectic nature * of lvalues in expressions, this is quite a bit different than the normal * after_expando, requiring a different function. Ugh. * * This replaces some much more complicated logic strewn * here and there that attempted to figure out just how long an expando * name was supposed to be. Well, now this changes that. This will slurp * up everything in 'start' that could possibly be put after a $ that could * result in a syntactically valid expando. All you need to do is tell it * if the expando is an rvalue or an lvalue (it *does* make a difference) */ static char * after_expando_special (expr_info *c) { char *start; char *rest; int call; if (!(start = c->ptr)) return c->ptr; for (;;) { rest = after_expando(start, 0, &call); if (*rest != '$') break; start = rest + 1; } if (c->ptr == rest) { yell("Erf. I'm trying to find an lval at [%s] and I'm not " "having much luck finding one. Punting the rest of " "this expression", c->ptr); return NULL; } /* * All done! */ return rest; } epic4-2.10.2.orig/source/screen.c0000644000000000000000000025764512113514421013365 0ustar /* $EPIC: screen.c,v 1.75 2013/02/27 23:38:57 jnelson Exp $ */ /* * screen.c * * Copyright (c) 1993-1996 Matthew Green. * Copyright © 1998 J. Kean Johnston, used with permission * Copyright © 1997, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #define __need_putchar_x__ #include "irc.h" #include "alias.h" #include "clock.h" #include "exec.h" #include "screen.h" #include "window.h" #include "output.h" #include "vars.h" #include "server.h" #include "list.h" #include "termx.h" #include "names.h" #include "ircaux.h" #include "input.h" #include "log.h" #include "hook.h" #include "dcc.h" #include "status.h" #include "commands.h" #include "parse.h" #include "newio.h" #define CURRENT_WSERV_VERSION 4 /* * When some code wants to override the default lastlog level, and needs * to have some output go into some explicit window (such as for /xecho -w), * then while to_window is set to some window, *ALL* output goes to that * window. Dont forget to reset it to NULL when youre done! ;-) */ Window *to_window; /* * When all else fails, this is the screen that is attached to the controlling * terminal, and we know *that* screen will always be there. */ Screen *main_screen; /* * This is the screen in which we last handled an input event. This takes * care of the input duties that "current_screen" used to handle. */ Screen *last_input_screen; /* * This is used to set the default output device for tputs_x(). This takes * care of the output duties that "current_screen" used to handle. Since * the input screen and output screen are independant, it isnt impossible * for a command in one screen to cause output in another. */ Screen *output_screen; /* * The list of all the screens we're handling. Under most cases, there's * only one screen on the list, "main_screen". */ Screen *screen_list = NULL; /* * Ugh. Dont ask. */ int normalize_never_xlate = 0; int normalize_permit_all_attributes = 0; /* * This file includes major work contributed by FireClown, and I am indebted * to him for the work he has graciously donated to the project. The major * highlights of his work include: * * -- ^C codes have been changed to mIRC-order. This is the order that * BitchX uses as well, so those scripts that use ^CXX should work without * changes now between epic and bitchx. * -- The old "ansi-order" ^C codes have been preserved, but in a different * way. If you do ^C30 through ^C37, you will set the foreground color * (directly corresponding to the ansi codes for 30-37), and if you do * ^C40 through ^C47, you will set the background. ^C50 through ^C57 * are reserved for bold-foreground, and blink-background. * -- $cparse() still outputs the "right" colors, so if you use $cparse(), * then these changes wont affect you (much). * -- Colors and ansi codes are either graciously handled, or completely * filtered out. Anything that cannot be handled is removed, so there * is no risk of dangerous codes making their way to your output. This * is accomplished by a low-grade ansi emulator that folds raw output * into an intermediate form which is used by the display routines. * * To a certain extent, the original code from FireClown was not yet complete, * and it was evident that the code was in anticipation of some additional * future work. We have completed much of that work, and we are very much * indebted to him for getting the ball rolling and supplying us with ideas. =) */ /* * * * * * * * * * * * * OUTPUT CHAIN * * * * * * * * * * * * * * * * * * * * To put a message to the "default" window, you must first call * set_display_target(nick/channel, lastlog_level) * Then you may call * say(), output(), yell(), put_it(), put_echo(), etc. * When you are done, make sure to * reset_display_target() * * To put a message to a specific, known window (you need it's refnum) * then you may just call directly: * display_to(winref, ...) * * To put a series of messages to a specific, known window, (need it's refnum) * You must first call: * message_to(winref) * Then you may call * say(), ouitput(), yell(), put_it(), put_echo(), etc. * When you are done, make sure to * message_to(-1); * * The 'display' (or 'display_to') functions are the main entry point for * all logical output from epic. These functions then figure out what * window the output will go to and invoke its 'add' function. From there, * whatever happens is implementation defined. * * This file implements the middle part of the "ircII window", everything * from the 'add' function to the low level terminal stuff. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static int rite (Window *window, const unsigned char *str); static void scroll_window (Window *window); static void add_to_window (Window *window, const unsigned char *str); static void window_disp (Window *window, const unsigned char *str, const unsigned char *orig_str); static int ok_to_output (Window *window); /* * XXX -- Full disclosure -- FireClown says it is completely the wrong * idea to do this (re-build attributes from scratch every time) because * it causes those using slow terminals or slow connections more pain than * is absolutely neccesary. While I admit that he has a lot more experience * than I do in all this, I'm not sure I have the ability to do all this * "optimally" while ensuring 100% accuracy. Maybe I'll luck out and he * will provide something that will be optimal *and* 100% accurate. ;-) */ /* * "Attributes" were an invention for epic5, and the general idea was * to expunge from the output chain all of those nasty logical toggle settings * which never really did work correctly. Rather than have half a dozen * functions all keep state about whether reverse/bold/underline/whatever is * on, or off, or what to do when it sees a toggle, we instead have one * function (normalize_string) which walks the string *once* and outputs a * completely normalized output string. The end result of this change is * that what were formerly "toggle" attributes now are "always-on" attributes, * and to turn off an attribute, you need to do an ALL_OFF (^O) and then * turn on whatever attributes are left. This is *significantly* easier * to parse, and yeilds much better results, at the expense of a few extra * bytes. * * Now on to the nitty gritty. Every character has a fudamental set of * attributes that apply to it. Each character has, by default, the same * set of fundamental attributes as the character before it. In any case * where this is NOT true, an "attribute marker" is put into the normalized * output to indicate what the new fundamental attributes are. These new * attributes continue to be used until another attribute marker is found. * * The "Attribute" structure is an internal structure that represents all * of the supported fundamental attributes. This is the prefered method * for keeping state of the attributes of a line. You can convert this * structure into an "attribute marker" by passing the string and an * Attribute struct to 'display_attributes'. The result is 5 bytes of * output, each byte has the high bit set (so str*() still work). You can * also convert an Attribute struct to standard ircII attribute characters * by calling 'logical_attributes'. The result will be an ALL_OFF (^O) * followed by all of the attributes that are ON in the struct. Finally, * you can suppress all attribute changes by calling ignore_attribute(). * These functions are used by normalize_string() to for their appropriate * uses. * * You can read an attribute marker from a string and convert it back to * an Attribute struct by calling the read_attributes() function. You can * actually perform the physical output operations neccesary to switch to * the values in an Attribute struct by calling term_attribute(). These * are used by various output routines for whatever reason. */ struct attributes { int reverse; int bold; int blink; int underline; int altchar; int color_fg; int color_bg; int fg_color; int bg_color; }; typedef struct attributes Attribute; const unsigned char *all_off (void) { #ifdef NO_CHEATING Attribute a; static unsigned char retval[6]; a->reverse = a->bold = a->blink = a->underline = a->altchar = 0; a->color_fg = a->fg_color = a->color_bg = a->bg_color = 0; display_attributes(retval, &a); return retval; #else static char retval[6]; retval[0] = '\006'; retval[1] = retval[2] = retval[3] = retval[4] = 0x80; retval[5] = 0; return retval; #endif } /* Put into 'output', an attribute marker corresponding to 'a' */ static size_t display_attributes (u_char *output, Attribute *a) { u_char val1 = 0x80; u_char val2 = 0x80; u_char val3 = 0x80; u_char val4 = 0x80; if (a->reverse) val1 |= 0x01; if (a->bold) val1 |= 0x02; if (a->blink) val1 |= 0x04; if (a->underline) val1 |= 0x08; if (a->altchar) val1 |= 0x10; if (a->color_fg) { val2 |= 0x01; val3 |= a->fg_color; } if (a->color_bg) { val2 |= 0x02; val4 |= a->bg_color; } output[0] = '\006'; output[1] = val1; output[2] = val2; output[3] = val3; output[4] = val4; output[5] = 0; return 5; } /* Put into 'output', logical characters so end result is 'a' */ static size_t logic_attributes (u_char *output, Attribute *a) { char *str = output; size_t count = 0; *str++ = ALL_OFF, count++; /* Colors need to be set first, always */ if (a->color_fg) { *str++ = '\003', count++; *str++ = '3', count++; *str++ = '0' + a->fg_color, count++; } if (a->color_bg) { if (!a->color_fg) *str++ = '\003', count++; *str++ = ',', count++; *str++ = '4', count++; *str++ = '0' + a->bg_color, count++; } if (a->bold) *str++ = BOLD_TOG, count++; if (a->blink) *str++ = BLINK_TOG, count++; if (a->reverse) *str++ = REV_TOG, count++; if (a->underline) *str++ = UND_TOG, count++; if (a->altchar) *str++ = ALT_TOG, count++; return count; } /* Suppress any attribute changes in the output */ static size_t ignore_attributes (u_char *output, Attribute *a) { return 0; } /* Read an attribute marker from 'input', put results in 'a'. */ static int read_attributes (const u_char *input, Attribute *a) { if (!input) return -1; if (*input != '\006') return -1; if (!input[0] || !input[1] || !input[2] || !input[3] || !input[4]) return -1; a->reverse = a->bold = a->blink = a->underline = a->altchar = 0; a->color_fg = a->fg_color = a->color_bg = a->bg_color = 0; input++; if (*input & 0x01) a->reverse = 1; if (*input & 0x02) a->bold = 1; if (*input & 0x04) a->blink = 1; if (*input & 0x08) a->underline = 1; if (*input & 0x10) a->altchar = 1; input++; if (*input & 0x01) { a->color_fg = 1; a->fg_color = input[1] & 0x7F; } if (*input & 0x02) { a->color_bg = 1; a->bg_color = input[2] & 0x7F; } return 0; } /* Invoke all of the neccesary functions so output attributes reflect 'a'. */ static void term_attribute (Attribute *a) { term_all_off(); if (a->reverse) term_standout_on(); if (a->bold) term_bold_on(); if (a->blink) term_blink_on(); if (a->underline) term_underline_on(); if (a->altchar) term_altcharset_on(); if (a->color_fg) { if (a->fg_color > 7) abort(); else term_set_foreground(a->fg_color); } if (a->color_bg) { if (a->bg_color > 7) abort(); else term_set_background(a->bg_color); } } /* * * * * * * * * * * * * COLOR SUPPORT * * * * * * * * * * * * * * * * */ /* * This parses out a ^C control sequence. Note that it is not acceptable * to simply slurp up all digits after a ^C sequence (either by calling * strtol(), or while (isdigit())), because people put ^C sequences right * before legit output with numbers (like the time in your status bar.) * Se we have to actually slurp up only those digits that comprise a legal * ^C code. */ static const u_char *read_color_seq (const u_char *start, void *d, int blinkbold) { /* * The proper "attribute" color mapping is for each ^C lvalue. * If the value is -1, then that is an illegal ^C lvalue. */ static int fore_conv[] = { 7, 0, 4, 2, 1, 1, 5, 3, /* 0-7 */ 3, 2, 6, 6, 4, 5, 0, 7, /* 8-15 */ 7, -1, -1, -1, -1, -1, -1, -1, /* 16-23 */ -1, -1, -1, -1, -1, -1, 0, 1, /* 24-31 */ 2, 3, 4, 5, 6, 7, -1, -1, /* 32-39 */ -1, -1, -1, -1, -1, -1, -1, -1, /* 40-47 */ -1, -1, 0, 1, 2, 3, 4, 5, /* 48-55 */ 6, 7, -1, -1, -1 /* 56-60 */ }; /* * The proper "attribute" color mapping is for each ^C rvalue. * If the value is -1, then that is an illegal ^C rvalue. */ static int back_conv[] = { 7, 0, 4, 2, 1, 1, 5, 3, 3, 2, 6, 6, 4, 5, 0, 7, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1 }; /* * Some lval codes represent "bold" colors. That actually reduces * to ^C + ^B, so that if you do ^B later, you get the * color. This table indicates whether a ^C code * turns bold ON or OFF. (Every color does one or the other) */ static int fore_bold_conv[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; /* * Some rval codes represent "blink" colors. That actually reduces * to ^C + ^F, so that if you do ^F later, you get the * color. This table indicates whether a ^C code * turns blink ON or OFF. (Every color does one or the other) */ static int back_blink_conv[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; /* * If /set term_does_bright_blink is on, this will be used instead * of back_blink_conv. On an xterm, this will cause the background * to be bold. */ static int back_bold_conv[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }; /* * And switch between the two. */ int *back_blinkbold_conv = blinkbold ? back_bold_conv : back_blink_conv; /* Local variables, of course */ const u_char * ptr = start; int c1, c2; Attribute * a; Attribute ad; int fg; int val; int noval; /* Reset all attributes to zero */ ad.bold = ad.underline = ad.reverse = ad.blink = ad.altchar = 0; ad.color_fg = ad.color_bg = ad.fg_color = ad.bg_color = 0; /* Copy the inward attributes, if provided */ a = (d) ? (Attribute *)d : &ad; /* * If we're passed a non ^C code, dont do anything. */ if (*ptr != '\003') return ptr; /* * This is a one-or-two-time-through loop. We find the maximum * span that can compose a legit ^C sequence, then if the first * nonvalid character is a comma, we grab the rhs of the code. */ for (fg = 1; ; fg = 0) { /* * If its just a lonely old ^C, then its probably a terminator. * Just skip over it and go on. */ ptr++; if (*ptr == 0) { if (fg) a->color_fg = a->fg_color = 0; a->color_bg = a->bg_color = 0; a->bold = a->blink = 0; return ptr; } /* * Check for the very special case of a definite terminator. * If the argument to ^C is -1, then we absolutely know that * this ends the code without starting a new one */ /* XXX *cough* is 'ptr[1]' valid here? */ else if (ptr[0] == '-' && ptr[1] == '1') { if (fg) a->color_fg = a->fg_color = 0; a->color_bg = a->bg_color = 0; a->bold = a->blink = 0; return ptr + 2; } /* * Further checks against a lonely old naked ^C. */ else if (!isdigit(ptr[0]) && ptr[0] != ',') { if (fg) a->color_fg = a->fg_color = 0; a->color_bg = a->bg_color = 0; a->bold = a->blink = 0; return ptr; } /* * Code certainly cant have more than two chars in it */ c1 = ptr[0]; c2 = ptr[1]; val = 0; noval = 0; #define mkdigit(x) ((x) - '0') /* Our action depends on the char immediately after the ^C. */ switch (c1) { /* These might take one or two characters */ case '0': case '1': case '2': case '3': case '4': case '5': { if (c2 >= '0' && c2 <= '9') { int val1; int val2; ptr++; val1 = mkdigit(c1); val2 = mkdigit(c1) * 10 + mkdigit(c2); if (fg) { if (fore_conv[val2] == -1) val = val1; else val = val2, ptr++; } else { if (back_conv[val2] == -1) val = val1; else val = val2, ptr++; } break; } /* FALLTHROUGH */ } /* These can only take one character */ case '6': case '7': case '8': case '9': { ptr++; val = mkdigit(c1); break; } /* * Y -> Y for any other nonnumeric Y */ default: { noval = 1; break; } } if (noval == 0) { if (fg) { a->color_fg = 1; a->bold = fore_bold_conv[val]; a->fg_color = fore_conv[val]; } else { a->color_bg = 1; a->blink = back_blinkbold_conv[val]; a->bg_color = back_conv[val]; } } if (fg && *ptr == ',') continue; break; } return ptr; } /**************************** STRIP ANSI ***********************************/ /* * Used as a translation table when we cant display graphics characters * or we have been told to do translation. A no-brainer, with little attempt * at being smart. * (JKJ: perhaps we should allow a user to /set this?) */ static u_char gcxlate[256] = { '*', '*', '*', '*', '*', '*', '*', '*', '#', '*', '#', '*', '*', '*', '*', '*', '>', '<', '|', '!', '|', '$', '_', '|', '^', 'v', '>', '<', '*', '=', '^', 'v', ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '_', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'Z', 'Y', 'X', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '?', 'C', 'u', 'e', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'i', 'i', 'i', 'A', 'A', 'e', 'e', 'e', 'o', 'o', 'o', 'u', 'u', 'y', 'O', 'U', 'C', '#', 'Y', 'P', 'f', 'a', 'i', 'o', 'u', 'n', 'N', '^', '^', '?', '<', '>', '2', '4', '!', '<', '>', '#', '#', '#', '|', '|', '|', '|', '+', '+', '+', '+', '|', '+', '+', '+', '+', '+', '+', '+', '+', '-', '+', '+', '+', '+', '+', '+', '+', '+', '=', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '#', '-', '|', '|', '-', 'a', 'b', 'P', 'p', 'Z', 'o', 'u', 't', '#', 'O', '0', 'O', '-', 'o', 'e', 'U', '*', '+', '>', '<', '|', '|', '/', '=', '*', '*', '*', '*', 'n', '2', '*', '*' }; /* * State 0 is a "normal, printable character" * State 1 is an "eight bit character" * State 2 is an "escape character" (\033) * State 3 is a "color code character" (\003) * State 4 is an "attribute change character" * State 5 is a "suppressed character" (always stripped) * State 6 is a "character that is never printable." * State 7 is a "beep" * State 8 is a "tab" * State 9 is a "non-destructive space" */ static u_char ansi_state[256] = { /* ^@ ^A ^B ^C ^D ^E ^F ^G */ 6, 6, 4, 3, 6, 4, 4, 7, /* 000 */ /* ^H ^I ^J ^K ^L ^M ^N ^O */ 6, 8, 0, 6, 0, 6, 6, 4, /* 010 */ /* ^P ^Q ^R ^S ^T ^U ^V ^W */ 6, 6, 6, 9, 4, 6, 4, 6, /* 020 */ /* ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ */ 6, 6, 6, 2, 6, 6, 6, 4, /* 030 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 040 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 050 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 060 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 070 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 100 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 110 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 120 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 130 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 140 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 150 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 170 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 200 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 210 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 220 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 230 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 240 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 250 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 260 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 270 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 300 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 310 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 320 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 330 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 340 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 350 */ 1, 1, 1, 1, 1, 1, 1, 1, /* 360 */ 1, 1, 1, 1, 1, 1, 1, 1 /* 370 */ }; /* * This started off as a general ansi parser, and it worked for stuff that * was going out to the display, but it couldnt deal properly with ansi codes, * and so when I tried to use it for the status bar, it just all fell to * pieces. After working it over, I came up with this. What this does * (believe it or not) is walk through and strip out all the ansi codes in * the target string. Any codes that we recognize as being safe (pretty much * just ^[[m), are converted back into their logical characters * (eg, ^B, ^R, ^_, etc), and everything else is completely blown away. * * If "width" is not -1, then every "width" printable characters, a \n * marker is put into the output so you can tell where the line breaks * are. Obviously, this is optional. It is used by prepared_display * and $leftpc(). * * XXX Some have asked that i "space out" the outputs with spaces and return * but one row of output, so that rxvt will paste it as all one line. Yea, * that might be nice, but that raises other, more thorny issues. */ /* * These macros help keep 8 bit chars from sneaking into the output stream * where they might be stripped out. */ #define this_char() (eightbit ? *str : (*str) & 0x7f) #define next_char() (eightbit ? *str++ : (*str++) & 0x7f) #define put_back() (str--) #define nlchar '\n' u_char * normalize_string (const u_char *str, int logical) { u_char * output; u_char chr; Attribute a; int pos; int maxpos; int args[10]; int nargs; int i, n; int ansi = get_int_var(DISPLAY_ANSI_VAR); int gcmode = get_int_var(DISPLAY_PC_CHARACTERS_VAR); int eightbit = term_eight_bit(); int beep_max, beep_cnt = 0; int tab_max, tab_cnt = 0; int nds_max, nds_cnt = 0; int pc = 0; int reverse, bold, blink, underline, altchar, color, allow_c1, boldback; size_t (*attrout) (u_char *, Attribute *) = NULL; /* Figure out how many beeps/tabs/nds's we can handle */ if (!(beep_max = get_int_var(BEEP_MAX_VAR))) beep_max = -1; if (!get_int_var(TAB_VAR)) tab_max = -1; else if ((tab_max = get_int_var(TAB_MAX_VAR)) < 0) tab_max = -1; if (!(nds_max = get_int_var(ND_SPACE_MAX_VAR))) nds_max = -1; if (normalize_permit_all_attributes) /* XXXX */ reverse = bold = blink = underline = altchar = color = allow_c1 = boldback = 1; else { reverse = get_int_var(INVERSE_VIDEO_VAR); bold = get_int_var(BOLD_VIDEO_VAR); blink = get_int_var(BLINK_VIDEO_VAR); underline = get_int_var(UNDERLINE_VIDEO_VAR); altchar = get_int_var(ALT_CHARSET_VAR); color = get_int_var(COLOR_VAR); allow_c1 = get_int_var(ALLOW_C1_CHARS_VAR); boldback = get_int_var(TERM_DOES_BRIGHT_BLINK_VAR); } if (logical == 0) attrout = display_attributes; /* prep for screen output */ else if (logical == 1) attrout = logic_attributes; /* non-screen handlers */ else if (logical == 2) attrout = ignore_attributes; /* $stripansi() function */ else if (logical == 3) attrout = display_attributes; /* The status line */ else panic("'logical == %d' is not valid.", logical); /* Reset all attributes to zero */ a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; /* * The output string has a few extra chars on the end just * in case you need to tack something else onto it. */ maxpos = strlen(str); output = (u_char *)new_malloc(maxpos + 192); pos = 0; while ((chr = next_char())) { if (pos > maxpos) { maxpos += 192; /* Extend 192 chars at a time */ RESIZE(output, unsigned char, maxpos + 192); } switch (ansi_state[chr]) { /* * State 0 is a normal, printable ascii character */ case 0: output[pos++] = chr; pc++; break; /* * State 1 is a high-bit character that may or may not * need to be translated first. * State 6 is an unprintable character that must be made * unprintable (gcmode is forced to be 1) */ case 1: case 5: case 6: { int my_gcmode = gcmode; /* * This is a very paranoid check to make sure that * the 8-bit escape codes dont elude us. */ if (allow_c1 == 0 && chr >= 128 && chr <= 159) my_gcmode = 0; if (ansi_state[chr] == 5) my_gcmode = 0; if (ansi_state[chr] == 6) my_gcmode = 1; if (normalize_never_xlate) my_gcmode = 4; switch (my_gcmode) { /* * In gcmode 5, translate all characters */ case 5: { output[pos++] = gcxlate[chr]; break; } /* * In gcmode 4, accept all characters */ case 4: { output[pos++] = chr; break; } /* * In gcmode 3, accept or translate chars */ case 3: { if (termfeatures & TERM_CAN_GCHAR) output[pos++] = chr; else output[pos++] = gcxlate[chr]; break; } /* * In gcmode 2, accept or highlight xlate */ case 2: { if (termfeatures & TERM_CAN_GCHAR) output[pos++] = chr; else { /* char */ a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = gcxlate[chr]; a.reverse = !a.reverse; pos += attrout(output + pos, &a); } break; } /* * gcmode 1 is "accept or reverse mangle" * If youre doing 8-bit, it accepts eight * bit characters. If youre not doing 8 bit * then it converts the char into something * printable and then reverses it. */ case 1: { if (termfeatures & TERM_CAN_GCHAR) output[pos++] = chr; else if ((chr & 0x80) && eightbit) output[pos++] = chr; else { a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = (chr | 0x40) & 0x7f; a.reverse = !a.reverse; pos += attrout(output + pos, &a); } break; } /* * gcmode 0 is "always strip out" */ case 0: break; } pc++; break; } /* * State 2 is the escape character */ case 2: { /* * The next thing we do is dependant on what the character * is after the escape. Be very conservative in what we * allow. In general, escape sequences shouldn't be very * complex at this point. * If we see an escape at the end of a string, just mangle * it and dont bother with the rest of the expensive * parsing. */ if (!ansi || this_char() == 0) { a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = '['; a.reverse = !a.reverse; pos += attrout(output + pos, &a); pc++; continue; } switch ((chr = next_char())) { /* * All these codes we just skip over. We're not * interested in them. */ /* * These are two-character commands. The second * char is the argument. */ case ('#') : case ('(') : case (')') : case ('*') : case ('+') : case ('$') : case ('@') : { chr = next_char(); if (chr == 0) put_back(); /* Bogus sequence */ break; } /* * These are just single-character commands. */ case ('7') : case ('8') : case ('=') : case ('>') : case ('D') : case ('E') : case ('F') : case ('H') : case ('M') : case ('N') : case ('O') : case ('Z') : case ('l') : case ('m') : case ('n') : case ('o') : case ('|') : case ('}') : case ('~') : case ('c') : { break; /* Don't do anything */ } /* * Swallow up graphics sequences... */ case ('G'): { while ((chr = next_char()) != 0 && chr != ':') ; if (chr == 0) put_back(); break; } /* * Not sure what this is, it's not supported by * rxvt, but its supposed to end with an ESCape. */ case ('P') : { while ((chr = next_char()) != 0 && chr != 033) ; if (chr == 0) put_back(); break; } /* * Anything else, we just munch the escape and * leave it at that. */ default: put_back(); break; /* * Strip out Xterm sequences */ case (']') : { while ((chr = next_char()) != 0 && chr != 7) ; if (chr == 0) put_back(); break; } /* * Now these we're interested in.... * (CSI sequences) */ case ('[') : { /* <<<<<<<<<<<< */ /* * Set up the arguments list */ nargs = 0; args[0] = args[1] = args[2] = args[3] = 0; args[4] = args[5] = args[6] = args[7] = 0; args[8] = args[9] = 0; /* * This stuff was taken/modified/inspired by rxvt. We do it this * way in order to trap an esc sequence that is embedded in another * (blah). We're being really really really paranoid doing this, * but it is for the best. */ /* * Check to see if the stuff after the command is a "private" * modifier. If it is, then we definitely arent interested. * '<' , '=' , '>' , '?' */ chr = this_char(); if (chr >= '<' && chr <= '?') next_char(); /* skip it */ /* * Now pull the arguments off one at a time. Keep pulling them * off until we find a character that is not a number or a semicolon. * Skip everything else. */ for (nargs = 0; nargs < 10; str++) { n = 0; for (n = 0; isdigit(this_char()); next_char()) n = n * 10 + (this_char() - '0'); args[nargs++] = n; /* * If we run out of code here, then we're totaly confused. * just back out with whatever we have... */ if (!this_char()) { output[pos] = output[pos + 1] = 0; return output; } if (this_char() != ';') break; } /* * If we find a new ansi char, start all over from the top * and strip it out too */ if (this_char() == 033) continue; /* * Support "spaces" (cursor right) code */ if (this_char() == 'a' || this_char() == 'C') { next_char(); if (nargs >= 1) { /* * Keep this within reality. */ if (args[0] > 256) args[0] = 256; /* This is just sanity */ if (pos + args[0] > maxpos) { maxpos += args[0]; RESIZE(output, u_char, maxpos + 192); } while (args[0]-- > 0) { if (nds_max > 0 && nds_cnt > nds_max) break; output[pos++] = ND_SPACE; pc++; nds_cnt++; } } break; } /* * The 'm' command is the only one that we honor. * All others are dumped. */ if (next_char() != 'm') break; /* * Walk all of the numeric arguments, plonking the appropriate * attribute changes as needed. */ for (i = 0; i < nargs; i++) { switch (args[i]) { case 0: /* Reset to default */ { a.reverse = a.bold = 0; a.blink = a.underline = 0; a.altchar = 0; a.color_fg = a.color_bg = 0; a.fg_color = a.bg_color = 0; pos += attrout(output + pos, &a); break; } case 1: /* bold on */ { if (bold) { a.bold = 1; pos += attrout(output + pos, &a); } break; } case 2: /* dim on -- not supported */ break; case 4: /* Underline on */ { if (underline) { a.underline = 1; pos += attrout(output + pos, &a); } break; } case 5: /* Blink on */ case 26: /* Blink on */ { if (blink) { a.blink = 1; pos += attrout(output + pos, &a); } break; } case 6: /* Blink off */ case 25: /* Blink off */ { a.blink = 0; pos += attrout(output + pos, &a); break; } case 7: /* Reverse on */ { if (reverse) { a.reverse = 1; pos += attrout(output + pos, &a); } break; } case 21: /* Bold off */ case 22: /* Bold off */ { a.bold = 0; pos += attrout(output + pos, &a); break; } case 24: /* Underline off */ { a.underline = 0; pos += attrout(output + pos, &a); break; } case 27: /* Reverse off */ { a.reverse = 0; pos += attrout(output + pos, &a); break; } case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: /* Set foreground color */ { if (color) { a.color_fg = 1; a.fg_color = args[i] - 30; pos += attrout(output + pos, &a); } break; } case 39: /* Reset foreground color to default */ { if (color) { a.color_fg = 0; a.fg_color = 0; pos += attrout(output + pos, &a); } break; } case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: /* Set background color */ { if (color) { a.color_bg = 1; a.bg_color = args[i] - 40; pos += attrout(output + pos, &a); } break; } case 49: /* Reset background color to default */ { if (color) { a.color_bg = 0; a.bg_color = 0; pos += attrout(output + pos, &a); } break; } default: /* Everything else is not supported */ break; } } /* End of for (handling esc-[...m) */ /* >>>>>>>>>>> */ } /* End of escape-[ code handling */ } /* End of ESC handling */ break; } /* End of case 2 handling */ /* * Skip over ^C codes, they're already normalized. * well, thats not totaly true. We do some mangling * in order to make it work better */ case 3: { const u_char *end; put_back(); end = read_color_seq(str, (void *)&a, boldback); /* * XXX - This is a short-term hack to prevent an * infinite loop. I need to come back and fix * this the right way in the future. * * The infinite loop can happen when a character * 131 is encountered when eight bit chars is OFF. * We see a character 3 (131 with the 8th bit off) * and so we ask skip_ctl_c_seq where the end of * that sequence is. But since it isnt a ^c sequence * it just shrugs its shoulders and returns the * pointer as-is. So we sit asking it where the end * is and it says "its right here". So there is a * need to check the retval of skip_ctl_c_seq to * actually see if there is a sequence here. If there * is not, then we just mangle this character. For * the record, char 131 is a reverse block, so that * seems the most appropriate thing to put here. */ if (end == str) { /* Turn on reverse if neccesary */ a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = ' '; a.reverse = !a.reverse; pos += attrout(output + pos, &a); pc++; next_char(); /* Munch it */ break; } /* Move to the end of the string. */ str = end; /* Suppress the color if no color is permitted */ if (!color) { a.color_fg = a.color_bg = 0; a.fg_color = a.bg_color = 0; break; } /* Output the new attributes */ pos += attrout(output + pos, &a); break; } /* * State 4 is for the special highlight characters */ case 4: { put_back(); switch (this_char()) { case REV_TOG: if (reverse) a.reverse = !a.reverse; break; case BOLD_TOG: if (bold) a.bold = !a.bold; break; case BLINK_TOG: if (blink) a.blink = !a.blink; break; case UND_TOG: if (underline) a.underline = !a.underline; break; case ALT_TOG: if (altchar) a.altchar = !a.altchar; break; case ALL_OFF: a.reverse = a.bold = a.blink = 0; a.underline = a.altchar = 0; a.color_fg = a.color_bg = 0; a.bg_color = a.fg_color = 0; break; default: break; } pos += attrout(output + pos, &a); next_char(); break; } case 7: /* bell */ { beep_cnt++; if ((beep_max == -1) || (beep_cnt > beep_max)) { a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = 'G'; a.reverse = !a.reverse; pos += attrout(output + pos, &a); pc++; } else output[pos++] = '\007'; break; } case 8: /* Tab */ { tab_cnt++; if (tab_max < 0 || (tab_max > 0 && tab_cnt > tab_max)) { a.reverse = !a.reverse; pos += attrout(output + pos, &a); output[pos++] = 'I'; a.reverse = !a.reverse; pos += attrout(output + pos, &a); pc++; } else { int len = 8 - (pc % 8); for (i = 0; i < len; i++) { output[pos++] = ' '; pc++; } } break; } case 9: /* Non-destruct space */ { nds_cnt++; /* * Just swallop up any ND's over the max */ if ((nds_max > 0) && (nds_cnt > nds_max)) ; else output[pos++] = ND_SPACE; break; } default: { panic("Unknown normalize_string mode"); break; } } /* End of huge ansi-state switch */ } /* End of while, iterating over input string */ /* Terminate the output and return it. */ if (logical == 0) { a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; pos += attrout(output + pos, &a); } output[pos] = output[pos + 1] = 0; return output; } /* * XXX I'm not sure where this belongs, but for now it goes here. * This function takes a type-1 normalized string (with the attribute * markers) and converts them back to logical characters. This is needed * for lastlog and the status line and so forth. */ u_char * denormalize_string (const u_char *str) { u_char * output = NULL; size_t maxpos; Attribute a; size_t span; size_t pos; /* Reset all attributes to zero */ a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; /* * The output string has a few extra chars on the end just * in case you need to tack something else onto it. */ maxpos = strlen(str); output = (u_char *)new_malloc(maxpos + 192); pos = 0; while (*str) { if (pos > maxpos) { maxpos += 192; /* Extend 192 chars at a time */ RESIZE(output, unsigned char, maxpos + 192); } switch (*str) { case '\006': { if (read_attributes(str, &a)) continue; /* Mangled */ str += 5; span = logic_attributes(output + pos, &a); pos += span; break; } default: { output[pos++] = *str++; break; } } } output[pos] = 0; return output; } /* * Prepare_display -- this is a new twist on FireClown's original function. * We dont do things quite the way they were explained in the previous * comment that used to be here, so here's the rewrite. ;-) * * This function is used to break a logical line of display into some * number of physical lines of display, while accounting for various kinds * of display codes. The logical line is passed in the 'orig_str' variable, * and the width of the physical display is passed in 'max_cols'. If * 'lused' is not NULL, then it points at an integer that specifies the * maximum number of lines that should be prepared. The actual number of * lines that are prepared is stored into 'lused'. The 'flags' variable * specifies some extra options, the only one of which that is supported * right now is "PREPARE_NOWRAP" which indicates that you want the function * to break off the text at 'max_cols' and not to "wrap" the last partial * word to the next line. ($leftpc() depends on this) */ #define SPLIT_EXTENT 40 unsigned char **prepare_display(const unsigned char *str, int max_cols, int *lused, int flags) { static int recursion = 0, output_size = 0; int pos = 0, /* Current position in "buffer" */ col = 0, /* Current column in display */ word_break = 0, /* Last end of word */ indent = 0, /* Start of second word */ firstwb = 0, /* Buffer position of second word */ line = 0, /* Current pos in "output" */ do_indent, /* Use indent or continued line? */ newline = 0; /* Number of newlines */ static u_char **output = (unsigned char **)0; const u_char *ptr; u_char buffer[BIG_BUFFER_SIZE + 1], *cont_ptr, *cont = empty_string, c, *pos_copy; const char *words; Attribute a; Attribute saved_a; u_char *cont_free = NULL; char * free_me_later = NULL; if (recursion) panic("prepare_display() called recursively"); recursion++; /* Reset all attributes to zero */ a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; saved_a.bold = saved_a.underline = saved_a.reverse = 0; saved_a.blink = saved_a.altchar = 0; saved_a.color_fg = saved_a.color_bg = saved_a.fg_color = 0; saved_a.bg_color = 0; do_indent = get_int_var(INDENT_VAR); if (!(words = get_string_var(WORD_BREAK_VAR))) words = ", "; if (!(cont_ptr = get_string_var(CONTINUED_LINE_VAR))) cont_ptr = empty_string; buffer[0] = 0; if (!output_size) { int new_i = SPLIT_EXTENT; RESIZE(output, char *, new_i); while (output_size < new_i) output[output_size++] = 0; } /* * Start walking through the entire string. */ for (ptr = str; *ptr && (pos < BIG_BUFFER_SIZE - 8); ptr++) { switch (*ptr) { case '\007': /* bell */ buffer[pos++] = *ptr; break; case '\n': /* Forced newline */ { newline = 1; if (indent == 0) indent = -1; word_break = pos; break; /* case '\n' */ } /* Attribute changes -- copy them unmodified. */ case '\006': { if (read_attributes(ptr, &a) == 0) { buffer[pos++] = *ptr++; buffer[pos++] = *ptr++; buffer[pos++] = *ptr++; buffer[pos++] = *ptr++; buffer[pos++] = *ptr; } else abort(); /* * XXX This isn't a hack, but it _is_ ugly! * Because I'm too lazy to find a better place * to put this (down among the line wrapping * logic would be a good place), I take the * cheap way out by "saving" any attribute * changes that occur prior to the first space * in a line. If there are no spaces for the * rest of the line, then this *is* the saved * attributes we will need to start the next * line. This fixes an abort(). */ if (word_break == 0) saved_a = a; continue; /* Skip the column check */ } default: { if (!strchr(words, *ptr)) { if (indent == -1) indent = col; buffer[pos++] = *ptr; col++; break; } /* FALLTHROUGH */ } case ' ': case ND_SPACE: { if (indent == 0) { indent = -1; firstwb = pos; } word_break = pos; saved_a = a; if (*ptr != ' ' && ptr[1] && (col + 1 < max_cols)) word_break++; buffer[pos++] = *ptr; col++; break; } } /* End of switch (*ptr) */ /* * Must check for cols >= maxcols+1 becuase we can have a * character on the extreme screen edge, and we would still * want to treat this exactly as 1 line, and col has already * been incremented. */ if ((col > max_cols) || newline) { /* * We just incremented col, but we need to decrement * it in order to keep the count correct! * --zinx */ if (col > max_cols) col--; /* * XXX Hackwork and trickery here. In the very rare * case where we end the output string *exactly* at * the end of the line, then do not do any more of * the following handling. Just punt right here. */ if (ptr[1] == 0) break; /* stop all processing */ /* * Default the end of line wrap to the last character * we parsed if there were no spaces in the line, or * if we're preparing output that is not to be * wrapped (such as for counting output length. */ if (word_break == 0 || (flags & PREPARE_NOWRAP)) word_break = pos; /* * XXXX Massive hackwork here. * * Due to some ... interesting design considerations, * if you have /set indent on and your first line has * exactly one word seperation in it, then obviously * there is a really long "word" to the right of the * first word. Normally, we would just break the * line after the first word and then plop the really * big word down to the second line. Only problem is * that the (now) second line needs to be broken right * there, and we chew up (and lose) a character going * through the parsing loop before we notice this. * Not good. It seems that in this very rare case, * people would rather not have the really long word * be sent to the second line, but rather included on * the first line (it does look better this way), * and so we can detect this condition here, without * losing a char but this really is just a hack when * it all comes down to it. Good thing its cheap. ;-) */ if (!*cont && (firstwb == word_break) && do_indent) word_break = pos; /* * If we are approaching the number of lines that * we have space for, then resize the master line * buffer so we dont run out. */ if (line >= output_size - 3) { int new_i = output_size + SPLIT_EXTENT; RESIZE(output, char *, new_i); while (output_size < new_i) output[output_size++] = 0; } /* XXXX HACK! XXXX HACK! XXXX HACK! XXXX */ /* * Unfortunately, due to the "line wrapping bug", if * you have a really long line at the end of the first * line of output, and it needs to be wrapped to the * second line of input, we were blindly assuming that * it would fit on the second line, but that may not * be true! If the /set continued_line jazz ends up * being longer than whatever was before the wrapped * word on the first line, then the resulting second * line would be > max_cols, causing corruption of the * display (eg, the status bar gets written over)! * * To counteract this bug, at the end of the first * line, we calcluate the continued line marker * *before* we commit the first line. That way, we * can know if the word to be wrapped will overflow * the second line, and in such case, we break that * word precisely at the current point, rather than * at the word_break point! This prevents the * "line wrap bug", albeit in a confusing way. */ /* * Calculate the continued line marker. This is * a little bit tricky because we cant figure it out * until after the first line is done. The first * time through, cont == empty_string, so if !*cont, * we know it has not been initialized. * * So if it has not been initialized and /set indent * is on, and the place to indent is less than a third * of the screen width and /set continued_line is * less than the indented width, then we pad the * /set continued line value out to the appropriate * width. */ if (!*cont) { int lhs_count = 0; int continued_count = 0; if (indent > max_cols / 3) indent = max_cols / 3; /* refined this to use proper logic to ** decide the length of cont. - pegasus */ char *copy = LOCAL_COPY(cont_ptr); free_me_later = copy = normalize_string(copy, 0); size_t cont_len = output_with_count(copy, 0, 0); if (do_indent && (cont_len < indent)) { size_t size = indent + 1 + strlen(cont_ptr) - cont_len; cont = alloca(size); /* sb pana */ snprintf(cont, size, "%-*s", size, cont_ptr); } /* * Otherwise, we just use /set continued_line, * whatever it is. */ else if (!*cont && *cont_ptr) cont = cont_ptr; cont_free = cont = normalize_string(cont, 0); /* * XXXX "line wrap bug" fix. If we are here, * then we are between the first and second * lines, and we might have a word that does * not fit on the first line that also does * not fit on the second line! We check for * that right here, and if it won't fit on * the next line, we revert "word_break" to * the current position. * * THIS IS UNFORTUNATELY VERY EXPENSIVE! :( */ c = buffer[word_break]; buffer[word_break] = 0; lhs_count = output_with_count(buffer, 0, 0); buffer[word_break] = c; continued_count = output_with_count(cont, 0, 0); /* * Chop the line right here if it will * overflow the next line. * * Save the attributes, too! (05/29/02) * * XXX Saving the attributes may be * spurious but i'm erring on the side * of caution for the moment. */ if (lhs_count <= continued_count) { word_break = pos; saved_a = a; } /* * XXXX End of nasty nasty hack. */ } /* * Now we break off the line at the last space or * last char and copy it off to the master buffer. */ c = buffer[word_break]; buffer[word_break] = 0; malloc_strcpy((char **)&(output[line++]), buffer); buffer[word_break] = c; /* * Skip over all spaces that occur after the break * point, up to the right part of the screen (where * we are currently parsing). This is what allows * lots and lots of spaces to take up their room. * We let spaces fill in lines as much as neccesary * and if they overflow the line we let them bleed * to the next line. */ while (word_break < pos && buffer[word_break] == ' ') word_break++; /* * At this point, we still have some junk left in * 'buffer' that needs to be moved to the next line. * But of course, all new lines must be prefixed by * the /set continued_line and /set indent stuff, so * we copy off the stuff we have to a temporary * buffer, copy the continued-line stuff into buffer * and then re-append the junk into buffer. Then we * fix col and pos appropriately and continue parsing * str... */ /* 'pos' has already been incremented... */ buffer[pos] = 0; pos_copy = LOCAL_COPY(buffer + word_break); strlcpy(buffer, cont, sizeof(buffer) / 2); display_attributes(buffer + strlen(buffer), &saved_a); strlcat(buffer, pos_copy, sizeof(buffer) / 2); display_attributes(buffer + strlen(buffer), &a); pos = strlen(buffer); /* Watch this -- ugh. how expensive! :( */ col = output_with_count(buffer, 0, 0); word_break = 0; newline = 0; /* * The 'lused' argument allows us to truncate the * parsing at '*lused' lines. This is most helpful * for the $leftpc() function, which sets a logical * screen width and asks us to "output" one line. */ if (*lused && line >= *lused) { *buffer = 0; break; } } /* End of new line handling */ } /* End of (ptr = str; *ptr && (pos < BIG_BUFFER_SIZE - 8); ptr++) */ /* Reset all attributes to zero */ a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; pos += display_attributes(buffer + pos, &a); buffer[pos] = '\0'; if (*buffer) malloc_strcpy((char **)&(output[line++]),buffer); recursion--; new_free(&output[line]); new_free(&cont_free); if (free_me_later) new_free(&free_me_later); *lused = line - 1; return output; } /* * rite: This is the primary display wrapper to the 'output_with_count' * function. This function is called whenever a line of text is to be * displayed to an irc window. It is assumed that the cursor has been * placed in the appropriate position before this function is called. * * This function will "scroll" the target window. Note that "scrolling" * is both a logical and physical act. The window needs to be told that * a line is going to be output, and so it needs to be able to adjust its * top_of_display pointer; the hardware terminal also needs to be scrolled * so that there is room to put the new text. scroll_window() handles both * of these tasks for us. * * output_with_count() actually calls putchar_x() for each character in * the string, doing the physical output. It also emits any attribute * markers that are in the string. It does do a clear-to-line, but it does * NOT move the cursor away from the end of the line. We do that after it * has returned. * * This function is used by both irciiwin_display, and irciiwin_repaint. * Dont ever 'fold' it in anywhere. * * The arguments: * window - The target window for the output * str - What is to be outputted */ static int rite (Window *window, const unsigned char *str) { output_screen = window->screen; scroll_window(window); if (window->screen && window->display_size) output_with_count(str, 1, foreground); window->cursor++; return 0; } /* * This is the main physical output routine. In its most obvious * use, 'cleareol' and 'output' is 1, and it outputs 'str' to the main * display (controlled by output_screen), outputting any attribute markers * that it finds along the way. The return value is the number of physical * printable characters output. However, if 'output' is 0, then no actual * output is performed, but the counting still takes place. If 'clreol' * is 0, then the rest of the line is not cleared after 'str' has been * completely output. If 'output' is 0, then clreol is ignored. * * In some cases, you may want to output in multiple calls, and "all_off" * should be set to 1 when you're all done with the end of the * If 'output' is 1 and 'all_off' is 1, do a term_all_off() when the output * is done. If 'all_off' is 0, then don't do an all_off, because */ int output_with_count (const unsigned char *str1, int clreol, int output) { int beep = 0, out = 0; Attribute a; const unsigned char *str; /* Reset all attributes to zero */ a.bold = a.underline = a.reverse = a.blink = a.altchar = 0; a.color_fg = a.color_bg = a.fg_color = a.bg_color = 0; for (str = str1; str && *str; str++) { switch (*str) { /* Attribute marker */ case '\006': { if (read_attributes(str, &a)) break; if (output) term_attribute(&a); str += 4; break; } /* Terminal beep */ case '\007': { beep++; break; } /* Dont ask */ case '\f': { if (output) { a.reverse = !a.reverse; term_attribute(&a); putchar_x('f'); a.reverse = !a.reverse; term_attribute(&a); } out++; break; } /* Non-destructive space */ case ND_SPACE: { if (output) term_cursor_right(); out++; /* Ooops */ break; } /* Any other printable character */ default: { /* * Note that 'putchar_x()' is safe here * because normalize_string() has already * removed all of the nasty stuff that could * end up getting here. And for those things * that are nasty that get here, its probably * because the user specifically asked for it. */ if (output) putchar_x(*str); out++; break; } } } if (output) { if (beep) term_beep(); if (clreol) term_clear_to_eol(); term_all_off(); /* Clean up after ourselves! */ } return out; } /* * add_to_screen: This adds the given null terminated buffer to the screen. * That is, it routes the line to the appropriate window. It also handles * /redirect handling. */ void add_to_screen (const unsigned char *buffer) { Window *tmp = NULL; int winref; /* * Just paranoia. */ if (!current_window) { puts(buffer); return; } if (dumb_mode) { add_to_lastlog(current_window, buffer); if (privileged_output || do_hook(WINDOW_LIST, "%u %s", current_window->refnum, buffer)) puts(buffer); fflush(stdout); return; } /* All windows MUST be "current" before output can occur */ update_all_windows(); /* * The highest priority is if we have explicitly stated what * window we want this output to go to. */ if (to_window) { add_to_window(to_window, buffer); return; } /* * The next priority is "LOG_CURRENT" which is the "default" * level for all non-routed output. That is meant to ensure that * any extraneous error messages goes to a window where the user * will see it. All specific output (e.g. incoming server stuff) * is routed through one of the LOG_* levels, which is handled * below. */ else if (who_level == LOG_CURRENT && ((winref = get_winref_by_servref(from_server)) > -1) && (tmp = get_window_by_refnum(winref))) { add_to_window(tmp, buffer); return; } /* * Next priority is if the output is targeted at a certain * user or channel (used for /window bind or /window nick targets) */ else if (who_from) { tmp = NULL; while (traverse_all_windows(&tmp)) { const char *chan = get_echannel_by_refnum(tmp->refnum); /* * Check for /WINDOW CHANNELs that apply. * (Any current channel will do) */ if (chan && !my_stricmp(who_from, chan)) { if (tmp->server == from_server) { add_to_window(tmp, buffer); return; } } /* * Check for /WINDOW QUERYs that apply. */ if (tmp->query_nick && ( ((who_level == LOG_MSG || who_level == LOG_NOTICE || who_level == LOG_DCC || who_level == LOG_CTCP || who_level == LOG_ACTION) && !my_stricmp(who_from, tmp->query_nick) && from_server == tmp->server) || ((who_level == LOG_DCC || who_level == LOG_CTCP || who_level == LOG_ACTION) && *tmp->query_nick == '=' && !my_stricmp(who_from, tmp->query_nick + 1)) || ((who_level == LOG_DCC || who_level == LOG_CTCP || who_level == LOG_ACTION) && *tmp->query_nick == '=' && !my_stricmp(who_from, tmp->query_nick)))) { add_to_window(tmp, buffer); return; } } tmp = NULL; while (traverse_all_windows(&tmp)) { /* * Check for /WINDOW NICKs that apply */ if (from_server == tmp->server) { if (find_in_list((List **)&(tmp->nicks), who_from, !USE_WILDCARDS)) { add_to_window(tmp, buffer); return; } } } /* * we'd better check to see if this should go to a * specific window (i dont agree with this, though) */ if (from_server != NOSERV && is_channel(who_from)) { if ((tmp = get_window_by_refnum(get_channel_winref(who_from, from_server)))) { add_to_window(tmp, buffer); return; } } } /* * Check to see if this level should go to current window */ if ((current_window_level & who_level) && ((winref = get_winref_by_servref(from_server)) > -1) && (tmp = get_window_by_refnum(winref))) { add_to_window(tmp, buffer); return; } /* * Check to see if any window can claim this level */ tmp = NULL; while (traverse_all_windows(&tmp)) { /* * Check for /WINDOW LEVELs that apply */ if (who_level == LOG_DCC && tmp->window_level & who_level) { add_to_window(tmp, buffer); return; } if (((from_server == tmp->server) || (from_server == NOSERV)) && (who_level & tmp->window_level)) { add_to_window(tmp, buffer); return; } } /* * If all else fails, if the current window is connected to the * given server, use the current window. */ if (from_server == current_window->server) { add_to_window(current_window, buffer); return; } /* * And if that fails, look for ANY window that is bound to the * given server (this never fails if we're connected.) */ tmp = NULL; while (traverse_all_windows(&tmp)) { if (tmp->server == from_server) { add_to_window(tmp, buffer); return; } } /* * No window found for a server is usually because we're * disconnected or not yet connected. */ add_to_window(current_window, buffer); return; } /* * add_to_window: Given a window and a line to display, this handles all * of the window-level stuff like the logfile, the lastlog, splitting * the line up into rows, adding it to the display (scrollback) buffer, and * if we're invisible and the user wants notification, we handle that too. * * add_to_display_list() handles the *composure* of the buffer that backs the * screen, handling HOLD_MODE, trimming the scrollback buffer if it gets too * big, scrolling the window and moving the top_of_window pointer as neccesary. * It also tells us if we should display to the screen or not. * * rite() handles the *appearance* of the display, writing to the screen as * neccesary. */ static void add_to_window (Window *window, const unsigned char *str) { char * pend; char * strval; char * free_me = NULL; if (get_server_redirect(window->server)) if (redirect_text(window->server, get_server_redirect(window->server), str, NULL, 0)) return; if (!privileged_output) { static int recursion = 0; if (!do_hook(WINDOW_LIST, "%u %s", window->refnum, str)) return; /* * If output rewriting causes more output, (such as a stray error * message) allow a few levels of nesting [just to be kind], but * cut the recursion off at its knees at 5 levels. This is an * entirely arbitrary value. Change it if you wish. * (Recursion detection by larne in epic4-2.1.3) */ recursion++; if (recursion < 5) { if ((pend = get_string_var(OUTPUT_REWRITE_VAR))) { char *prepend_exp; char argstuff[10240]; int args_flag; /* First, create the $* list for the expando */ snprintf(argstuff, 10240, "%u %s", window->refnum, str); /* Now expand the expando with the above $* */ prepend_exp = expand_alias(pend, argstuff, &args_flag, NULL); str = prepend_exp; free_me = prepend_exp; } } recursion--; /* Normalize the line of output */ strval = normalize_string(str, 0); } else strval = malloc_strdup(str); /* Pass it off to the window */ window_disp(window, strval, str); new_free(&strval); /* * This used to be in rite(), but since rite() is a general * purpose function, and this stuff really is only intended * to hook on "new" output, it really makes more sense to do * this here. This also avoids the terrible problem of * recursive calls to split_up_line, which are bad. */ if (!window->screen) { /* * This is for archon -- he wanted a way to have * a hidden window always beep, even if BEEP is off. * XXX -- str has already been freed here! ACK! */ if (window->beep_always && strchr(str, '\007')) { Window *old_to_window; term_beep(); old_to_window = to_window; to_window = current_window; say("Beep in window %d", window->refnum); to_window = old_to_window; } /* * Tell some visible window about our problems * if the user wants us to. */ if (!(window->miscflags & WINDOW_NOTIFIED) && who_level & window->notify_level) { window->miscflags |= WINDOW_NOTIFIED; if (window->miscflags & WINDOW_NOTIFY) { Window *old_to_window; int lastlog_level; lastlog_level = set_lastlog_msg_level(LOG_CRAP); old_to_window = to_window; to_window = current_window; say("Activity in window %d", window->refnum); to_window = old_to_window; set_lastlog_msg_level(lastlog_level); } update_all_status(); } } if (free_me) new_free(&free_me); cursor_in_display(window); } /* * The mid-level shim for output to all ircII type windows. * * By this point, the logical line 'str' is in the state it is going to be * put onto the screen. We need to put it in our lastlog [XXX Should that * be done by the front end?] and process it through the display chopper * (prepare_display) which slices and dices the logical line into manageable * chunks, suitable for putting onto the display. We then call our back end * function to do the actual physical output. */ static void window_disp (Window *window, const unsigned char *str, const unsigned char *orig_str) { u_char ** lines; int cols; int numl = 0; add_to_log(window->log_fp, window->refnum, orig_str, 0, NULL); add_to_logs(window->refnum, from_server, who_from, who_level, orig_str); add_to_lastlog(window, orig_str); if (window->screen) cols = window->screen->co - 1; /* XXX HERE XXX */ else cols = window->columns - 1; /* Suppress status updates while we're outputting. */ for (lines = prepare_display(str, cols, &numl, 0); *lines; lines++) { if (add_to_scrollback(window, *lines)) if (ok_to_output(window)) rite(window, *lines); } check_window_cursor(window); trim_scrollback(window); cursor_to_input(); } static int ok_to_output (Window *window) { /* * Output is ok as long as the three top of displays all are * within a screenful of the insertion point! */ if (window->scrollback_top_of_display) { if (window->scrollback_distance_from_display_ip > window->display_size) return 0; /* Definitely no output here */ } if (window->holding_top_of_display) { if (window->holding_distance_from_display_ip > window->display_size) return 0; /* Definitely no output here */ } return 1; /* Output is authorized */ } /* * scroll_window: Given a window, this is responsible for making sure that * the cursor is placed onto the "next" line. If the window is full, then * it will scroll the window as neccesary. The cursor is always set to the * correct place when this returns. */ static void scroll_window (Window *window) { if (dumb_mode) return; if (window->cursor > window->display_size) panic("Window [%d]'s cursor [%d] is off the display [%d]", window->refnum, window->cursor, window->display_size); /* * If the cursor is beyond the window then we should probably * look into scrolling. */ if (window->cursor == window->display_size) { int scroll; /* * If we ever need to scroll a window that is in scrollback * or in hold_mode, then that means either display_window isnt * doing its job or something else is completely broken. * Probably shouldnt be fatal, but i want to trap these. */ if (window->holding_distance_from_display_ip > window->display_size) panic("Can't output to window [%d] because it is holding stuff: [%d] [%d]", window->refnum, window->holding_distance_from_display_ip, window->display_size); if (window->scrollback_distance_from_display_ip > window->display_size) panic("Can't output to window [%d] because it is scrolling back: [%d] [%d]", window->refnum, window->scrollback_distance_from_display_ip, window->display_size); /* Scroll by no less than 1 line */ if ((scroll = get_int_var(SCROLL_LINES_VAR)) <= 0) scroll = 1; /* Adjust the top of the physical display */ if (window->screen && foreground && window->display_size) { term_scroll(window->top, window->top + window->cursor - 1, scroll); } /* Adjust the cursor */ window->cursor -= scroll; } /* * Move to the new line and wipe it */ if (window->screen && window->display_size) { window->screen->cursor_window = window; term_move_cursor(0, window->top + window->cursor); term_clear_to_eol(); cursor_in_display(window); } } /* * * * * CURSORS * * * * * */ /* * cursor_not_in_display: This forces the cursor out of the display by * setting the cursor window to null. This doesn't actually change the * physical position of the cursor, but it will force rite() to reset the * cursor upon its next call */ void cursor_not_in_display (Screen *s) { if (!s) s = output_screen; if (s->cursor_window) s->cursor_window = NULL; } /* * cursor_in_display: this forces the cursor_window to be the * current_screen->current_window. * It is actually only used in hold.c to trick the system into thinking the * cursor is in a window, thus letting the input updating routines move the * cursor down to the input line. Dumb dumb dumb */ void cursor_in_display (Window *w) { if (!w) w = current_window; if (w->screen) w->screen->cursor_window = w; } /* * is_cursor_in_display: returns true if the cursor is in one of the windows * (cursor_window is not null), false otherwise */ int is_cursor_in_display (Screen *screen) { if (!screen && current_window->screen) screen = current_window->screen; return (screen->cursor_window ? 1 : 0); } /* * * * * * * SCREEN UDPATING AND RESIZING * * * * * * * * */ /* * repaint_window_body: redraw the entire window's scrollable region * The old logic for doing a partial repaint has been removed with prejudice. */ void repaint_window_body (Window *window) { Display *curr_line; int count; if (!window) window = current_window; if (dumb_mode || !window->screen) return; global_beep_ok = 0; /* Suppress beeps */ if (window->scrollback_distance_from_display_ip > window->holding_distance_from_display_ip) { if (window->scrolling_distance_from_display_ip >= window->scrollback_distance_from_display_ip) curr_line = window->scrolling_top_of_display; else curr_line = window->scrollback_top_of_display; } else { if (window->scrolling_distance_from_display_ip >= window->holding_distance_from_display_ip) curr_line = window->scrolling_top_of_display; else curr_line = window->holding_top_of_display; } window->cursor = 0; for (count = 0; count < window->display_size; count++) { rite(window, curr_line->line); /* * Clean off the rest of this window. */ if (curr_line == window->display_ip) { window->cursor--; /* Bumped by rite */ for (; count < window->display_size; count++) { term_clear_to_eol(); term_newline(); } break; } curr_line = curr_line->next; } global_beep_ok = 1; /* Suppress beeps */ } /* * * * * * * * * * * * * * SCREEN MANAGEMENT * * * * * * * * * * * * */ /* * create_new_screen creates a new screen structure. with the help of * this structure we maintain ircII windows that cross screen window * boundaries. */ Screen *create_new_screen (void) { Screen *new_s = NULL, *list; static int refnumber = 0; for (list = screen_list; list; list = list->next) { if (!list->alive) { new_s = list; break; } if (!list->next) break; /* XXXX */ } if (!new_s) { new_s = (Screen *)new_malloc(sizeof(Screen)); new_s->screennum = ++refnumber; new_s->next = NULL; if (list) list->next = new_s; else screen_list = new_s; } new_s->last_window_refnum = 1; new_s->window_list = NULL; new_s->window_list_end = NULL; new_s->cursor_window = NULL; new_s->current_window = NULL; new_s->visible_windows = 0; new_s->window_stack = NULL; new_s->last_press.tv_sec = new_s->last_press.tv_usec = 0; new_s->last_key = NULL; new_s->quote_hit = 0; new_s->fdout = 1; new_s->fpout = stdout; new_s->fdin = 0; if (use_input) new_open(0); new_s->fpin = stdin; new_s->control = -1; new_s->wserv_version = 0; new_s->alive = 1; new_s->promptlist = NULL; new_s->tty_name = (char *) 0; new_s->li = current_term->TI_lines; new_s->co = current_term->TI_cols; new_s->old_li = 0; new_s->old_co = 0; new_s->buffer_pos = new_s->buffer_min_pos = 0; new_s->input_buffer[0] = '\0'; new_s->input_cursor = 0; new_s->input_visible = 0; new_s->input_start_zone = 0; new_s->input_end_zone = 0; new_s->input_prompt = NULL; new_s->input_prompt_len = 0; new_s->input_prompt_malloc = 0; new_s->input_line = 23; last_input_screen = new_s; if (!main_screen) main_screen = new_s; init_input(); return new_s; } #ifdef WINDOW_CREATE Window *create_additional_screen (void) { Window *win; Screen *oldscreen, *new_s; char *displayvar, *termvar; int screen_type = ST_NOTHING; ISA local_sockaddr; ISA new_socket; int new_cmd; fd_set fd_read; Timeval timeout; pid_t child; unsigned short port; int new_sock_size; char * wserv_path; if (!use_input) return NULL; if (!(wserv_path = get_string_var(WSERV_PATH_VAR))) { say("You need to /SET WSERV_PATH before using /WINDOW CREATE"); return NULL; } /* * Environment variable STY has to be set for screen to work.. so it is * the best way to check screen.. regardless of what TERM is, the * execpl() for screen won't just open a new window if STY isn't set, * it will open a new screen process, and run the wserv in its first * window, not what we want... -phone */ if (getenv("STY") && getenv("DISPLAY")) { char *p = get_string_var(WSERV_TYPE_VAR); if (p && !my_stricmp(p, "SCREEN")) screen_type = ST_SCREEN; else if (p && !my_stricmp(p, "XTERM")) screen_type = ST_XTERM; else screen_type = ST_SCREEN; /* Sucks to be you */ } else if (getenv("STY")) screen_type = ST_SCREEN; else if (getenv("DISPLAY") && getenv("TERM")) screen_type = ST_XTERM; else { say("I don't know how to create new windows for this terminal"); return NULL; } if (screen_type == ST_SCREEN) say("Opening new screen..."); else if (screen_type == ST_XTERM) { displayvar = getenv("DISPLAY"); termvar = getenv("TERM"); say("Opening new window..."); } else panic("Opening new wound"); local_sockaddr.sin_family = AF_INET; #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif local_sockaddr.sin_addr.s_addr = htonl((INADDR_ANY)); local_sockaddr.sin_port = 0; if ((new_cmd = client_bind((SA *)&local_sockaddr, sizeof(local_sockaddr))) < 0) { yell("Couldnt establish server side -- error [%d] [%s]", new_cmd, my_strerror(new_cmd, errno)); return NULL; } port = ntohs(local_sockaddr.sin_port); oldscreen = current_window->screen; new_s = create_new_screen(); /* * At this point, doing a say() or yell() or anything else that would * output to the screen will cause a refresh of the status bar and * input line. new_s->current_window is NULL after the above line, * so any attempt to reference $C or $T will be to NULL pointers, * which will cause a crash. For various reasons, we can't fire up * a new window this early, so its just easier to make sure we don't * output anything until kill_screen() or new_window() is called first. * You have been warned! */ switch ((child = fork())) { case -1: { kill_screen(new_s); say("I couldnt fire up a new wserv process"); break; } case 0: { char *opts; const char *xterm; char *args[64]; char **args_ptr = args; char geom[32]; int i; setuid(getuid()); setgid(getgid()); setsid(); /* * Make sure that no inhereted file descriptors * are left over past the exec. xterm will reopen * any fd's that it is interested in. * (Start at three sb kanan). */ for (i = 3; i < 256; i++) close(i); /* * Try to restore some sanity to the signal * handlers, since theyre not really appropriate here */ my_signal(SIGINT, SIG_IGN); my_signal(SIGSEGV, SIG_DFL); my_signal(SIGBUS, SIG_DFL); my_signal(SIGABRT, SIG_DFL); if (screen_type == ST_SCREEN) { opts = malloc_strdup(get_string_var(SCREEN_OPTIONS_VAR)); *args_ptr++ = malloc_strdup("screen"); while (opts && *opts) *args_ptr++ = malloc_strdup(new_next_arg(opts, &opts)); } else if (screen_type == ST_XTERM) { snprintf(geom, 31, "%dx%d", oldscreen->co + 1, oldscreen->li); opts = malloc_strdup(get_string_var(XTERM_OPTIONS_VAR)); if (!(xterm = getenv("XTERM"))) if (!(xterm = get_string_var(XTERM_VAR))) xterm = "xterm"; *args_ptr++ = malloc_strdup(xterm); *args_ptr++ = malloc_strdup("-geometry"); *args_ptr++ = malloc_strdup(geom); while (opts && *opts) *args_ptr++ = malloc_strdup(new_next_arg(opts, &opts)); *args_ptr++ = malloc_strdup("-e"); } *args_ptr++ = malloc_strdup(wserv_path); *args_ptr++ = malloc_strdup("localhost"); *args_ptr++ = malloc_strdup(ltoa((long)port)); *args_ptr++ = NULL; execvp(args[0], args); _exit(0); } } /* All the rest of this is the parent.... */ new_sock_size = sizeof(new_socket); FD_ZERO(&fd_read); FD_SET(new_cmd, &fd_read); timeout.tv_sec = (time_t) 10; timeout.tv_usec = 0; /* * This infinite loop sb kanan to allow us to trap transitory * error signals */ for (;;) /* * You need to kill_screen(new_s) before you do say() or yell() * if you know what is good for you... */ switch (select(new_cmd + 1, &fd_read, NULL, NULL, &timeout)) { case -1: { if ((errno == EINTR) || (errno == EAGAIN)) continue; /* FALLTHROUGH */ } case 0: { int old_errno = errno; int errnod = get_child_exit(child); close(new_cmd); kill_screen(new_s); kill(child, SIGKILL); if (new_s->fdin != 0) { say("The wserv only connected once -- it's probably " "an old, incompatable version."); } yell("child %s with %d", (errnod < 1) ? "signaled" : "exited", (errnod < 1) ? -errnod : errnod); yell("Errno is %d", old_errno); return NULL; } default: { if (new_s->fdin == 0) { new_s->fdin = accept(new_cmd, (SA *)&new_socket, &new_sock_size); if ((new_s->fdout = new_s->fdin) < 0) { close(new_cmd); kill_screen(new_s); yell("Couldn't establish data connection " "to new screen"); return NULL; } new_open(new_s->fdin); new_s->fpin = new_s->fpout = fdopen(new_s->fdin, "r+"); continue; } else { new_s->control = accept(new_cmd, (SA *)&new_socket, &new_sock_size); close(new_cmd); if (new_s->control < 0) { kill_screen(new_s); yell("Couldn't establish control connection " "to new screen"); return NULL; } new_open(new_s->control); if (!(win = new_window(new_s))) panic("WINDOW is NULL and it shouldnt be!"); return win; } } } return NULL; } /* Old screens never die. They just fade away. */ void kill_screen (Screen *screen) { Window *window; if (!screen) { say("You may not kill the hidden screen."); return; } if (main_screen == screen) { say("You may not kill the main screen"); return; } if (screen->fdin) { if (use_input) screen->fdin = new_close(screen->fdin); close(screen->fdout); close(screen->fdin); } if (screen->control) screen->control = new_close(screen->control); while ((window = screen->window_list)) { screen->window_list = window->next; add_to_invisible_list(window); } /* Take out some of the garbage left around */ screen->current_window = NULL; screen->window_list = NULL; screen->window_list_end = NULL; screen->cursor_window = NULL; screen->last_window_refnum = -1; screen->visible_windows = 0; screen->window_stack = NULL; screen->fpin = NULL; screen->fpout = NULL; screen->fdin = -1; screen->fdout = -1; new_free(&screen->input_prompt); /* Dont fool around. */ if (last_input_screen == screen) last_input_screen = main_screen; screen->alive = 0; make_window_current(NULL); say("The screen is now dead."); } #endif /* WINDOW_CREATE */ /* * * * * * * * * * * * * USER INPUT HANDLER * * * * * * * * * * * */ void do_screens (fd_set *rd, fd_set *wd) { Screen *screen; char buffer[IO_BUFFER_SIZE + 1]; if (use_input) for (screen = screen_list; screen; screen = screen->next) { if (!screen->alive) continue; #ifdef WINDOW_CREATE if (screen->control != -1 && FD_ISSET(screen->control, rd)) /* Wserv control */ { FD_CLR(screen->control, rd); if (dgets(screen->control, buffer, IO_BUFFER_SIZE, 1, NULL) < 0) { kill_screen(screen); yell("Error from remote screen [%d].", dgets_errno); continue; } if (!strncmp(buffer, "tty=", 4)) malloc_strcpy(&screen->tty_name, buffer + 4); else if (!strncmp(buffer, "geom=", 5)) { char *ptr; if ((ptr = strchr(buffer, ' '))) *ptr++ = 0; screen->li = atoi(buffer + 5); screen->co = atoi(ptr); refresh_a_screen(screen); } else if (!strncmp(buffer, "version=", 8)) { int version; version = atoi(buffer + 8); if (version != CURRENT_WSERV_VERSION) { yell("WSERV version %d is incompatable with this binary", version); kill_screen(screen); } screen->wserv_version = version; } } #endif if (FD_ISSET(screen->fdin, rd)) { int server; FD_CLR(screen->fdin, rd); /* No more! */ #ifdef WINDOW_CREATE if (screen != main_screen && screen->wserv_version == 0) { kill_screen(screen); yell("The WSERV used to create this new screen is too old."); return; } #endif /* * This section of code handles all in put from * the terminal(s) connected to ircII. Perhaps the * idle time *shouldn't* be reset unless its not a * screen-fd that was closed.. */ get_time(&idle_time); if (cpu_saver) reset_system_timers(); server = from_server; last_input_screen = screen; output_screen = screen; make_window_current(screen->current_window); /* * In a multi-screen environment, it's possible for * the user to "switch" between windows connected to * the same server on multiple screens; this would * be the only place we would know about that. So * every time the user presses a key we have to set * the screen's current window to be that window's * server's current window. Right. * XXX Why do I know I'm going to regret this? */ current_window->priority = current_window_priority++; from_server = current_window->server; if (dumb_mode) { if (dgets(screen->fdin, buffer, IO_BUFFER_SIZE, 1, NULL) < 0) { say("IRCII exiting on EOF from stdin"); irc_exit(1, "EPIC - EOF from stdin"); } if (strlen(buffer)) buffer[strlen(buffer) - 1] = 0; if (get_int_var(INPUT_ALIASES_VAR)) parse_line(NULL, buffer, empty_string, 1, 0); else parse_line(NULL, buffer, NULL, 1, 0); } else { char loc_buffer[BIG_BUFFER_SIZE + 1]; int n, i; /* * Read in from stdin. */ if ((n = read(screen->fdin, loc_buffer, BIG_BUFFER_SIZE)) > 0) { for (i = 0; i < n; i++) edit_char(loc_buffer[i]); } #ifdef WINDOW_CREATE /* * if the current screen isn't the main screen, * then the socket to the current screen must have * closed, so we call kill_screen() to handle * this - phone, jan 1993. * but not when we arent running windows - Fizzy, may 1993 * if it is the main screen we got an EOF on, we exit.. * closed tty -> chew cpu -> bad .. -phone, july 1993. */ else if (screen != main_screen) kill_screen(screen); #endif /* * If n == 0 or n == -1 at this point, then the read totally * died on us. This is almost without exception caused by * the ctty being revoke(2)d on us. 4.4BSD guarantees that a * revoke()d ctty will read an EOF, while i believe linux * fails with EBADF. In either case, a read failure on the * main screen is totaly fatal. */ else irc_exit(1, "Hey! Where'd my controlling terminal go?"); } from_server = server; } } } /* * * * * * * * * INPUT PROMPTS * * * * * * * * * * */ /* * add_wait_prompt: Given a prompt string, a function to call when * the prompt is entered.. some other data to pass to the function, * and the type of prompt.. either for a line, or a key, we add * this to the prompt_list for the current screen.. and set the * input prompt accordingly. * * XXXX - maybe this belongs in input.c? =) */ void add_wait_prompt (const char *prompt, void (*func)(char *, char *), char *data, int type, int echo) { WaitPrompt **AddLoc, *New; New = (WaitPrompt *) new_malloc(sizeof(WaitPrompt)); New->prompt = malloc_strdup(prompt); New->data = malloc_strdup(data); New->type = type; New->echo = echo; New->func = func; New->next = NULL; for (AddLoc = ¤t_window->screen->promptlist; *AddLoc; AddLoc = &(*AddLoc)->next); *AddLoc = New; if (AddLoc == ¤t_window->screen->promptlist) change_input_prompt(1); } /* * * * * * * * * * * * * * * * * COLOR SUPPORT * * * * * * * * * * */ /* * This parses out a ^C control sequence. Note that it is not acceptable * to simply slurp up all digits after a ^C sequence (either by calling * strtol(), or while (isdigit())), because people put ^C sequences right * before legit output with numbers (like the time in your status bar.) * Se we have to actually slurp up only those digits that comprise a legal * ^C code. */ ssize_t skip_ctl_c_seq (const u_char *start, int *lhs, int *rhs) { const u_char *after = start; u_char c1, c2; int * val; int lv1, rv1; /* * For our sanity, just use a placeholder if the caller doesnt * care where the end of the ^C code is. */ if (!lhs) lhs = &lv1; if (!rhs) rhs = &rv1; *lhs = *rhs = -1; /* * If we're passed a non ^C code, dont do anything. */ if (*after != '\003') return 0; /* * This is a one-or-two-time-through loop. We find the maximum * span that can compose a legit ^C sequence, then if the first * nonvalid character is a comma, we grab the rhs of the code. */ val = lhs; for (;;) { /* * If its just a lonely old ^C, then its probably a terminator. * Just skip over it and go on. */ after++; if (*after == 0) return (after - start); /* * Check for the very special case of a definite terminator. * If the argument to ^C is -1, then we absolutely know that * this ends the code without starting a new one */ if (after[0] == '-' && after[1] == '1') return (after + 2 - start); /* * Further checks against a lonely old naked ^C. */ if (!isdigit(after[0]) && after[0] != ',') return (after - start); /* * Code certainly cant have more than two chars in it */ c1 = after[0]; c2 = after[1]; /* * Our action depends on the char immediately after the ^C. */ switch (c1) { /* * 0X -> 0X for all numeric X */ case '0': after++; *val = c1 - '0'; if (c2 >= '0' && c2 <= '9') { after++; *val = *val * 10 + (c2 - '0'); } break; /* * 1X -> 1 X if X >= '7' * 1X -> 1X if X < '7' */ case '1': after++; *val = c1 - '0'; if (c2 >= '0' && c2 < '7') { after++; *val = *val * 10 + (c2 - '0'); } break; /* * 3X -> 3 X if X >= '8' * 3X -> 3X if X < '8' * (Same for 4X and 5X) */ case '3': case '4': after++; *val = c1 - '0'; if (c2 >= '0' && c2 < '8') { after++; *val = *val * 10 + (c2 - '0'); } break; case '5': after++; *val = c1 - '0'; if (c2 >= '0' && c2 < '9') { after++; *val = *val * 10 + (c2 - '0'); } break; /* * Y -> Y for any other numeric Y. */ case '2': case '6': case '7': case '8': case '9': *val = (c1 - '0'); after++; break; /* * Y -> Y for any other nonnumeric Y */ default: break; } if (val == lhs) { val = rhs; if (*after == ',') continue; } break; } return (after - start); } epic4-2.10.2.orig/source/keys.c0000644000000000000000000012606211556150466013064 0ustar /* $EPIC: keys.c,v 1.34 2011/04/28 02:30:14 jnelson Exp $ */ /* * keys.c: Keeps track of what happens whe you press a key. * * Copyright © 2002 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "config.h" #include "commands.h" #include "functions.h" #include "history.h" #include "ircaux.h" #include "input.h" #include "keys.h" #include "list.h" #include "names.h" #include "output.h" #include "screen.h" #include "stack.h" #include "termx.h" #include "vars.h" #include "window.h" #include "timer.h" /* This file is split into two pieces. The first piece represents bindings. * Bindings are now held in a linked list, allowing the user to add new ones * at will. Several management functions are placed here to add/remove * bindings, and the default pre-packaged bindings are placed in the * init_binds() function. */ /* (From the author): The following things bother me about this code: * * #1: I reuse the code from show_all_bindings in various forms all over * the place. It might be better to write small functions, and one * 'recurse_keys' function which is passed those small functions. * #2: This file is very disorganized and messy. */ /* * * * * * * * * * * * * * * BIND SECTION * * * * * * * * * * * * * * * * */ struct Binding *binding_list; /* Add a binding. A binding must have either a function, alias, or neither, * but never both. If no binding with this name exists, we create a new one * and fill in the details, then add it to the list of available bindings in * the client. Otherwise, we yell and go home. */ struct Binding *add_binding (const char *name, BindFunction func, char *alias) { struct Binding *bp; if (func && alias) { yell("add_binding(): func and alias both defined!"); return NULL; } if (!name) return NULL; /* no binding name. */ bp = find_binding(name); if (bp) { yell("binding %s already exists!", name); return NULL; } bp = new_malloc(sizeof(struct Binding)); bp->name = malloc_strdup(name); if (alias) { bp->alias = malloc_strdup(alias); bp->func = NULL; } else { bp->func = func; bp->alias = NULL; } bp->filename = malloc_strdup(current_package()); add_to_list((List **)&binding_list, (List *)bp); return bp; } static void remove_bound_keys(struct Key *, struct Binding *); void remove_binding (char *name) { struct Binding *bp; if (!name) return; bp = (struct Binding *)remove_from_list((List **)&binding_list, name); if (bp) { /* be sure to remove any keys bound to this binding first */ remove_bound_keys(head_keymap, bp); new_free(&bp->name); if (bp->alias) new_free(&bp->alias); if (bp->filename) new_free(&bp->filename); new_free(&bp); } return; } static void remove_bound_keys (struct Key *map, struct Binding *binding) { int c; for (c = 0; c <= KEYMAP_SIZE - 1;c++) { if (map[c].bound == binding) map[c].bound = NULL; if (map[c].map) remove_bound_keys(map[c].map, binding); } } struct Binding *find_binding (const char *name) { if (!name) return NULL; return (struct Binding *)find_in_list((List **)&binding_list, name, 0); } void init_binds (void) { #define ADDBIND(x, y) add_binding(x, y, NULL); /* there is no 'NOTHING' bind anymore. */ ADDBIND("ALTCHARSET", insert_altcharset ); ADDBIND("BACKSPACE", input_backspace ); ADDBIND("BACKWARD_CHARACTER", backward_character ); ADDBIND("BACKWARD_HISTORY", backward_history ); ADDBIND("BACKWARD_WORD", input_backward_word ); ADDBIND("BEGINNING_OF_LINE", input_beginning_of_line ); ADDBIND("BLINK", insert_blink ); ADDBIND("BOLD", insert_bold ); ADDBIND("CLEAR_SCREEN", clear_screen ); ADDBIND("COMMAND_COMPLETION", command_completion ); ADDBIND("CPU_SAVER", cpu_saver_on ); ADDBIND("DELETE_CHARACTER", input_delete_character ); ADDBIND("DELETE_NEXT_WORD", input_delete_next_word ); ADDBIND("DELETE_PREVIOUS_WORD", input_delete_previous_word ); ADDBIND("DELETE_TO_PREVIOUS_SPACE", input_delete_to_previous_space ); ADDBIND("END_OF_LINE", input_end_of_line ); ADDBIND("ERASE_LINE", input_clear_line ); ADDBIND("ERASE_TO_BEG_OF_LINE", input_clear_to_bol ); ADDBIND("ERASE_TO_END_OF_LINE", input_clear_to_eol ); ADDBIND("FORWARD_CHARACTER", forward_character ); ADDBIND("FORWARD_HISTORY", forward_history ); ADDBIND("FORWARD_WORD", input_forward_word ); ADDBIND("HIGHLIGHT_OFF", highlight_off ); ADDBIND("NEXT_WINDOW", next_window ); ADDBIND("PARSE_COMMAND", parse_text ); ADDBIND("PREVIOUS_WINDOW", previous_window ); ADDBIND("QUIT_IRC", irc_quit ); ADDBIND("QUOTE_CHARACTER", quote_char ); ADDBIND("REFRESH_INPUTLINE", refresh_inputline ); ADDBIND("REFRESH_SCREEN", (BindFunction) refresh_screen ); ADDBIND("REFRESH_STATUS", (BindFunction) update_all_status); ADDBIND("REVERSE", insert_reverse ); ADDBIND("SCROLL_BACKWARD", scrollback_backwards ); ADDBIND("SCROLL_END", scrollback_end ); ADDBIND("SCROLL_FORWARD", scrollback_forwards ); ADDBIND("SCROLL_START", scrollback_start ); ADDBIND("SELF_INSERT", input_add_character ); ADDBIND("SEND_LINE", send_line ); ADDBIND("SHOVE_TO_HISTORY", shove_to_history ); ADDBIND("STOP_IRC", term_pause ); ADDBIND("SWAP_LAST_WINDOW", swap_last_window ); ADDBIND("SWAP_NEXT_WINDOW", swap_next_window ); ADDBIND("SWAP_PREVIOUS_WINDOW", swap_previous_window ); ADDBIND("SWITCH_CHANNELS", switch_channels ); ADDBIND("TOGGLE_INSERT_MODE", toggle_insert_mode ); ADDBIND("TOGGLE_STOP_SCREEN", toggle_stop_screen ); ADDBIND("TRANSPOSE_CHARACTERS", input_transpose_characters ); ADDBIND("TYPE_TEXT", type_text ); ADDBIND("UNCLEAR_SCREEN", input_unclear_screen ); ADDBIND("UNDERLINE", insert_underline ); ADDBIND("UNSTOP_ALL_WINDOWS", unstop_all_windows ); ADDBIND("YANK_FROM_CUTBUFFER", input_yank_cut_buffer ); #undef ADDBIND } /* * * * * * * * * * * * * * * KEYS SECTION * * * * * * * * * * * * * * * * */ /* Keys support is below here. We have functions to add and remove * bindings, as well as get the binding for a key in a current input * sequence, or a string of keys. */ struct Key *construct_keymap (struct Key *); int clean_keymap (struct Key *); unsigned char *bind_string_compress (const unsigned char *, int *); unsigned char *bind_string_decompress (unsigned char *, const unsigned char *, int); static int bind_string (const u_char *, const char *, char *); struct Key *find_sequence (const unsigned char *, int); void show_all_bindings (struct Key *, const unsigned char *, size_t); void show_all_rbindings (struct Key *, const unsigned char *, int, struct Binding *); void show_key (struct Key *, const unsigned char *, int, int); /* this is set when we're post-init to keep track of changed keybindings. */ unsigned char bind_post_init = 0; struct Key *head_keymap; /* this function is used to actually execute the binding for a specific key. * it checks to see if the key needs to call an alias or a function, and * then makes the appropriate call. if the key is not bound to any action * at all, assume we were called as part of a timeout or a terminator on a * sequence that didn't resolve. if that is the case, use the special * 'key_exec_bt' function to walk backwards along the line and execute the * keys as if they were individually pressed. */ void key_exec_bt (struct Key *); static void key_exec (struct Key *key) { if (key == NULL) { yell("key_exec(): called with NULL key!"); return; /* nothing to do. */ } /* if the key isn't bound to anything, and it has an owner, assume we * got a premature terminator for one or more key sequences. call * key_exec_bt to go back and see about executing the input in smaller * chunks. */ if (key->bound == NULL) { if (key->owner != NULL) key_exec_bt(key); return; } /* check alias first, then function */ if (key->bound->alias != NULL) { /* I don't know if this is right ... */ char *exec = malloc_strdup(key->bound->alias); if (key->stuff) malloc_strcat_wordlist(&exec, " ", key->stuff); parse_line(NULL, exec, empty_string, 0, 0); new_free(&exec); } else if (key->bound->func != NULL) key->bound->func(key->val, key->stuff); return; } /* this function unwinds the current 'stack' of input keys, placing them * into a string, and then parses the string looking for the longest * possible input combinations and executing them as it goes. */ void key_exec_bt (struct Key *key) { unsigned char *kstr = empty_string, *nstr; int len = 1, kslen; struct Key *kp; /* now walk backwards, growing kstr as necessary */ while (key != NULL) { nstr = alloca(len + 1); memcpy(nstr + 1, kstr, len); nstr[0] = key->val; kstr = nstr; len++; key = key->owner; } /* kstr should contain our keystring now, so walk along it and find the * longest patterns available *that terminate*. what this means is that * we need to go backwards along kstr until we find something that * terminates, then we need to lop off that part of kstr, and start * again. this is not particularly efficient. :/ */ kslen = len; while (*kstr) { kp = NULL; nstr = kstr; kslen--; while (nstr != (kstr + kslen)) { if (nstr == kstr) /* beginning of string */ kp = &head_keymap[*nstr]; else if (kp->map != NULL) kp = &kp->map[*nstr]; else break; /* no luck here */ nstr++; } /* did we get to the end? if we did and found a key that executes, * go ahead and execute it. if kslen is equal to 1, and we didn't * have any luck, simply discard the key and continue plugging * forward. */ if (nstr == (kstr + kslen)) { if (kp->bound != NULL || kslen == 1) { if (kp->bound != NULL) key_exec(kp); len -= (nstr - kstr); kslen = len; kstr = nstr; /* move kstr forward */ continue; /* now move along */ } } /* otherwise, we'll just continue above (where kslen is decremented * and nstr is re-set */ } } /* this function tries to retrieve the binding for a key pressed on the * input line. depending on the circumstances, we may need to execute the * previous key's action (if there has been a timeout). The timeout factor * is set in milliseconds by the KEY_INTERVAL variable. See further for * instructions. :) */ struct Key *handle_keypress (struct Key *last, Timeval pressed, unsigned char key) { struct Key *kp; /* we call the timeout code here, too, just to be safe. */ last = timeout_keypress(last, pressed); /* if last is NULL (meaning we're in a fresh state), pull from the head * keymap. if last has a map, pull from that map. if last has no map, * something went wrong (we should never return a 'last' that is * mapless!) */ if (last == NULL) kp = &head_keymap[key]; else if (last->map != NULL) kp = &last->map[key]; else { yell("handle_keypress(): last is not NULL but has no map!"); return NULL; } /* If there is a map and a keybinding, schedule a timeout */ if (kp->map && kp->bound) add_timer(0, empty_string, get_int_var(KEY_INTERVAL_VAR) / 1000.0, 1, do_input_timeouts, NULL, NULL, -1); /* if the key has a map associated, we can't automatically execute the * action. return kp and wait quietly. */ if (kp->map != NULL) return kp; /* otherwise, we can just exec our key and return nothing. */ key_exec(kp); return NULL; } struct Key *timeout_keypress (struct Key *last, Timeval pressed) { int mpress = 0; /* ms count since last pressing */ Timeval tv; Timeval right_now; if (last == NULL) return NULL; /* fresh state, we need not worry about timeouts */ if (last->bound == NULL) return last; /* wait unconditionally if this key is unbound. */ get_time(&right_now); tv = time_subtract(pressed, right_now); mpress = tv.tv_sec * 1000; mpress += tv.tv_usec / 1000; if (mpress >= get_int_var(KEY_INTERVAL_VAR)) { /* we timed out. if the last key had some action associated, * execute that action. */ key_exec(last); return NULL; /* we're no longer waiting on this key's map */ } return last; /* still waiting.. */ } struct Key *construct_keymap (struct Key *owner) { int c; struct Key *map = new_malloc(sizeof(struct Key) * KEYMAP_SIZE); for (c = 0;c <= KEYMAP_SIZE - 1;c++) { map[c].val = c; map[c].bound = NULL; map[c].map = NULL; map[c].owner = owner; map[c].stuff = NULL; map[c].filename = NULL; } return map; } /* this function recursively 'cleans' keymaps. which is to say, if a map * has no viable members, it will destroy the map, but not before it calls * itself on sub-maps. this should be used whenever keys have been unbound * to keep memory clear and (more importantly) to make sure that artifacts * are not left around in the timeout system. the function returns positive * if *the map passed* was removed, negative otherwise. */ int clean_keymap (struct Key *map) { int c; int save = 0; /* walk through the map to see if things are in use. if something is * bound, the keymap will be saved. also if a key has a submap and that * submap cannot be cleaned, the keymap will be saved. we return 1 if * the map is saved, 0 otherwise. we walk through all keys here, even * if we know we're going to save the map early on. this allows the * cleaner to catch dead submaps in the current map. */ for (c = 0; c <= KEYMAP_SIZE - 1;c++) { if (map[c].bound) save = 1; /* key in use. save map. */ if (map[c].map) { if (clean_keymap(map[c].map)) save = 1; /* map still in use. */ else map[c].map = NULL; /* map destroyed, make sure to unlink. */ } } if (!save) new_free(&map); /* free the memory. */ return save; } /* this function compresses a user-input string of key sequences into * something interally useable. the following notations are supported: * * ^C (or ^c): control-character (c - 64). if 'c' is not >= 64, this * is treated as a literal sequence of ^ and then c. If 'c' is '?', we * treat the sequence as \177 (the DEL sequence, ascii 127, etc. :) * * \X: where X may (or may not) have special meaning. the following may be * useful as common shorthand: * \e: equivalent to ^[ (escape) * \xxx: octal sequence. * \^: escape the caret (hat, whatever.. :) * \\: the \ character. ;) */ unsigned char *bind_string_compress (const unsigned char *str, int *len) { unsigned char *new, *s; const unsigned char *oldstr; unsigned char c; #define isoctaln(x) ((x) > 47 && (x) < 56) if (!str) return NULL; s = new = new_malloc(strlen(str) + 1); /* we will always make the string smaller. */ oldstr = str; *len = 0; while (*str) { switch (*str) { case '^': str++; /* pass over the caret */ if (*str == '?') { s[*len] = '\177'; /* ^? is DEL */ *len += 1; str++; } else if (toupper(*str) < 64 || toupper(*str) > 95) { s[*len] = '^'; *len += 1; /* don't increment, since we're treating this normally. */ } else { if (isalpha(*str)) s[*len] = toupper(*str) - 64; else s[*len] = *str - 64; *len += 1; str++; } break; case '\\': str++; if (isoctaln(*str)) { c = (*str - 48); str++; if (isoctaln(*str)) { c *= 8; c += (*str - 48); str++; if (isoctaln(*str)) { c *= 8; c += (*str - 48); str++; } } s[*len] = c; *len += 1; } else if (*str == 'e') { s[*len] = '\033'; /* ^[ (escape) */ *len += 1; str++; } else if (*str) {/* anything else that was escaped */ s[*len] = *str++; *len += 1; } else { s[*len] = '\\'; /* end-of-string. no escape. */ *len += 1; } break; default: s[*len] = *str++; *len += 1; } } s[*len] = '\0'; if (!*len) { yell("bind_string_compress(): sequence [%s] compressed to nothing!", oldstr); new_free(&new); return NULL; } return new; /* should never be reached! */ } /* this decompresses a compressed bind string into human-readable form. it * assumes sufficient memory has already been allocated for it. */ unsigned char *bind_string_decompress (unsigned char *dst, const unsigned char *src, int srclen) { unsigned char *ret = dst; while (srclen) { if (*src < 32) { *dst++ = '^'; *dst++ = *src + 64; } else if (*src == 127) { *dst++ = '^'; *dst++ = '?'; } else *dst++ = *src; src++; srclen--; } *dst = '\0'; return ret; } /* this function takes a key sequence (user-input style), a function to bind * to, and optionally arguments to that function, and does all the work * necessary to bind it. it will create new keymaps as it goes, if * necessary, etc. */ static int bind_string (const unsigned char *sequence, const char *bindstr, char *args) { unsigned char *cs; /* the compressed keysequence */ unsigned char *s; int slen; struct Key *kp = NULL; struct Key *map = head_keymap; struct Binding *bp = NULL; if (!sequence || !bindstr) { yell("bind_string(): called without sequence or bind function!"); return 0; } /* nothing (the binding) is special, it's okay if they request * 'NOTHING', we just do some other work. */ if (my_stricmp(bindstr, "NOTHING") && (bp = find_binding(bindstr)) == NULL) { say("No such function %s", bindstr); return 0; } cs = bind_string_compress(sequence, &slen); if (cs == NULL) { yell("bind_string(): couldn't compress sequence %s", sequence); return 0; } s = cs; while (slen) { kp = &map[*s++]; slen--; if (slen) { /* create a new map if necessary.. */ if (kp->map == NULL) kp->map = map = construct_keymap(kp); else map = kp->map; } else { /* we're binding over whatever was here. check various things * to see if we're overwriting them. */ if (kp->stuff) new_free(&kp->stuff); if (kp->filename) new_free(&kp->filename); kp->bound = bp; kp->changed = bind_post_init; if (bp != NULL) { if (args) kp->stuff = malloc_strdup(args); kp->filename = malloc_strdup(current_package()); } } } /* if we're post-initialization, clean out the keymap with each call. */ if (bind_post_init) clean_keymap(head_keymap); new_free(&cs); return 1; } /* this tries to find the key identified by 'seq' which may be uncompressed. * if we can find the key bound to this sequence, return it, otherwise * return NULL. If slen is 0, assume this is an uncompressed sequence. If * it is not, assume it was compressed for us. */ struct Key *find_sequence (const unsigned char *seq, int slen) { unsigned char *cs = NULL; const unsigned char *s; struct Key *map = head_keymap; struct Key *key = NULL; if (!slen) { cs = bind_string_compress(seq, &slen); if (cs == NULL) return NULL; s = cs; } else s = seq; /* we have to find the key. this should only happen at the top * level, otherwise it's not going to act right! */ while (slen) { key = &map[*s++]; slen--; if (slen) { map = key->map; if (map == NULL) { new_free(&cs); return NULL; } } } if (cs != NULL) new_free(&cs); return key; } /* init_keys: initialize default keybindings that apply without terminal * specificity. we use the above functions to take care of this */ void init_keys (void) { int c; unsigned char s[2]; head_keymap = construct_keymap(NULL); #define BIND(x, y) bind_string(x, y, NULL); /* bind characters 32 - 255 to SELF_INSERT. */ s[1] = '\0'; for (c = 32;c <= KEYMAP_SIZE - 1;c++) { s[0] = c; BIND(s, "SELF_INSERT"); } /* now bind the special single-character inputs */ BIND("^A", "BEGINNING_OF_LINE"); BIND("^B", "BOLD"); BIND("^C", "SELF_INSERT"); BIND("^D", "DELETE_CHARACTER"); BIND("^E", "END_OF_LINE"); BIND("^F", "BLINK"); BIND("^G", "SELF_INSERT"); BIND("^H", "BACKSPACE"); BIND("^I", "TOGGLE_INSERT_MODE"); BIND("^J", "SEND_LINE"); BIND("^K", "ERASE_TO_END_OF_LINE"); BIND("^L", "REFRESH_SCREEN"); BIND("^M", "SEND_LINE"); BIND("^N", "FORWARD_HISTORY"); BIND("^O", "HIGHLIGHT_OFF"); BIND("^P", "BACKWARD_HISTORY"); BIND("^Q", "QUOTE_CHARACTER"); /* ^R */ BIND("^S", "TOGGLE_STOP_SCREEN"); BIND("^T", "TRANSPOSE_CHARACTERS"); BIND("^U", "ERASE_LINE"); BIND("^V", "REVERSE"); BIND("^W", "NEXT_WINDOW"); /* ^X (was META2_CHARACTER) */ BIND("^Y", "YANK_FROM_CUTBUFFER"); BIND("^Z", "STOP_IRC"); /* ^[ (was META1_CHARACTER) */ /* ^\ */ BIND("^]", "SHOVE_TO_HISTORY"); /* ^^ */ BIND("^_", "UNDERLINE"); /* mind the gap .. */ BIND("^?", "BACKSPACE"); #ifdef EMACS_KEYBINDS BIND("\\274", "SCROLL_START"); BIND("\\276", "SCROLL_END"); BIND("\\342", "BACKWARD_WORD"); BIND("\\344", "DELETE_NEXT_WORD"); BIND("\\345", "SCROLL_END"); BIND("\\346", "FORWARD_WORD"); BIND("\\350", "DELETE_PREVIOUS_WORD"); BIND("\\377", "DELETE_PREVIOUS_WORD"); #endif /* now for what was formerly meta1 (escape) sequences. */ BIND("^[^[", "COMMAND_COMPLETION"); BIND("^[.", "CLEAR_SCREEN"); BIND("^[<", "SCROLL_START"); BIND("^[>", "SCROLL_END"); /* ^[O and ^[[ were both META2_CHARACTER, see below .. */ BIND("^[b", "BACKWARD_WORD"); BIND("^[d", "DELETE_NEXT_WORD"); BIND("^[e", "SCROLL_END"); BIND("^[f", "FORWARD_WORD"); BIND("^[h", "DELETE_PREVIOUS_WORD"); BIND("^[n", "SCROLL_FORWARD"); BIND("^[p", "SCROLL_BACKWARD"); BIND("^[^?", "DELETE_PREVIOUS_WORD"); /* meta2 stuff. */ BIND("^[O^Z", "STOP_IRC"); BIND("^[[^Z", "STOP_IRC"); BIND("^[OA", "BACKWARD_HISTORY"); BIND("^[[A", "BACKWARD_HISTORY"); BIND("^[OB", "FORWARD_HISTORY"); BIND("^[[B", "FORWARD_HISTORY"); BIND("^[OC", "FORWARD_CHARACTER"); BIND("^[[C", "FORWARD_CHARACTER"); BIND("^[OD", "BACKWARD_CHARACTER"); BIND("^[[D", "BACKWARD_CHARACTER"); BIND("^[OF", "SCROLL_END"); BIND("^[[F", "SCROLL_END"); BIND("^[OG", "SCROLL_FORWARD"); BIND("^[[G", "SCROLL_FORWARD"); BIND("^[OH", "SCROLL_START"); BIND("^[[H", "SCROLL_START"); BIND("^[OI", "SCROLL_BACKWARD"); BIND("^[[I", "SCROLL_BACKWARD"); BIND("^[On", "NEXT_WINDOW"); BIND("^[[n", "NEXT_WINDOW"); BIND("^[Op", "PREVIOUS_WINDOW"); BIND("^[[p", "PREVIOUS_WINDOW"); BIND("^[O1~", "SCROLL_START"); /* these were meta30-33 before */ BIND("^[[1~", "SCROLL_START"); BIND("^[O4~", "SCROLL_END"); BIND("^[[4~", "SCROLL_END"); BIND("^[O5~", "SCROLL_BACKWARD"); BIND("^[[5~", "SCROLL_BACKWARD"); BIND("^[O6~", "SCROLL_FORWARD"); BIND("^[[6~", "SCROLL_FORWARD"); bind_post_init = 1; /* we're post init, now (except for init_termkeys, but see below for special handling) */ #undef BIND } /* init_termkeys: formerly init_keys2, this is called after we can get * terminal-specific key-sequences. */ void init_termkeys (void) { #define TBIND(x, y) { \ const char *l = get_term_capability(#x, 0, 1); \ if (l) \ bind_string(l, #y, NULL); \ } bind_post_init = 0; TBIND(key_up, BACKWARD_HISTORY); TBIND(key_down, FORWARD_HISTORY); TBIND(key_left, BACKWARD_CHARACTER); TBIND(key_right, FORWARD_CHARACTER); TBIND(key_ppage, SCROLL_BACKWARD); TBIND(key_npage, SCROLL_FORWARD); TBIND(key_home, SCROLL_START); TBIND(key_end, SCROLL_END); TBIND(key_ic, TOGGLE_INSERT_MODE); TBIND(key_dc, DELETE_CHARACTER); bind_post_init = 1; #undef TBIND } /* save_bindings is called by the /save command to..well.. save bindings. * we call the save_bindings_recurse() function which acts a lot like * (surprise surprise) show_all_bindings/show_key in tandem. */ void save_bindings_recurse (FILE *, struct Key *, const unsigned char *, size_t); void save_bindings (FILE *fp, int do_all) { save_bindings_recurse(fp, head_keymap, "", 0); } void save_bindings_recurse (FILE *fp, struct Key *map, const unsigned char *str, size_t len) { int c; unsigned char *newstr; unsigned char *ds; /* decompressed sequence */ size_t size; size = len + 2; newstr = alloca(size); strlcpy(newstr, str, size); ds = alloca(((len + 1) * 2) + 1); /* go through our map, see what is changed, and save it. recurse down * as necessary. */ newstr[len + 1] = '\0'; for (c = 0; c <= KEYMAP_SIZE - 1;c++) { newstr[len] = c; if (map[c].bound && map[c].changed) { bind_string_decompress(ds, newstr, len + 1); fprintf(fp, "BIND \"%s\" %s%s%s\n", ds, map[c].bound->name, (map[c].stuff ? " " : ""), (map[c].stuff ? map[c].stuff : "")); } if (map[c].map) save_bindings_recurse(fp, map[c].map, newstr, len + 1); } } /* this is called only by irc_exit, and its purpose is to free * all our allocated stuff. */ void remove_bindings_recurse (struct Key *); void remove_bindings (void) { while (binding_list != NULL) remove_binding(binding_list->name); remove_bindings_recurse(head_keymap); } void remove_bindings_recurse (struct Key *map) { int c; /* go through our map, clear any memory that might be left lying around. * recurse as necessary */ for (c = 0; c <= KEYMAP_SIZE - 1;c++) { if (map[c].map) remove_bindings_recurse(map[c].map); if (map[c].stuff) new_free(&map[c].stuff); if (map[c].filename) new_free(&map[c].filename); } new_free(&map); } /* this is called when a package is unloaded. we should unset any * package-specific keybindings, and also remove any package-specific bind * functions. */ void unload_bindings_recurse (const char *, struct Key *); void unload_bindings (const char *pkg) { struct Binding *bp, *bp2; /* clean the binds out first. */ bp = binding_list; while (bp != NULL) { bp2 = bp->next; if (!my_stricmp(bp->filename, pkg)) remove_binding(bp->name); bp = bp2; } unload_bindings_recurse(pkg, head_keymap); clean_keymap(head_keymap); } void unload_bindings_recurse (const char *pkg, struct Key *map) { int c; /* go through, see which keys are package specific, unload them. */ for (c = 0; c <= KEYMAP_SIZE - 1;c++) { /* if the key is explicitly bound to something, and it was done in * our package, unbind it. */ if (map[c].bound && !my_stricmp(map[c].filename, pkg)) { if (map[c].stuff) new_free(&map[c].stuff); if (map[c].filename) new_free(&map[c].filename); map[c].bound = NULL; } if (map[c].map) unload_bindings_recurse(pkg, map[c].map); } } /* set_key_interval: this is used to construct a new Timeval when the * 'KEY_INTERVAL' /set is changed. We modify an external variable which * defines how long the client will wait to timeout, at most. */ void set_key_interval (const void *stuff) { int msec = *(const int *)stuff; if (msec < 10) { say("Setting KEY_INTERVAL below 10ms is not recommended."); msec = 10; } set_int_var(KEY_INTERVAL_VAR, msec); } /* do_stack_bind: this handles the /stack .. bind command. below is the * function itself, as well as a structure used to hold keysequences which * have been stacked. it is currently not possible to stack entire maps of * keys. */ struct BindStack { struct BindStack *next; unsigned char *sequence; /* the (compressed) sequence of keys. */ int slen; /* the length of the compressed sequence. */ struct Key key; /* the key's structure. */ }; static struct BindStack *bind_stack = NULL; void do_stack_bind (int type, char *arg) { struct Key *key = NULL; struct Key *map = head_keymap; struct BindStack *bsp = NULL; struct BindStack *bsptmp = NULL; unsigned char *cs, *s; int slen; if (!bind_stack && (type == STACK_POP || type == STACK_LIST)) { say("BIND stack is empty!"); return; } if (type == STACK_PUSH) { /* compress the keysequence, then find the key represented by that * sequence. */ cs = bind_string_compress(arg, &slen); if (cs == NULL) return; /* yikes! */ /* find the key represented by the sequence .. */ key = find_sequence(cs, slen); /* key is now.. something. if it is NULL, assume there was nothing * bound. we still push an empty record on to the stack. */ bsp = new_malloc(sizeof(struct BindStack)); bsp->next = bind_stack; bsp->sequence = cs; bsp->slen = slen; bsp->key.changed = key ? key->changed : 0; bsp->key.bound = key ? key->bound : NULL; bsp->key.stuff = key ? (key->stuff ? malloc_strdup(key->stuff) : NULL) : NULL; bsp->key.filename = key ? malloc_strdup(key->filename) : NULL; bind_stack = bsp; return; } else if (type == STACK_POP) { unsigned char *compstr = bind_string_compress(arg, &slen); if (compstr == NULL) return; /* yikes! */ for (bsp = bind_stack;bsp;bsptmp = bsp, bsp = bsp->next) { if (slen == bsp->slen && !memcmp(bsp->sequence, compstr, slen)) { /* a winner! */ if (bsp == bind_stack) bind_stack = bsp->next; else bsptmp->next = bsp->next; break; } } /* we'll break out when we find our first binding, or if there is * nothing. we handle it below. */ if (bsp == NULL) { say("no bindings for %s are on the stack", arg); new_free(&compstr); return; } /* okay, we need to push this key back in to place. we have to * replicate bind_string since bind_string has some undesirable * effects. */ s = compstr; map = head_keymap; while (slen) { key = &map[*s++]; slen--; if (slen) { /* create a new map if necessary.. */ if (key->map == NULL) key->map = map = construct_keymap(key); else map = key->map; } else { /* we're binding over whatever was here. check various things to see if we're overwriting them. */ if (key->stuff) new_free(&key->stuff); if (key->filename) new_free(&key->filename); key->bound = bsp->key.bound; key->changed = bsp->key.changed; key->stuff = bsp->key.stuff; key->filename = bsp->key.filename; } } new_free(&compstr); new_free(&bsp->sequence); new_free(&bsp); return; } else if (type == STACK_LIST) { say("BIND STACK LISTING"); for (bsp = bind_stack;bsp;bsp = bsp->next) show_key(&bsp->key, bsp->sequence, bsp->slen, 0); say("END OF BIND STACK LISTING"); return; } say("Unknown STACK type ??"); } /* bindcmd: The /BIND command. The general syntax is: * * /BIND ([key-descr] ([bind-command] ([args]))) * Where: * KEY-DESCR := (Any string of keys, subject to bind_string_compress()) * BIND-COMMAND := (Any binding available) * * If given no arguments, this command shows all non-empty bindings which * are currently registered. * * If given one argument, that argument is to be a description of a valid * key sequence. The command will show the binding of that sequence, * * If given two arguments, the first argument is to be a description of a * valid key sequence and the second argument is to be a valid binding * command followed by any optionally appropriate arguments. The key * sequence is then bound to that action. * * The special binding command "NOTHING" actually unbinds the key. */ BUILT_IN_COMMAND(bindcmd) { const unsigned char *seq; char *function; int recurse = 0; if ((seq = new_next_arg(args, &args)) == NULL) { show_all_bindings(head_keymap, "", 0); return; } /* look for flags */ if (*seq == '-') { if (!my_strnicmp(seq + 1, "DEFAULTS", 1)) { init_keys(); init_termkeys(); return; } else if (!my_strnicmp(seq + 1, "SYMBOLIC", 1)) { char * symbol; if ((symbol = new_next_arg(args, &args)) == NULL) return; if ((seq = get_term_capability(symbol, 0, 1)) == NULL) { say("Symbolic name [%s] is not supported in your TERM type.", symbol); return; } } else if (!my_strnicmp(seq + 1, "RECURSIVE", 1)) { recurse = 1; if ((seq = new_next_arg(args, &args)) == NULL) { show_all_bindings(head_keymap, "", 0); return; } } } if ((function = new_next_arg(args, &args)) == NULL) { unsigned char *compstr; int slen; compstr = bind_string_compress(seq, &slen); if (compstr == NULL) return; /* umm.. */ show_key(NULL, compstr, slen, recurse); return; } /* bind_string() will check any errors for us. */ if (!bind_string(seq, function, *args ? args : NULL)) { if (!my_strnicmp(function, "meta", 4)) yell( "Please note that the META binding functions are no longer available. \ For more information please see the bind(4) helpfile and the file \ doc/keys distributed with the EPIC source." ); return; /* assume an error was spouted for us. */ } show_key(NULL, seq, 0, 0); } /* support function for /bind: this function shows, recursively, all the * keybindings. given a map and a string to work from. if the string is * NULL, the function recurses through the entire map. */ void show_all_bindings (struct Key *map, const unsigned char *str, size_t len) { int c; unsigned char *newstr; struct Binding *self_insert; size_t size; self_insert = find_binding("SELF_INSERT"); size = len + 2; newstr = alloca(size); strlcpy(newstr, str, size); /* show everything in our map. recurse down. */ newstr[len + 1] = '\0'; for (c = 0; c <= KEYMAP_SIZE - 1;c++) { newstr[len] = c; if (map[c].map || (map[c].bound && map[c].bound != self_insert)) show_key(&map[c], newstr, len + 1, 1); } } void show_key (struct Key *key, const unsigned char *str, int slen, int recurse) { struct Binding *bp; unsigned char *clean = alloca(((strlen(str) + 1) * 2) + 1); if (key == NULL) { key = find_sequence(str, slen); if (key == NULL) key = head_keymap; } bp = key->bound; if (!bp && ((recurse && !key->map) || !recurse)) say("[*] \"%s\" is bound to NOTHING", (slen ? bind_string_decompress(clean, str, slen) : str)); else { if (bp) { say("[%s] \"%s\" is bound to %s%s%s", (*key->filename ? key->filename : "*"), (slen ? bind_string_decompress(clean, str, slen) : str), bp->name, (key->stuff ? " " : ""), (key->stuff ? key->stuff : "")); } if (recurse && key->map) show_all_bindings(key->map, str, slen); } } /* the /rbind command. This command allows you to pass in the name of a * binding and find all the keys which are bound to it. we make use of a * function similar to 'show_all_bindings', but not quite the same, to * handle recursion. */ BUILT_IN_COMMAND(rbindcmd) { char *function; struct Binding *bp; if ((function = new_next_arg(args, &args)) == NULL) return; if ((bp = find_binding(function)) == NULL) { if (!my_stricmp(function, "NOTHING")) say("You cannot list all unbound keys."); else say("No such function %s", function); return; } show_all_rbindings(head_keymap, "", 0, bp); } void show_all_rbindings (struct Key *map, const unsigned char *str, int len, struct Binding *binding) { int c; unsigned char *newstr; size_t size; size = len + 2; newstr = alloca(size); strlcpy(newstr, str, size); /* this time, show only those things bound to our function, and call on * ourselves to recurse instead. */ newstr[len + 1] = '\0'; for (c = 0; c <= KEYMAP_SIZE - 1;c++) { newstr[len] = c; if (map[c].bound == binding) show_key(&map[c], newstr, len + 1, 0); if (map[c].map) show_all_rbindings(map[c].map, newstr, len + 1, binding); } } /* the parsekey command: this command allows the user to execute a * keybinding, regardless of whether it is bound or not. some keybindings * make more sense than others. :) we look for the function, build a fake * Key item, then call key_exec(). Unlike its predecessor this version * allows the user to pass extra data to the keybinding as well, thus making * things like /parsekey parse_command ... possible (if not altogether * valuable in that specific case) */ BUILT_IN_COMMAND(parsekeycmd) { struct Key fake; struct Binding *bp; char *func; if ((func = new_next_arg(args, &args)) != NULL) { bp = find_binding(func); if (bp == NULL) { say("No such function %s", func); return; } fake.val = '\0'; fake.bound = bp; fake.map = NULL; if (*args) fake.stuff = malloc_strdup(args); else fake.stuff = NULL; fake.filename = empty_string; key_exec(&fake); if (fake.stuff != NULL) new_free(&fake.stuff); } } /* Used by function_bindctl */ /* * $bindctl(FUNCTION [FUNC] ...) * CREATE [ALIAS]) * DESTROY) * EXISTS) * GET) * MATCH) * PMATCH) * GETPACKAGE) * SETPACKAGE [PACKAGE}) * $bindctl(SEQUENCE [SEQ] ...) * GET) * SET [FUNC] [EXTRA]) * GETPACKAGE) * SETPACKAGE [PACKAGE}) * $bindctl(MAP [SEQ]) * $bindctl(MAP [SEQ] CLEAR) * Where [FUNC] is the name of a binding function and [ALIAS] is any alias * name (we do not check to see if it exists!) and [SEQ] is any valid /bind * key sequence and [PACKAGE] is any free form package string. */ void bindctl_getmap (struct Key *, const unsigned char *, int, char **); char *bindctl (char *input) { char *listc; char *retval = NULL; GET_STR_ARG(listc, input); if (!my_strnicmp(listc, "FUNCTION", 1)) { struct Binding *bp; char *func; GET_STR_ARG(func, input); bp = find_binding(func); GET_STR_ARG(listc, input); if (!my_strnicmp(listc, "CREATE", 1)) { char *alias; GET_STR_ARG(alias, input); if (bp) { if (bp->func) RETURN_INT(0); remove_binding(bp->name); } RETURN_INT(add_binding(func, NULL, alias) ? 1 : 0); } else if (!my_strnicmp(listc, "DESTROY", 1)) { bp = find_binding(func); if (bp == NULL) RETURN_INT(0); if (bp->func != NULL) RETURN_INT(0); remove_binding(func); RETURN_INT(1); } else if (!my_strnicmp(listc, "EXISTS", 1)) { if (!my_stricmp(func, "NOTHING")) RETURN_INT(1); /* special case. */ RETURN_INT(find_binding(func) ? 1 : 0); } else if (!my_stricmp(listc, "GET")) { if (bp == NULL) RETURN_EMPTY; else if (bp->func) malloc_sprintf(&retval, "internal %p", bp->func); else malloc_sprintf(&retval, "alias %s", bp->alias); RETURN_STR(retval); } else if (!my_strnicmp(listc, "MATCH", 1)) { int len; len = strlen(func); for (bp = binding_list;bp;bp = bp->next) { if (!my_strnicmp(bp->name, func, len)) malloc_strcat_word(&retval, space, bp->name); } RETURN_STR(retval); } else if (!my_strnicmp(listc, "PMATCH", 1)) { for (bp = binding_list;bp;bp = bp->next) { if (wild_match(func, bp->name)) malloc_strcat_word(&retval, space, bp->name); } RETURN_STR(retval); } else if (!my_strnicmp(listc, "GETPACKAGE", 1)) { if (bp != NULL) RETURN_STR(bp->filename); } else if (!my_strnicmp(listc, "SETPACKAGE", 1)) { if (bp == NULL) RETURN_INT(0); malloc_strcpy(&bp->filename, input); RETURN_INT(1); } } else if (!my_strnicmp(listc, "SEQUENCE", 1)) { struct Key *key; unsigned char *seq; GET_STR_ARG(seq, input); key = find_sequence(seq, 0); GET_STR_ARG(listc, input); if (!my_stricmp(listc, "GET")) { if (key == NULL || key->bound == NULL) RETURN_EMPTY; retval = malloc_strdup(key->bound->name); if (key->stuff) malloc_strcat_wordlist(&retval, " ", key->stuff); RETURN_STR(retval); } else if (!my_stricmp(listc, "SET")) { GET_STR_ARG(listc, input); RETURN_INT(bind_string(seq, listc, (*input ? input : NULL))); } else if (!my_strnicmp(listc, "GETPACKAGE", 4)) { if (key == NULL) RETURN_EMPTY; RETURN_STR(key->filename); } else if (!my_strnicmp(listc, "SETPACKAGE", 4)) { if (key == NULL || key->bound == NULL) RETURN_INT(0); new_free(&key->filename); key->filename = malloc_strdup(input); } } else if (!my_strnicmp(listc, "MAP", 1)) { unsigned char *seq; int slen; struct Key *key; seq = new_next_arg(input, &input); if (seq == NULL) { bindctl_getmap(head_keymap, "", 0, &retval); RETURN_STR(retval); } seq = bind_string_compress(seq, &slen); key = find_sequence(seq, slen); listc = new_next_arg(input, &input); if (listc == NULL) { if (key == NULL || key->map == NULL) { new_free(&seq); RETURN_EMPTY; } bindctl_getmap(key->map, seq, slen, &retval); new_free(&seq); RETURN_STR(retval); } else if (!my_strnicmp(listc, "CLEAR", 1)) { if (key == NULL || key->map == NULL) RETURN_INT(0); remove_bindings_recurse(key->map); key->map = NULL; RETURN_INT(1); } } RETURN_EMPTY; } void bindctl_getmap (struct Key *map, const unsigned char *str, int len, char **ret) { int c; unsigned char *newstr; unsigned char *decomp; size_t size; size = len + 2; newstr = alloca(size); strlcpy(newstr, str, size); decomp = alloca(((len + 1) * 2) + 1); /* grab all keys that are bound, put them in ret, and continue. */ newstr[len + 1] = '\0'; for (c = 1; c <= KEYMAP_SIZE - 1;c++) { newstr[len] = c; if (map[c].bound) malloc_strcat_wordlist(ret, " ", bind_string_decompress(decomp, newstr, len + 1)); if (map[c].map) bindctl_getmap(map[c].map, newstr, len + 1, ret); } } epic4-2.10.2.orig/source/notice.c0000644000000000000000000003235207763532046013373 0ustar /* $EPIC: notice.c,v 1.27 2003/12/04 04:12:22 jnelson Exp $ */ /* * notice.c: special stuff for parsing NOTICEs * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1993, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "irc.h" #include "ctcp.h" #include "window.h" #include "lastlog.h" #include "flood.h" #include "vars.h" #include "ircaux.h" #include "hook.h" #include "ignore.h" #include "server.h" #include "output.h" #include "names.h" #include "parse.h" #include "notify.h" #include "notice.h" #include "commands.h" static time_t convert_note_time_to_real_time (char *stuff); static int kill_message (const char *from, const char *line); static int never_connected = 1; /* * The client apparantly never was adapted to handle the new NOTE syntax. * So i had to kludge this up to work with it. Currently, NOTEs are sent * something like this: * * NOTICE yournick :Note from nick!user@host /xxxd:xxh:xxm/ [N] message * * and parse() calls parse_notice(), who notices that there is no pefix * and passes it off to parse_local_server_notice(), who checks to see * if it is a note (it is), blows away the "Note from" part, and re-sets * the "from" and "FromUserHost" parts with the nick!user@host part and * passes us the buck with 'line' pointing at the time description * (the /.../ part) */ static void parse_note (char *from, char *line) { char *date, *flags, *high; time_t when; int level; switch (check_ignore(from, FromUserHost, IGNORE_NOTES)) { case IGNORED: return; case HIGHLIGHTED: high = highlight_char; break; default: high = empty_string; } if (check_flooding(from, FromUserHost, NOTE_FLOOD, line)) return; /* at this point, line looks like: "/xxxd:xxh:xxm/ [FLAGS] message goes here" */ date = next_arg(line, &line); flags = next_arg(line, &line); when = convert_note_time_to_real_time(date); level = set_lastlog_msg_level(LOG_NOTES); if (do_hook(NOTE_LIST, "%s %lu %s", from, when, line)) { if (time(NULL) - when > 60) /* not just sent */ put_it("%s[%s]%s %s (%s)", high, from, high, line, my_ctime(when)); else put_it("%s[%s]%s %s", high, from, high, line); } if (beep_on_level & LOG_NOTES) beep_em(1); set_lastlog_msg_level(level); } static time_t convert_note_time_to_real_time(char *stuff) { time_t days = 0, hours = 0, minutes = 0; stuff++; /* first character is a '/' */ days = strtoul(stuff, &stuff, 10); /* get the number of days */ stuff++; /* skip over the 'd' */ stuff++; /* skip over the ':' */ hours = strtoul(stuff, &stuff, 10); /* get the number of hours */ stuff++; /* skip over the 'h' */ stuff++; /* skip over the ':' */ minutes = strtoul(stuff, &stuff, 10); /* get the number of minutes */ stuff++; /* skip over the 'm' */ stuff++; /* skip over the '/' */ if (*stuff) yell("cntto: bad format"); hours += days * 24; minutes += hours * 60; return (time(NULL) - minutes * 60); } /* * This parses NOTICEs that are sent from that wacky ircd we are connected * to, and 'to' is guaranteed not to be a channel. */ static void parse_local_server_notice (const char *from, const char *to, const char *line) { int lastlog_level; const char * f; f = from; if (!f || !*f) if (!(f = get_server_itsname(from_server))) f = get_server_name(from_server); /* OPERator Notices */ if (!strncmp(line, "*** Notice -- ", 13)) { if (!strncmp(line + 14, "Received KILL message for ", 26)) if (kill_message(f, line + 40)) return; message_from(to, LOG_OPNOTE); lastlog_level = set_lastlog_msg_level(LOG_OPNOTE); if (!do_hook(OPER_NOTICE_LIST, "%s %s", f, line + 14)) return; } /* NOTEs */ else if (!strncmp(line, "Note", 4)) { char *note_from = NULL; char *point = NULL; if (strlen(line) > 10) { /* Skip the "Note From" part */ note_from = LOCAL_COPY(line + 10); if ((point = strchr(note_from, '!'))) { *point++ = 0; FromUserHost = line; if ((point = strchr(FromUserHost, ' '))) { *point++ = 0; parse_note(note_from, point); } FromUserHost = empty_string; } } return; } lastlog_level = set_lastlog_msg_level(LOG_SNOTE); message_from(to, LOG_SNOTE); /* Check to see if the notice already has its own header... */ if (do_hook(GENERAL_NOTICE_LIST, "%s %s %s", f, to, line)) { if (*line == '*' || *line == '#') { if (do_hook(SERVER_NOTICE_LIST, "%s %s", f, line)) put_it("%s", line); } else if (do_hook(SERVER_NOTICE_LIST, "%s *** %s", f, line)) say("%s", line); } if (lastlog_level) message_from(NULL, lastlog_level); } /* * The main handler for those wacky NOTICE commands... * This is as much like p_privmsg as i can get away with. */ void p_notice (const char *from, const char *comm, const char **ArgList) { const char *target, *message; int level, hook_type; const char * flood_channel = NULL; char * high; PasteArgs(ArgList, 1); if (!(target = ArgList[0])) { rfc1459_odd(from, comm, ArgList); return; } if (!(message = ArgList[1])) { rfc1459_odd(from, comm, ArgList); return; } set_server_doing_notice(from_server, 1); sed = 0; /* Do normal /CTCP reply handling */ /* XXX -- Casting "message" to (char *) is cheating. */ message = do_notice_ctcp(from, target, (char *) #ifdef HAVE_INTPTR_T (intptr_t) #endif message); if (!*message) { set_server_doing_notice(from_server, 0); return; } /* Check to see if it is a "Server Notice" */ if ((!from || !*from) || !strcmp(get_server_itsname(from_server), from)) { parse_local_server_notice(from, target, message); set_server_doing_notice(from_server, 0); return; } /* For pesky prefix-less NOTICEs substitute the server's name */ if (!from || !*from) from = get_server_name(from_server); /* * Note that NOTICEs from servers are not "server notices" unless * the target is not a channel (ie, it is sent to us). Any notice * that is sent to a channel is a normal NOTICE, notwithstanding * _who_ sent it. */ if (is_channel(target) && im_on_channel(target, from_server)) { flood_channel = target; hook_type = PUBLIC_NOTICE_LIST; } else if (!is_me(from_server, target)) { flood_channel = NULL; hook_type = NOTICE_LIST; } else { flood_channel = NULL; hook_type = NOTICE_LIST; target = from; } /* Check for /ignore's */ switch (check_ignore_channel(from, FromUserHost, target, IGNORE_NOTICES)) { case IGNORED: set_server_doing_notice(from_server, 0); return; case HIGHLIGHTED: high = highlight_char; break; /* oops! */ default: high = empty_string; } /* Let the user know if it is an encrypted notice */ /* Note that this is always hooked, even during a flood */ if (sed) { int do_return = 1; sed = 0; level = set_lastlog_msg_level(LOG_NOTICE); message_from(target, LOG_NOTICE); if (do_hook(ENCRYPTED_NOTICE_LIST, "%s %s %s", from, target, message)) do_return = 0; set_lastlog_msg_level(level); message_from(NULL, LOG_CRAP); if (do_return) { set_server_doing_notice(from_server, 0); return; } } if (new_check_flooding(from, FromUserHost, flood_channel, message, NOTICE_FLOOD)) { set_server_doing_notice(from_server, 0); return; } /* Beep the user if they asked us to */ if (beep_on_level & LOG_NOTICE) beep_em(1); /* Go ahead and throw it to the user */ level = set_lastlog_msg_level(LOG_NOTICE); message_from(target, LOG_NOTICE); if (do_hook(GENERAL_NOTICE_LIST, "%s %s %s", from, target, message)) { if (hook_type == NOTICE_LIST) { if (do_hook(hook_type, "%s %s", from, message)) put_it("%s-%s-%s %s", high, from, high, message); } else { if (do_hook(hook_type, "%s %s %s", from, target, message)) put_it("%s-%s:%s-%s %s", high, from, target, high, message); } } /* Clean up and go home. */ set_lastlog_msg_level(level); message_from(NULL, LOG_CRAP); set_server_doing_notice(from_server, 0); /* Alas, this is not protected by protocol enforcement. :( */ notify_mark(from_server, from, 1, 0); } /* * got_initial_version_28: this is called when ircii gets the serial * number 004 reply. We do this becuase the 004 numeric gives us the * server name and version in an easy to use fashion, and doesnt * rely on the syntax or construction of the 002 numeric. * * Hacked as neccesary by jfn, May 1995 */ void got_initial_version_28 (const char *server, const char *version, const char *umodes) { /* Worthless 004 reply. Hope for the best! */ if (!server || !version || !umodes) { set_server_version(from_server, Server2_8); set_server_version_string(from_server, ""); set_server_itsname(from_server, get_server_name(from_server)); } else { if (!strncmp(version, "2.8", 3)) { if (strstr(version, "mu") || strstr(version, "me")) set_server_version(from_server, Server_u2_8); else set_server_version(from_server, Server2_8); } else if (!strncmp(version, "2.9", 3)) set_server_version(from_server, Server2_9); else if (!strncmp(version, "2.10", 4)) set_server_version(from_server, Server2_10); else if (!strncmp(version, "u2.9", 4)) set_server_version(from_server, Server_u2_9); else if (!strncmp(version, "u2.10", 4)) set_server_version(from_server, Server_u2_10); else if (!strncmp(version, "u3.0", 4)) set_server_version(from_server, Server_u3_0); else set_server_version(from_server, Server2_8); set_server_version_string(from_server, version); set_server_itsname(from_server, server); set_possible_umodes(from_server, umodes); } reconnect_all_channels(); server_did_rejoin_channels(from_server); message_from(NULL, LOG_CRAP); reinstate_user_modes(); if (never_connected) { never_connected = 0; permit_status_update(1); if (!ircrc_loaded) load_ircrc(); if (default_channel) { e_channel("JOIN", default_channel, empty_string); new_free(&default_channel); } } else if (get_server_away(from_server)) set_server_away(from_server, get_server_away(from_server)); update_all_status(); do_hook(CONNECT_LIST, "%s %d %s", get_server_name(from_server), get_server_port(from_server), get_server_itsname(from_server)); window_check_channels(); } int kill_message (const char *from, const char *cline) { char *poor_sap; char *bastard; const char *path_to_bastard; char *reason; char *line; line = LOCAL_COPY(cline); poor_sap = next_arg(line, &line); /* Dalnet kill BBC and doesnt append the period */ if (!end_strcmp(poor_sap, ".", 1)) chop(poor_sap, 1); /* dalnet kill BBC and doesnt use "From", but "from" */ if (my_strnicmp(line, "From ", 5)) { yell("Attempted to parse an ill-formed KILL request [%s %s]", poor_sap, line); return 0; } line += 5; bastard = next_arg(line, &line); /* Hybrid BBC and doesn't include the kill-path. */ /* Fend off future BBC kills */ if (my_strnicmp(line, "Path: ", 6)) { path_to_bastard = "*"; reason = line; /* Hope for the best */ } else { line += 6; path_to_bastard = next_arg(line, &line); reason = line; } return !do_hook(KILL_LIST, "%s %s %s %s %s", from, poor_sap, bastard, path_to_bastard, reason); } /* * XXX - I suppose this doesn't belong here, but where does it belong? */ void load_ircrc (void) { char buffer[7]; strlcpy(buffer, "global", sizeof buffer); loading_global = 1; load("LOAD", buffer, empty_string); loading_global = 0; /* read the startup file */ if (access(epicrc_file, R_OK) == 0 && !quick_startup) { load("LOAD", epicrc_file, empty_string); startup_file = epicrc_file; } else if (access(ircrc_file, R_OK) == 0 && !quick_startup) { load("LOAD", ircrc_file, empty_string); startup_file = ircrc_file; } ircrc_loaded = 1; } epic4-2.10.2.orig/source/status.c0000644000000000000000000011727412171115775013437 0ustar /* $EPIC: status.c,v 1.39 2013/07/16 01:03:57 jnelson Exp $ */ /* * status.c: handles the status line updating, etc for IRCII * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1994 Jake Khuon. * Copyright © 1995, 2003 EPIC Software Labs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #define __need_putchar_x__ #include "irc.h" #include "dcc.h" #include "termx.h" #include "status.h" #include "server.h" #include "vars.h" #include "hook.h" #include "input.h" #include "commands.h" #include "window.h" #include "screen.h" #include "mail.h" #include "output.h" #include "names.h" #include "ircaux.h" #include "alias.h" #include "clock.h" #ifdef Char #undef Char #endif #define Char const char /* * Maximum number of "%" expressions in a status line format. If you change * this number, you must manually change the snprintf() in make_status */ #define STATUS_FUNCTION(x) Char * x (Window *window, int map, int key) #define MAX_FUNCTIONS 40 #define MAX_STATUS_USER 39 STATUS_FUNCTION(status_nickname); STATUS_FUNCTION(status_query_nick); STATUS_FUNCTION(status_right_justify); STATUS_FUNCTION(status_chanop); STATUS_FUNCTION(status_ssl); STATUS_FUNCTION(status_channel); STATUS_FUNCTION(status_server); STATUS_FUNCTION(status_mode); STATUS_FUNCTION(status_umode); STATUS_FUNCTION(status_insert_mode); STATUS_FUNCTION(status_overwrite_mode); STATUS_FUNCTION(status_away); STATUS_FUNCTION(status_network); STATUS_FUNCTION(status_oper); STATUS_FUNCTION(status_user); STATUS_FUNCTION(status_dcc); STATUS_FUNCTION(status_dcc_all); STATUS_FUNCTION(status_hold); STATUS_FUNCTION(status_version); STATUS_FUNCTION(status_clock); STATUS_FUNCTION(status_hold_lines); STATUS_FUNCTION(status_window); STATUS_FUNCTION(status_mail); STATUS_FUNCTION(status_refnum); STATUS_FUNCTION(status_refnum_real); STATUS_FUNCTION(status_null_function); STATUS_FUNCTION(status_notify_windows); STATUS_FUNCTION(status_voice); STATUS_FUNCTION(status_cpu_saver_mode); STATUS_FUNCTION(status_position); STATUS_FUNCTION(status_scrollback); STATUS_FUNCTION(status_scroll_info); STATUS_FUNCTION(status_windowspec); STATUS_FUNCTION(status_percent); STATUS_FUNCTION(status_test); STATUS_FUNCTION(status_swappable); /* These are used as placeholders for some expandos */ static char *mode_format = (char *) 0; static char *umode_format = (char *) 0; static char *query_format = (char *) 0; static char *clock_format = (char *) 0; static char *hold_lines_format = (char *) 0; static char *channel_format = (char *) 0; static char *cpu_saver_format = (char *) 0; static char *mail_format = (char *) 0; static char *nick_format = (char *) 0; static char *server_format = (char *) 0; static char *notify_format = (char *) 0; Status main_status; int main_status_init = 0; static void init_status (void); /* * Status updates are not permitted until we are connected to a server. * Got_initial_version_28 will set this to 1 when we first get connected * to a server. */ int status_updates_permitted = 0; /* * This is the list of possible expandos. Note that you should not use * the '{' character, as it would be confusing. It is already used for * specifying the map. */ struct status_formats { int map; char key; Char *(*callback_function)(Window *, int, int); char **format_var; int format_set; }; struct status_formats status_expandos[] = { { 0, 'A', status_away, NULL, -1 }, { 0, 'B', status_hold_lines, &hold_lines_format, STATUS_HOLD_LINES_VAR }, { 0, 'C', status_channel, &channel_format, STATUS_CHANNEL_VAR }, { 0, 'D', status_dcc, NULL, -1 }, { 0, 'F', status_notify_windows,¬ify_format, STATUS_NOTIFY_VAR }, { 0, 'G', status_network, NULL, -1 }, { 0, 'H', status_hold, NULL, -1 }, { 0, 'I', status_insert_mode, NULL, -1 }, { 0, 'K', status_scrollback, NULL, -1 }, { 0, 'L', status_cpu_saver_mode,&cpu_saver_format, STATUS_CPU_SAVER_VAR }, { 0, 'M', status_mail, &mail_format, STATUS_MAIL_VAR }, { 0, 'N', status_nickname, &nick_format, STATUS_NICK_VAR }, { 0, 'O', status_overwrite_mode,NULL, -1 }, { 0, 'P', status_position, NULL, -1 }, { 0, 'Q', status_query_nick, &query_format, STATUS_QUERY_VAR }, { 0, 'R', status_refnum, NULL, -1 }, { 0, 'S', status_server, &server_format, STATUS_SERVER_VAR }, { 0, 'T', status_clock, &clock_format, STATUS_CLOCK_VAR }, { 0, 'U', status_user, NULL, -1 }, { 0, 'V', status_version, NULL, -1 }, { 0, 'W', status_window, NULL, -1 }, { 0, 'X', status_user, NULL, -1 }, { 0, 'Y', status_user, NULL, -1 }, { 0, 'Z', status_user, NULL, -1 }, { 0, '#', status_umode, &umode_format, STATUS_UMODE_VAR }, { 0, '%', status_percent, NULL, -1 }, { 0, '*', status_oper, NULL, -1 }, { 0, '+', status_mode, &mode_format, STATUS_MODE_VAR }, { 0, '.', status_windowspec, NULL, -1 }, { 0, '=', status_voice, NULL, -1 }, { 0, '>', status_right_justify, NULL, -1 }, { 0, '@', status_chanop, NULL, -1 }, { 0, '|', status_ssl, NULL, -1 }, { 0, '0', status_user, NULL, -1 }, { 0, '1', status_user, NULL, -1 }, { 0, '2', status_user, NULL, -1 }, { 0, '3', status_user, NULL, -1 }, { 0, '4', status_user, NULL, -1 }, { 0, '5', status_user, NULL, -1 }, { 0, '6', status_user, NULL, -1 }, { 0, '7', status_user, NULL, -1 }, { 0, '8', status_user, NULL, -1 }, { 0, '9', status_user, NULL, -1 }, { 1, '0', status_user, NULL, -1 }, { 1, '1', status_user, NULL, -1 }, { 1, '2', status_user, NULL, -1 }, { 1, '3', status_user, NULL, -1 }, { 1, '4', status_user, NULL, -1 }, { 1, '5', status_user, NULL, -1 }, { 1, '6', status_user, NULL, -1 }, { 1, '7', status_user, NULL, -1 }, { 1, '8', status_user, NULL, -1 }, { 1, '9', status_user, NULL, -1 }, { 1, 'D', status_dcc_all, NULL, -1 }, { 1, 'F', status_notify_windows,¬ify_format, STATUS_NOTIFY_VAR }, { 1, 'K', status_scroll_info, NULL, -1 }, { 1, 'R', status_refnum_real, NULL, -1 }, { 1, 'S', status_server, &server_format, STATUS_SERVER_VAR }, { 1, 'T', status_test, NULL, -1 }, { 1, 'W', status_swappable, NULL, -1 }, { 1, '+', status_mode, &mode_format, STATUS_MODE_VAR }, { 2, '0', status_user, NULL, -1 }, { 2, '1', status_user, NULL, -1 }, { 2, '2', status_user, NULL, -1 }, { 2, '3', status_user, NULL, -1 }, { 2, '4', status_user, NULL, -1 }, { 2, '5', status_user, NULL, -1 }, { 2, '6', status_user, NULL, -1 }, { 2, '7', status_user, NULL, -1 }, { 2, '8', status_user, NULL, -1 }, { 2, '9', status_user, NULL, -1 }, { 2, 'S', status_server, &server_format, STATUS_SERVER_VAR }, { 2, 'W', status_window, NULL, -1 }, { 3, '0', status_user, NULL, -1 }, { 3, '1', status_user, NULL, -1 }, { 3, '2', status_user, NULL, -1 }, { 3, '3', status_user, NULL, -1 }, { 3, '4', status_user, NULL, -1 }, { 3, '5', status_user, NULL, -1 }, { 3, '6', status_user, NULL, -1 }, { 3, '7', status_user, NULL, -1 }, { 3, '8', status_user, NULL, -1 }, { 3, '9', status_user, NULL, -1 }, { 3, 'W', status_window, NULL, -1 } }; #define NUMBER_OF_EXPANDOS (sizeof(status_expandos) / sizeof(struct status_formats)) /* * convert_sub_format: This is used to convert the formats of the * sub-portions of the status line to a format statement specially designed * for that sub-portions. convert_sub_format looks for a single occurence of * %c (where c is passed to the function). When found, it is replaced by "%s" * for use in a snprintf. All other occurences of % followed by any other * character are left unchanged. Only the first occurence of %c is * converted, all subsequence occurences are left unchanged. This routine * mallocs the returned string. */ char *convert_sub_format (const char *format, char c) { char buffer[BIG_BUFFER_SIZE + 1]; int pos = 0; int dont_got_it = 1; if (!format) return NULL; /* NULL in, NULL out */ while (*format && pos < BIG_BUFFER_SIZE - 4) { if (*format != '%') { buffer[pos++] = *format++; continue; } format++; if (*format == c && dont_got_it) { dont_got_it = 0; buffer[pos++] = '%'; buffer[pos++] = 's'; format++; } else if (*format != '%') { buffer[pos++] = '%'; buffer[pos++] = '%'; buffer[pos++] = *format; format++; } else { buffer[pos++] = '%'; buffer[pos++] = '%'; } } buffer[pos] = 0; return malloc_strdup(buffer); } /* * This walks a raw format string and parses out any expandos that it finds. * An expando is handled by pre-fetching any string variable that is used * by the callback function, the callback function is registered, and a * %s format is put in the snprintf()-able return value (stored in buffer). * All other characters are copied as-is to the return value. */ static void build_status_format (Status *s, int k) { char buffer[BIG_BUFFER_SIZE + 1]; int cp; int map; char key; unsigned i; Char *raw = s->line[k].raw; char *format = buffer; cp = s->line[k].count = 0; while (raw && *raw && (format - buffer < BIG_BUFFER_SIZE - 4)) { if (*raw != '%') { *format++ = *raw++; continue; } /* It is a % */ map = 0; /* Find the map, if neccesary */ if (*++raw == '{') { char *endptr; raw++; map = strtoul(raw, &endptr, 10); if (*endptr != '}') { /* Unrecognized */ continue; } raw = endptr + 1; } key = *raw++; /* Choke once we get to the maximum number of expandos */ if (cp >= MAX_FUNCTIONS) continue; for (i = 0; i < NUMBER_OF_EXPANDOS; i++) { if (status_expandos[i].map != map || status_expandos[i].key != key) continue; if (status_expandos[i].format_var) new_free(status_expandos[i].format_var); if (status_expandos[i].format_set != -1) *(status_expandos[i].format_var) = convert_sub_format(get_string_var(status_expandos[i].format_set), key); *format++ = '%'; *format++ = 's'; s->line[k].func[cp] = status_expandos[i].callback_function; s->line[k].map[cp] = map; s->line[k].key[cp] = key; cp++; break; } } s->line[k].count = cp; *format = 0; malloc_strcpy(&(s->line[k].format), buffer); while (cp < MAX_FUNCTIONS) { s->line[k].func[cp] = status_null_function; s->line[k].map[cp] = 0; s->line[k].key[cp] = 0; cp++; } } /* * This function either rebuilds the status_func[] tables for each of the * three possible status_format's (single, lower double, upper double) for * a particular window (w != NULL) or for the global default status bars * (w == NULL) * * This function should only by the functions that actually change the * status formats (build_status, new_window, and window_status_format*) */ void rebuild_a_status (Window *w) { int i, k; Status *s; if (w) s = &w->status; else s = &main_status; for (k = 0; k < 3; k++) { new_free((char **)&s->line[k].format); s->line[k].count = 0; /* * If we have an overriding status_format, then we parse * that out. */ if (w && s->line[k].raw) build_status_format(s, k); /* * Otherwise, If this is for a window, just copy the essential * information over from the main status lines. */ else if (w) { s->line[k].format = malloc_strdup(main_status.line[k].format); for (i = 0; i < MAX_FUNCTIONS; i++) { s->line[k].func[i] = main_status.line[k].func[i]; s->line[k].map[i] = main_status.line[k].map[i]; s->line[k].key[i] = main_status.line[k].key[i]; } s->line[k].count = main_status.line[k].count; } /* * Otherwise, this *is* the main status lines we are generating * and we need to do all the normal shenanigans. */ else { if (k == 0) s->line[k].raw = get_string_var(STATUS_FORMAT_VAR); else if (k == 1) s->line[k].raw = get_string_var(STATUS_FORMAT1_VAR); else /* (k == 2) */ s->line[k].raw = get_string_var(STATUS_FORMAT2_VAR); build_status_format(s, k); } } } /* * This function causes every status bar, both global and per-window to be * rebuilt, and marks every window as needing its status bar redrawn. * This function can be quite expensive. * * This function should be called whenever you change the global status format * (/SET STATUS_FORMAT*) or one of the sub-components (/SET STATUS_*) * * This function is a /SET callback, so it must always take a (char *) as an * argument even though we don't care about it. */ void build_status (const void *stuff) { Window *w = NULL; if (!main_status_init) init_status(); rebuild_a_status(w); while (traverse_all_windows(&w)) rebuild_a_status(w); update_all_status(); } static void init_status (void) { int i, k; main_status.double_status = 0; main_status.special = 0; for (i = 0; i < 3; i++) { main_status.line[i].raw = NULL; main_status.line[i].format = NULL; main_status.line[i].count = 0; main_status.line[i].result = NULL; for (k = 0; k < MAX_FUNCTIONS; k++) { main_status.line[i].func[k] = NULL; main_status.line[i].map[k] = 0; main_status.line[i].key[k] = 0; } } main_status_init = 1; } /* * permit_status_update: sets the status_update_flag to whatever flag is. */ int permit_status_update (int flag) { int old_flag = status_updates_permitted; status_updates_permitted = flag; return old_flag; } /* * This just sucked beyond words. I was always planning on rewriting this, * but the crecendo of complaints with regards to this just got to be too * irritating, so i fixed it early. */ int make_status (Window *window, int must_redraw) { int status_line; u_char buffer [BIG_BUFFER_SIZE + 1]; u_char lhs_buffer [BIG_BUFFER_SIZE + 1]; u_char rhs_buffer [BIG_BUFFER_SIZE + 1]; Char *func_value [MAX_FUNCTIONS]; u_char *ptr; size_t save_size; /* We do NOT redraw status bars for hidden windows */ if (!window->screen || !status_updates_permitted) return -1; for (status_line = 0; status_line < window->status.double_status + 1; status_line++) { u_char lhs_fillchar[6], rhs_fillchar[6], *fillchar = lhs_fillchar, *lhp = lhs_buffer, *rhp = rhs_buffer, *cp, *start_rhs = 0, *str; int in_rhs = 0, pr_lhs = 0, pr_rhs = 0, line, *prc = &pr_lhs, i; fillchar[0] = fillchar[1] = 0; /* * If status line gets to one, then that means that * window->double_status is not zero. That means that * the status line we're working on is STATUS2. */ if (status_line) line = 2; /* * If status_line is zero, and window->double_status is * not zero (double status line is on) then we're working * on STATUS1. */ else if (window->status.double_status) line = 1; /* * So status_line is zero and window->double_status is zero. * So we're working on STATUS (0). */ else line = 0; /* * Sanity check: If the status format doesnt exist, dont do * anything for it. */ if (!window->status.line[line].format) continue; /* * Run each of the status-generating functions from the the * status list. Note that the retval of the functions is no * longer malloc()ed. This saves 40-some odd malloc/free sets * each time the status bar is updated, which is non-trivial. */ for (i = 0; i < MAX_FUNCTIONS; i++) { if (window->screen == NULL) return -1; if (window->status.line[line].func[i] == NULL) panic("status callback null. Window [%d], line [%d], function [%d]", window->refnum, line, i); func_value[i] = window->status.line[line].func[i] (window, window->status.line[line].map[i], window->status.line[line].key[i]); } /* * If the REVERSE_STATUS_LINE var is on, then put a reverse * character in the first position (itll get translated to * the tcap code in the output code. */ if (get_int_var(REVERSE_STATUS_LINE_VAR)) *buffer = REV_TOG , str = buffer + 1; else str = buffer; /* * Now press the status line into "buffer". The magic about * setting status_format is handled elsewhere. */ snprintf(str, BIG_BUFFER_SIZE - 1, window->status.line[line].format, func_value[0], func_value[1], func_value[2], func_value[3], func_value[4], func_value[5], func_value[6], func_value[7], func_value[8], func_value[9], func_value[10], func_value[11], func_value[12], func_value[13], func_value[14], func_value[15], func_value[16], func_value[17], func_value[18], func_value[19], func_value[20], func_value[21], func_value[22], func_value[23], func_value[24], func_value[25], func_value[26], func_value[27], func_value[28], func_value[29], func_value[30], func_value[31], func_value[32], func_value[33], func_value[34], func_value[35], func_value[36], func_value[37], func_value[38], func_value[39]); /* * If the user wants us to, pass the status bar through the * expander to pick any variables/function calls. * This is horribly expensive, but what do i care if you * want to waste cpu cycles? ;-) */ if (get_int_var(STATUS_DOES_EXPANDOS_VAR)) { int af = 0; int old_fs = from_server; Window *old = current_window; int owd = window_display; current_window = window; from_server = current_window->server; window_display = 0; str = expand_alias(buffer, empty_string, &af, NULL); window_display = owd; from_server = old_fs; current_window = old; strlcpy(buffer, str, sizeof buffer); new_free(&str); } /* * This converts away any ansi codes in the status line * in accordance with the currenet settings. This leaves us * with nothing but logical characters, which are then easy * to count. :-) */ str = normalize_string(buffer, 3); /* * Count out the characters. * Walk the entire string, looking for nonprintable * characters. We count all the printable characters * on both sides of the %> tag. */ ptr = str; cp = lhp; lhs_buffer[0] = rhs_buffer[0] = 0; while (*ptr) { /* * The FIRST such %> tag is used. * Using multiple %>s is bogus. */ if (*ptr == '\f' && start_rhs == NULL) { ptr++; start_rhs = ptr; fillchar = rhs_fillchar; in_rhs = 1; *cp = 0; cp = rhp; prc = &pr_rhs; } /* * Skip over attribute changes, not useful. */ else if (*ptr == '\006') { /* Copy the next 5 values */ *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; } /* * XXXXX This is a bletcherous hack. * If i knew what was good for me id not do this. */ else if (*ptr == 9) /* TAB */ { fillchar[0] = ' '; fillchar[1] = 0; do *cp++ = ' '; while (++(*prc) % 8); ptr++; } /* * So it is a printable character. */ else { *prc += 1; fillchar[0] = *cp++ = *ptr++; fillchar[1] = 0; } /* * Dont allow more than CO printable characters */ if (pr_lhs + pr_rhs >= window->screen->co) { *cp = 0; break; } } *cp = 0; /* What will we be filling with? */ if (get_int_var(STATUS_NO_REPEAT_VAR)) { lhs_fillchar[0] = ' '; lhs_fillchar[1] = 0; rhs_fillchar[0] = ' '; rhs_fillchar[1] = 0; } /* * Now if we have a rhs, then we have to adjust it. */ if (start_rhs) { int numf = 0; numf = window->screen->co - pr_lhs - pr_rhs -1; while (numf-- >= 0) strlcat(lhs_buffer, lhs_fillchar, sizeof lhs_buffer); } /* * No rhs? If the user wants us to pad it out, do so. */ else if (get_int_var(FULL_STATUS_LINE_VAR)) { int chars = window->screen->co - pr_lhs - 1; while (chars-- >= 0) strlcat(lhs_buffer, lhs_fillchar, sizeof lhs_buffer); } save_size = strlen(all_off()); strlcpy(buffer, lhs_buffer, sizeof buffer - save_size); strlcat(buffer, rhs_buffer, sizeof buffer - save_size); strlcat(buffer, all_off(), sizeof buffer); new_free(&str); /* * Ends up that BitchX always throws this hook and * people seem to like having this thrown in standard * mode, so i'll go along with that. */ do_hook(STATUS_UPDATE_LIST, "%d %d %s", window->refnum, status_line, buffer); if (dumb_mode || !foreground) continue; /* * Update the status line on the screen. * First check to see if it has changed * Remember this is only done in full screen mode. */ if (must_redraw || !window->status.line[status_line].result || strcmp(buffer, window->status.line[status_line].result)) { /* * Roll the new back onto the old */ malloc_strcpy(&window->status.line[status_line].result, buffer); /* * Output the status line to the screen */ output_screen = window->screen; term_move_cursor(0, window->bottom + status_line); output_with_count(buffer, 1, 1); cursor_in_display(window); } } cursor_to_input(); return 0; } /* Some useful macros */ /* * This is used to get the current window on a window's screen */ #define CURRENT_WINDOW window->screen->current_window /* * This tests to see if the window IS the current window on its screen */ #define IS_CURRENT_WINDOW (window->screen->current_window == window) /* * This tests to see if all expandoes are to appear in all status bars */ #define SHOW_ALL_WINDOWS (get_int_var(SHOW_STATUS_ALL_VAR)) /* * "Current-type" window expandoes occur only on the current window for a * screen. However, if /set show_status_all is on, then ALL windows act as * "Current-type" windows. */ #define DISPLAY_ON_WINDOW (IS_CURRENT_WINDOW || SHOW_ALL_WINDOWS) /* * These are the functions that all of the status expandoes invoke */ /* * This is your current nickname in the window. */ STATUS_FUNCTION(status_nickname) { static char my_buffer[64]; snprintf(my_buffer, 63, nick_format, get_server_nickname(window->server)); return my_buffer; } /* * This displays the server that the window is connected to. */ STATUS_FUNCTION(status_server) { char *rest; const char *n; char *name; char *next; static char my_buffer[64]; size_t len; #ifdef OLD_STATUS_S_EXPANDO_BEHAVIOR /* * If there is only one server, dont bother telling the user * what it is. */ if (connected_to_server == 1 && map == 0) return empty_string; #endif /* * If this window isnt connected to a server, say so. */ if (window->server == NOSERV) return "No Server"; /* * If the user doesnt want this expando, dont force it. */ if (!server_format) return empty_string; /* Figure out what server this window is on */ n = get_server_name(window->server); if (map == 2) { snprintf(my_buffer, 63, server_format, n); return my_buffer; } name = LOCAL_COPY(n); /* * If the first segment before the first dot is a number, * then its an ip address, and use the whole thing. */ if (strtoul(name, &next, 10) && *next == '.') { snprintf(my_buffer, 63, server_format, name); return my_buffer; } /* * Get the stuff to the left of the first dot. */ if (!(rest = strchr(name, '.'))) { snprintf(my_buffer, 63, server_format, name); return my_buffer; } /* * If the first segment is 'irc', thats not terribly * helpful, so get the next segment. */ if (!strncmp(name, "irc", 3)) { name = rest + 1; if (!(rest = strchr(name + 1, '.'))) rest = name + strlen(name); } /* * If the name of the server is > 60 chars, crop it back to 60. */ if ((len = rest - name) > 60) len = 60; /* * Plop the server into the server_format and return it. */ name[len] = 0; snprintf(my_buffer, 63, server_format, name); return my_buffer; } /* * This displays any nicks that you may have as your current query in the * given window. */ STATUS_FUNCTION(status_query_nick) { static char my_buffer[BIG_BUFFER_SIZE + 1]; if (window->query_nick && query_format) { snprintf(my_buffer, BIG_BUFFER_SIZE, query_format, window->query_nick); return my_buffer; } return empty_string; } /* * This forces anything to the right of this point to be right-justified * (if possible) on the status bar. Note that the right hand side is always * cropped, and not the left hand side. That is to say, this is a hint that * if the left hand side is too short, that the "filler" should be put here * at this point rather than at the end of the status line. */ STATUS_FUNCTION(status_right_justify) { static char my_buffer[] = "\f"; return my_buffer; } /* * Displays whatever windows are notifying, and have notified * (usually when output happens on hidden windows that you marked with * /window notify on) */ STATUS_FUNCTION(status_notify_windows) { int doneone = 0; char buf2[BIG_BUFFER_SIZE]; static char my_buffer[BIG_BUFFER_SIZE]; /* * This only goes to a current-type window. */ if (!DISPLAY_ON_WINDOW) return empty_string; *my_buffer = 0; *buf2 = 0; /* * Look for any notifying windows that have had some output since * they have been hidden and collect their refnums. */ window = NULL; while (traverse_all_windows(&window)) { if (window->miscflags & WINDOW_NOTIFIED) { if (doneone++) strlcat(buf2, ",", sizeof buf2); strlcat(buf2, (map == 1 && window->name) ? window->name : ltoa(window->refnum), sizeof buf2); } } /* * Only do the snprintf if there are windows to process. */ if (doneone && notify_format) snprintf(my_buffer, sizeof my_buffer, notify_format, buf2); return my_buffer; } /* * Displays what time it is on the current-type window */ STATUS_FUNCTION(status_clock) { static char my_buffer[81]; if (get_int_var(CLOCK_VAR) && clock_format && DISPLAY_ON_WINDOW) snprintf(my_buffer, 80, clock_format, get_clock()); else *my_buffer = 0; return my_buffer; } /* * The current channel mode for the current channel (if any) */ STATUS_FUNCTION(status_mode) { const char * mode = NULL; const char * chan = NULL; static char my_buffer[81]; /* If anything goes wrong, we return an empty string */ *my_buffer = 0; /* If the user has no mode format, or we're not connected, punt. */ if (!mode_format || window->server == NOSERV) return my_buffer; /* If there is a current channel, get it's mode */ if ((chan = get_echannel_by_refnum(window->refnum))) mode = get_channel_mode(chan, window->server); /* If this is %+, and there is not a mode, punt. */ if (mode == 0 && (!mode || !*mode)) return my_buffer; /* If this is %{1}+, and there is not a mode, use empty string */ if (!mode) mode = empty_string; /* * This gross hack is required to make sure that the * channel key doesnt accidentally contain anything * dangerous... */ if (get_int_var(STATUS_DOES_EXPANDOS_VAR)) { char *mode2 = alloca(strlen(mode) * 2 + 1); double_quote(mode, "$", mode2); mode = mode2; } /* Press the mode into the status format. */ snprintf(my_buffer, 80, mode_format, mode); return my_buffer; } /* * Your user mode for the server in this window. */ STATUS_FUNCTION(status_umode) { char localbuf[20]; static char my_buffer[81]; /* * If we are only on one server and this isnt the current-type * window, then dont display it here. */ if (connected_to_server == 1 && !DISPLAY_ON_WINDOW) return empty_string; /* * Punt if the window isnt connected to a server. */ if (window->server < 0) return empty_string; strlcpy(localbuf, get_umode(window->server), sizeof localbuf); if (!*localbuf) return empty_string; snprintf(my_buffer, 80, umode_format, localbuf); return my_buffer; } /* * Figures out whether or not youre a channel operator on the current * channel for this window. */ STATUS_FUNCTION(status_chanop) { char *text; const char *chan; if (window->server == NOSERV || (!(chan = get_echannel_by_refnum(window->refnum)))) return empty_string; if (get_channel_oper(chan, window->server) && (text = get_string_var(STATUS_CHANOP_VAR))) return text; if (get_channel_halfop(chan, window->server) && (text = get_string_var(STATUS_HALFOP_VAR))) return text; return empty_string; } /* * are we using SSL conenction? */ STATUS_FUNCTION(status_ssl) { char *text; if (window->server != NOSERV && get_server_isssl(window->server) && (text = get_string_var(STATUS_SSL_ON_VAR))) return text; else if ((text = get_string_var(STATUS_SSL_OFF_VAR))) return text; return empty_string; } /* * Figures out how many lines are being "held" (never been displayed, usually * because of hold_mode or scrollback being on) for this window. */ STATUS_FUNCTION(status_hold_lines) { int num; static char my_buffer[81]; int interval = window->hold_interval; int lines_held; if (interval == 0) interval = 1; /* XXX WHAT-ever */ if (window->holding_distance_from_display_ip > window->scrollback_distance_from_display_ip) lines_held = window->holding_distance_from_display_ip - window->display_size; else lines_held = window->scrollback_distance_from_display_ip - window->display_size; if (lines_held <= 0) return empty_string; if ((num = (lines_held / interval) * interval)) { snprintf(my_buffer, 80, hold_lines_format, ltoa(num)); return my_buffer; } return empty_string; } /* * Figures out what the current channel is for the window. */ STATUS_FUNCTION(status_channel) { const char *chan; char channel[IRCD_BUFFER_SIZE + 1]; static char my_buffer[IRCD_BUFFER_SIZE + 1]; int num; if (window->server == NOSERV || !channel_format) return empty_string; if (!(chan = get_echannel_by_refnum(window->refnum))) return empty_string; if (get_int_var(HIDE_PRIVATE_CHANNELS_VAR) && is_channel_private(chan, window->server)) strlcpy(channel, "*private*", sizeof channel); else strlcpy(channel, chan, sizeof channel); num = get_int_var(CHANNEL_NAME_WIDTH_VAR); if (num > 0 && (int)strlen(channel) > num) channel[num] = 0; snprintf(my_buffer, IRCD_BUFFER_SIZE, channel_format, check_channel_type(channel)); return my_buffer; } /* * Figures out if you are a channel voice for the current channel in this * window. For whatever reason, this wont display if youre also a channel * operator on the current channel in this window. */ STATUS_FUNCTION(status_voice) { char *text; const char *chan; if (window->server == NOSERV || (chan = get_echannel_by_refnum(window->refnum)) == NULL) return empty_string; if (get_channel_voice(chan, window->server) && !get_channel_oper(chan, window->server) && (text = get_string_var(STATUS_VOICE_VAR))) return text; return empty_string; } /* * Displays how much mail we think you have. */ STATUS_FUNCTION(status_mail) { const char * number; static char my_buffer[81]; /* * The order is important here. We check to see whether or not * this is a current-type window *FIRST* because most of the time * that will be false, and check_mail() is very expensive; we dont * want to do it if we're going to ignore the result. */ if (get_int_var(MAIL_VAR) && mail_format && DISPLAY_ON_WINDOW && (number = check_mail())) { snprintf(my_buffer, 80, mail_format, number); return my_buffer; } return empty_string; } /* * Display if "insert mode" is ON for the input line. */ STATUS_FUNCTION(status_insert_mode) { char *text; if (get_int_var(INSERT_MODE_VAR) && DISPLAY_ON_WINDOW && (text = get_string_var(STATUS_INSERT_VAR))) return text; return empty_string; } /* * Displays if "insert mode" is OFF for the input line. */ STATUS_FUNCTION(status_overwrite_mode) { char *text; if (!get_int_var(INSERT_MODE_VAR) && DISPLAY_ON_WINDOW && (text = get_string_var(STATUS_OVERWRITE_VAR))) return text; return empty_string; } /* * Displays if you are AWAY (protocol away) on the current server for * the window. */ STATUS_FUNCTION(status_away) { char *text; /* * If we're only on one server, only do this for the * current-type window. */ if (connected_to_server == 1 && !DISPLAY_ON_WINDOW) return empty_string; if (window->server != NOSERV && get_server_away(window->server) && (text = get_string_var(STATUS_AWAY_VAR))) return text; return empty_string; } /* * Displays the 005 "NETWORK" value for the current server for the window. */ STATUS_FUNCTION(status_network) { const char *text = NULL; if (window->server != NOSERV) text = get_server_005(window->server, "NETWORK"); return text ? text : empty_string; } /* * This is a generic status_userX variable. */ STATUS_FUNCTION(status_user) { char * text; int i; /* XXX Ick. Oh well. */ struct dummystruct { int map; char key; enum VAR_TYPES var; } lookup[] = { { 0, 'U', STATUS_USER0_VAR }, { 0, 'X', STATUS_USER1_VAR }, { 0, 'Y', STATUS_USER2_VAR }, { 0, 'Z', STATUS_USER3_VAR }, { 0, '0', STATUS_USER0_VAR }, { 0, '1', STATUS_USER1_VAR }, { 0, '2', STATUS_USER2_VAR }, { 0, '3', STATUS_USER3_VAR }, { 0, '4', STATUS_USER4_VAR }, { 0, '5', STATUS_USER5_VAR }, { 0, '6', STATUS_USER6_VAR }, { 0, '7', STATUS_USER7_VAR }, { 0, '8', STATUS_USER8_VAR }, { 0, '9', STATUS_USER9_VAR }, { 1, '0', STATUS_USER10_VAR }, { 1, '1', STATUS_USER11_VAR }, { 1, '2', STATUS_USER12_VAR }, { 1, '3', STATUS_USER13_VAR }, { 1, '4', STATUS_USER14_VAR }, { 1, '5', STATUS_USER15_VAR }, { 1, '6', STATUS_USER16_VAR }, { 1, '7', STATUS_USER17_VAR }, { 1, '8', STATUS_USER18_VAR }, { 1, '9', STATUS_USER19_VAR }, { 2, '0', STATUS_USER20_VAR }, { 2, '1', STATUS_USER21_VAR }, { 2, '2', STATUS_USER22_VAR }, { 2, '3', STATUS_USER23_VAR }, { 2, '4', STATUS_USER24_VAR }, { 2, '5', STATUS_USER25_VAR }, { 2, '6', STATUS_USER26_VAR }, { 2, '7', STATUS_USER27_VAR }, { 2, '8', STATUS_USER28_VAR }, { 2, '9', STATUS_USER29_VAR }, { 3, '0', STATUS_USER30_VAR }, { 3, '1', STATUS_USER31_VAR }, { 3, '2', STATUS_USER32_VAR }, { 3, '3', STATUS_USER33_VAR }, { 3, '4', STATUS_USER34_VAR }, { 3, '5', STATUS_USER35_VAR }, { 3, '6', STATUS_USER36_VAR }, { 3, '7', STATUS_USER37_VAR }, { 3, '8', STATUS_USER38_VAR }, { 3, '9', STATUS_USER39_VAR }, { 0, 0, 0 }, }; text = NULL; for (i = 0; lookup[i].var; i++) { if (map == lookup[i].map && key == lookup[i].key) { text = get_string_var(lookup[i].var); break; } } if (text && (DISPLAY_ON_WINDOW || map > 1)) return text; return empty_string; } STATUS_FUNCTION(status_hold) { char *text; if (window->holding_distance_from_display_ip > window->display_size || window->scrollback_distance_from_display_ip > window->display_size) if ((text = get_string_var(STATUS_HOLD_VAR))) return text; return empty_string; } STATUS_FUNCTION(status_oper) { char *text; if (window->server != NOSERV && get_server_operator(window->server) && (text = get_string_var(STATUS_OPER_VAR)) && (connected_to_server != 1 || DISPLAY_ON_WINDOW)) return text; else return empty_string; } STATUS_FUNCTION(status_window) { const char *text; if (!(text = get_string_var(STATUS_WINDOW_VAR))) text = empty_string; switch (map) { case 0: if (number_of_windows_on_screen(window) <= 1) break; /* FALLTHROUGH */ case 3: if (!IS_CURRENT_WINDOW) break; /* FALLTHROUGH */ case 2: return text; } return empty_string; } STATUS_FUNCTION(status_refnum) { static char my_buffer[81]; strlcpy(my_buffer, window->name ? window->name : ltoa(window->refnum), sizeof my_buffer); return my_buffer; } STATUS_FUNCTION(status_refnum_real) { static char my_buffer[81]; strlcpy(my_buffer, ltoa(window->refnum), sizeof my_buffer); return my_buffer; } STATUS_FUNCTION(status_version) { if (DISPLAY_ON_WINDOW) return irc_version; /* XXXX */ return empty_string; } STATUS_FUNCTION(status_null_function) { return empty_string; } /* * This displays the DCC "Progress Meter", which goes to the window that * has level DCC. OR, if "current_window_level" includes DCC, then this * goes to the current window. */ STATUS_FUNCTION(status_dcc) { if ((current_window_level & LOG_DCC && IS_CURRENT_WINDOW) || (window->window_level & LOG_DCC)) return DCC_get_current_transfer(); return empty_string; } /* * As above, but always return the indicator. */ STATUS_FUNCTION(status_dcc_all) { return DCC_get_current_transfer(); } /* * This displays something if the client is in 'cpu saver' mode. * A discussion of that mode should be found in irc.c, so i wont get * into it here. */ STATUS_FUNCTION(status_cpu_saver_mode) { static char my_buffer[81]; if (cpu_saver && cpu_saver_format) { snprintf(my_buffer, 80, cpu_saver_format, "CPU"); return my_buffer; } return empty_string; } /* * This is a private expando that i use for testing. But if you want to * use it, more power to you! I reserve the right to change this expando * at my whims. You should not rely on anything specific happening here. */ STATUS_FUNCTION(status_position) { static char my_buffer[81]; snprintf(my_buffer, 80, "(%d/%d/%d-%d-%d)", window->scrolling_distance_from_display_ip, window->holding_distance_from_display_ip, window->scrollback_distance_from_display_ip, window->display_size, window->cursor); #if 0 window->screen->input_line, window->screen->input_cursor); #endif return my_buffer; } /* * This returns something if this window is currently in scrollback mode. * Useful if you sometimes forget! */ STATUS_FUNCTION(status_scrollback) { char *stuff; if (window->scrollback_top_of_display && (stuff = get_string_var(STATUS_SCROLLBACK_VAR))) return stuff; else return empty_string; } STATUS_FUNCTION(status_scroll_info) { static char my_buffer[81]; if (window->scrollback_top_of_display) { snprintf(my_buffer, 80, " (Scroll: %d of %d)", window->scrollback_distance_from_display_ip, window->display_buffer_size - 1); } else *my_buffer = 0; return my_buffer; } STATUS_FUNCTION(status_windowspec) { static char my_buffer[81]; if (window->status.special) strlcpy(my_buffer, window->status.special, sizeof my_buffer); else *my_buffer = 0; return my_buffer; } STATUS_FUNCTION(status_percent) { static char percent[] = "%"; return percent; } STATUS_FUNCTION(status_test) { static char retval[] = "TEST"; return retval; } /* * This returns something if this window is currently in scrollback mode. * Useful if you sometimes forget! */ STATUS_FUNCTION(status_swappable) { char *stuff; if (!window->swappable && (stuff = get_string_var(STATUS_NOSWAP_VAR))) return stuff; else return empty_string; } epic4-2.10.2.orig/source/functions.c0000644000000000000000000050643610770363043014122 0ustar /* $EPIC: functions.c,v 1.161 2008/03/20 04:20:51 jnelson Exp $ */ /* * functions.c -- Built-in functions for ircII * * Copyright (c) 1990 Michael Sandroff. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-1996 Matthew Green. * Copyright © 1993, 2003 EPIC Software Labs * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, the above paragraph (the one permitting redistribution), * this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The names of the author(s) may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Some of the "others" include: * Matt Carothers Colten Edwards * James Sneeringer Eli Sand */ /* * I split alias.c because it was just getting out of hand. */ #include "irc.h" #include "alias.h" #include "alist.h" #include "array.h" #include "clock.h" #include "dcc.h" #include "debug.h" #include "commands.h" #include "files.h" #include "flood.h" #include "ignore.h" #include "input.h" #include "ircaux.h" #include "keys.h" #include "log.h" #include "names.h" #include "output.h" #include "parse.h" #include "screen.h" #include "server.h" #include "status.h" #include "vars.h" #include "window.h" #include "termx.h" #include "notify.h" #include "numbers.h" #include "sedcrypt.h" #include "timer.h" #include "functions.h" #include "options" #include "words.h" #ifdef HAVE_REGEX_H # include #endif #ifdef HAVE_UNAME # include #endif #ifdef NEED_GLOB # include "glob.h" #else # include #endif #include static char *alias_detected (void), *alias_sent_nick (void), *alias_recv_nick (void), *alias_msg_body (void), *alias_joined_nick (void), *alias_public_nick (void), *alias_dollar (void), *alias_channel (void), *alias_server (void), *alias_query_nick (void), *alias_target (void), *alias_nick (void), *alias_invite (void), *alias_cmdchar (void), *alias_line (void), *alias_away (void), *alias_oper (void), *alias_chanop (void), *alias_modes (void), *alias_buffer (void), *alias_time (void), *alias_version (void), *alias_currdir (void), *alias_current_numeric (void), *alias_server_version (void), *alias_show_userhost (void), *alias_show_realname (void), *alias_online (void), *alias_idle (void), *alias_version_str (void), *alias_banner (void); typedef struct { char name; char *(*func) (void); } BuiltIns; static BuiltIns built_in[] = { { '.', alias_sent_nick }, { ',', alias_recv_nick }, { ':', alias_joined_nick }, { ';', alias_public_nick }, { '$', alias_dollar }, { 'A', alias_away }, { 'B', alias_msg_body }, { 'C', alias_channel }, { 'D', alias_detected }, { 'E', alias_idle }, { 'F', alias_online }, { 'G', alias_banner }, { 'H', alias_current_numeric }, { 'I', alias_invite }, { 'J', alias_version_str }, { 'K', alias_cmdchar }, { 'L', alias_line }, { 'M', alias_modes }, { 'N', alias_nick }, { 'O', alias_oper }, { 'P', alias_chanop }, { 'Q', alias_query_nick }, { 'R', alias_server_version }, { 'S', alias_server }, { 'T', alias_target }, { 'U', alias_buffer }, { 'V', alias_version }, { 'W', alias_currdir }, { 'X', alias_show_userhost }, { 'Y', alias_show_realname }, { 'Z', alias_time }, { 0, NULL } }; /* the 30 "standard" functions */ static char *function_channels (char *), *function_connect (char *), *function_curpos (char *), *function_decode (unsigned char *), *function_encode (unsigned char *), *function_index (char *), *function_ischannel (char *), *function_ischanop (char *), *function_left (char *), *function_listen (char *), *function_match (char *), *function_mid (char *), *function_pid (char *), *function_ppid (char *), *function_rand (char *), *function_right (char *), *function_rindex (char *), *function_rmatch (char *), *function_servers (char *), *function_srand (char *), *function_stime (char *), *function_strip (char *), *function_tdiff (char *), *function_tdiff2 (char *), *function_time (char *), *function_tolower (char *), *function_toupper (char *), *function_userhost (char *), *function_winnum (char *), *function_winnam (char *), *function_word (char *), *function_utime (char *), *function_strftime (char *), /* the countless "extended" functions */ *function_abs (char *), *function_acos (char *), *function_asin (char *), *function_atan (char *), *function_acosh (char *), *function_asinh (char *), *function_atanh (char *), *function_after (char *), *function_afterw (char *), *function_aliasctl (char *), *function_ascii (char *), *function_asciiq (char *), *function_before (char *), *function_beforew (char *), *function_bindctl (char *), *function_builtin (char *), *function_ceil (char *), *function_center (char *), *function_cexist (char *), *function_channel (char *), *function_channelmode (char *), *function_chmod (char *), *function_chngw (char *), *function_chop (char *), *function_chops (char *), *function_chr (char *), *function_chrq (char *), *function_cipher (char *), *function_close (char *), *function_cofilter (char *), *function_corfilter (char *), *function_common (char *), *function_convert (char *), *function_copattern (char *), *function_corpattern (char *), *function_cos (char *), *function_cosh (char *), *function_count (char *), *function_cparse (char *), *function_crypt (char *), *function_currchans (char *), *function_dccctl (char *), *function_deuhc (char *), *function_diff (char *), *function_encryptparm (char *), *function_eof (char *), *function_epic (char *), *function_error (char *), *function_exec (char *), *function_exp (char *), *function_fnexist (char *), *function_fexist (char *), *function_filter (char *), *function_findw (char *), *function_findws (char *), *function_floor (char *), *function_fromw (char *), *function_fsize (char *), *function_ftime (char *), *function_ftruncate (char *), *function_functioncall (char *), *function_geom (char *), *function_getcap (char *), *function_getcommands (char *), *function_getenv (char *), *function_getfunctions (char *), *function_getgid (char *), *function_getlogin (char *), *function_getopt (char *), *function_getpgrp (char *), *function_getserial (char *), *function_getset (char *), *function_getsets (char *), *function_getuid (char *), *function_glob (char *), *function_globi (char *), *function_hash_32bit (char *), *function_idle (char *), *function_igmask (char *), *function_ignorectl (char *), *function_igtype (char *), *function_indextoword (char *), *function_info (char *), *function_insert (char *), *function_insertw (char *), *function_iptolong (char *), *function_iptoname (char *), *function_irclib (char *), *function_isalpha (char *), *function_isaway (char *), *function_ischanvoice (char *), *function_isconnected (char *), *function_iscurchan (char *), *function_isdigit (char *), *function_isdisplaying (char *), *function_isencrypted (char *), *function_isfilevalid (char *), *function_ishalfop (char *), *function_isnumber (char *), *function_jn (char *), *function_joinstr (char *), *function_jot (char *), *function_key (char *), *function_killpid (char *), *function_lastserver (char *), *function_leftpc (char *), *function_leftw (char *), *function_levelwindow (char *), *function_loadinfo (char *), *function_log (char *), *function_log10 (char *), *function_logctl (char *), *function_longtoip (char *), *function_mask (char *), *function_maxlen (char *), *function_metric_time (char *), *function_midw (char *), *function_mkdir (char *), *function_msar (char *), *function_nametoip (char *), *function_nochops (char *), *function_nohighlight (char *), *function_notify (char *), *function_notifywindows (char *), *function_notw (char *), *function_numlines (char *), *function_numonchannel (char *), *function_numsort (char *), *function_numwords (char *), *function_onchannel (char *), *function_open (char *), *function_outputinfo (char *), *function_pad (char *), *function_pattern (char *), *function_pass (char *), #ifdef PERL *function_perl (char *), *function_perlcall (char *), *function_perlxcall (char *), #endif *function_prefix (char *), *function_printlen (char *), *function_querywin (char *), *function_randread (char *), *function_read (char *), *function_realpath (char *), *function_regcomp (char *), *function_regcomp_cs (char *), *function_regexec (char *), *function_regerror (char *), *function_regfree (char *), *function_regmatches (char *), *function_remw (char *), *function_remws (char *), *function_rename (char *), *function_repeat (char *), *function_rest (char *), *function_restw (char *), *function_reverse (char *), *function_revw (char *), *function_rewind (char *), *function_rfilter (char *), *function_rightw (char *), *function_rigmask (char *), *function_rigtype (char *), *function_rmdir (char *), *function_rpattern (char *), *function_rsubstr (char *), *function_sar (char *), *function_sedcrypt (char *), *function_seek (char *), *function_server_version (char *), *function_serverctl (char *), *function_servergroup (char *), *function_servername (char *), *function_servernick (char *), *function_servernum (char *), *function_serverourname (char *), *function_servertype (char *), *function_servports (char *), *function_serverwin (char *), *function_sin (char *), *function_sinh (char *), *function_skip (char *), *function_sort (char *), *function_split (char *), *function_splice (char *), *function_ssl (char *), *function_stat (char *), *function_status (char *), *function_stripansi (char *), *function_stripansicodes(char *), *function_stripc (char *), *function_stripcrap (char *), *function_strlen (char *), *function_strtol (char *), *function_substr (char *), *function_tan (char *), *function_tanh (char *), *function_tell (char *), *function_timerctl (char *), #ifdef TCL *function_tcl (char *), #endif *function_tobase (char *), *function_tow (char *), *function_translate (char *), *function_truncate (char *), *function_ttyname (char *), *function_twiddle (char *), *function_uhc (char *), *function_umask (char *), *function_umode (char *), *function_uname (char *), *function_uniq (char *), *function_unlink (char *), *function_unsplit (char *), *function_urldecode (char *), *function_urlencode (char *), *function_winbound (char *), *function_which (char *), *function_winchan (char *), *function_wincurline (char *), *function_windowctl (char *), *function_winlevel (char *), *function_winline (char *), *function_winnames (char *), *function_winrefs (char *), *function_winsbsize (char *), *function_winscreen (char *), *function_winserv (char *), *function_winsize (char *), *function_winstatsize (char *), *function_winvisible (char *), *function_wordtoindex (char *), *function_write (char *), *function_writeb (char *), *function_yn (char *); extern char *function_push (char *), *function_pop (char *), *function_shift (char *), *function_unshift (char *); typedef char *(bf) (char *); typedef struct { const char *name; bf *func; } BuiltInFunctions; /* * This is the built-in function list. This list *must* be sorted because * it is binary searched. See the code for each function to see how it * is used. Or see the help files. Or see both. Oh heck. Look at the code * and see how it REALLY works, regardless of the documentation >;-) */ static BuiltInFunctions built_in_functions[] = { { "ABS", function_abs }, { "ACOS", function_acos }, { "ACOSH", function_acosh }, { "AFTER", function_after }, { "AFTERW", function_afterw }, { "ALIASCTL", function_aliasctl }, { "ASCII", function_ascii }, { "ASCIIQ", function_asciiq }, { "ASIN", function_asin }, { "ASINH", function_asinh }, { "ATAN", function_atan }, { "ATANH", function_atanh }, { "BEFORE", function_before }, { "BEFOREW", function_beforew }, { "BINDCTL", function_bindctl }, { "BUILTIN_EXPANDO", function_builtin }, { "CEIL", function_ceil }, { "CENTER", function_center }, { "CEXIST", function_cexist }, { "CHANMODE", function_channelmode }, { "CHANNEL", function_channel }, { "CHANUSERS", function_onchannel }, { "CHANWIN", function_winchan }, { "CHMOD", function_chmod }, { "CHNGW", function_chngw }, { "CHOP", function_chop }, { "CHOPS", function_chops }, { "CHR", function_chr }, { "CHRQ", function_chrq }, { "CIPHER", function_cipher }, { "CLOSE", function_close }, { "COFILTER", function_cofilter }, { "COMMON", function_common }, { "CONNECT", function_connect }, { "CONVERT", function_convert }, { "COPATTERN", function_copattern }, { "CORFILTER", function_corfilter }, { "CORPATTERN", function_corpattern }, { "COS", function_cos }, { "COSH", function_cosh }, { "COUNT", function_count }, { "CPARSE", function_cparse }, { "CRYPT", function_crypt }, { "CURPOS", function_curpos }, { "CURRCHANS", function_currchans }, { "DCCCTL", function_dccctl }, { "DECODE", (bf *)function_decode }, { "DELARRAY", function_delarray }, { "DELITEM", function_delitem }, { "DELITEMS", function_delitems }, { "DEUHC", function_deuhc }, { "DIFF", function_diff }, { "ENCODE", (bf *)function_encode }, { "ENCRYPTPARM", function_encryptparm }, { "EOF", function_eof }, { "EPIC", function_epic }, { "EXEC", function_exec }, { "EXP", function_exp }, { "FERROR", function_error }, { "FEXIST", function_fexist }, { "FILTER", function_filter }, { "FINDITEM", function_finditem }, #if 1 { "FINDITEMS", function_finditems }, #endif { "FINDW", function_findw }, { "FINDWS", function_findws }, { "FLOODINFO", function_floodinfo }, { "FLOOR", function_floor }, { "FNEXIST", function_fnexist }, { "FREWIND", function_rewind }, { "FROMW", function_fromw }, { "FSEEK", function_seek }, { "FSIZE", function_fsize }, { "FSKIP", function_skip }, { "FTELL", function_tell }, { "FTIME", function_ftime }, { "FTRUNCATE", function_ftruncate }, { "FUNCTIONCALL", function_functioncall }, { "GEOM", function_geom }, { "GETARRAYS", function_getarrays }, { "GETCAP", function_getcap }, { "GETCOMMANDS", function_getcommands }, { "GETENV", function_getenv }, { "GETFUNCTIONS", function_getfunctions }, { "GETGID", function_getgid }, { "GETITEM", function_getitem }, { "GETLOGIN", function_getlogin }, { "GETMATCHES", function_getmatches }, { "GETOPT", function_getopt }, { "GETPGRP", function_getpgrp }, { "GETRMATCHES", function_getrmatches }, { "GETSERIAL", function_getserial }, { "GETSET", function_getset }, { "GETSETS", function_getsets }, { "GETTMATCH", function_gettmatch }, { "GETUID", function_getuid }, { "GLOB", function_glob }, { "GLOBI", function_globi }, { "HASH_32BIT", function_hash_32bit }, { "IDLE", function_idle }, { "IFINDFIRST", function_ifindfirst }, { "IFINDITEM", function_ifinditem }, #if 1 { "IFINDITEMS", function_ifinditems }, #endif { "IGETITEM", function_igetitem }, { "IGETMATCHES", function_igetmatches }, { "IGETRMATCHES", function_igetrmatches }, { "IGMASK", function_igmask }, { "IGNORECTL", function_ignorectl }, { "IGTYPE", function_igtype }, { "INDEX", function_index }, { "INDEXTOITEM", function_indextoitem }, { "INDEXTOWORD", function_indextoword }, { "INFO", function_info }, { "INSERT", function_insert }, { "INSERTW", function_insertw }, { "IPTOLONG", function_iptolong }, { "IPTONAME", function_iptoname }, { "IRCLIB", function_irclib }, { "ISALPHA", function_isalpha }, { "ISAWAY", function_isaway }, { "ISCHANNEL", function_ischannel }, { "ISCHANOP", function_ischanop }, { "ISCHANVOICE", function_ischanvoice }, { "ISCONNECTED", function_isconnected }, { "ISCURCHAN", function_iscurchan }, { "ISDIGIT", function_isdigit }, { "ISDISPLAYING", function_isdisplaying }, { "ISENCRYPTED", function_isencrypted }, { "ISFILEVALID", function_isfilevalid }, { "ISHALFOP", function_ishalfop }, { "ISNUMBER", function_isnumber }, { "ITEMTOINDEX", function_itemtoindex }, { "JN", function_jn }, { "JOINSTR", function_joinstr }, { "JOT", function_jot }, { "KEY", function_key }, { "KILLPID", function_killpid }, { "LASTLOG", function_lastlog }, /* lastlog.h */ { "LASTSERVER", function_lastserver }, { "LEFT", function_left }, { "LEFTPC", function_leftpc }, { "LEFTW", function_leftw }, { "LEVELWINDOW", function_levelwindow }, { "LINE", function_line }, /* lastlog.h */ { "LISTARRAY", function_listarray }, { "LISTEN", function_listen }, { "LOADINFO", function_loadinfo }, { "LOG", function_log }, { "LOG10", function_log10 }, { "LOGCTL", function_logctl }, /* logfiles.h */ { "LONGTOIP", function_longtoip }, { "MASK", function_mask }, { "MATCH", function_match }, { "MATCHITEM", function_matchitem }, { "MAXLEN", function_maxlen }, { "METRIC_TIME", function_metric_time }, { "MID", function_mid }, { "MIDW", function_midw }, { "MKDIR", function_mkdir }, { "MSAR", function_msar }, { "MYCHANNELS", function_channels }, { "MYSERVERS", function_servers }, { "NAMETOIP", function_nametoip }, { "NOCHOPS", function_nochops }, { "NOHIGHLIGHT", function_nohighlight }, { "NOTIFY", function_notify }, { "NOTIFYWINDOWS", function_notifywindows }, { "NOTW", function_notw }, { "NUMARRAYS", function_numarrays }, { "NUMITEMS", function_numitems }, { "NUMLINES", function_numlines }, { "NUMONCHANNEL", function_numonchannel }, { "NUMSORT", function_numsort }, { "NUMWORDS", function_numwords }, { "ONCHANNEL", function_onchannel }, { "OPEN", function_open }, { "OUTPUTINFO", function_outputinfo }, { "PAD", function_pad }, { "PASS", function_pass }, { "PATTERN", function_pattern }, #ifdef PERL { "PERL", function_perl }, { "PERLCALL", function_perlcall }, { "PERLXCALL", function_perlxcall }, #endif { "PID", function_pid }, { "POP", function_pop }, { "PPID", function_ppid }, { "PREFIX", function_prefix }, { "PRINTLEN", function_printlen }, { "PUSH", function_push }, { "QUERYWIN", function_querywin }, { "RAND", function_rand }, { "RANDREAD", function_randread }, { "READ", function_read }, { "REALPATH", function_realpath }, { "REGCOMP", function_regcomp }, { "REGCOMP_CS", function_regcomp_cs }, { "REGERROR", function_regerror }, { "REGEXEC", function_regexec }, { "REGFREE", function_regfree }, { "REGMATCHES", function_regmatches }, { "REMW", function_remw }, { "REMWS", function_remws }, { "RENAME", function_rename }, { "REPEAT", function_repeat }, { "REST", function_rest }, { "RESTW", function_restw }, { "REVERSE", function_reverse }, { "REVW", function_revw }, { "RFILTER", function_rfilter }, { "RIGHT", function_right }, { "RIGHTW", function_rightw }, { "RIGMASK", function_rigmask }, { "RIGTYPE", function_rigtype }, { "RINDEX", function_rindex }, { "RMATCH", function_rmatch }, { "RMATCHITEM", function_rmatchitem }, { "RMDIR", function_rmdir }, { "RPATTERN", function_rpattern }, { "RSUBSTR", function_rsubstr }, { "SAR", function_sar }, { "SEDCRYPT", function_sedcrypt }, { "SERVERCTL", function_serverctl }, { "SERVERGROUP", function_servergroup }, { "SERVERNAME", function_servername }, { "SERVERNICK", function_servernick }, { "SERVERNUM", function_servernum }, { "SERVEROURNAME", function_serverourname }, { "SERVERTYPE", function_servertype }, { "SERVERWIN", function_serverwin }, { "SERVPORTS", function_servports }, { "SETITEM", function_setitem }, { "SHIFT", function_shift }, { "SIN", function_sin }, { "SINH", function_sinh }, { "SORT", function_sort }, { "SPLICE", function_splice }, { "SPLIT", function_split }, { "SRAND", function_srand }, { "SSL", function_ssl }, { "STAT", function_stat }, { "STATUS", function_status }, { "STIME", function_stime }, { "STRFTIME", function_strftime }, { "STRIP", function_strip }, { "STRIPANSI", function_stripansi }, { "STRIPANSICODES", function_stripansicodes }, { "STRIPC", function_stripc }, { "STRIPCRAP", function_stripcrap }, { "STRLEN", function_strlen }, { "STRTOL", function_strtol }, { "SUBSTR", function_substr }, { "TAN", function_tan }, { "TANH", function_tanh }, #ifdef TCL { "TCL", function_tcl }, #endif { "TDIFF", function_tdiff }, { "TDIFF2", function_tdiff2 }, { "TIME", function_time }, { "TIMERCTL", function_timerctl }, { "TOBASE", function_tobase }, { "TOLOWER", function_tolower }, { "TOUPPER", function_toupper }, { "TOW", function_tow }, { "TR", function_translate }, { "TRUNC", function_truncate }, { "TTYNAME", function_ttyname }, { "TWIDDLE", function_twiddle }, { "UHC", function_uhc }, { "UMASK", function_umask }, { "UNAME", function_uname }, { "UNIQ", function_uniq }, { "UNLINK", function_unlink }, { "UNSHIFT", function_unshift }, { "UNSPLIT", function_unsplit }, { "URLDECODE", function_urldecode }, { "URLENCODE", function_urlencode }, { "USERHOST", function_userhost }, { "USERMODE", function_umode }, { "USETITEM", function_usetitem }, { "UTIME", function_utime }, { "VERSION", function_server_version }, { "WHICH", function_which }, { "WINBOUND", function_winbound }, { "WINCHAN", function_winchan }, { "WINCURSORLINE", function_wincurline }, { "WINDOWCTL", function_windowctl }, { "WINLEVEL", function_winlevel }, { "WINLINE", function_winline }, { "WINNAM", function_winnam }, { "WINNICKLIST", function_winnames }, { "WINNUM", function_winnum }, { "WINREFS", function_winrefs }, { "WINSCREEN", function_winscreen }, { "WINSCROLLBACKSIZE", function_winsbsize }, { "WINSERV", function_winserv }, { "WINSIZE", function_winsize }, { "WINSTATUSSIZE", function_winstatsize }, { "WINVISIBLE", function_winvisible }, { "WORD", function_word }, { "WORDTOINDEX", function_wordtoindex }, { "WRITE", function_write }, { "WRITEB", function_writeb }, { "XDEBUG", function_xdebug }, { "YN", function_yn }, { (char *) 0, NULL } }; #define NUMBER_OF_FUNCTIONS (sizeof(built_in_functions) / sizeof(BuiltInFunctions)) - 2 char *built_in_alias (char c, int *returnval) { BuiltIns *tmp; for (tmp = built_in;tmp->name;tmp++) { if (c == tmp->name) { if (returnval) { *returnval = 1; return NULL; } else return tmp->func(); } } return NULL; /* Pretty sure this should be NULL */ } /* * call_function has changed a little bit. Now we take the entire call * including args in the paren list. This is a bit more convenient for * the callers, since there are a bunch of them and all of them seperately * handling extracting the args is just a pain in the butt. */ char *call_function (char *name, const char *args, int *args_flag) { char *tmp; char *result = (char *) 0; char *debug_copy = (char *) 0; int cnt, pos; char *lparen; int debugging; size_t size; char * buf; debugging = get_int_var(DEBUG_VAR); if ((lparen = strchr(name, '('))) { ssize_t span; if ((span = MatchingBracket(lparen + 1, '(', ')')) >= 0) lparen[1 + span] = 0; else yell("Unmatched lparen in function call [%s]", name); *lparen++ = 0; } else lparen = empty_string; tmp = expand_alias(lparen, args, args_flag, NULL); debug_copy = LOCAL_COPY(tmp); upper(name); find_fixed_array_item(built_in_functions, sizeof(BuiltInFunctions), NUMBER_OF_FUNCTIONS + 1, name, &cnt, &pos); if (cnt < 0) result = built_in_functions[pos].func(tmp); else result = call_user_function(name, tmp); size = strlen(name) + strlen(debug_copy) + 15; buf = (char *)alloca(size); snprintf(buf, size, "$%s(%s)", name, debug_copy); MUST_BE_MALLOCED(result, buf); if (debugging & DEBUG_FUNCTIONS) privileged_yell("Function %s(%s) returned %s", name, debug_copy, result); new_free(&tmp); return result; } static int func_exist (char *name) { int cnt, pos; char * tmp; tmp = LOCAL_COPY(name); upper(tmp); find_fixed_array_item(built_in_functions, sizeof(BuiltInFunctions), NUMBER_OF_FUNCTIONS + 1, tmp, &cnt, &pos); if (cnt < 0) return 1; return 0; } /* built in expando functions */ static char *alias_line (void) { return malloc_strdup(get_input()); } static char *alias_buffer (void) { return malloc_strdup(cut_buffer); } static char *alias_time (void) { return malloc_strdup(get_clock()); } static char *alias_dollar (void) { return malloc_strdup("$"); } static char *alias_detected (void) { return malloc_strdup(last_notify_nick); } static char *alias_nick (void) { return malloc_strdup((current_window->server != NOSERV) ? get_server_nickname(current_window->server) : empty_string); } static char *alias_away (void) { return malloc_strdup(get_server_away(from_server)); } static char *alias_sent_nick (void) { return malloc_strdup((get_server_sent_nick(from_server)) ? get_server_sent_nick(from_server) : empty_string); } static char *alias_recv_nick (void) { return malloc_strdup((get_server_recv_nick(from_server)) ? get_server_recv_nick(from_server) : empty_string); } static char *alias_msg_body (void) { return malloc_strdup((get_server_sent_body(from_server)) ? get_server_sent_body(from_server) : empty_string); } static char *alias_joined_nick (void) { return malloc_strdup((get_server_joined_nick(from_server)) ? get_server_joined_nick(from_server) : empty_string); } static char *alias_public_nick (void) { return malloc_strdup((get_server_public_nick(from_server)) ? get_server_public_nick(from_server) : empty_string); } static char *alias_show_realname (void) { return malloc_strdup(realname); } static char *alias_version_str (void) { return malloc_strdup(irc_version); } static char *alias_invite (void) { return malloc_strdup((get_server_invite_channel(from_server)) ? get_server_invite_channel(from_server) : empty_string); } static char *alias_oper (void) { return malloc_strdup((from_server != -1) ? get_server_operator(from_server) ? get_string_var(STATUS_OPER_VAR) : empty_string : empty_string); } static char *alias_version (void) { return malloc_strdup(internal_version); } static char *alias_show_userhost (void) { return malloc_strdup(get_server_userhost(from_server)); } static char *alias_online (void) { return malloc_sprintf(NULL, "%ld",(long)start_time.tv_sec); } static char *alias_idle (void) { return malloc_sprintf(NULL, "%ld",time(NULL)-idle_time.tv_sec); } static char *alias_current_numeric (void) { return malloc_sprintf(NULL, "%03d", -current_numeric); } static char *alias_banner (void) { return malloc_strdup(banner()); } static char *alias_currdir (void) { char *tmp = (char *)new_malloc(MAXPATHLEN+1); return getcwd(tmp, MAXPATHLEN); } static char *alias_channel (void) { const char *tmp; return malloc_strdup((tmp = get_echannel_by_refnum(0)) ? tmp : zero); } static char *alias_server (void) { return malloc_strdup((parsing_server_index != NOSERV) ? get_server_itsname(parsing_server_index) : (get_window_server(0) != NOSERV) ? get_server_itsname(get_window_server(0)) : empty_string); } static char *alias_query_nick (void) { const char *tmp; return malloc_strdup((tmp = query_nick()) ? tmp : empty_string); } static char *alias_target (void) { const char *tmp; return malloc_strdup((tmp = get_target_by_refnum(0)) ? tmp : empty_string); } static char *alias_cmdchar (void) { const char *cmdchars; char tmp[2]; if ((cmdchars = get_string_var(CMDCHARS_VAR)) == (char *) 0) cmdchars = DEFAULT_CMDCHARS; tmp[0] = cmdchars[0]; tmp[1] = 0; return malloc_strdup(tmp); } static char *alias_chanop (void) { const char *tmp; return malloc_strdup(((tmp = get_echannel_by_refnum(0)) && get_channel_oper(tmp, get_window_server(0))) ? "@" : empty_string); } static char *alias_modes (void) { const char *tmp; return malloc_strdup((tmp = get_echannel_by_refnum(0)) ? get_channel_mode(tmp, get_window_server(0)) : empty_string); } static char *alias_server_version (void) { int s = from_server; if (s == NOSERV) { if (primary_server != NOSERV) s = primary_server; else return malloc_strdup(empty_string); } return malloc_strdup(get_server_version_string(s)); } /* * * * * * * * * * These are the built-in functions. About 80 of them are here, the rest are in array.c. All of the stock client's functions are supported, as well as about 60 more. Most of the 30 stock client's functions have been re-written for optimization reasons, and also to further distance ircii's code from EPIC. * * * * * * * * * */ /* * Usage: $left(number text) * Returns: the leftmost characters in . * Example: $left(5 the quick brown frog) returns "the q" * * Note: the difference between $[10]foo and $left(10 foo) is that the former * is padded and the latter is not. */ BUILT_IN_FUNCTION(function_left, word) { int count; GET_INT_ARG(count, word); RETURN_IF_EMPTY(word); if (count < 0) RETURN_EMPTY; if (strlen(word) > (size_t)count) word[count] = 0; RETURN_STR(word); } /* * Usage: $right(number text) * Returns: the rightmost characters in . * Example: $right(5 the quick brown frog) returns " frog" */ BUILT_IN_FUNCTION(function_right, word) { int count; GET_INT_ARG(count, word); RETURN_IF_EMPTY(word); if (count < 0) RETURN_EMPTY; if (strlen(word) > (size_t)count) word += strlen(word) - count; RETURN_STR(word); } /* * Usage: $mid(start number text) * Returns: the th through +th characters in . * Example: $mid(3 4 the quick brown frog) returns " qui" * * Note: the first character is numbered zero. */ BUILT_IN_FUNCTION(function_mid, word) { int start, length; GET_INT_ARG(start, word); GET_INT_ARG(length, word); RETURN_IF_EMPTY(word); if (start < (int)strlen(word)) { word += start; if (length < 0) RETURN_EMPTY; if ((size_t)length < strlen(word)) word[length] = 0; } else word = EMPTY; RETURN_STR(word); } /* * Usage: $rand(max) * Returns: A random number from zero to max-1. * Example: $rand(10) might return any number from 0 to 9. */ BUILT_IN_FUNCTION(function_rand, word) { unsigned long tempin, ret; static unsigned long rn = 0; GET_INT_ARG(tempin, word); if (tempin == 0) ret = random_number(0); else { if (rn < tempin) rn ^= random_number(0); ret = rn % tempin; rn /= tempin; } RETURN_INT(ret); } /* * Usage: $srand(seed) * Returns: Nothing. * Side effect: seeds the random number generater. * Note: the argument is ignored. */ BUILT_IN_FUNCTION(function_srand, word) { random_number(time(NULL)); RETURN_EMPTY; } /* * Usage: $time() * Returns: The number of seconds that has elapsed since Jan 1, 1970, GMT. * Example: $time() returned something around 802835348 at the time I * wrote this comment. */ BUILT_IN_FUNCTION(function_time, input) { RETURN_INT(time(NULL)); } /* * Usage: $stime(time) * Returns: The human-readable form of the date based on the