mirror of
https://github.com/GeorgeMcMullen/rxIRC.git
synced 2026-01-12 00:02:51 +00:00
1087 lines
33 KiB
Plaintext
1087 lines
33 KiB
Plaintext
/* rxIRC
|
|
* Internet Relay Chat client program for VM/CMS systems
|
|
* written by Carl 'LynX' v. Loesch (loesch@informatik.uni-oldenburg.de)
|
|
* Credits for suggestions, code contribution, miscellaneous help go to:
|
|
* Jose Maria Blasco, Doug Sewell, Martin Ahlborn, Jim McMaster,
|
|
* Scott Maxell, Juan Courcoul, Rob Blais, Mike Letourneau, Grant Pair
|
|
* (in historical order mostly). Thank y'all very much!
|
|
*
|
|
* requires RXSOCKET MODULE version 2 by Arty Ecock (eckcu@cunyvm.bitnet)
|
|
*
|
|
* Copyright (C)1991,2,3,4 by LynX & CvO University Oldenburg, Germany
|
|
* You may freely use this software at your own risk.
|
|
*
|
|
* Warning: Changing the code to display fake user information is
|
|
* considered an offense by many IRC administrators!
|
|
*
|
|
*/ progname='rxIRC'; vers='2.1'; trace 'O'
|
|
address "COMMAND"; signal on HALT; "VMFCLEAR"
|
|
cmds='AWAY AWAIT ADMIN CHANNEL CONNECT DEOP DIE HASH INFO ISON JOIN KICK',
|
|
'KILL LIST LINKS LUSERS MODE MAIL MOTD NAMES NICK NOTICE NOTE OPER PASS',
|
|
'PART REHASH RESTART QUIT SERVICE SQUIT SUMMON STATS TIME TRACE',
|
|
'USERS USERHOST VOICE WHOWAS WALLOPS WALL XTRA'
|
|
log=0; query=; ignore=; omit=; lastjoin=; lastsender=; lastorigin=;
|
|
export=; onoff.1="on"; onoff.0="off"
|
|
invitation=; away=; ll.=; curll=1; logevent=0; target=time('R')
|
|
v.=; al.=; varnames=; aliasnames=; cmdchar=; userinfo=; sourcing=0
|
|
have_rxwt=0; who_empty=0; catmode=0; catlist=; abortsource=0; skiplines=0
|
|
nflist=; nfhere=; nfcatch=0
|
|
"EXECIO * CP (STEM PF. STRING QUERY PF"
|
|
do i=1 to pf.0
|
|
a=word(pf.i,2)
|
|
if a/='UNDEFINED' & a/='RETRIEVE' then,
|
|
"CP SET" subword(pf.i,1,2) '!'subword(pf.i,3)
|
|
end
|
|
"EXECIO * CP (STEM QT. STRING QUERY TERM"
|
|
"CP TERM LINEND OFF"
|
|
"CP TERM CHARDEL OFF"
|
|
"CP TERM LINESIZE 130"
|
|
sock=; buffer=; alphalo=xrange('a','z'); alphahi=xrange('A','Z')
|
|
lf='25'x; cr='0d'x; msa='01'x; rev='02'x; beep='2f'x; undl='32'x
|
|
bold='1f'x; hi='1de8'x; lo='1d60'x; yo='1d44'x
|
|
nice.=; u@n.=; via.=;
|
|
realname=; servername=;
|
|
ignore_reply = "Your messages are not being received."
|
|
"IDENTIFY (LIFO"; pull me . mynode . rscs a .
|
|
logfile=translate(a,'_','/') "IRCLOG A0"
|
|
writelog="EXECIO 1 DISKW" logfile "(STRI"
|
|
'STATE RXSOCKET MODULE *'
|
|
if rc=0 then do
|
|
parse value SOCKET('version') with . . rc .
|
|
if rc >= 2.0 then rc=0
|
|
else rc=28
|
|
end
|
|
if rc/=0 then call BYE "RXSOCKET version 2 required"
|
|
do 3
|
|
parse value SOCKET('INITIALIZE', "rxIRC", 7) with rc . etc
|
|
if rc=2004 then do
|
|
say '<cleaning up a zombie rxsocket nucext>'
|
|
'NUCXDROP RXSOCKET'
|
|
end
|
|
else leave
|
|
end
|
|
if rc/=0 then call BYE "socket init error:" etc
|
|
parse value SOCKET('GETHOSTNAME') with . hostname
|
|
parse value SOCKET('GETDOMAINNAME') with . domain
|
|
'REXXWAIT TEST'
|
|
select
|
|
when rc=0 then nop
|
|
when rc=1 then do
|
|
'REXXWAIT LOAD'
|
|
if rc/=0 then call BYE "REXXWAIT can't be loaded"
|
|
end
|
|
otherwise call BYE "REXXWAIT MODULE required"
|
|
end
|
|
have_rxwt=1
|
|
'IMMCMD SET HI'
|
|
"NAMEF :NICK RXIRC :SERVER :PORT :LOGGING :QUIET_IGNORE :SHOW_TIME ",
|
|
":BOLD_CHAR :BEEP_CHAR :LOUD_BEEPS :SHOW_NUMBERS :LIST_ALL :BROWSER",
|
|
":PASS (LIFO FILE RXIRC"
|
|
if rc/=0 then call BYE "missing or unreadable RXIRC NAMES file"
|
|
parse pull server_pass
|
|
pull viewcmd; pull def_listall; pull def_numb; pull def_loud
|
|
parse pull beepch; parse pull boldch; parse pull showtime; pull def_quiet
|
|
pull def_log; parse pull def_port; parse pull def_server
|
|
if viewcmd='' then call BYE 'no ":browser" tag defined in RXIRC NAMES'
|
|
if beepch='' then beepch=d2c(0)
|
|
if boldch='' then boldch=d2c(0)
|
|
"GLOBALV SELECT CENV GET IRCNICK IRCSERVER IRCNAME IRCPORT"
|
|
|
|
"NAMEFIND :USERID" me ":NICK :NAME :MOTTO :CMDCHAR :IRCNICK :IRCNAME ",
|
|
":WWWPORT (LIFO"
|
|
if rc=0 then do
|
|
parse pull wwwport; if wwwport/='' & ^datatype(wwwport,'W') then do
|
|
wwwport=; call BYE "WWW port must be numeric"; end
|
|
parse pull name; parse pull nick
|
|
if ircnick="" then ircnick=nick
|
|
if ircname="" then ircname=name
|
|
parse pull cmdchar; parse pull userinfo
|
|
parse pull realname; parse pull nick
|
|
if ircnick="" then ircnick=nick
|
|
if ircname="" then ircname=realname
|
|
end
|
|
|
|
parse arg nick server name '('o; upper o
|
|
if nick/='' then ircnick = nick
|
|
if ircnick='' then ircnick=me
|
|
capnick = translate(ircnick)
|
|
if server/='' then ircserver=server
|
|
else if ircserver='' then ircserver=def_server
|
|
if name/='' then ircname = name
|
|
if ircname='' then ircname=me "at" mynode".bitnet"
|
|
if cmdchar="" then cmdchar="/"
|
|
do while o/=""
|
|
parse var o opt o
|
|
select
|
|
when abbrev("PORT", opt, 1) then parse var o ircport o
|
|
when abbrev("LIST_ALL", opt, 2) then parse var o def_listall o
|
|
when abbrev("LOGGING", opt, 1) then parse var o def_log o
|
|
when abbrev("LOUD_BEEPS", opt, 3) then parse var o def_loud o
|
|
when abbrev("NUMBERS", opt, 1) then parse var o def_numb o
|
|
when abbrev("QUIET_IGNORE", opt, 1) then parse var o def_quiet o
|
|
otherwise call BYE "unknown option" opt
|
|
end
|
|
end
|
|
if ircport='' then ircport=def_port
|
|
if def_listall="ON" then listall=1; else listall=0
|
|
if def_log="ON" then log=1; else log=0
|
|
if def_loud="ON" then loud=1; else loud=0
|
|
if def_numb="ON" then numb=1; else numb=0
|
|
if def_quiet="ON" then quiet=1; else quiet=0
|
|
if log then writelog "IRC Session started on" date() "at" time()
|
|
if datatype(left(ircnick,1))='NUM' then ircnick='u'ircnick
|
|
if ^datatype(showtime,'w') then showtime=80
|
|
if userinfo="" then userinfo="- no info given by user -"
|
|
|
|
parse value RESETVALUE('ALL') with rc .
|
|
if rc/=0 then call BYE "problem w/RESETVALUE"
|
|
parse value SETVALUE('TIME ==:==:00') with rc .
|
|
if rc/=0 then call BYE "problem w/SETVALUE TIME"
|
|
parse value SETVALUE('MSG IUCV') with rc .
|
|
if rc/=0 then call BYE "problem w/SETVALUE MSG IUCV"
|
|
|
|
if wwwport<1024 then wwwport=''
|
|
else do
|
|
parse value SOCKET('SOCKET') with rc www etc
|
|
if rc/=0 then call BYE "socket:" etc
|
|
parse value SOCKET('SETSOCKOPT',www,'SOL_SOCKET','SO_ASCII','ON'),
|
|
with rc . etc
|
|
if rc/=0 then call BYE "setsockopt:" etc
|
|
parse value SOCKET('BIND', www, 'AF_INET' wwwport SOCKET('GETHOSTID')),
|
|
with rc . etc
|
|
if rc/=0 then call BYE "bind:" etc
|
|
parse value SOCKET('LISTEN', www, 9) with rc . etc
|
|
if rc/=0 then call BYE "listen:" etc
|
|
parse value SOCKET('IOCTL', www, 'FIONBIO', 1) with rc . etc
|
|
if rc/=0 then call BYE "nonblocking i/o:" etc
|
|
myurl="http://"hostname"."domain":"wwwport"/"
|
|
end
|
|
|
|
call S progname||hi||vers||yo"- You are" ircnick "("ircname")"
|
|
call S "Logging is" onoff.log"; Audible bells are",
|
|
onoff.loud"; Quiet ignore is" onoff.quiet
|
|
if www/='' then call S "Builtin httpd active as"hi||myurl||yo
|
|
call CONNECT ircserver
|
|
call SOURCE "PROFILE", 1
|
|
if nflist/='' then do; nfcatch=1; call SEND "ISON" nflist; end
|
|
call S copies("-",79)lo
|
|
do forever
|
|
"IMMCMD STATUS HI"
|
|
if rc/=0 then call S,
|
|
'Sorry, "hi" is a system reserved word. Try an other operating system.'
|
|
parse value WAIT('TIME','CONS','MSG','SOCKET READ *') with rc type data
|
|
select
|
|
when rc/=0 then call BYE "REXXWAIT returning" rc
|
|
when type='SOCKET' & data='READ' sock then do
|
|
parse value SOCKET('READ', sock) with rc . data
|
|
if rc=54 then call BYE
|
|
if rc/=0 then call BYE 'socket read error' rc
|
|
buffer = buffer || data
|
|
do forever
|
|
if index(buffer, lf)=0 then leave
|
|
parse var buffer in (lf) buffer
|
|
call OUT PARSE(strip(in,,cr))
|
|
end
|
|
end
|
|
when type = 'CONS' then if data/='' then do
|
|
rc=time('R')
|
|
call EDIT data
|
|
curll=curll+1; ll.curll=hi||data||lo; k=curll-50; ll.k=;
|
|
if log then writelog ' 'data
|
|
end
|
|
when type = 'MSG' then do
|
|
parse var data . . no'('id'): 'data
|
|
if id='' then id='RSCS'
|
|
origin=id'@'no
|
|
ni=NICE(origin)
|
|
if FINDM(ignore,origin) | FINDM(ignore,ni) then do
|
|
if ^quiet & left(data,1)/='*' then call TELL origin '*' ignore_reply
|
|
end; else do
|
|
call OUT hi||ni':'lo||data
|
|
if away/='' & left(data,1)/='*' & origin/=lastorigin then do
|
|
call TELL origin '* away:' away
|
|
lastorigin = origin
|
|
end
|
|
end
|
|
end
|
|
when type = 'TIME' then do
|
|
parse var data . hh':'mm':' .
|
|
if datatype(mm/showtime,'w') then call S 'It is now' hh':'mm
|
|
if nflist/='' then do; nfcatch=1; call SEND "ISON" nflist; end
|
|
'EXECIO 1 CP(VAR A STR Q' me
|
|
parse var a . '-' a .
|
|
if a='DSC' then do
|
|
data='virtual machine runs disconnected'
|
|
call SEND 'QUIT :'data
|
|
call BYE data
|
|
end
|
|
end
|
|
when type='SOCKET' then do
|
|
parse var data . gsock
|
|
if gsock=www then do
|
|
parse value SOCKET('ACCEPT', www) with rc gsock . gport gipnum
|
|
end; else do
|
|
parse value SOCKET('READ', gsock) with rc . data
|
|
if rc=54 then iterate
|
|
if rc/=0 then call S 'Read error on http connection' gsock '('rc')'
|
|
else do
|
|
if data='' then do; SOCKET('CLOSE', gsock); iterate; end
|
|
parse var data cmd url .
|
|
parse var url URL(lf) .
|
|
if url='/' then url='/index.html'
|
|
parse var url '/'fn'.'ft'/' x; upper fn ft
|
|
if x='' & fn/='' & fn/='*' & ft/='' & ft/='*' &,
|
|
(cmd='GET'|cmd='HEAD') & FINDM(export,fn'.'ft) then do
|
|
call S 'httpd: request from' gipnum':' cmd url
|
|
/* 'MAKEBUF'; 'LISTFILE' fn ft '(STACK'; t=rc; 'DROPBUF' */
|
|
'STATE' fn ft
|
|
if rc=0 then do
|
|
call WRITE gsock "HTTP/1.0 200 Sure"
|
|
call WRITE gsock "Server:" progname"/"vers
|
|
if ft='HTML' then ct='html'; else ct='plain'
|
|
call WRITE gsock "Content-type: text/"ct
|
|
call WRITE gsock ''
|
|
if cmd='GET' then call WRITEFILE gsock fn ft pubmode
|
|
end
|
|
end; else call S 'httpd: invalid request ('cmd url') from' gipnum
|
|
SOCKET('SHUTDOWN', gsock)
|
|
end
|
|
end
|
|
end
|
|
otherwise call S 'Unexpected event:' type data
|
|
end
|
|
end
|
|
|
|
PARSE:
|
|
parse arg a
|
|
if loud & pos(beep,a)/=0 then "BEEP"
|
|
tu=; a=translate(a,"%"||beepch||"_",rev||beep||undl)
|
|
i=1; j=0; do forever; i=index(a,bold,i)
|
|
if i=0 then leave
|
|
if j=0 then a=insert(hi,a,i)
|
|
else a=insert(lo,a,i)
|
|
a=delstr(a,i,1)
|
|
j=1-j
|
|
end
|
|
if j=1 then a=a||lo
|
|
if left(a,1)=':' then do
|
|
parse var a ':'s m e f ':'g
|
|
parse var s s"!"sad
|
|
end
|
|
else do; s=''; parse var a m e f ':'g; end
|
|
f=strip(f)
|
|
logevent = 1
|
|
select
|
|
when m='CHANNEL' then if e="0"
|
|
then tu='***' s 'leaves this channel'
|
|
else tu='***' s 'joins this channel'
|
|
when m='INVITE' then do
|
|
f=strip(word(f g,1))
|
|
invitation = f
|
|
lastsender = s
|
|
tu='***' s '('sad') invites you to channel' f g; end
|
|
when m='JOIN' then do
|
|
e=strip(word(e g,1))
|
|
tu='***' s '('sad') joins channel' e
|
|
if s=ircnick then target=translate(e)
|
|
else lastjoin=s
|
|
end
|
|
when m='KICK' then tu='***' s 'kicks' f 'off channel' e '('g')'
|
|
when m='KILL' then tu='You were killed by' s subword(g,2)
|
|
when m='MODE' then tu='Mode change:' s 'sets' f 'on' e||g
|
|
when m='MSG' then tu='<'s'>' g
|
|
when m='NICK' then tu='***' s 'is now known as' e||g
|
|
when m='NOTICE' then select
|
|
when s='' | s=servername then do
|
|
if word(g,1)="***" then tu=subword(g,2)
|
|
else tu=g
|
|
a=; parse var tu 'Your host is 'g'['a .
|
|
if a/='' then servername=g
|
|
end
|
|
when translate(e)=capnick then do
|
|
if ^FINDM(ignore,s) & ^FINDM(ignore,sad) then do
|
|
tu='-'s'-' g; lastsender=s
|
|
end
|
|
end
|
|
otherwise if ^FINDM(omit,s) & ^FINDM(omit,sad) then tu='-'s':'e'-' g
|
|
end
|
|
when m='PART' then tu='***' s 'leaves channel' e
|
|
when m='PING' then call SEND("PONG :"ircnick)
|
|
when m='PRIVMSG' then do
|
|
if translate(e)=capnick then do
|
|
if FINDM(ignore,s) | FINDM(ignore,sad) then do
|
|
if ^quiet then call SEND('NOTICE' s ':'ignore_reply)
|
|
return ''; end
|
|
else do
|
|
if CTCP(1 g) then tu='*'s'*' g
|
|
lastsender=s
|
|
end
|
|
end
|
|
else if ^FINDM(omit,s) & ^FINDM(omit,sad) then
|
|
if CTCP(0 g) then do
|
|
if translate(e)=target then tu='<'s'>' g
|
|
else tu='<'s':'e'>' g
|
|
end
|
|
end
|
|
when m='QUIT' then tu='Signoff by' s '('g')'
|
|
when m='TOPIC' then tu='***' s 'sets the topic to:' g
|
|
when m='WALLOPS' then tu='Wallops from' s':' g
|
|
when m='WALL' then tu='Broadcast from' s':' g
|
|
when m='221' then tu='Your mode is' g
|
|
when m='301' then tu=f 'is away:' g
|
|
when m='302' then do
|
|
parse var g ni'='uh
|
|
if left(uh,1)='+' then aw='here'
|
|
else aw='away'
|
|
tu=ni 'is' aw '('substr(uh,2)')'
|
|
end
|
|
when m='303' & nfcatch then call ISON g
|
|
when m='311' then do
|
|
parse var f ni ui no .
|
|
tu=ni 'is' ui'@'no '('g')'
|
|
end
|
|
when m='314' then do; parse var f ni ui no .
|
|
tu=ni 'was' ui'@'no '('g')'; end
|
|
when m='312' then tu='via' word(f,2) '('g')'
|
|
when m='315' then if who_empty then call S 'No matches for /who'
|
|
when m='319' then tu='on channels:' g
|
|
when m='317' then tu='apparently idle' word(f,2)/60 'minutes'
|
|
when m='322' then do
|
|
parse var f ch n .
|
|
if ch/='*' & substr(ch,2,1)/='27'x then do
|
|
if catmode then do; if n>4 then catlist=ch catlist; end
|
|
else if listall | n>7 then call OUT left(ch,13) left(n,4)g
|
|
end; end
|
|
when m='323' then do
|
|
if catmode then do
|
|
call OUT 'Channels:' catlist; catlist=; catmode=0; end; end
|
|
when m='324' then tu='The mode on channel' word(f,1) 'is' word(f,2)
|
|
when m='332' then tu='The topic is:' g
|
|
when m='341' then tu='Inviting' word(f,1) 'to channel' word(f,2)
|
|
when m='352' then do
|
|
parse var f ch us no . ni st .
|
|
if st="S" then return ''
|
|
who_empty=0; n=subword(g,2)
|
|
do forever; a=64-(length(n)+length(us)+length(no))
|
|
if (length(no)+a > 13) then leave
|
|
n=subword(n, 1, words(n)-1)'..'; end
|
|
if (a < 0) then k=hi||n||lo||us"@*"right(no,length(no)+a-1)
|
|
else if (ch/='*' & a>length(ch)) then
|
|
k=lo||ch||hi||n||lo||copies(' ',a-length(ch)-1)us"@"no
|
|
else k=hi||n||lo||copies(' ',a)us"@"no
|
|
call S left(st,3)yo||left(ni,9)k
|
|
end
|
|
when m='353' then do; ch=word(f,2); a=words(g)
|
|
if ch/='*' & (a>6 | translate(ch)=target) then call OUT hi||left(ch,15)yo||g
|
|
end
|
|
when m='313'|m='364' then tu=f g
|
|
when m='004'|m='318'|m='321'|m='365'|m='366'|m='406' then nop
|
|
when m='001' then do; servername=s; tu=subword(g,1,words(g)-1); end
|
|
when m='376' then call SOURCE "CONNECT", 1
|
|
when m='252'|m='254' then tu=f g
|
|
otherwise select
|
|
when g="" then tu=f
|
|
when f=""|f=s then tu=g
|
|
otherwise tu=f":" g
|
|
end
|
|
if s/="" & s/=servername then tu='('s')' tu
|
|
if numb then tu='{'m'}' tu
|
|
end
|
|
return translate(tu,"@",msa)
|
|
|
|
VAR:
|
|
parse arg x
|
|
select
|
|
when datatype(x,'w') then return '$'||x
|
|
when x=',' then return lastsender
|
|
when x=':' then return lastjoin
|
|
when x='A' then return away
|
|
when x='C' then return target
|
|
when x='H' then return m
|
|
when x='I' then return invitation
|
|
when x='K' then return cmdchar
|
|
when x='N' then return ircnick
|
|
when x='Q' then return query
|
|
when x='S' then return servername
|
|
when x='T' then do
|
|
if query='' then return target
|
|
else return query
|
|
end
|
|
when x='U' then return myurl
|
|
when x='V' then return vers
|
|
when x='Z' then return left(time(),5)
|
|
when x='$' then return '$'
|
|
otherwise return v.x
|
|
end
|
|
return '<error>'
|
|
|
|
SET:
|
|
parse arg z
|
|
if z='' then do i=1 to words(varnames)
|
|
z=word(varnames,i); call S '$('z') is "'v.z'"'
|
|
end
|
|
else do
|
|
parse var z a b
|
|
if b='' then call S 'Variable' a 'has the value "'v.a'"'
|
|
else do; v.a=b; if find(varnames,a)=0 then varnames=a varnames; end
|
|
end
|
|
return
|
|
|
|
EDIT:
|
|
parse arg in
|
|
if left(in,1)="!" then call EXECUTE substr(in,2)
|
|
else if left(in,1)/=cmdchar then do
|
|
if query/='' then call SEND 'PRIVMSG' query ':'in
|
|
else if target/=0 then call SEND 'PRIVMSG' target ':'in
|
|
else call S 'You should join a channel or query a user first'
|
|
end
|
|
else if left(in,2)=cmdchar' ' then call SEND 'PRIVMSG' target ':'substr(in,3)
|
|
else call SHELL substr(in,2)
|
|
return
|
|
|
|
SHELL:
|
|
parse arg lin
|
|
if abbrev('ALIAS', translate(word(lin,1)), 2) then do
|
|
parse var lin . name lin
|
|
if name='' then do i=1 to words(aliasnames)
|
|
name=word(aliasnames,i); call S name': "'al.name'"'
|
|
end
|
|
else do
|
|
upper name
|
|
if lin='' then call S name': "'al.name'"'
|
|
else do; al.name=lin
|
|
if find(aliasnames,name)=0 then aliasnames=name aliasnames; end
|
|
end
|
|
return
|
|
end
|
|
do while lin/=''
|
|
if left(lin,1)='*' then return
|
|
parse var lin one '15'x lin
|
|
par=; lc=; com='$'; al.com = one
|
|
do while al.com/=''; sa=al.com
|
|
do while left(sa,1)='%'
|
|
parse var sa '%'var sa
|
|
parse var par sb par
|
|
v.var=sb
|
|
end
|
|
if par/='' then do; sa=sa par; par=''; end
|
|
sb=; do while sa/=''
|
|
parse var sa k'$'y sa
|
|
if y='' then do; sb=sb||k; leave; end
|
|
if left(y,1)='(' then do; parse var y 2 x')'y; sa=y sa; end
|
|
else do; x=left(y,1); sa=substr(y,2) sa; end
|
|
sb=sb||k||VAR(x)
|
|
end
|
|
parse var sb com par '::' next
|
|
upper com
|
|
if next/='' then lin=next||'15'x||lin
|
|
if find(lc, com)=0 then lc=com lc
|
|
else do; call S 'Alias loop of "'com'" encountered'; return; end
|
|
end
|
|
call COMMAND com par
|
|
end
|
|
return
|
|
|
|
COMMAND:
|
|
parse arg q r; out=; upper q
|
|
if abbrev('LEAVE',q,2) then q='PART'
|
|
select
|
|
when abbrev('ABORT',q,2) then call BYE "your abort request"
|
|
when abbrev('AWAY',q,2) then do; lastorigin=; away=r; out="AWAY :"r; end
|
|
when abbrev('BYE',q,1)|abbrev('SIGNOFF',q,6)|abbrev('QUIT',q,3) then do
|
|
call SEND('QUIT' r); call BYE; end
|
|
when abbrev('CATALOG',q,2) then do; catmode=1; out='LIST' r; end
|
|
when abbrev('CHANNEL',q,1) then do
|
|
if r="" then do; call S "Talking to" target; return; end
|
|
if target/="" & target/=0 then call SEND("PART" target);
|
|
out="JOIN" r
|
|
end
|
|
when abbrev('CLEAR',q,2) then "VMFCLEAR"
|
|
when abbrev('CMDCHARACTER',q,2) then cmdchar=left(r,1)
|
|
when q='ECHO' then call OUT r
|
|
when abbrev('EXECUTE',q,1) then call EXECUTE r
|
|
when abbrev('EXPORT',q,4) then call EXPORT r
|
|
when abbrev('EXPRESSION',q,4) then call SET word(r,1) EXPR(subword(r,2))
|
|
when abbrev('FOLLOW',q,1) then out='JOIN' invitation
|
|
when abbrev('HELP',q,1) then do
|
|
address 'CMS' "HELP RXIRC"; say; end
|
|
when q='IF' then do
|
|
parse var r cond a r
|
|
if translate(a)/='THEN' then call S "IF" cond": THEN is missing"
|
|
else do
|
|
rc = INTERP("if ("cond") then rc=0; else rc=1")
|
|
if rc=0 then call COMMAND r
|
|
end
|
|
end
|
|
when abbrev('INTERPRET',q,3) then call INTERP r
|
|
when abbrev('INVITE',q,1) then do
|
|
if words(r)=1 & target/=0 then out='INVITE' r target
|
|
else out='INVITE' r
|
|
end
|
|
when abbrev('LASTLOG',q,2) then call LASTLOG r
|
|
when abbrev('LOGGING',q,2) then call LOGGING r
|
|
when abbrev('NICKNAME',q,1) then if r='' then out='WHOIS' ircnick
|
|
else do; out='NICK' r; ircnick=r; capnick=translate(r); end
|
|
when q='NF'|abbrev('NOTIFY',q,4) then call NOTIFY r
|
|
when left(q,2)='PF' then 'CP SET' q r
|
|
when abbrev('REPLY',q,1) then call QUERY lastsender
|
|
when abbrev('SERVER',q,1) then call CONNECT r
|
|
when q='SET' then call SET r
|
|
when q='SKIP' & sourcing then if datatype(r,'w') then skiplines=r
|
|
when abbrev('SOURCE',q,2) then call SOURCE r
|
|
when abbrev('STATUS',q,1) then do; out='WHOIS' ircnick
|
|
call OUT 'Target:' target'; Query:' query'; Invitation:' invitation'; Last sender:' lastsender'; Last joined:' lastjoin
|
|
end
|
|
when q='STOP' & sourcing then abortsource=1
|
|
when abbrev('TALKTO',q,2) then do
|
|
if r/="" then target=translate(word(r,1))
|
|
call S 'Now talking to' target
|
|
end
|
|
when abbrev('TELL',q,2) then call TELL r
|
|
when abbrev('TOGGLE',q,3) then call TOGGLE r
|
|
when abbrev('VERSION',q,3) then do; out='VERSION' r
|
|
if r='' then call S progname vers
|
|
end
|
|
when abbrev('VIEWLOG',q,2) & viewcmd/='' then do
|
|
address 'CMS' viewcmd logfile; say; end
|
|
when abbrev('XAMINE',q,1) then out='WHOIS' lastsender
|
|
when abbrev('YELL',q,1) then call TELL word(r,1) '<'ircnick'>' subword(r,2)
|
|
when q='CHOP' then out="MODE" target "+ooo" r
|
|
when abbrev('DATE',q,1) then out="TIME" r
|
|
when abbrev('DESCRIBE',q,2) then do; parse var r whom desc
|
|
out='PRIVMSG' whom ':'msa'ACTION' desc||msa; end
|
|
when abbrev('IGNORE',q,2) then call IGNORE r
|
|
when q='K' then out="KICK" target r
|
|
when abbrev('LOCALWHO',q,1)|q="LCL" then do
|
|
who_empty=1; out="WHO *"right(domain,trunc(length(domain)/2)); end
|
|
when q='M'|q='MSG'|abbrev('MESSAGE',q,3) then do
|
|
parse var r ni r; out='PRIVMSG' ni ':'r; end
|
|
when abbrev('OMIT',q,2) then call OMIT r
|
|
when abbrev('QUERY',q,1) then call QUERY r
|
|
when abbrev('REQUEST',q,3)|q='CTCP' then do
|
|
parse var r ni rq .; upper rq
|
|
if ni="" then ni=capnick
|
|
if rq="" then rq="VERSION"
|
|
out='PRIVMSG' ni ':'msa||rq||msa
|
|
end
|
|
when q='SAY' then out='PRIVMSG' target ':'r
|
|
when q='SWHO' then out='NAMES'
|
|
when q='T' then out='TOPIC' target ':'r
|
|
when abbrev('TOPIC',q,2) then out='TOPIC' word(r,1) ':'subword(r,2)
|
|
when q='WHO' then do
|
|
who_empty=1
|
|
if r="" then out='WHO' target
|
|
else out='WHO' r
|
|
end
|
|
when abbrev('TCPIPSTATUS',q,3) then do
|
|
parse value SOCKET('SOCKETSETSTATUS') with rc . q etc
|
|
call S 'Status' q '('rc');' etc'; Input buffer length is' length(buffer)
|
|
end
|
|
when abbrev('WHOIS',q,1) then if r="" then out='WHOIS' ircnick
|
|
else out='WHOIS' r
|
|
when abbrev('UMODE',q,1) then out='MODE' ircnick r
|
|
when q='UNCHOP' then out="MODE" target "-ooo" r
|
|
otherwise if ACTION(q r) then do
|
|
call OUT '*' ircnick r
|
|
if query="" then out='PRIVMSG' target ':'msa'ACTION' r||msa
|
|
else out='PRIVMSG' query ':'msa'ACTION' r||msa
|
|
end
|
|
else do
|
|
li=cmds; out=q r
|
|
do while li/=''; parse var li el li
|
|
if abbrev(el,q,1) then do; out=el r; leave; end
|
|
end; end; end
|
|
call SEND out
|
|
out=; return
|
|
|
|
IGNORE:
|
|
arg a
|
|
do words(a)
|
|
parse var a x a
|
|
z=find(ignore,x); if z/=0 then
|
|
ignore=strip(delword(ignore,z,1))
|
|
else ignore=x ignore
|
|
end
|
|
call OUT 'You are ignoring:' ignore
|
|
if quiet then call S "And you don't send notices about it (quiet ignore)."
|
|
return
|
|
|
|
EXPORT:
|
|
arg a
|
|
do words(a)
|
|
parse var a x a
|
|
z=find(export,x); if z/=0 then
|
|
export=strip(delword(export,z,1))
|
|
else export=x export
|
|
end
|
|
call OUT 'You are exporting:' export
|
|
return
|
|
|
|
OMIT:
|
|
arg a
|
|
do words(a)
|
|
parse var a x a
|
|
z=find(omit,x); if z/=0 then
|
|
omit=strip(delword(omit,z,1))
|
|
else omit=x omit
|
|
end
|
|
call OUT 'You are omitting:' omit
|
|
return
|
|
|
|
QUERY:
|
|
parse arg qq
|
|
if query/='' then call S 'Terminating query with' query
|
|
query=qq
|
|
if qq/='' then call S 'Starting a query with' qq
|
|
else call S 'Talking to' target
|
|
return
|
|
|
|
LASTLOG:
|
|
arg a
|
|
if ^datatype(a,"W") | a<1 | a>80 then a=20
|
|
else a=a-1
|
|
'VMFCLEAR'; call S lo'Messages received last:'
|
|
do i=curll-a to curll; if ll.i/='' then call OUT hi'|'yo||ll.i; end
|
|
return
|
|
|
|
LOGGING:
|
|
arg a
|
|
if a='ON' & log=0 then do
|
|
writelog "<--> IRC log started on" date() "at" time()
|
|
say 'Logging started.'; log=1; end
|
|
else if a='OFF' & log=1 then do
|
|
writelog "<--> IRC log ended on" date() "at" time()
|
|
say 'Logging ended.'; log=0; end
|
|
else call S 'Logging is' onoff.log
|
|
return
|
|
|
|
S:
|
|
parse arg k; say k; if log then writelog k
|
|
if logevent/=0 then do
|
|
curll=curll+1; ll.curll=k; logevent=0; k=curll-50; ll.k=; end
|
|
return
|
|
|
|
OUT:
|
|
parse arg x; if x="" then return
|
|
if length(x) < 81 then y=0
|
|
else do 1
|
|
y=pos(word(x,2),x)-1; if y>30 | y<0 then y=3
|
|
z=lastpos(" ",x,80)
|
|
if z<30 then do; y=3; z=77; end
|
|
call S left(x,z); x=substr(x,z+1)
|
|
do while length(x)+y > 80
|
|
z=lastpos(" ",x,80-y); if z<30 then do; y=3; z=77; end
|
|
call S copies(" ",y)left(x,z); x=substr(x,z+1)
|
|
end
|
|
end
|
|
call S copies(" ",y)x
|
|
return
|
|
|
|
CONNECT:
|
|
parse arg ircserver port .
|
|
if ircserver="" then do
|
|
call S "Tell me the internet address of an IRC server"
|
|
return
|
|
end
|
|
if datatype(port)="NUM" then ircport = port
|
|
if sock/='' then do; call SEND("QUIT"); call SHUT; "CP SLEEP 3 SEC"; end
|
|
in.2=me x2c('4b404b') ':'ircname
|
|
parse value SOCKET('SOCKET', 'AF_INET', 'SOCK_STREAM') with rc sock etc
|
|
if rc/=0 then do; sock=; call BYE "socket error:" etc; end
|
|
parse value SOCKET('SETSOCKOPT',sock,'SOL_SOCKET','SO_ASCII','ON') with rc . etc
|
|
if rc/=0 then call BYE "setsockopt:" etc
|
|
call S "Connecting to" ircserver "on port" ircport"." etc
|
|
parse value SOCKET('CONNECT', sock, 'AF_INET' ircport ircserver) with rc . etc
|
|
if rc/=0 then call BYE "connect:" etc
|
|
parse value SOCKET('IOCTL', sock, 'FIONBIO', 1) with rc . etc
|
|
if rc/=0 then call BYE "nonblocking i/o:" etc
|
|
if server_pass/='' then do; call SEND("PASS" server_pass); server_pass=; end
|
|
call SEND(x2c('D5C9C3D2') ircnick)
|
|
call SEND(x2c('E4E2C5D9') in.2)
|
|
return
|
|
|
|
CTCP:
|
|
parse arg fla bla
|
|
if pos(msa,bla)=0 then return 1
|
|
parse var bla . (msa) ctcp bla (msa) .
|
|
select
|
|
when ctcp="ACTION" then call OUT '*' s bla
|
|
when ctcp="CLIENTINFO" then
|
|
call MSAREPLY "CLIENTINFO ACTION CLIENTINFO FINGER TIME URL USERINFO VERSION"
|
|
when ctcp="FINGER" then
|
|
call MSAREPLY "FINGER" realname '('me'@'hostname'.'domain',',
|
|
me'@'mynode') - Idle' trunc(time('E'),2) 'seconds'
|
|
when ctcp="TIME" then call MSAREPLY "TIME" left(time(),5)
|
|
when ctcp="URL" then do
|
|
if wwwport='' then call MSAREPLY "ERRMSG No http port set up by user"
|
|
else call MSAREPLY "URL" myurl
|
|
end
|
|
when ctcp="USERINFO" then call MSAREPLY "USERINFO" userinfo
|
|
when ctcp="VERSION" then
|
|
call MSAREPLY "VERSION" progname vers "VM/CMS",
|
|
":Survival package for VM-struck humans"
|
|
otherwise if fla=1 then call MSAREPLY "ERRMSG Huh? Can't do" ctcp
|
|
end
|
|
return 0
|
|
|
|
MSAREPLY:
|
|
parse arg lyrics
|
|
call SEND("NOTICE" s ":"msa||lyrics||msa)
|
|
return
|
|
|
|
SYNTAX:
|
|
say errortext(rc)
|
|
return 0
|
|
|
|
HALT:
|
|
call BYE "halt request"
|
|
BYE:
|
|
parse arg reason
|
|
save_rc = rc
|
|
if reason/="" then call S "Terminating because of" reason '('rc')'
|
|
if log then do
|
|
writelog "<--> IRC session ended on" date() "at" time()
|
|
"FINIS * * *"
|
|
end
|
|
do i=1 to pf.0
|
|
a=word(pf.i,2)
|
|
if a='RETRIEVE' then iterate
|
|
if a='UNDEFINED' then "CP SET" word(pf.i,1)
|
|
else "CP SET" pf.i
|
|
end
|
|
i=1; parse var qt.i 'LINEND' a',' . 'CHARDEL' k',' .
|
|
'CP TERM LINEND' a 'CHARDEL' k
|
|
i=2; parse var qt.i 'LINESIZE' a',' .
|
|
'CP TERM LINESIZE' a
|
|
if www/='' then do
|
|
SOCKET('SHUTDOWN',www); SOCKET('CLOSE',www); www=; end
|
|
if sock/='' then do
|
|
call SHUT
|
|
parse value SOCKET('TERMINATE') with .
|
|
"NUCXDROP RXSOCKET"
|
|
end
|
|
if have_rxwt then RESETVALUE('ALL')
|
|
exit save_rc
|
|
|
|
ACTION:
|
|
parse arg q r
|
|
select
|
|
when abbrev("APPLAUD",q,3) then a="applauds wholeheartedly"
|
|
when q="BOW" then a="bows gracefully"
|
|
when abbrev("COMFORT",q,3) then a="comforts you"
|
|
when abbrev("CUDDLE",q,3) then a="cuddles you"
|
|
when abbrev("DANCE",q,3) then a="dances a waltz with you"
|
|
when abbrev("GIGGLE",q,3) then a="giggles inanely"
|
|
when abbrev("GRIN",q,2) then a="grins"
|
|
when q="HUG" then a="hugs you"
|
|
when abbrev("LAUGH",q,2) then a="laughs wholeheartedly"
|
|
when q="ME"|abbrev("EMOTE",q,1) then return 1
|
|
when q="NOD" then a="nods solemnly"
|
|
when abbrev("SHRUG",q,2) then a="shrugs"
|
|
when abbrev("SIGH",q,2) then a="sighs deeply"
|
|
when abbrev("SMILE",q,2) then a="smiles"
|
|
when abbrev("THANK",q,2) then a="thanks you from the bottom of the heart"
|
|
when abbrev("WAVE",q,2) then a="waves goodbye to you"
|
|
when abbrev("WINK",q,2) then a="winks suggestively"
|
|
when abbrev("YAWN",q,2) then a="yawns tiredly"
|
|
otherwise return 0; end
|
|
if r="" then r=a'.'
|
|
else r=word(a,1) r'.'
|
|
return 1
|
|
|
|
FINDM: procedure
|
|
arg patlist, token
|
|
do words(patlist)
|
|
parse var patlist a patlist
|
|
if MATCH(a,token) then return 1
|
|
end
|
|
return 0
|
|
|
|
MATCH: procedure
|
|
arg pattern, token
|
|
do i = 1 by 1 while i < length(pattern)
|
|
ss = substr(pattern,i,2)
|
|
select
|
|
when ss = '**' then do
|
|
pattern = delstr(pattern,i,1)
|
|
i = i - 1
|
|
end
|
|
when ss = '*?' then pattern = overlay('?*',pattern,i,2)
|
|
otherwise nop
|
|
end
|
|
end
|
|
return MATCHINT(pattern,token)
|
|
|
|
MATCHINT: procedure
|
|
arg pattern, token
|
|
if pattern == token then return 1
|
|
if pattern == '*' then return 1
|
|
if verify(pattern,'*?','M') = 0 then return 0
|
|
ptrp = 1
|
|
ptrt = 1
|
|
lenp = length(pattern)
|
|
lent = length(token)
|
|
do search = 1 by 1
|
|
select
|
|
when ptrp > lenp & ptrt > lent
|
|
then return 1
|
|
when ptrp > lenp then return 0
|
|
when ptrt > lent then return 0
|
|
otherwise nop
|
|
end
|
|
pchar = substr(pattern,ptrp,1)
|
|
tchar = substr(token,ptrt,1)
|
|
select
|
|
when pchar = tchar | pchar = '?'
|
|
then do
|
|
ptrp = ptrp + 1
|
|
ptrt = ptrt + 1
|
|
iterate search
|
|
end
|
|
when pchar = '*' & ptrp = lenp
|
|
then return 1
|
|
when pchar = '*' then do
|
|
ptrp = ptrp + 1
|
|
pchar = substr(pattern,ptrp,1)
|
|
do ptrt = ptrt to lent
|
|
tchar = substr(token,ptrt,1)
|
|
if pchar = tchar then do
|
|
if ptrp = lenp & ptrt = lent
|
|
then return 1
|
|
if MATCHINT(substr(pattern,ptrp+1),substr(token,ptrt+1)) then return 1
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
otherwise return 0
|
|
end
|
|
end
|
|
call BYE 'a mistake'
|
|
|
|
SEND:
|
|
parse arg qp
|
|
if qp='' then return
|
|
if left(qp, 9)='PRIVMSG +' then do
|
|
parse var qp . '+'ni' :'tx
|
|
call TELL ni tx
|
|
end
|
|
else do
|
|
qp=translate(qp,beep||bold,beepch||boldch)
|
|
parse value SOCKET('WRITE', sock, qp||cr||lf) with rc . etc
|
|
if rc/=0 then call BYE "socket write error:" etc
|
|
end
|
|
return
|
|
|
|
SHUT:
|
|
a=sock; sock=; servername=;
|
|
parse value SOCKET('SHUTDOWN', a,'BOTH') with rc . etc
|
|
if rc/=0 then call BYE "socket shut error:" etc
|
|
parse value SOCKET('CLOSE', a) with rc . etc
|
|
if rc/=0 then call BYE "socket close error:" etc
|
|
return
|
|
|
|
NICE:
|
|
arg u'@'v;if v='' then v=mynode
|
|
if nice.u.v/='' then return nice.u.v
|
|
'NAMEF :userid' u ':node' v ':nick (LIFO'
|
|
if rc=0 then parse pull nice.u.v .
|
|
else if v=mynode then do
|
|
'NAMEF :userid' u ':node :nick (LIFO'
|
|
if rc=0 then do
|
|
parse pull nice.u.v .
|
|
pull ln .
|
|
if ln='' then return nice.u.v
|
|
end
|
|
nice.u.v=u
|
|
end
|
|
else if u='RSCS' then nice.u.v=v
|
|
else nice.u.v=u'@'v
|
|
return nice.u.v
|
|
|
|
U@N:
|
|
parse arg x z; if q='' then return 0 'missing args'
|
|
upper x; parse var x x'@'y
|
|
if y/='' then return x y z
|
|
if word(z,1)='AT' then do
|
|
parse var z . y z; upper y
|
|
if y='' then return 0 'missing node'
|
|
return x y z;end
|
|
if u@n.x/='' then return u@n.x z
|
|
'NAMEF :nick' x ':userid :node :via (LIFO'
|
|
if rc=0 then do 1
|
|
pull k; pull y; pull a
|
|
if a='' then leave
|
|
if y='' then y=mynode
|
|
u@n.q=a y; if via.a.y='' then via.a.y=k
|
|
return a y z
|
|
end
|
|
u@n.x = x mynode
|
|
return x mynode z
|
|
|
|
TELL:
|
|
parse arg tea
|
|
parse value U@N(tea) with xid xnod tea
|
|
if xid=0 then do
|
|
call OUT xnod tea
|
|
return
|
|
end
|
|
err=; if translate(left(tea,4))='VIA ' then do
|
|
parse var tea . via tea
|
|
upper via
|
|
if via='NONE' then via=;
|
|
via.xid.xnod = via
|
|
end
|
|
else via=via.xid.xnod
|
|
select
|
|
when via='SMSG'|via='SEND' then do
|
|
if xnod/=mynode then err='SEND & SMSG only local'
|
|
else do
|
|
if via='SMSG' then parse value diagrc(8,'SMSG' xid tea) with rc . err
|
|
else do
|
|
parse var tea cp? tea?
|
|
if translate(cp?)='CP' then
|
|
parse value diagrc(8,'SEND CP' xid translate(tea?)) with rc . err
|
|
else parse value diagrc(8,'SEND' xid tea) with rc . err
|
|
end; end; end
|
|
when via=''|left(via,1)/="'" then do
|
|
if via='RSCS' then do;viar=1;via='';end;else viar=0
|
|
if via/='' then via='CMD' via
|
|
if xid='RSCS'|(xid=rscs&xnod=mynode) then do
|
|
if xnod=mynode&^viar then parse value diagrc(8,'SM' rscs tea) with rc . err
|
|
else parse value diagrc(8,'SM' rscs via 'CMD' xnod tea) with rc . err
|
|
end
|
|
else do
|
|
if xnod=mynode&^viar then parse value diagrc(8,'M' xid tea) with rc . err
|
|
else parse value diagrc(8,'SM' rscs via 'MSG' xnod xid tea) with rc . err
|
|
end
|
|
end
|
|
otherwise
|
|
parse var via "'"via"'"
|
|
if word(via,1)='CP' then do
|
|
parse value diagrc(8,subword(via,2) tea) with rc . err
|
|
if rc=1 then err=via "unknown."
|
|
end
|
|
else do
|
|
if xnod=mynode|xnod='' then address cms via xid tea
|
|
else address cms via NICE(xid'@'xnod) tea
|
|
if rc>0 then err='Rc' rc 'from' via'.'
|
|
if rc<0 then do;rc=24;err='Invalid VIA'; end
|
|
end; end
|
|
if err/='' then call OUT strip(translate(err,' ','15'x))
|
|
return
|
|
|
|
SOURCE:
|
|
arg sfn, sfl
|
|
if sfn='' then do
|
|
call S "You must specify a file to /source"
|
|
return -1
|
|
end
|
|
sfn = sfn 'RXIRC *'
|
|
"STATE" sfn
|
|
if rc/=0 then do
|
|
if sfl/=1 then call S 'Could not access' sfn
|
|
end
|
|
else do
|
|
'MAKEBUF'; 'EXECIO * DISKR' sfn '(FIFO FINIS'; skiplines=0;
|
|
do queued(); sourcing=1
|
|
parse pull l; if abortsource then iterate
|
|
if skiplines=0 then call SHELL strip(l)
|
|
else skiplines=skiplines-1
|
|
end
|
|
abortsource=0; sourcing=0; 'DROPBUF'
|
|
end
|
|
return
|
|
|
|
TOGGLE:
|
|
parse arg n o
|
|
if ^datatype(n,'W')|n<1|n>24 then do
|
|
call S 'Invalid PF key "'n'".'; return; end
|
|
o = strip(o); sep = left(o,1)
|
|
parse var o (sep) com (sep) o
|
|
'CP SET PF'n 'IMM /TOGGLE' n sep||o||sep||com
|
|
call SHELL strip(com)
|
|
drop sep
|
|
return
|
|
|
|
EXPR:
|
|
procedure
|
|
parse arg expr
|
|
signal on SYNTAX
|
|
INTERPRET("expr = ("expr")")
|
|
signal off SYNTAX
|
|
return expr
|
|
|
|
INTERP:
|
|
procedure
|
|
arg statement
|
|
signal on SYNTAX; INTERPRET(statement); signal off SYNTAX
|
|
return rc
|
|
|
|
NOTIFY:
|
|
arg a
|
|
do i=1 to words(a)
|
|
x=word(a,i); y=find(nflist,x); z=find(translate(nfhere),a)
|
|
if z/=0 then nfhere=strip(delword(nfhere,z,1))
|
|
if y/=0 then nflist=strip(delword(nflist,y,1))
|
|
else nflist=nflist x
|
|
end
|
|
call OUT 'Observing:' nflist
|
|
if a='' then call OUT 'Present:' nfhere
|
|
return
|
|
|
|
ISON:
|
|
parse arg g
|
|
i=1; do words(nfhere)
|
|
a=word(nfhere,i)
|
|
if find(g,a)=0 then do
|
|
nfhere = strip(delword(nfhere,i,1))
|
|
call OUT a "has gone"
|
|
end
|
|
else i=i+1
|
|
end
|
|
do i=1 to words(g)
|
|
a=word(g,i)
|
|
if find(nfhere,a)=0 then do
|
|
nfhere = a nfhere
|
|
call SEND "USERHOST" a
|
|
end
|
|
end
|
|
nfcatch=0
|
|
return
|
|
|
|
EXECUTE:
|
|
parse arg a
|
|
if a='' then do
|
|
say 'Suspending rxIRC; Enter "return" to return'
|
|
a='SUBSET'
|
|
end
|
|
address 'CMS' a
|
|
if rc=0 then say "rxIRC ready"
|
|
else say "rxIRC ready("rc")"
|
|
return
|
|
|
|
WRITE:
|
|
parse arg qp tx
|
|
parse value SOCKET('WRITE', qp, tx||cr||lf) with rc . etc
|
|
if rc/=0 then call S "Socket write error:" etc
|
|
return
|
|
|
|
WRITEFILE:
|
|
parse arg qp fn ft .
|
|
'MAKEBUF'
|
|
'EXECIO * DISKR' fn ft '(FINIS FIFO'
|
|
if rc=0 then do
|
|
do queued()
|
|
parse pull l
|
|
call WRITE qp l
|
|
if rc/=0 then do
|
|
call S 'httpd: File transmission interrupted (by caller probably)'
|
|
signal DROPIT
|
|
end
|
|
end
|
|
call S 'httpd: Sent' fn ft
|
|
end
|
|
DROPIT:
|
|
'DROPBUF'
|
|
return
|