Sirocco - an irc-like gale wrapper

I use way too many instant messenging systems. I've come to the conclusion that Gale is the one true messenging system, but the interface is unlike what most people are used to. Fugu is helpful to the windows people and anyone else who likes GUIs, but not the Unix people who are used to IRC. (Okay, Tessa recently wrote vtfugu - fugu for curses - but still.)

So I wrote Sirocco (or if you like sIRoCco) to make gale look like irc. It requires ssfe, the split screen front end which comes with sirc

Download Sirocco

Incidentally, the name Sirocco, suggested by silly@ugcs.caltech.edu, means:

From Webster's Revised Unabridged Dictionary (1913) [web1913]:

  Sirocco \Si*roc"co\ (s[i^]*r[o^]k"k[-o]), n.
     In general, any hot dry wind of cyclonic origin, blowing from
     arid or heated regions, including the desert wind of Southern
     California

So now you know.


#!/usr/bin/perl

#
# sirocco - an irc-like wrapper around gale via gsend/gsub
#
# This script can be called as both the front-end and the gsubrc
#

# Todo:
# - better use of ssfe status line (print "`#ssfe#smsg\n";)
# - better display formatting
#	- make sure we don't show return receipts
#	- don't show the "channel" for the current channel
#	- make the lines look like irc
#	- deal with different domains somehow (just show for ones that don't
#		match the domain for the current channel?)
#	- deal with authentication and encryption (colors?)
# - add a /reload
# - add a /help
# - make novice mode etc. conform to actual irc syntax
# - clean up env var namespace
# - re-evaluate use of env vars as a means of passing state between
#	instances
# - override the id_class client id or at least add a fragment
#	identifying ourselves
# - add BSD-style license notice - hey, you - I'm not liable
# - add support for negative subscriptions
# - take commandline arguments
# - handle #/& in "channel" names
# - support dumping urls put to a browser
# - all ^/ need to be trapped

# Before anything else, find path to us.
# This is a bad way to do it.
chop ($pathme = `which $0`);


# If we're called as a gsubrc, just print and exit.
if ($ENV{IMAGSUBRC}){
	$to = $ENV{GALE_TO};
	$from = $ENV{GALE_FROM};
	$to =~ s/\@.*//g;
	$from =~ s/\@.*//g;
	print "<${from}/#${to}> ";
	undef $/;
	$_ = <>;
	print;
	exit(0);
}

# If we're not running out of ssfe, call it.
if (!($ENV{INSSFE})){
	$ENV{INSSFE}="1";
	exec "ssfe $pathme" || die "Couldn't find ssfe - make sure it's installed and in your path\n";
}


# Main, as it were.

@sublist=("pub.me.${ENV{USER}}");
$curchan="$sublist[0]";

$host=`hostname`;
chop $host;
$domain=$host;
$domain =~ s/.*\.([^.]+\.[^.]+)$/$1/g;
$medefault="${ENV{USER}}\@${domain}";
$ENV{"SIROCCOnovice"} = "true";

$| = 1;
print "Enter your personal gale address ($medefault): ";
chop($me = <>);
print "\n";
$me ||= $medefault;

unshift(@sublist,$me);

sub onexit {
	($child) && kill (15,$child);
	exit(0);
}

sub restart_gsub {
	unless ($child == 0){
		kill 15,$child;
		unless ($child = fork){
			$ENV{IMAGSUBRC}="1";
			open(STDERR,">/dev/null");
			exec {"gsub"} "gsub","-q","-f","$pathme","-n",@sublist;
		}
	}
}

$SIG{TERM} = \&onexit;

unless ($child=fork){ 
	$ENV{IMAGSUBRC}="1";
	open(STDERR,">/dev/null");
	exec {"gsub"} "gsub","-q","-f","$pathme","-n",@sublist;
}

# main loop
while (<>){

	chop;
	next if (/^$/);
	# Catch commands to us - use irc convention of ^/
	if (/^\/join /){
 		$newsub = $_;
		$newsub =~ s/^\/join //;
		$curchan = $newsub;
		if ($ENV{"SIROCCOnovice"} =~ /^(on|yes|true)$/i){
			@sublist=("$newsub");
		} else {
			unless (grep(/^$newsub$/,@sublist)){
				push(@sublist,$newsub);
			}
		}
		# print "Adding $newsub to subscription list.\n";
		restart_gsub();
	} elsif (/^\/set /){
		($set,$name,$val) = split(/[\s]/,$_,3);
		$ENV{"SIROCCO${name}"} = $val;
	} elsif (/^\/quit$/){
		onexit();
	} elsif (/^\/debug$/){
		print "$0: $$: ------------------- debug -----------------\n";
		print "$0: $$: \$curchan = \"$curchan\"\n";
		print "$0: $$: \@sublist = \"",join(",",@sublist),"\"\n";
		print "$0: $$: child gsub is pid $child\n";
		for $envar (sort(keys(%ENV))){
			if ($envar =~ /^SIROCCO/){
				$ssgvar = $envar;
				$ssgvar =~ s/^SIROCCO//;
				print "$0: $$: $ssgvar = \"$ENV{$envar}\"\n";
			}
		}
		print "$0: $$: ----------------- end debug ---------------\n";
	} else {
		open(GSEND,"|gsend $curchan");
		print GSEND "$_\n";
		close GSEND;
	}
}