ircii.pl 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!@l_prefix@/bin/perl
  2. ##
  3. ## ircii.pl -- ircII command line wrapper (for optional SSL support)
  4. ##
  5. require 5.008;
  6. use strict;
  7. use warnings;
  8. use IO::File;
  9. use Getopt::Long;
  10. use File::Temp qw(tempfile tempdir);
  11. # external programs
  12. my $irc = '@l_prefix@/libexec/ircii/irc';
  13. my $stunnel = '@l_prefix@/sbin/stunnel';
  14. # define command line options
  15. my $opt = {};
  16. my %options = (
  17. # standard ircII options
  18. 'c=s' => \$opt->{-c},
  19. 'p=s' => \$opt->{-p},
  20. 'P=s' => \$opt->{-P},
  21. 'f' => \$opt->{-f},
  22. 'F' => \$opt->{-F},
  23. 'r' => \$opt->{-r},
  24. 's' => \$opt->{-s},
  25. 'S' => \$opt->{-S},
  26. 'h=s' => \$opt->{-h},
  27. 'H=s' => \$opt->{-H},
  28. 'd' => \$opt->{-d},
  29. 'q' => \$opt->{-q},
  30. 'a' => \$opt->{-a},
  31. 'b' => \$opt->{-b},
  32. 'l=s' => \$opt->{-l},
  33. 'I=s' => \$opt->{-I},
  34. 't' => \$opt->{-t},
  35. 'T' => \$opt->{-T},
  36. 'i=s' => \$opt->{-i},
  37. 'help' => \$opt->{-help},
  38. # add-on wrapper options
  39. 'ssl' => \$opt->{-ssl},
  40. );
  41. # parse command line options
  42. {
  43. local @ARGV = @ARGV;
  44. my $p = new Getopt::Long::Parser;
  45. $p->configure("bundling");
  46. $p->getoptions(%options) || die "option parsing failed";
  47. }
  48. # remove add-on option
  49. if (defined($opt->{-ssl})) {
  50. for (my $i = 0; $i < @ARGV; $i++) {
  51. if ($ARGV[$i] eq '--ssl') {
  52. splice(@ARGV, $i, 1);
  53. last;
  54. }
  55. }
  56. }
  57. if (defined($opt->{-ssl})) {
  58. # encrypted IRC-over-SSL connection
  59. if (not -x $stunnel) {
  60. print STDERR "irc:ERROR: stunnel(1) required -- please install \"stunnel\" package.\n";
  61. exit(1);
  62. }
  63. # determine parameters
  64. srand(time() ^ $$);
  65. my $lhost = $opt->{-h};
  66. my $lport = 60000 + int(rand() * 1000);
  67. my $rhost = ((defined($ARGV[-1]) and $ARGV[-1] !~ m|^-|) ? $ARGV[-1] : "irc");
  68. my $rport = ($opt->{-p} || 994);
  69. # start an SSL tunnel
  70. my $tmpdir = tempdir("/tmp/ircII-XXXXXX", CLEANUP => 1);
  71. my $pidfile = "$tmpdir/stunnel.pid";
  72. my $logfile = "$tmpdir/stunnel.log";
  73. my $cfgfile = "$tmpdir/stunnel.cfg";
  74. my $io = new IO::File ">$cfgfile" || die;
  75. $io->print(
  76. "client = yes\n" .
  77. "pid = $pidfile\n" .
  78. "output = $logfile\n" .
  79. "[ircs]\n" .
  80. (defined($lhost) ?
  81. "local = $lhost\n" : "") .
  82. "accept = localhost:$lport\n" .
  83. "connect = $rhost:$rport\n"
  84. );
  85. $io->close();
  86. system $stunnel, $cfgfile;
  87. sleep(1);
  88. # manipulate ircII command line arguments
  89. splice(@ARGV, -2, 0, "-p", $lport);
  90. $ARGV[-1] = "localhost";
  91. # start ircII through SSL tunnel
  92. my $rc = system $irc, @ARGV;
  93. # shutdown SSL tunnel
  94. system("kill `cat $pidfile 2>/dev/null`");
  95. undef $tmpdir;
  96. # exit with ircII return code
  97. exit($rc);
  98. }
  99. else {
  100. # unencrypted IRC connection
  101. exec $irc, @ARGV;
  102. }