1use Irssi; 2use strict; 3use FileHandle; 4 5use vars qw($VERSION %IRSSI); 6 7$VERSION = "0.9.8.2"; 8%IRSSI = ( 9 authors => 'Andreas \'ads\' Scherbaum <ads@wars-nicht.de>', 10 name => 'screen_away', 11 description => 'set (un)away, if screen is attached/detached', 12 license => 'GPL v2', 13 url => 'none', 14); 15 16# screen_away irssi module 17# 18# written by Andreas 'ads' Scherbaum <ads@ufp.de> 19# 20# changes: 21# 20.12.2014 fix the bug when screenname is changed during the session 22# 07.02.2004 fix error with away mode 23# thanks to Michael Schiansky for reporting and fixing this one 24# 07.08.2004 new function for changing nick on away 25# 24.08.2004 fixing bug where the away nick was not storedcorrectly 26# thanks for Harald Wurpts for help debugging this one 27# 17.09.2004 rewrote init part to use $ENV{'STY'} 28# 05.12.2004 add patch for remember away state 29# thanks to Jilles Tjoelker <jilles@stack.nl> 30# change "chatnet" to "tag" 31# 18.05.2007 fix '-one' for SILC networks 32# 33# 34# usage: 35# 36# put this script into your autorun directory and/or load it with 37# /SCRIPT LOAD <name> 38# 39# there are 5 settings available: 40# 41# /set screen_away_active ON/OFF/TOGGLE 42# /set screen_away_repeat <integer> 43# /set screen_away_message <string> 44# /set screen_away_window <string> 45# /set screen_away_nick <string> 46# 47# active means, that you will be only set away/unaway, if this 48# flag is set, default is ON 49# repeat is the number of seconds, after the script will check the 50# screen status again, default is 5 seconds 51# message is the away message sent to the server, default: not here ... 52# window is a window number or name, if set, the script will switch 53# to this window, if it sets you away, default is '1' 54# nick is the new nick, if the script goes away 55# will only be used it not empty 56# 57# normal you should be able to rename the script to something other 58# than 'screen_away' (as example, if you dont like the name) by simple 59# changing the 'name' parameter in the %IRSSI hash at the top of this script 60 61 62# variables 63my $timer_name = undef; 64my $away_status = 0; 65my %old_nicks = (); 66my %away = (); 67 68# Register formats 69Irssi::theme_register( 70[ 71 'screen_away_crap', 72 '{line_start}{hilight ' . $IRSSI{'name'} . ':} $0' 73]); 74 75# if we are running 76my $screen_away_used = 0; 77 78# try to find out, if we are running in a screen 79# (see, if $ENV{STY} is set 80if (!defined($ENV{STY})) { 81 # just return, we will never be called again 82 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 83 "could not open status file for parent process (pid: " . getppid() . "): $!"); 84 return; 85} 86 87my ($socket_pid, $socket_name, $socket_path); 88 89# search for socket 90# normal we could search the socket file, ... if we know the path 91# but so we have to call one time the screen executable 92# disable locale 93# the quotes around C force perl 5.005_03 to use the shell 94# thanks to Jilles Tjoelker <jilles@stack.nl> for pointing this out 95my $socket = `LC_ALL="C" screen -ls`; 96 97 98 99my $running_in_screen = 0; 100# locale doesnt seems to be an problem (yet) 101if ($socket !~ /^No Sockets found/s) { 102 # ok, should have only one socket 103 # $STY won't change if sessionname is changed during session 104 # therefore first find the pid and use that to find the actual sessionname 105 $socket_pid = substr($ENV{'STY'}, 0, index($ENV{'STY'}, '.')); 106 $socket_path = $socket; 107 $socket_path =~ s/^.*\d+ Sockets? in ([^\n]+)\..*$/$1/s; 108 $socket_name = $socket; 109 $socket_name =~ s/^.+?($socket_pid\.\S+).+$/$1/s; 110 if (length($socket_path) != length($socket)) { 111 # only activate, if string length is different 112 # (to make sure, we really got a dir name) 113 $screen_away_used = 1; 114 } else { 115 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 116 "error reading screen informations from:"); 117 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 118 "$socket"); 119 return; 120 } 121} 122 123# last check 124if ($screen_away_used == 0) { 125 # we will never be called again 126 return; 127} 128 129# build complete socket name 130$socket = $socket_path . "/" . $socket_name; 131 132# register config variables 133Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1); 134Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5); 135Irssi::settings_add_str('misc', $IRSSI{'name'} . '_message', "not here ..."); 136Irssi::settings_add_str('misc', $IRSSI{'name'} . '_window', "1"); 137Irssi::settings_add_str('misc', $IRSSI{'name'} . '_nick', ""); 138 139# init process 140screen_away(); 141 142# screen_away() 143# 144# check, set or reset the away status 145# 146# parameter: 147# none 148# return: 149# 0 (OK) 150sub screen_away { 151 my ($away, @screen, $screen); 152 153 # only run, if activated 154 if (Irssi::settings_get_bool($IRSSI{'name'} . '_active') == 1) { 155 if ($away_status == 0) { 156 # display init message at first time 157 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 158 "activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds)"); 159 } 160 # get actual screen status 161 my @screen = stat($socket); 162 # 00100 is the mode for "user has execute permissions", see stat.h 163 if (($screen[2] & 00100) == 0) { 164 # no execute permissions, Detached 165 $away = 1; 166 } else { 167 # execute permissions, Attached 168 $away = 2; 169 } 170 171 # check if status has changed 172 if ($away == 1 and $away_status != 1) { 173 # set away 174 if (length(Irssi::settings_get_str($IRSSI{'name'} . '_window')) > 0) { 175 # if length of window is greater then 0, make this window active 176 Irssi::command('window goto ' . Irssi::settings_get_str($IRSSI{'name'} . '_window')); 177 } 178 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 179 "Set away"); 180 my $message = Irssi::settings_get_str($IRSSI{'name'} . '_message'); 181 if (length($message) == 0) { 182 # we have to set a message or we wouldnt go away 183 $message = "not here ..."; 184 } 185 my ($server); 186 foreach $server (Irssi::servers()) { 187 if (!$server->{usermode_away}) { 188 # user isnt yet away 189 $away{$server->{'tag'}} = 0; 190 $server->command("AWAY " . (($server->{chat_type} ne 'SILC') ? "-one " : "") . "$message") if (!$server->{usermode_away}); 191 if (length(Irssi::settings_get_str($IRSSI{'name'} . '_nick')) > 0) { 192 # only change, if actual nick isnt already the away nick 193 if (Irssi::settings_get_str($IRSSI{'name'} . '_nick') ne $server->{nick}) { 194 # keep old nick 195 $old_nicks{$server->{'tag'}} = $server->{nick}; 196 # set new nick 197 $server->command("NICK " . Irssi::settings_get_str($IRSSI{'name'} . '_nick')); 198 } 199 } 200 } else { 201 # user is already away, remember this 202 $away{$server->{'tag'}} = 1; 203 } 204 } 205 $away_status = $away; 206 } elsif ($away == 2 and $away_status != 2) { 207 # unset away 208 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap', 209 "Reset away"); 210 my ($server); 211 foreach $server (Irssi::servers()) { 212 if ($away{$server->{'tag'}} == 1) { 213 # user was already away, dont reset away 214 $away{$server->{'tag'}} = 0; 215 next; 216 } 217 $server->command("AWAY" . (($server->{chat_type} ne 'SILC') ? " -one" : "")) if ($server->{usermode_away}); 218 if (defined($old_nicks{$server->{'tag'}}) and length($old_nicks{$server->{'tag'}}) > 0) { 219 # set old nick 220 $server->command("NICK " . $old_nicks{$server->{'tag'}}); 221 $old_nicks{$server->{'tag'}} = ""; 222 } 223 } 224 $away_status = $away; 225 } 226 } 227 # but everytimes install a new timer 228 register_screen_away_timer(); 229 return 0; 230} 231 232# register_screen_away_timer() 233# 234# remove old timer and install a new one 235# 236# parameter: 237# none 238# return: 239# none 240sub register_screen_away_timer { 241 if (defined($timer_name)) { 242 # remove old timer, if defined 243 Irssi::timeout_remove($timer_name); 244 } 245 # add new timer with new timeout (maybe the timeout has been changed) 246 $timer_name = Irssi::timeout_add(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'screen_away', ''); 247} 248 249