From c597ff40a3b00537c7b2656ea67acebbc7863503 Mon Sep 17 00:00:00 2001 From: octo Date: Mon, 6 Jun 2005 13:23:17 +0000 Subject: [PATCH] A bug in lib/Onis/Parser/Persistent.pm has been fixed. --- lib/Onis/Data/Persistent/Dbm.pm | 1 + lib/Onis/Parser/Persistent.pm | 359 ++++++++++++++++++++++++++++++++++++++++ onis | 4 +- onis.conf | 2 +- 4 files changed, 363 insertions(+), 3 deletions(-) create mode 100644 lib/Onis/Parser/Persistent.pm diff --git a/lib/Onis/Data/Persistent/Dbm.pm b/lib/Onis/Data/Persistent/Dbm.pm index 402d0ee..6f9c5d7 100644 --- a/lib/Onis/Data/Persistent/Dbm.pm +++ b/lib/Onis/Data/Persistent/Dbm.pm @@ -49,6 +49,7 @@ $DBMDirectory =~ s#/+$##g; if (!$DBMDirectory or !-d $DBMDirectory) { print STDERR < 0, + Feb => 1, + Mar => 2, + Apr => 3, + May => 4, + Jun => 5, + Jul => 6, + Aug => 7, + Sep => 8, + Oct => 9, + Nov => 10, + Dec => 11 +); + +@MONTHNUMS = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; + +our $TimeNewest = Onis::Data::Persistent->new ('TimeNewest', 'inode', 'time'); +our $AbsoluteTime = 0; +our $TimeData = +{ + Seeking => 1, + NeedsRewind => 1, + Duration => 0 +}; +our $CurFile = 0; + +my $VERSION = '$Id: Persistent.pm,v 1.7 2004/01/07 20:31:17 octo Exp $'; +print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG); + +return (1); + +=head1 Exported routines + +=head2 get_state (); + +This routine decides between four states: ``don't have time'', ``line is +old'', ``parse this line'' and ``rewind file and begin again''. The last +three imply that the time has been set. + +B: The parser should tell the main routine to +rewind the file and start reading at the beginning again. This is +neccessay if we went past the point where we left off during the last run. +In this case zero is returned. + +B: If the parser should parse the line and call I +with the results this routine returns one. + +B: If the parser should simply ignore this line and +continue with the next one this routine returns three. + +B: No time is set. Ignore lines until a date is found. + +The desire is to pass the return code back to the main routine, unless it +is equal to one. The parser should then return one upon success, two upon +failure. + +=cut + +# Return values: +# 0 == rewind file +# 1 == line parsed +# 2 == unable to parse +# 3 == line old +# 4 == don't have date +sub get_state +{ + my ($newest) = $TimeNewest->get ($CurFile); + $newest ||= 0; + + # We're seeking for an absolute date. + if ($TimeData->{'Seeking'}) + { + # We're still seeking for a date.. + if (!$AbsoluteTime) + { + return (4); + } + + # we're seeking past this date + elsif ($newest) + { + # We have a date and it's before the date we're seeking for. + # So we continue seeking.. + if ($AbsoluteTime <= $newest) + { + if ($::DEBUG & 0x40) + { + print STDERR $/, __FILE__, ": Absolute time found. Is earlier than the newest time. Disabling ``NeedsRewind''."; + } + $TimeData->{'NeedsRewind'} = 0; + + # line old. ignore it + return (3); + } + + # We went too far, so we have to go back. + # We substract the duration since the beginning + # of the file and tell the main routine to rewind + # the file. + elsif ($TimeData->{'NeedsRewind'}) + { + my $found; + my $set; + my $diff = $TimeData->{'Duration'}; + + $found = localtime ($AbsoluteTime) if ($::DEBUG & 0x40); + + $AbsoluteTime -= $diff; + + if ($::DEBUG & 0x40) + { + $set = localtime ($AbsoluteTime); + print STDERR $/, __FILE__, ": Absolute time ``$found'' found. Setting back $diff seconds to ``$set''" if ($::DEBUG & 0x40); + } + + $TimeData->{'NeedsRewind'} = 0; + delete ($TimeData->{'LastHourSeen'}); + delete ($TimeData->{'LastMinuteSeen'}); + + # rewind file + return (0); + } + + # This is the line we were looking for. + # It's past $newest, but not the first absolute time found. + else + { + print STDERR $/, __FILE__, ": Seeking done." if ($::DEBUG & 0x40); + $TimeData->{'Seeking'} = 0; + } + } + + # $newest is not set but we have an absolute date. + else + { + print STDERR $/, __FILE__, ": \$newest not set. Setting it to \$AbsoluteTime." if ($::DEBUG & 0x40); + + $TimeData->{'Seeking'} = 0; + + # We had to read some lines to get an absolute date. + # Lets go back. + if ($TimeData->{'Duration'}) + { + my $diff = $TimeData->{'Duration'}; + if ($::DEBUG & 0x40) + { + my $time = localtime ($AbsoluteTime); + print STDERR $/, __FILE__, ": AbsolutTime found is ``$time'', but we are $diff seconds into the file."; + } + + $AbsoluteTime -= $TimeData->{'Duration'}; + + if ($::DEBUG & 0x40) + { + my $time = localtime ($AbsoluteTime); + print STDERR $/, __FILE__, ": Corrected AbsolutTime (set back $diff seconds) is ``$time''"; + } + + delete ($TimeData->{'LastHourSeen'}); + delete ($TimeData->{'LastMinuteSeen'}); + + # tell parser to rewind file + return (0); + } + + # We didn't miss anything, so we don't need to rewind the file. + else + { + $newest = $AbsoluteTime; + $TimeNewest->put ($CurFile, $newest); + return (1); + } + } + } + + # Ok, we're in the past. Let's skip that line.. + # This is NOT supposed to happen. If it does, it's a bug! + elsif ($AbsoluteTime < $newest) + { + my $now = localtime ($AbsoluteTime); + my $then = localtime ($newest); + print STDERR $/, __FILE__, ": Absolute time set, but we're in the past. Skipping. ($now < $then)" if ($::DEBUG & 0x40); + return (3); + } + + # We're up to date. $TimeNewest needs to be set accordingly.. + elsif ($AbsoluteTime != $newest) + { + if ($::DEBUG & 0x40) + { + my $time = localtime ($AbsoluteTime); + print STDERR $/, __FILE__, ": Updating. Newest time is now ``$time''"; + } + + $newest = $AbsoluteTime; + $TimeNewest->put ($CurFile, $newest); + } + + return (1); +} + +=head2 add_relative_time ($hour, $min); + +This routine does two different things, depending on wether or not the +absolute time is known. + +If the absolute time is not known, it will add up the seconds since the +start of the file. When we know the absolute time later we can subtract +that value to get the absolute time of the beginning of the file. + +If the absolute time is known it simply adds to it to keep it up to date. + +=cut + +sub add_relative_time +{ + my $this_hour = shift; + my $this_minute = shift; + + my $this_seconds = ($this_hour * 3600) + ($this_minute * 60); + + if ((defined ($TimeData->{'LastHourSeen'})) + and (defined ($TimeData->{'LastMinuteSeen'}))) + { + my $diff = 0; + my $last_hour = $TimeData->{'LastHourSeen'}; + my $last_minute = $TimeData->{'LastMinuteSeen'}; + my $last_seconds = ($last_hour * 3600) + ($last_minute * 60); + + if ($last_seconds > $this_seconds) + { + $this_seconds += 86400; # one day + } + + $diff = $this_seconds - $last_seconds; + + if ($::DEBUG & 0x40) + { + print STDERR $/, __FILE__, ': '; + printf STDERR ("diff ('%02u:%02u', '%02u:%02u') = %u seconds", + $last_hour, $last_minute, + $this_hour, $this_minute, + $diff); + } + + # FIXME needs testing! + if (!$AbsoluteTime) + { + $TimeData->{'Duration'} += $diff; + } + else + { + $AbsoluteTime += $diff; + } + } + + $TimeData->{'LastHourSeen'} = $this_hour; + $TimeData->{'LastMinuteSeen'} = $this_minute; +} + +=head2 set_absolute_time ($year, $month, $day, $hour, $min, $sec); + +As the name suggests this routine sets the absolute time. + +=cut + +sub set_absolute_time +{ + my $year = shift; + my $month = shift; + my $day = shift; + my $hour = shift; + my $min = shift; + my $sec = shift; + + $year -= 1900; + + my $time = timelocal ($sec, $min, $hour, $day, $month, $year); + print STDERR $/, __FILE__, ": Set absolute time to ", scalar (localtime ($time)) if ($::DEBUG & 0x40); + + # Add diff if this is the first + if (!$AbsoluteTime) + { + add_relative_time ($hour, $min); + } + else + { + # FIXME neccessary? + $TimeData->{'LastHourSeen'} = $hour; + $TimeData->{'LastMinuteSeen'} = $min; + } + + $AbsoluteTime = $time; +} + +sub get_absolute_time +{ + return ($AbsoluteTime); +} + +=head2 newfile (); + +Resets the internal counters to be ready for another file. + +=cut + +sub newfile +{ + my $inode = shift; + + my ($time) = $TimeNewest->get ($inode); + $time ||= 0; + $TimeNewest->put ($inode, $time); + + $AbsoluteTime = 0; + $TimeData->{'Duration'} = 0; + $TimeData->{'NeedsRewind'} = 1; + $TimeData->{'Seeking'} = 1; + delete ($TimeData->{'LastHourSeen'}); + delete ($TimeData->{'LastMinuteSeen'}); +} diff --git a/onis b/onis index 28a092f..d67b789 100755 --- a/onis +++ b/onis @@ -27,7 +27,7 @@ BEGIN # 0x0400 Data::Core (dump incoming data to stderr) # 0x0800 Data::Core (initializing) # 0x1000 Onis::Users - $::DEBUG = 0x0000; + $::DEBUG = 0x0240; } use strict; @@ -249,7 +249,7 @@ for (get_config ('input')) } } - newfile ($FileInfo->{$inode}); + newfile ($inode); while (<$logfile>) { s/\n|\r//g; diff --git a/onis.conf b/onis.conf index 2a8a73b..64bfe4d 100644 --- a/onis.conf +++ b/onis.conf @@ -152,7 +152,7 @@ storage_file: "storage.dat"; # Sets the directory in which the storage file(s) should be kept. This is used # by ``Dbm'' and ``Storable''. -storage_dir: "~/.onis/data"; +#storage_dir: "/home/user/.onis/data"; # -- 2.11.0