1# vim:syntax=perl 2# vim:tabstop=4 3# vim:shiftwidth=4 4# vim:foldmethod=marker 5# vim:foldenable 6# vim:enc=utf-8 7######################################################################################################## 8## WARNING!! BAD ENGLISH BELOW :P 9## 10## This script is designed for those who have been using muh irc bouncer. 11## Basicly this script just monitors the proxy module and if new client 12## connects it sets you automatically back from away state and when client 13## disconnects it sets you automatically away if you arent allready away. 14## 15## Other hand if you dont use irssi-proxy you still have a good reason to 16## use this if you want to forward messages that come to you while 17## you are away to email box. 18## This is usefull for forwarding messages to an SMS-gateway ;) 19## 20## btw.. if you find any bugs or have any ideas for development of this 21## script dont hesitate to send msg to BCOW@IrcNET 22## or send email to anttip@n0-life.com 23## 24#### Version history: 25# 0.1 26# * basic functionality 27# 0.2b 28# * a patch from Wulf that gives a user ability to change the autoaway reason. 29# * Added away_level parameter that gives you ability to control how many 30# clients there can be connected to the irssi_proxy module before you are 31# set away. 32# * You arent set away when disconnecting from the irssi_proxy if you already 33# are away. This means that your current away reason isn't changed. 34# * Sends cumulated away messages back to the client when it connects to the 35# irssi_proxy module. 36# 0.2c 37# * Fixes bug where cummulated messages weren't sent. 38# * Code cleanup. 39# * Text wrapping to standart 80x24 text console. 40# * Added debug mode. 41# * Added script modes. 42# * Got rid of crappy irssi setings system. 43# * New logging expansion capability, either time or line based. 44# 0.2d 45# * Micro fix to get back only when needed 46# 0.2e 47# * Changed default values for $config{script_mode} and $config{emailto} for IRC-only and a non-existing placeholder respectively. 48#### To come / planned / wanted: 49# * Make expansion system log several channels at once. 50# * Make this script server based. 51######################################################################################################## 52 53use strict; 54use warnings; 55 56# irssi imports 57use Irssi; 58use Irssi::Irc; 59use vars qw($VERSION %IRSSI %config); 60 61$VERSION = "0.2e"; 62%IRSSI = ( 63 authors => "BCOW", 64 contact => "anttip\@n0-life.com", 65 name => "awayproxy", 66 description => "Sets nick away when client discconects from the " 67 . "irssi-proxy. If away gathers messages targeted to nick and forwards " 68 . "them to an email address.", 69 license => "GPLv2", 70 url => "http://www.n0-life.com", 71); 72 73# After how much seconds we can check if there are any messages to send? 74$config{check_interval} = 45; 75# this setting controls that when this amout of clients are connected to the 76# proxy module script sets you away. If you set this to 0 you are set away when 77# no clients are connected to the proxy module. If you set this to lets say 5 78# then you will be set away allways when the amount of clients connected to the 79# proxy module is 5 or under. 80$config{away_level} = 0; 81# Controls expansion mode. This mode records pub msgs that come after one with 82# your nick in it. you can use line counting or time counting. 83# 0 - off 84# line - line counting 85# time - time counting 86$config{expansion_mode} = 'time'; 87# How many lines include after start line? 88$config{expansion_lines} = 12; 89# After how many seconds stop gathering msgs? 90$config{expansion_timeout} = 90; 91# script operation mode: 92# 0 - to send messages both to email and when you get back to proxy 93# 1 - only email 94# 2 - only irc 95# 3 - off 96$config{script_mode} = 2; 97# email address where to send the email 98$config{emailto} = 'recipient@domain.tld'; 99# sendmail location 100$config{sendmail} = '/usr/sbin/sendmail'; 101# who is the sender of the email 102$config{emailfrom} = 'sender@domain.tld'; 103# Subject of email 104$config{emailsubject} = '[irssi-proxy]'; 105# and the awayreason setting (Thanx Wulf) 106$config{awayreason} = 'Auto-away because client has disconnected from proxy.'; 107# Debugging mode 108$config{debug} = 0; 109 110# -- Don't change anything below this line if you don't know Perl. -- 111# number of clients connected 112$config{clientcount} = 0; 113# number of lines recorded 114$config{expansion_lines_count} = 0; 115 116$config{expansion_started} = 0; 117# the small list and archive list 118$config{awaymsglist} = []; 119$config{awaymsglist2} = []; 120 121if ( $config{script_mode} == 0 || $config{script_mode} == 1 ) { # {{{ 122 # timeouts for check loop 123 debug('Timer on, timeout: ' . $config{check_interval}); 124 Irssi::timeout_add($config{check_interval} * 1000, 'msgsend_check', ''); 125} # }}} 126 127sub debug { # {{{ 128 if ($config{debug}) { 129 my $text = shift; 130 my $caller = caller; 131 Irssi::print('From ' . $caller . ":\n" . $text); 132 } 133} # }}} 134sub msgsend_check { # {{{ 135 # If there are any messages to send 136 my $count = @{$config{awaymsglist}}; 137 debug("Checking for messages: $count"); 138 # Check if we didn't grep msgs right now 139 if ($count > 0 && !$config{expansion_started}) { 140 # Concentate messages into one text. 141 my $text = join "\n", @{$config{awaymsglist}}; 142 # Then empty list. 143 $config{awaymsglist} = []; 144 # Finally send email 145 debug("Concentated msgs: $text"); 146 send_mail($text); 147 } 148} # }}} 149sub send_mail { # {{{ 150 my $text = shift; 151 debug("Sending mail"); 152 open MAIL, q{|-}, $config{sendmail} . " -t"; 153 print MAIL "To: $config{emailto}\n"; 154 print MAIL "From: $config{emailfrom}\n"; 155 print MAIL "Subject: $config{emailsubject}\n"; 156 print MAIL "$text"; 157 close MAIL; 158} # }}} 159sub client_connect { # {{{ 160 my (@servers) = Irssi::servers; 161 162 $config{clientcount}++; 163 debug("Client connected, current script mode: $config{script_mode}"); 164 165 # setback 166 foreach my $server (@servers) { 167 # if you're away on that server send yourself back 168 if ($server->{usermode_away} == 1) { 169 $server->send_raw('AWAY :'); 170 # and then send the current contents of archive list as notify's to 171 # your self ;) 172 # .. weird huh? :) 173 # This sends all the away messages to ALL the servers where you are 174 # connected... this is somewhat weird i know 175 # but if someone wants to make a patch to this i would really 176 # appreciate it. 177 if ($config{script_mode} == 0 || $config{script_mode} == 2) { 178 debug('Sending notices'); 179 $server->send_raw('NOTICE ' . $server->{nick} . " :$_") 180 for @{$config{awaymsglist2}}; 181 } 182 } 183 } 184 # and "clear" the awaymessage list 185 $config{awaymsglist2} = [] 186 if $config{script_mode} == 0 || $config{script_mode} == 2; 187} # }}} 188sub client_disconnect { # {{{ 189 my (@servers) = Irssi::servers; 190 debug('Client Disconnectted'); 191 192 $config{clientcount}-- unless $config{clientcount} == 0; 193 194 # setaway 195 if ($config{clientcount} <= $config{away_level}) { 196 # ok.. we have the away_level of clients connected or less. 197 foreach my $server (@servers) { 198 if ($server->{usermode_away} == "0") { 199 # we are not away on this server allready.. set the autoaway 200 # reason 201 $server->send_raw( 202 'AWAY :' . $config{awayreason} 203 ); 204 } 205 } 206 } 207} # }}} 208sub msg_pub { # {{{ 209 my ($server, $data, $nick, $mask, $target) = @_; 210 211 sub push_into_archive { # {{{ 212 my ($nick, $mask, $target, $data) = @_; 213 # simple list that is emptied on the email run 214 push @{$config{awaymsglist}}, "<$nick!$mask\@$target> $data" 215 if $config{script_mode} == 0 || $config{script_mode} == 1; 216 # archive list that is emptied only on the client connect run 217 push @{$config{awaymsglist2}}, "<$nick!$mask\@$target> $data" 218 if $config{script_mode} == 0 || $config{script_mode} == 2; 219 } # }}} 220 221 if ($config{expansion_started}) { 222 if ($config{expansion_mode} eq 'line') { 223 if ($config{expansion_lines_count} <= $config{expansion_lines} -1) { 224 if ($config{expansion_chan} eq $target) { 225 debug("In effect from line expansion, pushing on. Cnt: " 226 . $config{expansion_lines_count}); 227 push_into_archive($nick, $mask, $target, $data); 228 $config{expansion_lines_count}++; 229 } 230 } 231 else { 232 debug("Line counter reached max, stopping expansion"); 233 $config{expansion_lines_count} = 0; 234 $config{expansion_started} = 0; 235 $config{expansion_chan} = ''; 236 } 237 } 238 elsif ($config{expansion_mode} eq 'time') { 239 if ($config{expansion_chan} eq $target) { 240 debug("Time expansion in effect, pushing on."); 241 push_into_archive($nick, $mask, $target, $data); 242 } 243 } 244 } 245 elsif ($server->{usermode_away} == "1" && $data =~ /$server->{nick}/i) { 246 debug("Got pub msg with my name"); 247 push_into_archive($nick, $mask, $target, $data); 248 if ($config{expansion_mode}) { 249 debug("Starting expansion in mode: " . $config{expansion_mode}); 250 $config{expansion_started} = 1; 251 $config{expansion_chan} = $target; 252 $config{expansion_time_out} = Irssi::timeout_add( 253 $config{expansion_timeout} * 1000, 'expansion_stop', '' 254 ) if $config{expansion_mode} eq 'time'; 255 } 256 } 257} # }}} 258sub expansion_stop { # {{{ 259 debug("Stopping expansion from timer"); 260 $config{expansion_started} = 0; 261 $config{expansion_chan} = ''; 262} # }}} 263sub msg_pri { # {{{ 264 my ($server, $data, $nick, $address) = @_; 265 if ($server->{usermode_away} == "1") { 266 debug("Got priv msg"); 267 # simple list that is emptied on the email run 268 push @{$config{awaymsglist}}, "<$nick!$address> $data" 269 if $config{script_mode} == 0 || $config{script_mode} == 1; 270 # archive list that is emptied only on the client connect run 271 push @{$config{awaymsglist2}}, "<$nick!$address> $data" 272 if $config{script_mode} == 0 || $config{script_mode} == 2; 273 } 274} # }}} 275 276Irssi::signal_add_last('proxy client connected', 'client_connect'); 277Irssi::signal_add_last('proxy client disconnected', 'client_disconnect'); 278Irssi::signal_add_last('message public', 'msg_pub'); 279Irssi::signal_add_last('message private', 'msg_pri'); 280