# nicks and hosts must go in ~/.irssi/sos.oplist in the current format
# nickname host1 host2
# username .*\!ident\@.*\.isp\.com
use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
$VERSION = "0.5";
%IRSSI = (
authors => "David O\'Rourke",
contact => "EFNet\://phyber\@\#irssi",
name => "sos",
description => "Simple Op Script",
licence => "GPL General Public Licence",
changed => "10.7.2003 20:02"
);
# might make this more configurable later. ie. a /set setting
my $passwd = "somepass";
my $chan = "\#somechan";
my %ops;
# host to regexp, borrowed from 'friends_shasta.pl'
my %htr = ();
# fill the hash
foreach my $i (0..255) {
my $ch = chr($i);
$htr{$ch} = "\Q$ch\E";
}
# wildcards to regexp
$htr{'?'} = '.';
$htr{'*'} = '.*';
sub uhost_to_regexp($) {
my ($mask) = @_;
$mask = lcase_hostpart($mask);
$mask =~ s/(.)/$htr{$1}/g;
return $mask;
}
sub lcase_hostpart($) {
my ($host) = @_;
$host =~ s/(.+)\@(.+)/sprintf("%s@%s", $1, lc($2));/eg;
return $host;
}
# read the sos.oplist file.
# entryname .*\!ident\@.*some\.host\.com
sub cmd_load_ops {
my ($file) = Irssi::get_irssi_dir."/sos.oplist";
my ($count) = 0;
my ($nick, @hostmasks);
local(*FILE);
%ops = ( );
open FILE, "< $file";
while (<FILE>) {
($nick, @hostmasks) = split;
$ops{$nick} = "@hostmasks";
}
close FILE;
$count = keys %ops;
Irssi::print "Loaded $count channel ops from $file";
}
sub check_host {
my ($hostmask) = @_;
my @checkhost;
my $key;
my $valid = 0;
foreach $key (sort keys %ops) {
@checkhost = $ops{$key};
for my $validhost (split(/ /, "@checkhost")) {
#Irssi::print "Comparing $hostmask => $validhost";
if ($hostmask =~ /$validhost/) {
Irssi::print "Authenticated: $hostmask";
$valid = 1;
}
}
# if we found a matching host, stop the loop
last if ($valid == 1);
}
return $valid;
}
sub valid_op {
my ($servtag, $nick) = @_;
my $server = Irssi::server_find_tag($servtag);
# let's not try to send the MODE if we arn't opped.
my $channel = $server->channel_find($chan);
return if (!$channel->{chanop});
Irssi::print "Giving ops to $nick on $chan";
$server->send_raw("MODE $chan +o $nick") if ($server);
}
sub event_check_op {
my ($server, @data) = @_;
# split the host and nick from the msg
my $hostmask = pop(@data);
my $nick = pop(@data);
my $msg = "@data";
# stop right now if $msg isn't the passwd
return if ("$msg" ne "$passwd");
# if it was the passwd, let's check out the hostmask
$hostmask = "$nick!$hostmask";
$hostmask = lcase_hostpart($hostmask);
# check if the host is valid
my $valid = check_host($hostmask);
# stop if the host wasn't valid
#Irssi::print "UnAuthorised: $hostmask" if ($valid == 0);
return if ($valid == 0);
# stop the signal if everything checks out.
# we don't need a new query everytime someone msgs us the passwd
Irssi::signal_stop();
# ok, so if we're here, it MUST be a valid op, right?
my $servtag = $server->{tag};
valid_op($servtag, $nick);
}
Irssi::signal_add_first('message private', 'event_check_op');
Irssi::command_bind('oplist_reload', 'cmd_load_ops');
# load op list on script start
cmd_load_ops;