From d5701d108190a251839e049f68e910d151d59b5b Mon Sep 17 00:00:00 2001 From: dedeibel Date: Mon, 2 Jan 2017 23:28:47 +0100 Subject: Added post auth command, for example to trigger a chanserv invite --- scripts/nickserv.pl | 193 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 180 insertions(+), 13 deletions(-) (limited to 'scripts/nickserv.pl') diff --git a/scripts/nickserv.pl b/scripts/nickserv.pl index c1d9ce8..216a6b7 100644 --- a/scripts/nickserv.pl +++ b/scripts/nickserv.pl @@ -24,7 +24,7 @@ use strict; use Irssi; use vars qw($VERSION %IRSSI); -$VERSION = "1.10"; +$VERSION = "1.11"; %IRSSI = ( authors => 'Geert Hauwaerts', @@ -41,6 +41,9 @@ my $nickservnet_file = "nickserv.networks"; my @nickservauth = (); my $nickservauth_file = "nickserv.auth"; +my @nickservpostcmd = (); +my $nickservpostcmd_file = "nickserv.postcmd"; + my $irssidir = Irssi::get_irssi_dir(); my $help = < ] [addnick ] + [addpostcmd ] [delnet ] [delnick ] - [help listnet listnick] - -addnet: Add a new network into the NickServ list. -addnick: Add a new nickname into the NickServ list. -delnet: Delete a network from the NickServ list. -delnick: Delete a nickname from the NickServ list. -listnet: Display the contents of the NickServ network list. -listnick: Display the contents of the NickServ nickname list. -help: Display this useful little helptext. + [delpostcmd ] + [help listnet listnick listpostcmd] + +addnet: Add a new network into the NickServ list. +addnick: Add a new nickname into the NickServ list. +addpostcmd: Add a new post auth command for nickname into the NickServ list. +delnet: Delete a network from the NickServ list. +delnick: Delete a nickname from the NickServ list. +delpostcmd: Deletes all post auth command for nickame. +listnet: Display the contents of the NickServ network list. +listnick: Display the contents of the NickServ nickname list. +listpostcmd: Display the contents of the NickServ postcmd list. +help: Display this useful little helptext. Examples: (all on one line) /NICKSERV addnet Freenode NickServ\@services. /NICKSERV addnick Freenode Geert mypass +/NICKSERV addpostcmd Freenode Geert ^MSG ChanServ invite #heaven /NICKSERV delnet Freenode /NICKSERV delnick Freenode Geert @@ -74,19 +83,25 @@ EOF Irssi::theme_register([ 'nickserv_usage_network', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addnet ircnet services@host%_".', 'nickserv_usage_nickname', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addnick ircnet nickname password%_".', + 'nickserv_usage_postcmd', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV addpostcmd ircnet nickname command%_".', 'nickserv_delusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnet ircnet%_".', 'nickserv_delnickusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnick ircnet nickname%_".', + 'nickserv_delpostcmdusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delpostcmd ircnet nickname%_".', 'nickserv_delled', '%R>>%n %_NickServ:%_ Deleted %_$0%_ and his nicknames from the NickServ ircnet list.', 'nickserv_delled_nick', '%R>>%n %_NickServ:%_ Deleted %_$1%_ from the NickServ list on $0.', + 'nickserv_delled_postcmd', '%R>>%n %_NickServ:%_ Deleted all entries for %_$1%_ from the NickServ postcmd list on $0.', 'nickserv_nfound', '%R>>%n %_NickServ:%_ The NickServ ircnet %_$0%_ could not be found.', 'nickserv_nfound_nick', '%R>>%n %_NickServ:%_ The NickServ nickname %_$0%_ could not be found on $1.', + 'nickserv_nfound_postcmd', '%R>>%n %_NickServ:%_ The NickServ nickname %_$0%_ could not be found on $1.', 'nickserv_usage', '%R>>%n %_NickServ:%_ Insufficient parameters: Use "%_/NICKSERV help%_" for further instructions.', 'nickserv_no_net', '%R>>%n %_NickServ:%_ Unknown Irssi ircnet %_$0%_.', 'nickserv_wrong_host', '%R>>%n %_NickServ:%_ Malformed services hostname %_$0%_.', 'already_loaded_network', '%R>>%n %_NickServ:%_ The ircnet %_$0%_ already exists in the NickServ ircnet list, please remove it first.', 'nickserv_loaded_nick', '%R>>%n %_NickServ:%_ The nickname %_$0%_ already exists in the NickServ authlist on %_$1%_, please remove it first.', 'nickserv_not_loaded_net', '%R>>%n %_NickServ:%_ The ircnet %_$0%_ doesn\'t exists in the NickServ ircnet list, please add it first.', + 'nickserv_not_loaded_nick', '%R>>%n %_NickServ:%_ The nickname %_$0%_ doesn\'t exists in the NickServ authlist on %_$1%_, please add it first.', 'saved_nickname', '%R>>%n %_NickServ:%_ Added nickname %_$1%_ on %_$0%_.', + 'saved_postcmd', '%R>>%n %_NickServ:%_ Added postcmd %_$1%_ on %_$0%_: %_%2%_.', 'network_print', '$[!-2]0 $[20]1 $2', 'password_request', '%R>>%n %_NickServ:%_ Auth Request from NickServ on %_$0%_.', 'password_accepted', '%R>>%n %_NickServ:%_ Password accepted on %_$0%_.', @@ -96,6 +111,9 @@ Irssi::theme_register([ 'nickname_print', '$[!-2]0 $[20]1 $[18]2 $3', 'nickname_info', '%_ # Ircnet Nickname Password%_', 'nickname_empty', '%R>>%n %_NickServ:%_ Your NickServ authlist is empty.', + 'postcmd_print', '$[!-2]0 $[20]1 $[18]2 $3', + 'postcmd_info', '%_ # Ircnet Nickname Postcmd%_', + 'postcmd_empty', '%R>>%n %_NickServ:%_ Your NickServ postcmd list is empty.', 'nickserv_help', '$0', 'saved_network', '%R>>%n %_NickServ:%_ Added services mask "%_$1%_" on %_$0%_.', 'nickserv_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.' @@ -187,6 +205,30 @@ sub load_nickservnick { } } +sub load_nickservpostcmd { + + my ($file) = @_; + + @nickservpostcmd = (); + + if (-e $file) { + local *F; + open(F, "<" ,$file); + local $/ = "\n"; + + while () { + chop; + my $new_postcmd = new_postcmd(split("\t")); + + if (($new_postcmd->{ircnet} ne "") && ($new_postcmd->{nick} ne "") && ($new_postcmd->{postcmd} ne "")) { + push(@nickservpostcmd, $new_postcmd); + } + } + + close(F); + } +} + sub save_nickservnick { my ($file) = @_; @@ -203,12 +245,33 @@ sub save_nickservnick { close(F); } else { - create_nick_file($file); + create_save_file($file); save_nickservnick($file); } } -sub create_nick_file { +sub save_nickservpostcmd { + + my ($file) = @_; + + return unless scalar @nickservpostcmd; # there's nothing to save + + if (-e $file) { + local *F; + open(F, ">", $file); + + for (my $n = 0; $n < @nickservpostcmd; ++$n) { + print(F join("\t", $nickservpostcmd[$n]->{ircnet}, $nickservpostcmd[$n]->{nick}, $nickservpostcmd[$n]->{postcmd}) . "\n"); + } + + close(F); + } else { + create_save_file($file); + save_nickservpostcmd($file); + } +} + +sub create_save_file { my ($file) = @_; @@ -228,10 +291,21 @@ sub new_nickserv_nick { return $nsnick; } +sub new_postcmd { + + my $nspostcmd = {}; + + $nspostcmd->{ircnet} = shift; + $nspostcmd->{nick} = shift; + $nspostcmd->{postcmd} = shift; + + return $nspostcmd; +} + sub add_nickname { my ($network, $nickname, $password) = split(" ", $_[0], 3); - my ($correct_network, $correct_nickname, $correct_password); + my ($correct_network, $correct_nickname); if ($network eq "" || $nickname eq "" || $password eq "") { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_nickname'); @@ -264,6 +338,42 @@ sub add_nickname { } } +sub add_postcmd { + + my ($network, $nickname, $postcmd) = split(" ", $_[0], 3); + my ($correct_network, $correct_nickname); + + if ($network eq "" || $nickname eq "" || $postcmd eq "") { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_postcmd'); + return; + } + + if ($network) { + if (!already_loaded_net($network)) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_net', $network); + return; + } else { + $correct_network = 1; + } + } + + if ($nickname) { + if (!already_loaded_nick($nickname, $network)) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_nick', $nickname, $network); + return; + } else { + $correct_nickname = 1; + } + } + + if ($correct_network && $correct_nickname) { + push(@nickservpostcmd, new_postcmd($network, $nickname, $postcmd)); + save_nickservpostcmd("$irssidir/$nickservpostcmd_file"); + + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_postcmd', $network, $nickname, $postcmd); + } +} + sub add_network { my ($network, $hostname) = split(" ", $_[0], 2); @@ -382,6 +492,19 @@ sub list_nick { } } +sub list_postcmd { + + if (@nickservpostcmd == 0) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_empty'); + } else { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_info'); + + for (my $n = 0; $n < @nickservpostcmd ; ++$n) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_print', $n, $nickservpostcmd[$n]->{ircnet}, $nickservpostcmd[$n]->{nick}, $nickservpostcmd[$n]->{postcmd}); + } + } +} + sub nickserv_notice { my ($server, $data, $nick, $address) = @_; @@ -442,6 +565,7 @@ sub nickserv_notice { } elsif ($text =~ /^Password accepted - you are now recognized/ || $text =~ /^You are now identified for/) { Irssi::signal_stop(); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_accepted', $server->{tag}); + run_postcmds($server, $server->{tag}, $server->{nick}) } elsif ($text =~ /^Password Incorrect/ || $text =~ /^Password incorrect./) { Irssi::signal_stop(); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_wrong', $server->{tag}); @@ -449,6 +573,17 @@ sub nickserv_notice { } } +sub run_postcmds { + my ($server, $tag, $nick) = @_; + return unless scalar @nickservpostcmd; # there's nothing to save + + for my $cmd (@nickservpostcmd) { + if ($tag eq $cmd->{ircnet} && $nick eq $cmd->{nick} && $cmd->{postcmd}) { + $server->command($cmd->{postcmd}); + } + } +} + sub is_nickserv { my ($net, $host) = @_; @@ -521,6 +656,28 @@ sub del_nickname { } } +sub del_postcmd { + + my ($ircnet, $nickname) = split(" ", $_[0], 2); + my ($nickindex); + + if ($ircnet eq "" || $nickname eq "") { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delpostcmdusage'); + return; + } + + my $size_before = scalar(@nickservpostcmd); + @nickservpostcmd = grep { !( lc($_->{ircnet}) eq lc($ircnet) && lc($_->{nick}) eq lc($nickname) )} @nickservpostcmd; + my $size_after = scalar(@nickservpostcmd); + + if ($size_before != $size_after) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled_postcmd', $ircnet, $nickname); + save_nickservpostcmd("$irssidir/$nickservpostcmd_file"); + } else { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_postcmd', $ircnet, $nickname); + } +} + sub nickserv_runsub { my ($data, $server, $item) = @_; @@ -535,6 +692,7 @@ sub nickserv_runsub { load_nickservnet("$irssidir/$nickservnet_file"); load_nickservnick("$irssidir/$nickservauth_file"); +load_nickservpostcmd("$irssidir/$nickservpostcmd_file"); Irssi::command_bind('nickserv', 'nickserv_runsub'); Irssi::command_bind('ns', 'nickserv_runsub'); @@ -545,18 +703,27 @@ Irssi::command_bind('ns addnet', 'add_network'); Irssi::command_bind('nickserv addnick', 'add_nickname'); Irssi::command_bind('ns addnick', 'add_nickname'); +Irssi::command_bind('nickserv addpostcmd', 'add_postcmd'); +Irssi::command_bind('ns addpostcmd', 'add_postcmd'); + Irssi::command_bind('nickserv listnet', 'list_net'); Irssi::command_bind('ns listnet', 'list_net'); Irssi::command_bind('nickserv listnick', 'list_nick'); Irssi::command_bind('ns listnick', 'list_nick'); +Irssi::command_bind('nickserv listpostcmd', 'list_postcmd'); +Irssi::command_bind('ns listpostcmd', 'list_postcmd'); + Irssi::command_bind('nickserv delnet', 'del_network'); Irssi::command_bind('ns delnet', 'del_network'); Irssi::command_bind('nickserv delnick', 'del_nickname'); Irssi::command_bind('ns delnick', 'del_nickname'); +Irssi::command_bind('nickserv delpostcmd', 'del_postcmd'); +Irssi::command_bind('ns delpostcmd', 'del_postcmd'); + Irssi::command_bind('nickserv help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) }); Irssi::command_bind('ns help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) }); -- cgit v1.2.3 From 9d4f90c395fef0b7eaa382000a82e26b671f5a20 Mon Sep 17 00:00:00 2001 From: dedeibel Date: Tue, 3 Jan 2017 21:26:25 +0100 Subject: Removed early exit when writing files which prevented deleting the last entry of a list. Closed files after creating them (touch) --- scripts/nickserv.pl | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'scripts/nickserv.pl') diff --git a/scripts/nickserv.pl b/scripts/nickserv.pl index 216a6b7..02a5983 100644 --- a/scripts/nickserv.pl +++ b/scripts/nickserv.pl @@ -147,8 +147,6 @@ sub save_nickservnet { my ($file) = @_; - return unless scalar @nickservnet; # there's nothing to save - if (-e $file) { local *F; open(F, ">", $file); @@ -206,7 +204,6 @@ sub load_nickservnick { } sub load_nickservpostcmd { - my ($file) = @_; @nickservpostcmd = (); @@ -230,11 +227,8 @@ sub load_nickservpostcmd { } sub save_nickservnick { - my ($file) = @_; - return unless scalar @nickservauth; # there's nothing to save - if (-e $file) { local *F; open(F, ">", $file); @@ -251,11 +245,8 @@ sub save_nickservnick { } sub save_nickservpostcmd { - my ($file) = @_; - return unless scalar @nickservpostcmd; # there's nothing to save - if (-e $file) { local *F; open(F, ">", $file); @@ -272,11 +263,10 @@ sub save_nickservpostcmd { } sub create_save_file { - my ($file) = @_; - my $umask = umask 0077; # save old umask open(F, ">", $file) or die "Can't create $file. Reason: $!"; + close(F); umask $umask; } @@ -565,7 +555,7 @@ sub nickserv_notice { } elsif ($text =~ /^Password accepted - you are now recognized/ || $text =~ /^You are now identified for/) { Irssi::signal_stop(); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_accepted', $server->{tag}); - run_postcmds($server, $server->{tag}, $server->{nick}) + run_postcmds($server, $server->{tag}, $server->{nick}) } elsif ($text =~ /^Password Incorrect/ || $text =~ /^Password incorrect./) { Irssi::signal_stop(); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_wrong', $server->{tag}); -- cgit v1.2.3 From 6342d84f5f6871442f61b4f0c7c262eb7cf4c474 Mon Sep 17 00:00:00 2001 From: dedeibel Date: Tue, 17 Jan 2017 00:18:42 +0100 Subject: Nickserv script refactoring, modernized file handling and reused common code parts. Refactoring save file location building to single position. Removing postcmds after deletion of net or nick. --- scripts/nickserv.pl | 453 ++++++++++++++++++++++++---------------------------- 1 file changed, 208 insertions(+), 245 deletions(-) (limited to 'scripts/nickserv.pl') diff --git a/scripts/nickserv.pl b/scripts/nickserv.pl index 02a5983..ff2738d 100644 --- a/scripts/nickserv.pl +++ b/scripts/nickserv.pl @@ -32,19 +32,20 @@ $VERSION = "1.11"; name => 'nickserv.pl', description => 'This script will authorize you into NickServ.', license => 'GNU General Public License', - url => 'http://irssi.hauwaerts.be/nickserv.pl', + url => 'https://github.com/irssi/scripts.irssi.org/blob/master/scripts/nickserv.pl', + changed => 'Di 17. Jan 19:32:45 CET 2017', ); +my $irssidir = Irssi::get_irssi_dir(); + my @nickservnet = (); -my $nickservnet_file = "nickserv.networks"; +my $nickservnet_file = "$irssidir/nickserv.networks"; my @nickservauth = (); -my $nickservauth_file = "nickserv.auth"; +my $nickservauth_file = "$irssidir/nickserv.auth"; my @nickservpostcmd = (); -my $nickservpostcmd_file = "nickserv.postcmd"; - -my $irssidir = Irssi::get_irssi_dir(); +my $nickservpostcmd_file = "$irssidir/nickserv.postcmd"; my $help = <>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnet ircnet%_".', 'nickserv_delnickusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delnick ircnet nickname%_".', 'nickserv_delpostcmdusage', '%R>>%n %_NickServ:%_ Insufficient parameters: Usage "%_/NICKSERV delpostcmd ircnet nickname%_".', - 'nickserv_delled', '%R>>%n %_NickServ:%_ Deleted %_$0%_ and his nicknames from the NickServ ircnet list.', - 'nickserv_delled_nick', '%R>>%n %_NickServ:%_ Deleted %_$1%_ from the NickServ list on $0.', + 'nickserv_delled', '%R>>%n %_NickServ:%_ Deleted %_$0%_ and it\'s nicknames and post commands from the NickServ ircnet list.', + 'nickserv_delled_nick', '%R>>%n %_NickServ:%_ Deleted %_$1%_ and it\'s post commands from the NickServ list on $0.', 'nickserv_delled_postcmd', '%R>>%n %_NickServ:%_ Deleted all entries for %_$1%_ from the NickServ postcmd list on $0.', 'nickserv_nfound', '%R>>%n %_NickServ:%_ The NickServ ircnet %_$0%_ could not be found.', 'nickserv_nfound_nick', '%R>>%n %_NickServ:%_ The NickServ nickname %_$0%_ could not be found on $1.', - 'nickserv_nfound_postcmd', '%R>>%n %_NickServ:%_ The NickServ nickname %_$0%_ could not be found on $1.', + 'nickserv_nfound_postcmd', '%R>>%n %_NickServ:%_ The NickServ post commands for nickname %_$1%_ could not be found on $0.', 'nickserv_usage', '%R>>%n %_NickServ:%_ Insufficient parameters: Use "%_/NICKSERV help%_" for further instructions.', 'nickserv_no_net', '%R>>%n %_NickServ:%_ Unknown Irssi ircnet %_$0%_.', 'nickserv_wrong_host', '%R>>%n %_NickServ:%_ Malformed services hostname %_$0%_.', @@ -123,177 +124,163 @@ sub load_nickservnet { my ($file) = @_; - @nickservnet = (); - - if (-e $file) { - local *F; - open(F, "<", $file); - local $/ = "\n"; - - while () { - chop; - my $new_nsnet = new_nickserv_network(split("\t")); - - if (($new_nsnet->{name} ne "") && ($new_nsnet->{host} ne "")) { - push(@nickservnet, $new_nsnet); - } - } - - close(F); - } + @nickservnet = load_file($file, sub { + my $new_nsnet = new_nickserv_network(@_); + return undef if ($new_nsnet->{name} eq "" || $new_nsnet->{host} eq ""); + return $new_nsnet; + }); } sub save_nickservnet { - my ($file) = @_; - - if (-e $file) { - local *F; - open(F, ">", $file); - - for (my $n = 0; $n < @nickservnet; ++$n) { - print(F join("\t", $nickservnet[$n]->{name}, $nickservnet[$n]->{host}) . "\n"); - } - - close(F); - } else { - create_network_file($file); - save_nickservnet($file); - } -} - -sub create_network_file { - - my ($file) = @_; - - open(F, ">", $file) or die "Can't create $file. Reason: $!"; + save_file($nickservnet_file, \@nickservnet, \&nickservnet_as_list); } sub new_nickserv_network { - my $nsnet = {}; + return { + name => shift, + host => shift + }; +} + +sub nickservnet_as_list { - $nsnet->{name} = shift; - $nsnet->{host} = shift; + my $nickserv_net = shift; - return $nsnet; + return ( + $nickserv_net->{name}, + $nickserv_net->{host} + ); } sub load_nickservnick { my ($file) = @_; - @nickservauth = (); + @nickservauth = load_file($file, sub { + my $new_nsnick = new_nickserv_nick(@_); - if (-e $file) { - local *F; - open(F, "<" ,$file); - local $/ = "\n"; + return undef if ($new_nsnick->{ircnet} eq "" || $new_nsnick->{nick} eq "" || $new_nsnick->{pass} eq ""); + return $new_nsnick; + }); +} - while () { - chop; - my $new_nsnick = new_nickserv_nick(split("\t")); - - if (($new_nsnick->{ircnet} ne "") && ($new_nsnick->{nick} ne "") && ($new_nsnick->{pass} ne "")) { - push(@nickservauth, $new_nsnick); - } - } - - close(F); - } +sub save_nickservnick { + + save_file($nickservauth_file, \@nickservauth, \&nickserv_nick_as_list); } -sub load_nickservpostcmd { - my ($file) = @_; +sub new_nickserv_nick { - @nickservpostcmd = (); + return { + ircnet => shift, + nick => shift, + pass => shift + }; +} - if (-e $file) { - local *F; - open(F, "<" ,$file); - local $/ = "\n"; +sub nickserv_nick_as_list { - while () { - chop; - my $new_postcmd = new_postcmd(split("\t")); - - if (($new_postcmd->{ircnet} ne "") && ($new_postcmd->{nick} ne "") && ($new_postcmd->{postcmd} ne "")) { - push(@nickservpostcmd, $new_postcmd); - } - } - - close(F); - } + my $nickserv_nick = shift; + return ( + $nickserv_nick->{ircnet}, + $nickserv_nick->{nick}, + $nickserv_nick->{pass} + ); } -sub save_nickservnick { +sub load_nickservpostcmd { + my ($file) = @_; - if (-e $file) { - local *F; - open(F, ">", $file); + @nickservpostcmd = load_file($file, sub { + my $new_postcmd = new_postcmd(@_); - for (my $n = 0; $n < @nickservauth; ++$n) { - print(F join("\t", $nickservauth[$n]->{ircnet}, $nickservauth[$n]->{nick}, $nickservauth[$n]->{pass}) . "\n"); - } - - close(F); - } else { - create_save_file($file); - save_nickservnick($file); - } + return undef if ($new_postcmd->{ircnet} eq "" || $new_postcmd->{nick} eq "" || $new_postcmd->{postcmd} eq ""); + return $new_postcmd; + }); } sub save_nickservpostcmd { - my ($file) = @_; - if (-e $file) { - local *F; - open(F, ">", $file); + save_file($nickservpostcmd_file, \@nickservpostcmd, \&postcmd_as_list); +} - for (my $n = 0; $n < @nickservpostcmd; ++$n) { - print(F join("\t", $nickservpostcmd[$n]->{ircnet}, $nickservpostcmd[$n]->{nick}, $nickservpostcmd[$n]->{postcmd}) . "\n"); - } - - close(F); - } else { - create_save_file($file); - save_nickservpostcmd($file); - } +sub new_postcmd { + + return { + ircnet => shift, + nick => shift, + postcmd => shift + }; } -sub create_save_file { - my ($file) = @_; - my $umask = umask 0077; # save old umask - open(F, ">", $file) or die "Can't create $file. Reason: $!"; - close(F); - umask $umask; +sub postcmd_as_list { + my $postcmd = shift; + + return ( + $postcmd->{ircnet}, + $postcmd->{nick}, + $postcmd->{postcmd} + ); } -sub new_nickserv_nick { +# file: filename to be read +# parse_line_fn: receives array of entries of a single line as input, should +# return parsed data object or undef in the data is incomplete +# returns: parsed data array +sub load_file { + + my ($file, $parse_line_fn) = @_; + my @parsed_data = (); - my $nsnick = {}; + if (-e $file) { + open(my $fh, "<", $file); + local $/ = "\n"; + + while (<$fh>) { + chomp; + my $data = $parse_line_fn->(split("\t")); + push(@parsed_data, $data) if $data; + } - $nsnick->{ircnet} = shift; - $nsnick->{nick} = shift; - $nsnick->{pass} = shift; + close($fh); + } - return $nsnick; + return @parsed_data; } -sub new_postcmd { +# file: filename to be written, is created accessable only by the user +# data_ref: array ref of data entries +# serialize_fn: receives a data reference and should return an array or tuples +# for that data that will be serialized into one line +sub save_file { + + my ($file, $data_ref, $serialize_fn) = @_; + + create_private_file($file) unless -e $file; + + open(my $fh, ">", $file) or die "Can't create $file. Reason: $!"; - my $nspostcmd = {}; + for my $data (@$data_ref) { + print($fh join("\t", $serialize_fn->($data)), "\n"); + } + + close($fh); +} - $nspostcmd->{ircnet} = shift; - $nspostcmd->{nick} = shift; - $nspostcmd->{postcmd} = shift; +sub create_private_file { - return $nspostcmd; + my ($file) = @_; + my $umask = umask 0077; # save old umask + open(my $fh, ">", $file) or die "Can't create $file. Reason: $!"; + close($fh); + umask $umask; } sub add_nickname { - + my ($network, $nickname, $password) = split(" ", $_[0], 3); my ($correct_network, $correct_nickname); @@ -301,7 +288,7 @@ sub add_nickname { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_nickname'); return; } - + if ($network) { if (!already_loaded_net($network)) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_net', $network); @@ -310,7 +297,7 @@ sub add_nickname { $correct_network = 1; } } - + if ($nickname) { if (already_loaded_nick($nickname, $network)) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_loaded_nick', $nickname, $network); @@ -319,17 +306,17 @@ sub add_nickname { $correct_nickname = 1; } } - + if ($correct_network && $correct_nickname) { push(@nickservauth, new_nickserv_nick($network, $nickname, $password)); - save_nickservnick("$irssidir/$nickservauth_file"); - + save_nickservnick(); + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_nickname', $network, $nickname); } } sub add_postcmd { - + my ($network, $nickname, $postcmd) = split(" ", $_[0], 3); my ($correct_network, $correct_nickname); @@ -337,7 +324,7 @@ sub add_postcmd { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_postcmd'); return; } - + if ($network) { if (!already_loaded_net($network)) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_net', $network); @@ -346,7 +333,7 @@ sub add_postcmd { $correct_network = 1; } } - + if ($nickname) { if (!already_loaded_nick($nickname, $network)) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_not_loaded_nick', $nickname, $network); @@ -355,28 +342,28 @@ sub add_postcmd { $correct_nickname = 1; } } - + if ($correct_network && $correct_nickname) { push(@nickservpostcmd, new_postcmd($network, $nickname, $postcmd)); - save_nickservpostcmd("$irssidir/$nickservpostcmd_file"); - + save_nickservpostcmd(); + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_postcmd', $network, $nickname, $postcmd); } } sub add_network { - + my ($network, $hostname) = split(" ", $_[0], 2); my ($correct_net, $correct_host); - + if ($network eq "" || $hostname eq "") { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_usage_network'); return; } - + if ($network) { my ($ircnet) = Irssi::chatnet_find($network); - + if (!$ircnet) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_no_net', $network); return; @@ -387,7 +374,7 @@ sub add_network { $correct_net = 1; } } - + if ($hostname) { if ($hostname !~ /^[.+a-zA-Z0-9_-]{1,}@[.+a-zA-Z0-9_-]{1,}$/) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_wrong_host', $hostname); @@ -396,68 +383,44 @@ sub add_network { $correct_host = 1; } } - + if ($correct_net && $correct_host) { push(@nickservnet, new_nickserv_network($network, $hostname)); - save_nickservnet("$irssidir/$nickservnet_file"); - + save_nickservnet(); + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'saved_network', $network, $hostname); } } sub already_loaded_net { - my ($ircnet) = @_; - my $loaded = check_loaded_net($ircnet); - - if ($loaded > -1) { - return 1; - } - - return 0; -} - -sub check_loaded_net { - my ($ircnet) = @_; $ircnet = lc($ircnet); - for (my $loaded = 0; $loaded < @nickservnet; ++$loaded) { - return $loaded if (lc($nickservnet[$loaded]->{name}) eq $ircnet); + for my $loaded (@nickservnet) { + return 1 if (lc($loaded->{name}) eq $ircnet); } - - return -1; + + return 0; } sub already_loaded_nick { - my ($nickname, $network) = @_; - my $loaded = check_loaded_nick($nickname, $network); - - if ($loaded > -1) { - return 1; - } - - return 0 -} -sub check_loaded_nick { - - my ($nickname, $network) = @_; - $nickname = lc($nickname); $network = lc($network); - - for (my $loaded = 0; $loaded < @nickservauth; ++$loaded) { - return $loaded if (lc($nickservauth[$loaded]->{nick}) eq $nickname && lc ($nickservauth[$loaded]->{ircnet}) eq $network); + + for my $loaded (@nickservauth) { + return 1 if (lc($loaded->{nick}) eq $nickname && + lc($loaded->{ircnet}) eq $network); } - - return -1; + + return 0; } sub list_net { - + if (@nickservnet == 0) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'network_empty'); } else { @@ -470,7 +433,7 @@ sub list_net { } sub list_nick { - + if (@nickservauth == 0) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickname_empty'); } else { @@ -483,7 +446,7 @@ sub list_nick { } sub list_postcmd { - + if (@nickservpostcmd == 0) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'postcmd_empty'); } else { @@ -496,7 +459,7 @@ sub list_postcmd { } sub nickserv_notice { - + my ($server, $data, $nick, $address) = @_; my ($target, $text) = $data =~ /^(\S*)\s:(.*)/; @@ -505,14 +468,14 @@ sub nickserv_notice { if ($text =~ /^(?:If this is your nickname, type|Please identify via|Type) \/msg NickServ (?i:identify)/ || $text =~ /^This nickname is registered and protected. If it is your/ || $text =~ /This nickname is registered\. Please choose a different nickname/) { my $password = get_password($server->{tag}, $server->{nick}); - + if ($password == -1) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_request', $server->{tag}); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_nick', $server->{nick}, $server->{tag}); Irssi::signal_stop(); return; } - + Irssi::signal_stop(); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'password_request', $server->{tag}); $server->command("^MSG NickServ IDENTIFY $password"); @@ -564,34 +527,38 @@ sub nickserv_notice { } sub run_postcmds { - my ($server, $tag, $nick) = @_; - return unless scalar @nickservpostcmd; # there's nothing to save + my ($server, $ircnet, $nick) = @_; + return if @nickservpostcmd == 0; for my $cmd (@nickservpostcmd) { - if ($tag eq $cmd->{ircnet} && $nick eq $cmd->{nick} && $cmd->{postcmd}) { + if ($ircnet eq $cmd->{ircnet} && + $nick eq $cmd->{nick} && + $cmd->{postcmd}) { $server->command($cmd->{postcmd}); } } } sub is_nickserv { - + my ($net, $host) = @_; for (my $loaded = 0; $loaded < @nickservnet; ++$loaded) { - return 1 if (lc($nickservnet[$loaded]->{name}) eq lc($net) && lc($nickservnet[$loaded]->{host}) eq lc($host)); + return 1 if (lc($nickservnet[$loaded]->{name}) eq lc($net) && + lc($nickservnet[$loaded]->{host}) eq lc($host)); } return 0; } sub get_password { - + my ($ircnet, $nick) = @_; - + for (my $loaded = 0; $loaded < @nickservauth; ++$loaded) { - return $nickservauth[$loaded]->{pass} if (lc($nickservauth[$loaded]->{ircnet}) eq lc($ircnet) && lc($nickservauth[$loaded]->{nick}) eq lc($nick)); + return $nickservauth[$loaded]->{pass} if (lc($nickservauth[$loaded]->{ircnet}) eq lc($ircnet) && + lc($nickservauth[$loaded]->{nick}) eq lc($nick)); } - + return -1; } @@ -610,47 +577,54 @@ sub del_network { $ircnetindex = 1; } } - + if ($ircnetindex) { @nickservnet = grep {lc($_->{name}) ne lc($ircnet)} @nickservnet; @nickservauth = grep {lc($_->{ircnet}) ne lc($ircnet)} @nickservauth; + @nickservpostcmd = grep {lc($_->{ircnet}) ne lc($ircnet)} @nickservpostcmd; Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled', $ircnet); - save_nickservnet("$irssidir/$nickservnet_file"); - save_nickservnick("$irssidir/$nickservauth_file"); + save_nickservnet(); + save_nickservnick(); + save_nickservpostcmd(); } else { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound', $ircnet); } } sub del_nickname { - + my ($ircnet, $nickname) = split(" ", $_[0], 2); my ($nickindex); - + if ($ircnet eq "" || $nickname eq "") { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delnickusage'); return; } for (my $index = 0; $index < @nickservauth; ++$index) { - if (lc($nickservauth[$index]->{ircnet}) eq lc($ircnet) && lc($nickservauth[$index]->{nick}) eq lc($nickname)) { + if (lc($nickservauth[$index]->{ircnet}) eq lc($ircnet) && + lc($nickservauth[$index]->{nick}) eq lc($nickname)) { $nickindex = splice(@nickservauth, $index, 1); - } + } } if ($nickindex) { + @nickservpostcmd = grep {lc($_->{ircnet}) ne lc($ircnet) || + lc($_->{nick}) ne lc($nickname)} + @nickservpostcmd; + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled_nick', $ircnet, $nickname); - save_nickservnick("$irssidir/$nickservauth_file"); + save_nickservnick(); + save_nickservpostcmd(); } else { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_nick', $ircnet, $nickname); } } sub del_postcmd { - + my ($ircnet, $nickname) = split(" ", $_[0], 2); - my ($nickindex); - + if ($ircnet eq "" || $nickname eq "") { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delpostcmdusage'); return; @@ -662,17 +636,17 @@ sub del_postcmd { if ($size_before != $size_after) { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_delled_postcmd', $ircnet, $nickname); - save_nickservpostcmd("$irssidir/$nickservpostcmd_file"); + save_nickservpostcmd(); } else { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_nfound_postcmd', $ircnet, $nickname); } } sub nickserv_runsub { - + my ($data, $server, $item) = @_; $data =~ s/\s+$//g; - + if ($data) { Irssi::command_runsub('nickserv', $data, $server, $item); } else { @@ -680,42 +654,31 @@ sub nickserv_runsub { } } -load_nickservnet("$irssidir/$nickservnet_file"); -load_nickservnick("$irssidir/$nickservauth_file"); -load_nickservpostcmd("$irssidir/$nickservpostcmd_file"); +load_nickservnet($nickservnet_file); +load_nickservnick($nickservauth_file); +load_nickservpostcmd($nickservpostcmd_file); Irssi::command_bind('nickserv', 'nickserv_runsub'); Irssi::command_bind('ns', 'nickserv_runsub'); -Irssi::command_bind('nickserv addnet', 'add_network'); -Irssi::command_bind('ns addnet', 'add_network'); - -Irssi::command_bind('nickserv addnick', 'add_nickname'); -Irssi::command_bind('ns addnick', 'add_nickname'); - -Irssi::command_bind('nickserv addpostcmd', 'add_postcmd'); -Irssi::command_bind('ns addpostcmd', 'add_postcmd'); - -Irssi::command_bind('nickserv listnet', 'list_net'); -Irssi::command_bind('ns listnet', 'list_net'); - -Irssi::command_bind('nickserv listnick', 'list_nick'); -Irssi::command_bind('ns listnick', 'list_nick'); - -Irssi::command_bind('nickserv listpostcmd', 'list_postcmd'); -Irssi::command_bind('ns listpostcmd', 'list_postcmd'); - -Irssi::command_bind('nickserv delnet', 'del_network'); -Irssi::command_bind('ns delnet', 'del_network'); - -Irssi::command_bind('nickserv delnick', 'del_nickname'); -Irssi::command_bind('ns delnick', 'del_nickname'); - -Irssi::command_bind('nickserv delpostcmd', 'del_postcmd'); -Irssi::command_bind('ns delpostcmd', 'del_postcmd'); - Irssi::command_bind('nickserv help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) }); Irssi::command_bind('ns help' => sub { Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_help', $help) }); +# "command binding" -> "function name" mapping +for my $cmd (( + ['addnet' => 'add_network'], + ['addnick' => 'add_nickname'], + ['addpostcmd' => 'add_postcmd'], + ['listnet' => 'list_net'], + ['listnick' => 'list_nick'], + ['listpostcmd' => 'list_postcmd'], + ['delnet' => 'del_network'], + ['delnick' => 'del_nickname'], + ['delpostcmd' => 'del_postcmd'], +)) { + Irssi::command_bind("nickserv $cmd->[0]", $cmd->[1]); + Irssi::command_bind("ns $cmd->[0]", $cmd->[1]); +} + Irssi::signal_add('event notice', 'nickserv_notice'); Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'nickserv_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors}); -- cgit v1.2.3