watch-file.pl
I really needed a small script capable of executing another script whenever a file change - eg. when watching a log file of Apache for changes. Therefore I tried a couple of different approaches but ended up with this which is quite easy on the resouces of the CPU.
#!/usr/bin/perl
# 2007 Rune M. Barnkob
# -------------------------------------
# 2007-06-16 First release
# -------------------------------------
# We can always use another OSS license, so here goes: use this for whatever you want -
# weapons, nuclear powerplants, chemical waste disposal plants - just dont come crying
# to me if it fails in any way. (but you are free to report bugs)
# Use whatever license you choose appropriate from
# http://www.opensource.org/licenses/alphabetical
use strict;
use POSIX qw(setsid);
if (@ARGV < 3) {
die "Usage: watch-file.pl \n";
}
my $file = shift(@ARGV);
my $log = shift(@ARGV);
my $LOG;
# gracefully chopped from http://www.webreference.com/perl/tutorial/9/3.html
sub daemonize {
open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork) or die "Can't fork: $!";
exit if $pid;
setsid or die "Can't start a new session: $!";
umask 0;
logmsg("Daemonized...");
}
# print new log message
sub logmsg {
my ($msg) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900; $mon += 1;
if (not defined($LOG)) {
open($LOG, ">>$log");
printf($LOG "%04d-%02d-%02d %02d:%02d:%02d (%04d) %s\n",
$year, $mon, $mday,
$hour, $min, $sec,
$$, "New log");
$| = 1;
}
if (defined($msg)) {
printf($LOG "%04d-%02d-%02d %02d:%02d:%02d (%04d) %s\n",
$year, $mon, $mday,
$hour, $min, $sec,
$$, $msg);
}
}
# handle SIGHUP by closing log and opening again - useful for log rotation
sub hndl_sighup {
logmsg("Closing log on SIGHUP...");
close($LOG); undef($LOG);
logmsg();
}
$SIG{HUP} = \&hndl_sighup;
# handle SIGTERM gracefully
sub hndl_sigterm {
logmsg("Exiting...");
exit;
}
$SIG{TERM} = \&hndl_sigterm;
# ###########################################################
#
# we must daemonize first in order to open log file correctly
daemonize();
$| = 1;
my $last_mtime;
while (1) {
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($file);
if ($mtime != $last_mtime) {
$last_mtime = $mtime;
logmsg("Exec '@ARGV'");
open STDOUT, ">>$log-STDOUT";
open STDERR, ">>$log-STDERR";
system(@ARGV);
}
sleep(1);
}
ban.pl
Another this I noticed was the many attempts at logging in on the server with invalid user names and/or bad passwords, so I created this script.
So feel free to use this config or any variants you might create and please forward then to me so I may learn from them.
Keywords: SSH, watch, file, notification, monitor, invalid user, ban, crack, hack

