#!/usr/bin/perl -U -- # -*-Per ############################################################################## # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ############################################################################## # NAME # timeout # # SYNOPSIS # timeout -help # timeout -c console_timeout # timeout -t network_timeout # timeout -p ppp_timeout # # OPTIONS # -help print this help # -c console_timeout set the console timeout (0-XX minutes) # -t network_timeout set the network timeout (0-XX minutes) # -p ppp_timeout set the ppp timeout (0-XX minutes) # --query [c|t|p] query an individual value # # DESCRIPTION # # ############################################################################## # REVISION HISTORY # # $Log: timeout,v $ # Revision 1.3 2003/05/01 18:42:42 billf # *** empty log message *** # # Revision 1.2 2003/03/25 14:43:26 billf # changed 'telnet' to network, since we don't want telnet to be used # # Revision 1.1.1.1 2003/03/17 16:14:09 billf # Initial import # # ############################################################################## $debug = 0 ; # change to 1 to enable debugging messages $VERSION = "1.09" ; $MAX_TIMEOUT = 30 ; $LINE_LIMIT = 1000 ; ## help fight against infinite loops: i'm just paranoid # # Includes # require "newgetopt.pl"; # # Setup program name and revision vars. # $program = $0 ; # get program name # now do $program = basename $program $program =~ s:^[/]*([\.\w\-]+[/])*([\.\w\-]+)$:$2: ; $rev = '$Revision: 1.3 $ ' ; # get RCS Revision level $rev =~ s/[\:\$\s]*//g ; $rev =~ s/Revision//g ; # reduced to number $lockFile = "/var/tmp/timeout.lock" ; # inactivity timeout vars $network_timeout = ""; $console_timeout = ""; $ppp_timeout = ""; $network_timeout_display = ""; $console_timeout_display = ""; $ppp_timeout_display = ""; $console = "ttyS0" ; # parsing vars $ppp_file_name = "" ; # passed to the update_ppp_options_file so that both pap and chap files can be updated $timeouts_file_exists = 1; # if timeouts file doesn't exist, create it $debugParseConf = 0; $update_timeout = 0; $queryOnly = 0; $valueToQuery = ""; # # Program main # print STDERR "$program: calling &NGetOpt ...\n" if $debug ; &NGetOpt( ("help", "c=s", "t=s", "p=s", "d", "v", "version", "query=s") ) or exit(1); print STDERR "$program: ... return from &NGetOpt\n" if $debug ; if ($opt_help) { print STDERR "$program: calling usage ...\n" if $debug ; &usage; print STDERR "$program: ... return from usage\n" if $debug ; exit(1); } if ($opt_version or $opt_v) { print "timeout V$VERSION\n" ; exit(1); } if ($opt_d) { # Add code to process -p switch # if ($debug) { print "Got -d $opt_d\n" if $debug ; $debugParseConf = 1; } } if (!($opt_c eq "")) { # Add code to process -c switch # if ($opt_c > $MAX_TIMEOUT) { print STDERR "$opt_c is greater than the max timeout ($MAX_TIMEOUT).\n"; exit 1; } $update_timeout = 1; if ($opt_c eq "disabled"){ $console_timeout = "0"; } else { $console_timeout = $opt_c; } print "Got -c $opt_c\n" if $debugParseConf ; } if (!($opt_t eq "")) { # Add code to process -t switch # if ($opt_t > $MAX_TIMEOUT) { print STDERR "$opt_t is greater than the max timeout ($MAX_TIMEOUT).\n"; exit 1; } $update_timeout = 1; if ($opt_t eq "disabled") { $network_timeout = "0"; } else { $network_timeout = $opt_t; } print "Got -t $opt_t\n" if $debugParseConf ; } if (!($opt_p eq "")) { # Add code to process -p switch # if ($opt_p > $MAX_TIMEOUT) { print STDERR "$opt_p is greater than the max timeout of $MAX_TIMEOUT.\n"; exit 1; } $update_timeout = 1; if ($opt_p eq "disabled") { $ppp_timeout = "0"; } else { $ppp_timeout = $opt_p; } print "Got -p $opt_p\n" if $debugParseConf ; } if (!($opt_query eq "")) { $update_timeout = 0; ## force no updates even if someone specifies on commandline $valueToQuery = $opt_query; $queryOnly = 1; $valueToQuery = "c" if ($opt_query eq "-c"); $valueToQuery = "t" if ($opt_query eq "-t"); $valueToQuery = "p" if ($opt_query eq "-p"); die "Invalid value to query: $opt_query\n" if (!($valueToQuery eq "c" or $valueToQuery eq "t" or $valueToQuery eq "p")); } ## ## no parameters to change timeouts, lets display current settings only ## if (!$update_timeout) { &parse_timeouts_file(); &parse_ppp_options_file(); $console_timeout_display = $console_timeout; $console_timeout_display = "disabled" if ($console_timeout eq "" or $console_timeout == 0); print "console inactivity timeout = " if (!$queryOnly); print "$console_timeout_display\n" if (!$queryOnly or $valueToQuery eq "c"); $network_timeout_display = $network_timeout; $network_timeout_display = "disabled" if ($network_timeout eq "" or $network_timeout == 0); print "network/ssh inactivity timeout = " if (!$queryOnly); print "$network_timeout_display\n" if (!$queryOnly or $valueToQuery eq "t"); $ppp_timeout_display = $ppp_timeout; $ppp_timeout_display = "disabled" if ($ppp_timeout eq "" or $ppp_timeout == 0); print "ppp inactivity timeout = " if (!$queryOnly); print "$ppp_timeout_display\n" if (!$queryOnly or $valueToQuery eq "p"); } else { # # Verify via the lockFile that another instance is not running. # if ( open (LOCKFILE, "<$lockFile") ) { # Oops, anther instance is running... $pid = ; chomp $pid ; close (LOCKFILE) ; die "$program - Someone is already running $program with PID=$pid\n" . "You must wait for them to finish.\n\n" . "It is possilbe that a " . "previous instance has failed to complete properly\n" . "and left its lockfile in place. In that case remove the " . "file:\n$lockFile\n" ; } open (LOCKFILE, ">$lockFile") or die "$program - open $lockFile: $!\n" ; print LOCKFILE "$$\n" ; close (LOCKFILE) or die "$program - close $lockFile: $!\n" ; # if for some reason timeout doesn't exist then create a blank one $fileName = "/etc/timeouts" ; if (!(-e $fileName) ) { print qq(\nCreating $fileName for timeoutd\n) if $debugParseConf ; open (WRCONFFILE, ">$fileName") or die "open $fileName: $!\n" ; print WRCONFFILE "# created by timeout\n" ; close (WRCONFFILE) ; chmod (0644, $fileName) ; # 644 hex } &update_timeouts_file() if (($console_timeout =~ m|[\s]*[\d]{1,5}|) or ($network_timeout =~ m|[\s]*[\d]{1,5}|)); # update both pap or chap ppp/options files $ppp_file_name = "/etc/ppp/options.pap" ; &update_ppp_options_file() if (($ppp_timeout =~ m|[\s]*[\d]{1,5}|) and !($ppp_timeout eq "")); $ppp_file_name = "/etc/ppp/options.chap" ; &update_ppp_options_file() if (($ppp_timeout =~ m|[\s]*[\d]{1,5}|) and !($ppp_timeout eq "")); # Remove the lock file unlink ($lockFile) or die "$program - unable to remove lock file $lockFile: $!\n" ; exec ("service timeoutd restart") if !($^O eq "MSWin32") ; } exit 0 ; ## parse the timeouts config file ## look for the console timeout sub parse_timeouts_file { my $lineCount = 0 ; my $fileName = "/etc/timeouts" ; my $value = "" ; open (CONFFILE, "<$fileName") or return 0 ; print "Parsing $fileName ...\n" if $verbose ; CONFSCAN: while () { print STDERR " " . $_ if $debugParseConf ; chomp ; $value = $_ ; my ($days,$device,$user,$group,$inactivity_timeout,$others) = split (/:/, $value); ## skip lines that start "#" or are blank next CONFSCAN if m/^[\s\#]+/ or /^$/; print "DAYS: $days\n" if $debugParseConf ; print "DEVICES: $device\n" if $debugParseConf ; print "USERS: $user\n" if $debugParseConf ; print "GROUPS: $group\n" if $debugParseConf ; print "INACTIVITY TIMEOUT: $inactivity_timeout\n" if $debugParseConf ; print "OTHER: $others\n" if $debugParseConf ; if ( $days eq "Al" and $device eq $console and $user eq "*" and $group eq "*" ) { $console_timeout = $inactivity_timeout ; print "c = $console_timeout\n" if $debugParseConf ; } if ( $days eq "Al" and $device eq "pts/*" and $user eq "*" and $group eq "*" ) { $network_timeout = $inactivity_timeout ; print "t = $network_timeout\n" if $debugParseConf ; } ++$lineCount; if ($lineCount > $LINE_LIMIT) { print STDERR "Line limit exceeded reading file: $fileName (limit=$LINE_LIMIT).\n" ; break; } } print "...Done Parsing $fileName\n" if $debugParseConf ; close (CONFFILE) or die "close $fileName: $!\n" ; return 1; } ## parse the /etc/options config file ## look for the "idle " which is expressed in seconds sub parse_ppp_options_file { my $i = 0 ; my $fileName = "/etc/ppp/options" ; my $value = "" ; open (CONFFILE, "<$fileName") or die "open $fileName: $!\n" ; print "Parsing $fileName ...\n" if $verbose ; CONFSCAN: while () { print STDERR " " . $_ if $debugParseConf ; chomp ; $value = $_ ; print STDERR "line = $value\n" if $debugParseConf; ## skip lines that start "#" or are blank next CONFSCAN if m/^[\s\#]+/ or /^$/; if (m|^[\s]*idle|) { $value =~ /(^[\s]*idle[\s]+)([\d]{1,5})([\s]*$)/; print "timeout = $2 seconds\n" if $debugParseConf; $ppp_timeout = $2 / 60; print "timeout = $ppp_timeout minutes\n" if $debugParseConf; } } print "...Done Parsing $fileName\n" if $debugParseConf ; close (CONFFILE) or die "close $fileName: $!\n" ; return 1; } ## write changes to the specified system config file sub update_timeouts_file { my $lineCount = 0 ; my $paramval = "" ; my $fileName = "/etc/timeouts" ; my $found_console_timeout = 0; my $found_network_timeout = 0; # used for network and ssh my $create_timeouts_file = 0; if (-e $fileName ) { print qq(\nSaving $fileName to $fileName.old\n) if $debugParseConf ; rename ($fileName, $fileName.".old") ; open (CONFFILE, "<$fileName.old") or $timeouts_file_exists = 0; } else { print qq(\nCreating $fileName\n) if $debugParseConf ; $create_timeouts_file = 1; } open (WRCONFFILE, ">$fileName") or die "open $fileName: $!\n" ; print "Updating $fileName ...\n" if $verbose ; if (! $create_timeouts_file) { WRCONFSCAN: while () { print STDERR $_ if $debugParseConf ; # for each line of the file, see if we can match anything we are # looking for. $value = $_ ; ++$lineCount; if ($lineCount > $LINE_LIMIT) { print STDERR "Line limit exceeded reading file: $fileName (limit=$LINE_LIMIT).\n" ; break; } my ($days,$device,$user,$group,$inactivity_timeout,$others) = split (/:/, $value); ## skip lines that start "#" or are blank if ( m/^[\s\#]+/ or /^$/ ) { print WRCONFFILE $value; # preserve line next WRCONFSCAN; } if ( $debugParseConf ) { print "DAYS: $days\n" if $debugParseConf ; print "DEVICES: $device\n" if $debugParseConf ; print "USERS: $user\n" if $debugParseConf ; print "GROUPS: $group\n" if $debugParseConf ; print "INACTIVITY TIMEOUT: $inactivity_timeout\n" if $debugParseConf ; print "OTHER: $others\n" if $debugParseConf ; } # console inactivity timeout value # line looks like==>Al:$console:*:*:1:2:3:4 if (!($console eq "") and !($opt_c eq "") and ($value =~ m|^[\s]*Al[\s]*:[\s]*$console[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*|) ) { $value =~ s|^([\s]*Al[\s]*:[\s]*$console[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*)([\d]{1,3})([\s]*:.*)$|$1$console_timeout$3|; print WRCONFFILE $value; # preserve line print $value if $debugParseConf; $found_console_timeout = 1; } else { if (!($console eq "") and !($opt_c eq "") and ($value =~ m|^[\s]*Al[\s]*:[\s]*$console[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*|) ) { $value =~ s|^([\s]*Al[\s]*:[\s]*$console[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*)([\d]{1,3})([\s]*:.*)$|$1$console_timeout$3|; print WRCONFFILE $value; # preserve line $found_console_timeout = 1; print $value if $debugParseConf; } else { # network/ssh inactivity timeout value # line looks like==>Al:pts/*:*:*:1:5:6:7 if (!($opt_t eq "") and ($value =~ m|^[\s]*Al[\s]*:[\s]*pts/\*[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*|) ) { $value =~ s|^([\s]*Al[\s]*:[\s]*pts/\*[\s]*:[\s]*\*[\s]*:[\s]*\*[\s]*:[\s]*)([\d]{1,3})([\s]*:.*)$|$1$network_timeout$3|; print WRCONFFILE $value; $found_network_timeout = 1; print $value if $debugParseConf; } else { print WRCONFFILE $value; # preserve line } } } } # while loop through timeouts file } # timeouts file exists print WRCONFFILE "Al:$console:*:*:$console_timeout:0:0:0\n" if (($console ne "") and !($opt_c eq "") and ! $found_console_timeout); print WRCONFFILE "Al:pts/*:*:*:$network_timeout:0:0:0\n" if (!($opt_t eq "") and ! $found_network_timeout); print "...Done Updating $fileName\n" if $verbose ; close (CONFFILE) if ! $create_timeouts_file or die "close $fileName: $!\n" ; close (WRCONFFILE) or die "close $fileName: $!\n" ; chmod (0644, $fileName) or die "chmod($mode, $fileName: $!\n"; # 644 hex return 1; } ## write changes to the specified system config file sub update_ppp_options_file { my $lineCount = 0 ; my $paramval = "" ; my $foundIdle = 0; my $seconds = $ppp_timeout * 60; print "Update the ppp/options file\n" if $debugParseConf; die "$program - file $ppp_file_name: Does not Exist\n" if ! -e $ppp_file_name ; print qq(\nSaving $ppp_file_name to $ppp_file_name.old\n) if $verbose ; my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($fileName); rename ($ppp_file_name, $ppp_file_name.".old") ; open (CONFFILE, "<$ppp_file_name.old") or die "open $ppp_file_name.old: $!\n" ; open (WRCONFFILE, ">$ppp_file_name") or die "open $ppp_file_name: $!\n" ; print "Updating $ppp_file_name ...\n" if $verbose ; WRCONFSCAN: while () { print STDERR $_ if $debugParseConf ; # for each line of the file, see if we can match anything we are # looking for. $value = $_ ; ++$lineCount; if ($lineCount > $LINE_LIMIT) { print STDERR "Line limit exceeded reading file: $ppp_file_name (limit=$LINE_LIMIT).\n" ; break; } ## skip lines that start "#" or are blank if ( m/^[\s\#]+/ or /^$/ ) { print WRCONFFILE $value; # preserve line next WRCONFSCAN; } if ( $debugParseConf ) { print $value if $debugParseConf ; } # ppp inactivity timeout value # line looks like==>idle 123 if (!($opt_p eq "") and ($value =~ m|^[\s]*idle[\s]+|) ) { ## don't write idle xxx if it is disabled if ($ppp_timeout != 0) { $value =~ s|^([\s]*idle[\s]+)([\d]{1,4})([\s]*)$|$1$seconds$3|; print WRCONFFILE $value; # preserve line print $value if $debugParseConf; } $foundIdle = 1; } else { print WRCONFFILE $value; # preserve line } } if ($seconds != 0) { print WRCONFFILE "idle $seconds\n" if (! $foundIdle); } print "...Done Updating $ppp_file_name\n" if $verbose ; close (CONFFILE) or die "close $ppp_file_name: $!\n" ; close (WRCONFFILE) or die "close $ppp_file_name: $!\n" ; chmod($mode, $ppp_file_name) or die "chmod($mode, $ppp_file_name: $!\n"; return 1; } sub usage { print "Usage: timeout [options] set/display the timeout settings\n"; print " for a login session.\n"; print "-h show this help\n"; print "--help same as -h\n"; print " setting a timeout to 0 disables that option\n"; print "-c [timeout] set the console timeout (0-$MAX_TIMEOUT minutes)\n"; print "-t [timeout] set the network timeout (0-$MAX_TIMEOUT minutes)\n"; print "-p [timeout] set the ppp idle timeout (0-$MAX_TIMEOUT minutes)\n"; print "--query [c|t|p] query the value of the timeout corresponding to the\n"; print " letter(c-console, t-network, p-ppp)\n"; #print (stdout, "-m [timeout] set the modem timeout (0-"$MAX_TIMEOUT" minutes)\n"; }