git: 9front

ref: fb1240ae3e6bec6061fe18c3aa14e2edb02cd74a
dir: /rc/bin/ircrc/

View raw version
#!/bin/rc

rfork ne

nl='
'
server=irc.oftc.net
port=6697
realname='<nil>'
target=''
netdir=()
nick=$user
username=$user
pass=()
tls=1
serverpass=()

fn sighup {
	exit 'hang up'
}

fn sigint sigterm {
	if (! ~ $#netdir 0)
		echo  QUIT :Leaving... > $netdir/data
}

fn work {
	if(~ $#serverpass 1)
		echo PASS $serverpass
	echo USER $username foo bar :$realname
	echo NICK $nick
	if (~ $#pass 1)
		echo PRIVMSG NickServ :IDENTIFY $pass
	if(! ~ $target ''){
		title $target
		echo JOIN $target
	}
	awk -v 'target='^$"target '
	BEGIN{
		if(target ~ /.+,.+/){
			n = split(target, a, ",")
			target = a[n]
		}
	}
	function title(){
		system("title ''"target"''")
	}
	function etime(c, t){
		c = "date -f ''[\\[]hh:mm[\\]]''"
		c | getline t
		close(c)
		return t
	}
	function out(nskip, space, pref, echo){
		if(nskip){
			r = "^";
			for(i = 0; i < nskip; i++)
				r = r "[^\t ]+[\t ]*"
			sub(r, "")
		}
		if(echo)
			print echo $0 >"/dev/cons"
		print pref (space&&$0 ? " " : "") $0
	}
	$1 !~ /^\//{
		out(0, 0, "PRIVMSG "target" :", NF>0 ? etime()" ("target")	⇐	" : "")
		next
	}
	$1 == "/!"{
		if(NF > 1){
			c = substr($0, index($0, $2))
			while(c | getline)
				out(0, 0, "PRIVMSG "target" :", "PRIVMSG "target" :")
			close(c)
		}
		next
	}
	$1 == "/M"{ out(1, 1, "MODE"); next }
	$1 == "/N"{ if(NF > 2) out(2, 0, "NOTICE "$2" :"); next }
	$1 == "/T"{ if(NF > 1) out(1, 1, "TOPIC"); next }
	$1 == "/W"{ out(1, 1, "WHOIS"); next }
	$1 == "/a"{ out(1, 0, "AWAY :"); next }
	$1 == "/j"{
		if(NF == 2 || NF == 3){
			target = $2
			title()
			if(target ~ /.+,.+/)
				target = a[split(target, a, ",")]
			out(1, 1, "JOIN")
		}
		next
	}
	$1 == "/l"{ out(1, 1, "LIST"); next }
	$1 == "/m"{
		if(NF > 2)
			out(2, 0, "PRIVMSG "$2" :", etime()" ("$2")	⇐	")
		next
	}
	$1 == "/n"{ nick = $2; out(1, 1, "NICK"); next }
	$1 == "/p"{ if(NF > 1) out(2, 0, "PART "$2" :"); next }
	$1 == "/q"{ out(1, 0); next }
	$1 == "/t"{ target = $2; title(); next }
	$1 == "/u"{ out(1, 1, "USERS"); next }
	$1 == "/w"{ out(1, 1, "WHO"); next }
	$1 == "/x"{ out(1, 0, "QUIT :"); exit }
	{ print "unknown command" >"/dev/cons" }
	END{ print "QUIT :Leaving..." }
	'
	exit
}

fn misc {
	sed '
		s/^://
		s/!~?[a-zA-Z0-9_@\-|.{=\/:]+ /:/' |
	awk -F ':' '
	{
		s =  $2 " «" $1 "»\t" $3;
		for(i = 4; i < NF+1; i++)
			s = s ":" $i;
		printf("%s\n", s);
	}' 
}

fn notice {
	sed '
		s/^NOTICE /:'^$server^':/
		s/^://
		s/!~?[a-zA-Z0-9_@\-|.{=\/]+ /:/' |
	awk -F ':' '
	{
		s = "-" $1 "-	⇒\t" $3;
		for(i = 4; i < NF+1; i++)
			s = s ":" $i;
		printf("%s\n", s);
	}' 
}

fn numeric {
	sed 's/^:[a-zA-Z0-9_@\-|.!=#]+ //
		s/ '^$nick^' //
		s/^353= /***	Users on /
		s/^[0-9][0-9][0-9] ?:?/***	/'
}

fn privmsg {
	sed ' 
		s/^:/«/
		s/!~?[a-zA-Z0-9_@\-|.{=\/:]+ PRIVMSG /»	⇒	:/
		s/#[a-zA-Z0-9_@\-|.#]+/(&)/' | 
	awk -F ':' '
	{
		s = $2 $1  $3;
		for(i = 4; i < NF+1; i++)
			s = s ":" $i;
		printf("%s\n", s);
	}'
}

fn pretty {
	while (line=`$nl{read}) {
		cmd=`{echo $line}
		switch ($line) {
		case *PRIVMSG*
			line = `$nl{echo -n $line | privmsg}
		case *JOIN* *QUIT* *PART* *NICK*
			line = `$nl{echo -n $line | misc}
		case *NOTICE*
			line = `$nl{echo -n $line | notice}
		case PING* # *PING* could also be CASEMAPPING
			echo PONG $cmd(2) > $netdir/data
			line = ()
		case *
			line = `$nl{echo -n $line | numeric}
		}
		if (! ~ $#line 0)
			echo `{date -f '[\[]hh:mm[\]]'} $line
	}
	exit
}

fn title {
	if (! ~ $#winid 0) {
		if (test -f /mnt/acme/$winid/ctl)
			echo name /$server/$"1/-ircrc > /mnt/acme/$winid/ctl
	}
	if not
		label $"1@$server
}

while (~ $1 -*) {
	switch ($1) {
	case -n
		nick=$2
		shift
	case -p
		port=$2
		shift
	case -r
		realname=$2
		shift
	case -t
		target=$2
		shift
	case -u
		username=$2
		shift
	case -T
	case -U
		tls=0
	case -*
		echo 'usage: ircrc  [-p port] [-r realname] [-t target] [-n nick] [-u username] [-U] [server]' >[1=2]
		exit 'usage'
	}
	shift
}

if (~ $#* 1) {
	switch ($1) {
	case bitlbee
		server=im.bitlbee.org
	case oftc
		server=irc.oftc.net
	case *
		server=$1
	}
}

title $target
userpass=`{auth/userpasswd -n 'server='^$server^' service=irc user='^$nick >[2]/dev/null}
if(~ $#userpass 2)
	pass=$userpass(2)
userpass=`{auth/userpasswd -n 'server='^$server^' service=ircsrv user='^$nick >[2]/dev/null}
if(~ $#userpass 2)
	serverpass=$userpass(2)

p='/n/ircrc'
bind '#|' $p
echo connecting to tcp!$server!$port...
if(~ $tls 0){
	aux/trampoline tcp!$server!$port <>$p/data1 >[1=0] &
}
if not {
	tlsclient tcp!$server!$port <>$p/data1 >[1=0] &
}
netdir=$p
<$netdir/data tr -d '\x2\x8\xd\x1f' | pretty &
>$netdir/data work