#!@l_prefix@/bin/perl
##
##  ircii.pl -- ircII command line wrapper (for optional SSL support)
##  Copyright (c) 2005-2007 Ralf S. Engelschall <rse@engelschall.com>
##

require 5.008;
use strict;
use warnings;
use IO::File;
use Getopt::Long;
use File::Temp qw(tempfile tempdir);

#   external programs
my $irc     = '@l_prefix@/libexec/ircii/irc';
my $stunnel = '@l_prefix@/sbin/stunnel';

#   define command line options
my $opt = {};
my %options = (
    #   standard ircII options
    'c=s'  => \$opt->{-c},
    'p=s'  => \$opt->{-p},
    'P=s'  => \$opt->{-P},
    'f'    => \$opt->{-f},
    'F'    => \$opt->{-F},
    'r'    => \$opt->{-r},
    's'    => \$opt->{-s},
    'S'    => \$opt->{-S},
    'h=s'  => \$opt->{-h},
    'H=s'  => \$opt->{-H},
    'd'    => \$opt->{-d},
    'q'    => \$opt->{-q},
    'a'    => \$opt->{-a},
    'b'    => \$opt->{-b},
    'l=s'  => \$opt->{-l},
    'I=s'  => \$opt->{-I},
    't'    => \$opt->{-t},
    'T'    => \$opt->{-T},
    'i=s'  => \$opt->{-i},
    'help' => \$opt->{-help},
    #   add-on wrapper options
    'ssl'  => \$opt->{-ssl},
);

#   parse command line options
{
    local @ARGV = @ARGV;
    my $p = new Getopt::Long::Parser;
    $p->configure("bundling");
    $p->getoptions(%options) || die "option parsing failed";
}

#   remove add-on option
if (defined($opt->{-ssl})) {
    for (my $i = 0; $i < @ARGV; $i++) {
        if ($ARGV[$i] eq '--ssl') {
            splice(@ARGV, $i, 1);
            last;
        }
    }
}

if (defined($opt->{-ssl})) {
    #   encrypted IRC-over-SSL connection
    if (not -x $stunnel) {
        print STDERR "irc:ERROR: stunnel(1) required -- please install \"stunnel\" package.\n";
        exit(1);
    }

    #   determine parameters
    srand(time() ^ $$);
    my $lhost = $opt->{-h};
    my $lport = 60000 + int(rand() * 1000);
    my $rhost = ((defined($ARGV[-1]) and $ARGV[-1] !~ m|^-|) ? $ARGV[-1] : "irc");
    my $rport = ($opt->{-p} || 994);

    #   start an SSL tunnel
    my $tmpdir = tempdir("/tmp/ircII-XXXXXX", CLEANUP => 1);
    my $pidfile = "$tmpdir/stunnel.pid";
    my $logfile = "$tmpdir/stunnel.log";
    my $cfgfile = "$tmpdir/stunnel.cfg";
    my $io = new IO::File ">$cfgfile" || die;
    $io->print(
        "client  = yes\n" .
        "pid     = $pidfile\n" .
        "output  = $logfile\n" .
        "[ircs]\n" .
        (defined($lhost) ?
        "local   = $lhost\n" : "") .
        "accept  = localhost:$lport\n" .
        "connect = $rhost:$rport\n"
    );
    $io->close();
    system $stunnel, $cfgfile;
    sleep(1);

    #   manipulate ircII command line arguments
    splice(@ARGV, -2, 0, "-p", $lport);
    $ARGV[-1] = "localhost";

    #   start ircII through SSL tunnel
    my $rc = system $irc, @ARGV;

    #   shutdown SSL tunnel
    system("kill `cat $pidfile 2>/dev/null`");
    undef $tmpdir;

    #   exit with ircII return code
    exit($rc);
}
else {
    #   unencrypted IRC connection
    exec $irc, @ARGV;
}

