shithub: ircs

ref: 3d67aef1674ebfcc63bac043711f14ddd4765c94
dir: ircs/ircx

View raw version
#!/bin/rc
# ircx: ircs ui
rfork e

flagfmt='e,p,r,T,U,s srvname,f file,t target,b lines'
args='[nick[!user] addr]'

srv=ircs
mainlog=()
log=()
opt=()

lines=()
target=()
offset=()

help='<del>, /q       quit ircx (leaves ircs running)
/h              print this help
/j #channel     join #channel and set it as target
/n nick         change nick
/N              list nicks on channel target
/p [message]    part from channel target
/Q [message]    quit (stops ircs)
/r message      send raw message to server
/t target       set target (channel or nick)
/T [topic]      get [set] topic of channel target
/w mask         send who query
/W mask         send whois query
/x              create new ircx window
[/ ]message     send message to target
/me message	send an action emote'

fn usage{
	aux/usage
	exit usage
}
fn fatal{
	echo $* >[1=2]
	exit $"*
}
fn isnum{
	echo $1 | grep -s '^[0-9]+$'
}
fn clear{
	awk 'BEGIN {
		for(i = 0; i < '$1'; i++)
			printf "\x08"
	}'
}
fn runtail{
	{	tail -$2
		while(sleep 1) cat
	} <$1 &
	tailpid=$apid
}
fn oldlabel{
	if(! ~ $#oldlabel 0)
		label $oldlabel
}
fn killtail{
	@{
		echo kill >/proc/$tailpid/note
	} &
}
fn saveoffset{
	if(~ $#offset 1 && test -r $log)
		wc -l <$log | tr -d ' ' >$offset
}
fn shutdown{
	saveoffset
	killtail
	oldlabel
	exit 0
}
fn sighup sigint sigterm{
	shutdown
}
fn send{
	if(test -e /srv/$srv)
		echo $* >>/srv/$srv
	if not{
		echo /srv/$srv not found '(ircs stopped?)'
		shutdown
	}
}
fn settarget{
	if(~ $1 ''){
		target=()
		label $mainlog
	}
	if not{
		target=$1
		label $target
	}
}
fn newtarget{
	if(~ $#flagf 1)
		settarget $newtarget
	if not{
		if(~ $newtarget '#'*){
			f=/tmp/$srv/$newtarget
			sleep 1
		}
		if not{
			settarget $newtarget
			f=$mainlog
		}
		if(! ~ $f $log){
			if(test -r $f){
				settarget $newtarget
				saveoffset
				offset=()
				killtail
				log=$f
				echo $log
				runtail $log 10
			}
			if not
				echo can''''t access $f
		}
	}
	newtarget=()
}
fn lines{
	if(~ $#offset 1 && test -r $offset && test -r $log){
		n₀=`{cat $offset}
		n₁=`{wc -l <$log}
		δn=`{echo $n₁ - $n₀ + 10 | bc}
		echo $δn
	}
	if not
		echo 10
}

if(! ifs=() eval `{aux/getflags $*} || ! ~ $#* 0 2)
	usage

if(~ $#flagb 1){
	if(! isnum $flagb)
		usage
	lines=$flagb
}
if(~ $#flagt 1)
	target=$flagt

if(~ $#flags 1){
	if(~ $flags '')
		fatal empty srvname
	srv=$flags
	opt=($opt -s $srv)
}
if(~ $#flagf 1){
	mainlog=$flagf
	opt=($opt -f $mainlog)
}
if not{
	mainlog=/tmp/$srv/log
	if(~ $#lines 0){
		offset=/tmp/$srv/offsets/log
		mkdir -p /tmp/$srv/offsets
	}
}
if(~ $#flage 1) opt=($opt -e)
if(~ $#flagp 1) opt=($opt -p)
if(~ $#flagr 1) opt=($opt -r)
if(~ $#flagT 1) opt=($opt -T)
if(~ $#flagU 1) opt=($opt -U)

switch($#*){
case 0
	for(i in /srv/$srv $mainlog)
		if(! test -e $i)
			fatal $i not found
case 2
	if(test -e /srv/$srv)
		fatal ircs already running
	nick=$1
	addr=$2
	ircs $opt $nick $addr
	stat=$status
	if(! ~ $stat '')
		exit $stat
case *
	usage
}

oldlabel=`{cat /dev/label}
oifs=$ifs
log=$mainlog

if(~ $#target 1){
	label $target
	if(~ $target '#'*){
		send JOIN $target
		if(~ $#flagf 0){
			log=/tmp/$srv/$target
			if(~ $#lines 0)
				offset=/tmp/$srv/offsets/$target
			if(! test -e $log)
				sleep 1
		}
	}
}
if not
	label $log

if(~ $#lines 0)
	lines=`{lines}

echo $log -$lines
runtail $log $lines

while(ifs=() line=`{read | tr -d \xa}){
	ifs=$oifs
	clear `{echo $line | wc -r}

	if(! ~ $line ''){
		msg=()
		*=`{echo $line}
		cmd=$1
		shift

		switch($cmd){
		case /h
			echo $help
		case /j
			if(~ $#* 0)
				echo no channel
			if not{
				msg='JOIN '^$"*
				newtarget=$1
			}
		case /t
			if(~ $#* 0)
				echo no target
			if not
				newtarget=$1
		case /N
			if(! ~ $target '#'*)
				echo no channel
			if not
				msg='NAMES '^$target
		case /T
			if(! ~ $target '#'*)
				echo no channel
			if not{
				msg='TOPIC '^$target
				if(! ~ $#* 0)
					msg=$msg^' :'^$"*
			}
		case /p
			if(! ~ $target '#'*)
				echo no channel
			if not{
				msg='PART '^$target
				if(! ~ $#* 0)
					msg=$msg^' :'^$"*
				newtarget=''
			}
		case /q
			shutdown
		case /Q
			if(~ $#* 0)
				send QUIT
			if not
				send 'QUIT :'^$"*
			sleep 1
			shutdown
		case /r
			if(~ $#* 0)
				echo no message
			if not{
				ifs=()
				msg=`{echo -n $line | sed 's!^[ 	]*/r[ 	]+!!'}
				ifs=$oifs
			}
		case /n
			if(~ $#* 0)
				echo no nick
			if not
				msg='NICK '^$1
		case /w
			if(~ $#* 0)
				echo no mask
			if not
				msg='WHO '^$"*
		case /W
			if(~ $#* 0)
				echo no mask
			if not
				msg='WHOIS '^$"*
		case /x
			window -m ircx $opt
		case /
			if(~ $#target 0)
				echo no target
			if not{
				ifs=()
				line=`{echo -n $line | sed 's!^[ 	]*/[ 	]*!!'}
				ifs=$oifs				
				msg='PRIVMSG '^$target^' :'^$line
			}
		case /me
			if(~ $#target 0)
				echo no target
			if not
				msg='PRIVMSG '^$target^' :ACTION '^$"*^''	
		case /*
			echo unknown command
		case *
			if(~ $#target 0)
				echo no target
			if not
				msg='PRIVMSG '^$target^' :'^$line
		}
		if(! ~ $#msg 0)
			send $msg

		if(~ $#newtarget 1)
			newtarget
	}
}
shutdown