#!/usr/bin/perl -w # # pipe-watcher # John Simpson 2005-10-07 # # watch a pipe for activity # when it sees activity, runs a script # ############################################################################### # # Copyright (C) 2005 John Simpson. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # or visit http://www.gnu.org/licenses/gpl.txt # ############################################################################### require 5.003 ; use strict ; $| = 1 ; # the name of the pipe to watch my $pfile = "/tmp/update-qmail" ; # the script (or program) we run whenever activity is seen my $cmd = "/service/qmail-updater/update-qmail" ; my $cmd_needs_data = 0 ; # delay (in seconds) to keep the program from being flooded my $min_delay = 5 ; ############################################################################### ############################################################################### ############################################################################### print "starting\n" ; unlink $pfile ; system "mkfifo -m u=rw,go=w $pfile" ; unless ( -p $pfile ) { print "ERROR: Can\'t create fifo $pfile: $!\n" ; sleep 30 ; exit 1 ; } my @s = stat $pfile ; unless ( $< == $s[4] ) { print "ERROR: My uid doesn't own $pfile (me=$< owner=$s[4])\n" ; sleep 30 ; exit 1 ; } my $lastrun = 0 ; while ( 1 ) { my $text = "" ; my ( $rv ) ; ### wait on the pipe to give us data print "waiting for input on $pfile\n" ; open ( I , "<$pfile" ) or die "Can\'t open $pfile for reading: $!\n" ; print "gathering input\n" ; while ( my $line = ) { $text .= $line ; } close I ; chomp $text ; print "/-----\n$text\n\\-----\n" ; $lastrun = time ; ######################################## # run the command. # the input from the pipe is in "$text" if you need it. # remember to include "2>&1" in your command if you want # the output from the command to end up in the log file print "running [$cmd] (output follows)\n/-----\n" ; if ( $cmd_needs_data ) { if ( open ( C , "| $cmd 2>&1" ) ) { print C $text ; close C ; print "\\-----\n" ; } else { print "\\----- Unable to run: $!\n" ; } } else { $rv = system ( "$cmd 2>&1" ) ; print "\\----- rv=$rv\n" ; } if ( time < ( $lastrun + $min_delay ) ) { my $nsec = $lastrun + $min_delay - time ; print "sleeping $nsec seconds...\n" ; sleep $nsec ; } }