#!/usr/bin/perl -w use strict qw(refs vars); use POSIX; our $polltime= 60; our $logfile= "/var/log/news.notice"; our ($loghandle, $logfile_devino); sub current_devino () { return join '.', (stat _)[0..1]; } our %months; $months{ (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec))[$_] }= $_ foreach qw(0..11); sub processline_core ($) { local ($_) = @_; my ($mon,$dom,$h,$m,$s) = s/^ ([A-Z][a-z]{2}) [ ] ([ 013]\d) [ ] ([ 0-2]\d) : (\d\d) : (\d\d) [ ] [-0-9a-z]+ /x; return "date re not matched" unless defined $mon; $mon= $months{$mon}; return "unknown month $mon" unless defined $mon; my $isdst= 0; $ts= mktime($s,$m,$h, $dom,$current_year, 0,0, $isdst); $last_ts= } sub backlog () { my $fh= new IO::File '<', "$logfile.0"; if (!$fh) { die "$logfile.0 $!" unless $!==&ENOENT; return; } while (defined(my $l= <$fh>)) { $l =~ s/\n$// or last; processline($l); } close $fh; } sub logpoll () { my $lbuf= ''; my $waited_eol= 0; for (;;) { sleep($polltime); if (!$loghandle) { $loghandle= new IO::File '<', $logfile; if (!$loghandle) { die "$logfile $!" unless $!==&ENOENT; next; } stat $loghandle or die $!; $logfile_devino= join '.', (stat _)[0..1]; } for (;;) { if ($lbuf =~ s/\n$//) { processline($l); $lbuf= ''; } my $xtra= <$loghandle>; if (!defined $xtra) { die "$logfile $!" if $loghandle->error; last; } $lbuf .= $xtra; } if (stat $logfile) { next if $logfile_devino eq current_devino; } else { die "$logfile $!" unless $!==&ENOENT; } # current file is no longer right if (length $lbuf) { # wait for the rest of the line ? next unless $waited_eol++ > 3; } $lbuf= ''; close $loghandle; $loghandle= undef; } } backlog(); logpoll();