}
+#------------------------------------------------------------------------------------------
+
+=head2 collect_old_logfiles( $file )
+
+Ermittelt alle alten, bisher rotierten Logdateien zu der uebergebenen Logdatei und gibt diese
+als Hash-Ref mit den Dateinamen als Key und dem Zeitstempel der letzten Aenderung als Wert zurueck.
+
+=cut
+
+sub collect_old_logfiles($$) {
+
+ my $self = shift;
+ my $file = shift;
+ my $p = verbose() ? __PACKAGE__ . "::collect_old_logfiles(): " : "";
+
+ my ( $dir, $basename, $olddir, $pattern, $t );
+ my ( @Pattern, @Liste, @Stats );
+
+ my $ce = $self->{'c'}->compressext();
+ if ( not defined($ce) or $ce =~ /^\s*$/ ) {
+ $ce = ".gz";
+ }
+ $ce = "." . $ce if $ce ne "" and $ce !~ /^\./;
+ print $p . "Kompressionsendung '$ce'.\n" if verbose() > 3;
+
+ unless ( $file ) {
+ carp( $p . "Keine Logdatei uebergeben!\n" );
+ return undef;
+ }
+ print $p . "Ermittle alten Logdateien fuer '$file'.\n" if verbose();
+ my $f = $self->{'c'}{'logfiles'}{$file};
+
+ my $ext = defined $f->{'extension'} ? $f->{'extension'} : "";
+ $ext = "" if $ext =~ /^\s*$/;
+ $ext = "." . $ext if $ext ne "" and $ext !~ /^\./;
+ my $ext_ohne = $ext;
+
+ # Compress-Endung hinten dran bammeln ...
+ if ( $f->{'compress'} ) {
+ my $ce = $self->{'c'}->compressext();
+ if ( not defined($ce) or $ce =~ /^\s*$/ ) {
+ $ce = ".gz";
+ }
+ $ce = "." . $ce if $ce ne "" and $ce !~ /^\./;
+ $ext .= $ce;
+ }
+
+ my $res = {};
+
+ unless ( ( $dir, $basename ) = $file =~ m#(.*)/([^/]*)$# ) {
+ warn $p . "Ungueltiger Logdateiname: '$file'\n";
+ return undef;
+ }
+
+ if ( $f->{'dateext'} ) {
+ $basename .= ".*";
+ }
+
+ if ( $f->{'olddir'} and $f->{'olddir'}{'dirname'} ) {
+
+ # Ersetzung aller Platzhalter in Olddir-Angabe
+
+ $olddir = $f->{'olddir'}{'dirname'};
+
+ # Verzeichnisname ...
+ $olddir =~ s/(?:\${dirname}|\$dirname(?![a-zA-Z0-9_]))/$dir/g;
+
+ # Basename ...
+ $olddir =~ s/(?:\${basename}|\$basename(?![a-zA-Z0-9_]))/$basename/g;
+
+ # Nodename
+ $t = $self->{'template'}{'nodename'};
+ $olddir =~ s/(?:\${nodename}|\$nodename(?![a-zA-Z0-9_]))/$t/g;
+
+ # Domain
+ $t = $self->{'template'}{'domain'};
+ $olddir =~ s/(?:\${domain}|\$domain(?![a-zA-Z0-9_]))/$t/g;
+
+ # Platform
+ $t = $self->{'template'}{'platform'};
+ $olddir =~ s/(?:\${platform}|\$platform(?![a-zA-Z0-9_]))/$t/g;
+
+ # Isa
+ $t = $self->{'template'}{'isa'};
+ $olddir =~ s/(?:\${isa}|\$isa(?![a-zA-Z0-9_]))/$t/g;
+
+ # Release
+ $t = $self->{'template'}{'release'};
+ $olddir =~ s/(?:\${release}|\$release(?![a-zA-Z0-9_]))/$t/g;
+
+ # Machine
+ $t = $self->{'template'}{'machine'};
+ $olddir =~ s/(?:\${machine}|\$machine(?![a-zA-Z0-9_]))/$t/g;
+
+ $olddir = $dir . "/" . $olddir unless $olddir =~ m#^/#;
+
+ # Ersetzen aller POSIX::strftime-Platzhalter durch Shell-Pattern:
+ # Wochentag
+ $olddir =~ s/\%a/*/gi;
+ # Monatsname
+ $olddir =~ s/\%b/*/gi;
+ $olddir =~ s/\%h/*/g;
+ # Datum komplett
+ $olddir =~ s/\%c/*/g;
+ # Jahrhundert
+ $olddir =~ s/\%C/[0-9][0-9]/g;
+ # Tag im Monat
+ $olddir =~ s/\%d/[0-9][0-9]/g;
+ # Datum als %m/%d/%y
+ $olddir =~ s#\%D#[0-9][0-9]/[0-9][0-9]/[0-9][0-9]#g;
+ $olddir =~ s#\%x#[0-9][0-9]/[0-9][0-9]/[0-9][0-9]#g;
+ # Stunde im 24h-Format
+ $olddir =~ s/\%H/[012][0-9]/g;
+ # Stunde im 12h-Format
+ $olddir =~ s/\%J/[01][0-9]/g;
+ # Nummer des Tags im Jahr
+ $olddir =~ s/\%j/[0123][0-9][0-9]/g;
+ # Stunde im 24h-Format
+ $olddir =~ s/\%k/[\\ 12][0-9]/g;
+ # Stunde im 12h-Format
+ $olddir =~ s/\%l/[\\ 1][0-9]/g;
+ # Monatsnummer
+ $olddir =~ s/\%m/[0-9][0-9]/g;
+ # Minute
+ $olddir =~ s/\%M/[0-5][0-9]/g;
+ # AM/PM
+ $olddir =~ s/\%p/[AP]M/g;
+ # komplette Uhrzeit im 12h-Format mit AM/PM
+ $olddir =~ s/\%r/[01][0-9]:[0-5][0-9]:[0-5][0-9] [AP]M/g;
+ # Uhrzeit im Format %H:%M
+ $olddir =~ s/\%R/[012][0-9]:[0-5][0-9]/g;
+ # Sekunden
+ $olddir =~ s/\%S/[0-6][0-9]/g;
+ # komplette Uhrzeit im 24h-Format
+ $olddir =~ s/\%T/[012][0-9]:[0-5][0-9]:[0-5][0-9]/g;
+ $olddir =~ s/\%X/[012][0-9]:[0-5][0-9]:[0-5][0-9]/g;
+ # Wochentag als Zahl (1-7)
+ $olddir =~ s/\%u/[0-7]/g;
+ $olddir =~ s/\%w/[0-7]/g;
+ # Nummer der Woche im Jahr
+ $olddir =~ s/\%U/[0-5][0-9]/g;
+ $olddir =~ s/\%V/[0-5][0-9]/g;
+ $olddir =~ s/\%W/[0-5][0-9]/g;
+ # Jahr
+ $olddir =~ s/\%Y/[1-9][0-9][0-9][0-9]/g;
+ # Zeitzone
+ $olddir =~ s/\%Z/*/g;
+
+ } else {
+
+ $olddir = $dir;
+
+ }
+
+ push @Pattern, $olddir . "/" . $basename . $ext;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9]" . $ext;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9]" . $ext;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9][0-9]" . $ext;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9][0-9][0-9]" . $ext;
+ if ( $f->{'compress'} ) {
+ push @Pattern, $olddir . "/" . $basename . $ext_ohne;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9]" . $ext_ohne;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9]" . $ext_ohne;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9][0-9]" . $ext_ohne;
+ push @Pattern, $olddir . "/" . $basename . ".[0-9][0-9][0-9][0-9]" . $ext_ohne;
+ }
+
+# $pattern = '"' . join( '" "', @Pattern ) . '"';
+# print $p . "Suchpattern nach den alten Logdateien: '$pattern'.\n" if verbose() > 2;
+
+# @Liste = glob( $pattern );
+
+ foreach $pattern ( @Pattern ) {
+ print $p . "Suche nach Pattern '$pattern'.\n" if verbose() > 2;
+ @Liste = glob( $pattern );
+ for ( @Liste ) {
+ print " - '$_'\n" if verbose() > 3;
+ @Stats = stat $_;
+ $res->{$_} = $Stats[9];
+ }
+ }
+
+ return $res;
+}
+
#------------------------------------------------------------------------------------
=head2 create_olddir ( $logfile )
$t_new = $target . "." . $i . $ext;
$t_new_ohne = $target . "." . $i . $ext_ohne;
print $p . "Zyklische Rotation '$t_ohne' -> '$t_new_ohne'.\n" if verbose() > 3;
- $pair = { 'from' => $t_ohne,
- 'to' => $t_new_ohne,
+ $pair = { 'from' => $t_ohne,
+ 'to' => $t_new_ohne,
+ 'compressed' => 0,
};
+ $pair->{'compressed'} = 1 if -f $t and $f->{'compress'};
unshift @{$res->{'move'}}, $pair;
$t = $t_new;
$t_ohne = $t_new_ohne;
my $file = shift;
my $p = verbose() ? __PACKAGE__ . "::rotate_file(): " : "";
- #my ( $dir, $adir, $mode, $owner, $group, $olddir );
- #my ( $pmode, $puid, $pgid );
- #my ( @Dirs, @Stats );
+ my ( $target, $rotates, $pair, $from, $to );
+ my ( $omode, $ouid, $ogid, $nmode, $nuid, $ngid, $atime, $mtime );
+ my ( @Stats );
- my ( $target, $rotates );
-
- my $uid = $>;
- my ( $gid ) = $) =~ /^(\d+)/;
+ my $ce = $self->{'c'}->compressext();
+ if ( not defined($ce) or $ce =~ /^\s*$/ ) {
+ $ce = ".gz";
+ }
+ $ce = "." . $ce if $ce ne "" and $ce !~ /^\./;
+ print $p . "Kompressionsendung '$ce'.\n" if verbose() > 2;
unless ( $file ) {
carp( $p . "Keine Logdatei uebergeben!\n" );
print $p . "Ermittelte Moves: " . Dumper($rotates) if verbose() > 2;
+ # Zuerst mal alles Alte zyklisch rotieren ...
+
+ for $pair ( @{$rotates->{'move'}} ) {
+ $from = $pair->{'from'};
+ $to = $pair->{'to'};
+ if ( $pair->{'compressed'} ) {
+ $from .= $ce;
+ $to .= $ce;
+ }
+ print $p . "Umbenennung '$from' => '$to'.\n";
+ unless ( $self->{'test'} ) {
+ unless ( move $from, $to ) {
+ warn $p . "Konnte '$from' nicht in '$to' umbenennen: $!\n";
+ return undef;
+ }
+ }
+ }
+
+ # Jetzt die eigentliche Rotation ...
+
+ $from = $rotates->{'rotate'}{'from'};
+ $to = $rotates->{'rotate'}{'to'};
+
+ $f->{'rotated'} = $to;
+
+ if ( $f->{'copytruncate'} ) {
+ # alte Permissions und Besitzer der rotierten Datei ermitteln
+ @Stats = stat $from;
+ ( $omode, $ouid, $ogid, $atime, $mtime ) = @Stats[ 2, 4, 5, 8, 9 ];
+ print $p . "Kopiere '$from' nach '$to' ...\n";
+ unless ( $self->{'test'} ) {
+ unless ( copy $from, $to ) {
+ warn $p . "Konnte '$from' nicht nach '$to' kopieren: $!\n";
+ return undef;
+ }
+ }
+
+ print $p . "Trunce Datei '$from' ...\n";
+ unless ( $self->{'test'} ) {
+ if ( open FILE, ">$from" ) {
+ close FILE;
+ } else {
+ warn $p . "Konnte Logdatei '$from' nicht truncen: $!\n";
+ return undef;
+ }
+ }
+
+ # gewünschte Permissions setzen
+ print $p . "Setze Permissions von '$to'.\n" if verbose();
+ unless ( $self->{'test'} ) {
+ unless ( chmod $omode, $to ) {
+ warn $p . "Setzen der Permissions von '$to' war nnicht erfolgreich: $!\n";
+ }
+ }
+
+ # gewünschte Besitzer stzen
+ print $p . "Setze Besitzer von '$to'.\n" if verbose();
+ unless ( $self->{'test'} ) {
+ unless ( chown $ouid, $ogid, $to ) {
+ warn $p . "Setzen des Besitzers von '$to' war nicht erfolgreich: $!\n";
+ }
+ }
+
+ # Access- und Modification-Time setzen ...
+ print $p . "Setze Access- und Modification-Time von '$to'.\n" if verbose();
+ unless ( $self->{'test'} ) {
+ unless ( utime $atime, $mtime, $to ) {
+ warn $p . "Setzen der Access- und Modification-Time von '$to' war nicht erfolgreich: $!\n";
+ }
+ }
+
+ } else {
+
+ print $p . "Benenne um bzw. verschiebe '$from' nach '$to' ...\n";
+ unless ( $self->{'test'} ) {
+ unless ( move $from, $to ) {
+ warn $p . "Konnte '$from' nicht nach '$to' umbenennen/verschieben: $!\n";
+ return undef;
+ }
+ }
+
+ if ( $f->{'create'} ) {
+
+ print $p . "Lege '$from' neu an ...\n";
+ unless ( $self->{'test'} ) {
+ if ( open FILE, ">$from" ) {
+ close FILE;
+ } else {
+ warn $p . "Konnte Logdatei '$from' nicht neu anlegen: $!\n";
+ return undef;
+ }
+ }
+
+ # alte Permissions und Besitzer der neu angelegten Datei ermitteln
+ @Stats = stat $from;
+
+ ( $omode, $ouid, $ogid ) = @Stats[ 2, 4, 5 ];
+ # gewünschte Permissions und Besitzer ermittel
+ $nmode = $f->{'create'}{'mode'} || 0644;
+ $nuid = $f->{'create'}{'owner'};
+ $ngid = $f->{'create'}{'group'};
+
+ if ( $nmode != $omode ) {
+ # gewünschte Permissions setzen
+ print $p . "Setze Permissions von '$from'.\n" if verbose();
+ unless ( $self->{'test'} ) {
+ unless ( chmod $nmode, $from ) {
+ warn $p . "Setzen der Permissions von '$from' war nnicht erfolgreich: $!\n";
+ }
+ }
+ }
+
+ if ( $ouid != $nuid or $ogid != $ngid ) {
+ # gewünschte Besitzer stzen
+ print $p . "Setze Besitzer von '$from'.\n" if verbose();
+ unless ( $self->{'test'} ) {
+ unless ( chown $nuid, $ngid, $from ) {
+ warn $p . "Setzen des Besitzers von '$from' war nicht erfolgreich: $!\n";
+ }
+ }
+ }
+
+ }
+
+ }
+
+ # Ermittlung aller bisherigen Logfiles ...
+ my $old_logfiles = $self->collect_old_logfiles( $file );
+ unless ( $old_logfiles ) {
+ warn $p . "Fehler beim Ermitteln der bisher rotierten Logfiles.\n";
+ return undef;
+ }
+ print $p . "Liste aller bisher rotierten Logfiles: " . Dumper($old_logfiles) if verbose() > 1;
+ $f->{'oldfiles'} = $old_logfiles;
return 1;