pcw / extras / chat.sh

#!/bin/sh

# SERVERS should be a file with a list of servers, each followed by the ii
# command line for that server (except the -s because we start with the server)
# A -i prefix argument will override the one provided here, useful if you want
# a specific server somewhere other than the given hierarchy, but it should be
# noted that the fifo path will still be relative to $PREFIX/$serv/. There are
# then a list of "fifo command" pairs for each server. If a line ends with a "w"
# we wait a few seconds before executing it (default 5). Each server block
# should be separated by a new line. The commands for a given server are
# performed in serial, and each block runs in parallel. I do not do any error
# checking for you, so don't screw up the format. I never claimed this was
# pretty, just that it works for me :-)
# For example, my $SERVERS file (nick and pass changed of course)
#
# <start of $SERVERS>
# irc.oftc.net -n mynick
# nickserv/in identify mypass w
# in /j #ii
# in /j #suckless
# in /j #heresy
# nickserv/in /l w
#
# localhost -n mynick -p 13245
# &bitlbee/in identify mypass
# &bitlbee/in blist w
# <EOF>
#
# TIP: note the use of 'w' both when identifying to nickserv and leaving
#      nickserv. The first one is to give ii some time to connect, the second
#      should wait until after nickserv replies to your identify, so you don't
#      reopen a window when it does so. the "nickserv/in /l w" is at the end
#      so I don't have to wait for that command before executing the others

TITLE="pcw"
PREFIX="$HOME/irc"
SERVERS="$PREFIX/servers"
LOG="$PREFIX/log"

DELAY=5 # seconds to wait when we get a "w"

trap "" HUP

if ! tmux -L "$TITLE" list-sessions | grep -q "^$TITLE"; then
	tmux -L "$TITLE" new-session -d -s "$TITLE"
	sleep .1
fi

{
	echo
	date

	if pgrep -lf "pcw $PREFIX"; then
		echo "killing previous pcw"
		pkill -f "pcw $PREFIX"
	fi
} >> "$LOG" 2>&1

# not inside ^that block because it needs to be run in the background
which pcw > /dev/null 2>&1 && pcw "$PREFIX" >> "$LOG" 2>&1 &

while read line; do
	args="$line"
	serv="${line%% *}"
	commands=
	while read line; do
		[ -n "$line" ] || break #stop on empty line
		commands="$commands;$line"
	done

	echo "starting $serv"
	echo "find log in $PREFIX/$serv/log"
	echo "commands $commands"
	[ -d "$PREFIX/$serv" ] || mkdir "$PREFIX/$serv"

	{
		echo
		date
		echo "ii -i $PREFIX -s $args"
	} >> "$PREFIX/$serv/log" 2>&1

	while true; do
		find "$PREFIX/$serv" | grep "in$" | xargs rm # clean stale fifos
		# compress old stuff, means fewer lines for cw to rewrite for reflows,
		# and we still get to keep the old stuff, and it's smaller
		for f in $(find "$PREFIX/$serv" | grep "out$"); do
			gzip -c "$f" >> "${f}_old.gz"
			rm "$f"
		done
		oIFS="$IFS"
		IFS=";"
		for line in $commands; do
			[ -n "$line" ] || continue
			fifo="${line%% *}"
			cmd="${line#* }"
			cmd="${cmd% w}"
			printf "trying $cmd > $PREFIX/$serv/$fifo."

			if echo "$line" | grep -q " w$"; then
				printf " delay $DELAY seconds."
				sleep $DELAY
			fi
				
			# wait for the fifo to exist, don't want to make a normal file
			i=0
			while [ $i -lt 10 -a ! -p "$PREFIX/$serv/$fifo" ]; do
				i=$((i + 1))
				printf "."
				sleep 1
			done
			if ! [ -p "$PREFIX/$serv/$fifo" ]; then
				echo "FAILED: timeout"
				continue
			fi
			echo "$cmd" > "$PREFIX/$serv/$fifo"
			echo "OK"
		done >> "$PREFIX/$serv/log" 2>&1 & # background so we can start ii

		IFS="$oIFS"
		eval ii -i "$PREFIX" -s $args
		[ $? -eq 2 ] || break # only restart ii on timeout (not default for ii)
	done >> "$PREFIX/$serv/log" 2>&1 & # instead of locking the main one...

done < "$SERVERS" >> "$LOG" 2>&1

tmux -L "$TITLE" attach-session -t "$TITLE"

# vim: set ts=4 sw=4 noexpandtab:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.