Patrick Andrieu: time() unterschlägt eine Ziffer?

Beitrag lesen

Hallo alle!

Für die Neuauflage meines Page-Views-Counters (bis jetzt noch in der alten Form online: http://old.atomic-eggs.com/cgi-bin/html_log.cgi <- dies ist allerdings die Auswertung, der Code vom tatsächlichen Counter folgt weiter unten, allerdings schon der neue Code) lasse ich, anstatt wie bisher das komplette Datum (braucht Speicherplatz), lediglich den Unix-Timestamp in die Flatfile eintragen. Eine Dateizeile sieht dann so aus:

1234567890•zähldateiname•remotehost•ip•user-agent•referrer•auflösung•farbtiefe

(Jaja, mir ist klar, dass Auflösung und Farbtiefe (eigentlich auch der UA) vollkommen nichtssagend sind, aber die Interessenten sehen sowas gerne ;) )

Nun ja, und eben entdecke ich einen Bug in der Auswertung, schau in der Flatfile nach, und siehe da: In irgendeiner Zeile war der Timestamp statt 10-stellig nur 9-stellig, die 4. Ziffer von rechts aus gezählt fehlte. Das ergab dann der 7.12.1973 ;)

Wie kommt sowas? Durch das Speichern des Rückgabewerts von time() in $time?

Hier der Code:

#!/usr/bin/perl -w  
  
use strict;  
use me::Date;  
use CGI;  
use CGI::Carp qw(fatalsToBrowser);            # Nur während der Entwicklung  
use Net::hostent qw(gethost);  
  
my $cgi = new CGI;  
my $today = me::Date->new('de');  
my $time = time();  
my $month = @{$today->this_month}[0];  
my $year = $today->full_year;  
  
my $logfile = $month eq 'März' ? 'me/Maerz_'.$year : 'me/'.$month.'_'.$year;  
my $monthsfile = 'me/Monate_'.$year;  
my $sep = "\x07";                             # Separator ist das Bullet-Zeichen: •  
my $pic = 'http://old.atomic-eggs.com/old_pics/stats.gif';  
  
getHostName();  
  
sub getHostName {  
  my $h = gethost($ENV{REMOTE_ADDR}) || "";  
  my $host = $h ? $h->name : 'na';  
  write_log($host);  
}  
  
sub write_log  {  
  my $host = shift;  
  my $ua = $ENV{HTTP_USER_AGENT};  
  my $ip = $ENV{REMOTE_ADDR};  
  my $ref = $cgi->param('ref') || 'da';  
  my $page = $cgi->param('page') || 'np';  
  my $res = $cgi->param('res') || 'oj';  
  my $cDp = $cgi->param('cdp') || 'ne';  
  
  $ua =~ s#<script(.*?)</script># - Murks im User-Agent! - #gi;  
  $ua =~ s/^<noscript>.*$/Murks im User-Agent!/gi;  
  
  for ($host,$ua,$ref) {  
    $_ =~ s/$sep/-/g;  
  }  
  
  $ref = 'oj' if ($ref eq 'da' && $res eq 'oj' && $cDp eq 'ne');  
  
  my @logdata = ($time,$page,$host,$ip,$ua,$ref,$res,$cDp);  
  #                0     1    2     3   4    5   6    7  
  
  $| = 1;  
  
  my @lflines;  
  my @mflines;  
  my $count = 0;  
  
          # Logdatei öffnen, wenn existiert  
          # Wenn ja, Inhalt in @lflines einlesen, Anzahl Zeilen ermitteln und $count zuweisen  
          # Wenn nicht (else): @lflines ist ein leeres Array  
  if (-e "$logfile.txt") {  
    open FILE,"$logfile.txt" or die "Kann Logdatei $logfile.txt nicht öffnen. Grund: $^E.";  
    flock FILE, 2;  
    @lflines=<FILE>;  
    $count = $.;  
    close FILE;  
  } else { @lflines = (); }  
  
   open LOG,">$logfile.txt" or die "Kann Logdatei $logfile.txt nicht öffnen. Grund: $^E.";  
   flock LOG, 2;  
   $count++;  
   print LOG join ($sep, @logdata),"\n";  
   print LOG @lflines;  
   close LOG;  
  
          # Monatsdatei (Monate_YYYY.txt) öffnen, wenn existiert  
          # Wenn ja, Inhalt in @mflines einlesen, in letzter Zeile prüfen ob aktueller Monat  
          ##### - wenn aktueller Monat in letzter Zeile gefunden, nur die Page-Views-Zahl ändern  
          ##### - wenn nicht, Zeile mit aktuellem Monat hinzufügen  
          # Wenn Datei noch nicht existiert, Array @mflines's erstes Element definieren  
          # Die Datei wird im zweiten OPEN geöffnet und neu geschrieben (wenn nicht existent, wird angelegt und geschrieben)  
  if (-e "$monthsfile.txt") {  
    open MONTHS,"$monthsfile.txt" or die "Kann Logdatei $monthsfile.txt nicht öffnen. Grund: $^E.";  
    flock MONTHS, 2;  
    @mflines=<MONTHS>;  
    close MONTHS;  
    if ((split /$sep/, $mflines[-1])[0] eq $month) {  
      $mflines[-1] = join($sep, ($month,$count));  
    } else {  
      push @mflines, join($sep, ($month,$count));  
    }  
  } else { $mflines[0] = join($sep, ($month,$count)); }  
  
   open MONTHS,">$monthsfile.txt" or die "Kann Logdatei $monthsfile.txt nicht öffnen. Grund: $^E.";  
   flock MONTHS, 2;  
   print MONTHS @mflines, "\n";  
   close MONTHS;  
  
   print "Location: $pic\n\n";  
}

Oder hat die Tatsache irgendeinen Einfluß, dass bei den auskommentierten Zeilen das #-Zeichen nicht als erstes Zeichen steht, sondern diese eingerückt sind (das Forumsscript zeigt die Kommentare nicht grau an...)?

Viele Grüße aus Frankfurt/Main,
Patrick

--
_ - jenseits vom delirium - _

   Diblom   [link:hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash]
J'ai 10 ans! | Achtung Agentur! | Nichts ist unmöglich? Doch! | Heute schon gegökt?