]> Frank Brehm's Git Trees - my-stuff/postfix-maps.git/commitdiff
Bis zum Aufruf vom postmap/postalias gekommen
authorFrank Brehm <frank@brehm-online.com>
Thu, 5 Aug 2010 16:21:57 +0000 (16:21 +0000)
committerFrank Brehm <frank@brehm-online.com>
Thu, 5 Aug 2010 16:21:57 +0000 (16:21 +0000)
git-svn-id: http://svn.brehm-online.com/svn/my-stuff/postfix-maps/trunk@108 ec8d2aa5-1599-4edb-8739-2b3a1bc399aa

lib/FrBr/Postfix/App.pm

index b74ef392a563cf544afdc14cb9f2780118898911..2db4368967b054ca1242fc0e6b2a8de166154827 100644 (file)
@@ -24,6 +24,7 @@ use MooseX::Types::Path::Class;
 use Path::Class;
 use Encode qw( decode_utf8 encode_utf8 is_utf8 );
 use POSIX qw( strftime );
+use File::Copy;
 
 extends 'FrBr::Common::MooseX::App';
 
@@ -188,6 +189,35 @@ sub _build_valid_maptypes {
     };
 }
 
+#-----------------------------------------
+
+=head2 postfix_binary
+
+HashRef mit den Postfix-Binaries
+
+=cut
+
+has 'postfix_binary' => (
+    is              => 'ro',
+    isa             => 'HashRef',
+    traits          => [ 'NoGetopt' ],
+    lazy            => 1,
+    builder         => '_build_postfix_binary',
+    documentation   => 'HashRef mit allen wichtigen Postfix-Binaries.',
+);
+
+#------
+
+sub _build_postfix_binary {
+    return {
+        'postalias' => '/usr/sbin/postalias',
+        'postconf'  => '/usr/sbin/postconf',
+        'postfix'   => '/usr/sbin/postfix',
+        'postmap'   => '/usr/sbin/postmap',
+    };
+}
+
+
 #---------------------------------------------------------------------------
 
 # Ändern der Eigenschaften einiger geerbter Attribute
@@ -310,7 +340,7 @@ after 'evaluate_config' => sub {
     }
 
     if ( $self->verbose >= 2 ) {
-        for my $key qw( postfix_dir work_dir postfix_maps restart_postfix valid_maptypes ) {
+        for my $key qw( postfix_dir work_dir postfix_binary postfix_maps restart_postfix valid_maptypes ) {
             my $tmp = $self->$key;
         }
     }
@@ -635,7 +665,7 @@ sub do_mapping {
         eval {
             for my $rs ( $self->schema->resultset($resultset)->search( $map->{'where'}, $o_opts )->all() ) {
 
-                my $field1 = $rs->get_column( $cols->[0] );
+                my $field1 = encode_utf8( lc( decode_utf8( $rs->get_column( $cols->[0] ) ) ) );
                 my $field2 = $two_identic_cols ? $field1 :  $rs->get_column( $cols->[1] );
                 $field1 .= ':' if $map->{'text_type'} eq 'aliases';
                 printf FILE "%-*s   %s\n", $max_col_length, $field1, $field2;
@@ -653,10 +683,286 @@ sub do_mapping {
 
     close FILE;
 
+    my $changed = 0;
+    my $binary = $self->postfix_binary;
+
+    $changed = 1 unless -f $map->{'mapfile'};
+    $changed = 1 if $self->_diff_files( $map->{'workfile'}, $map->{'mapfile'}, $map->{'text_type'} );
+    $self->debug( sprintf( "Mapping '%s' hat sich %s.", $mapname, ( $changed ? 'GEÄNDERT' : 'NICHT VERÄNDERT' ) ) );
+
+    if ( $changed ) {
+
+        $self->info( sprintf( "Aktualisiere Mapping '%s' in Datei '%s' ...", $mapname, $map->{'mapfile'} ) );
+
+        $self->debug( sprintf( "Kopiere Datei '%s' nach '%s' ...", $map->{'workfile'}, $map->{'mapfile'} ) );
+        copy $map->{'workfile'}, $map->{'mapfile'};
+
+        if ( $map->{'exec_map'} ) {
+
+            my $cmd = $map->{'text_type'} eq 'aliases' ? $binary->{'postalias'} : $binary->{'postmap'};   
+            my @Args = ( $cmd, $map->{'db_type'} . ":" . $map->{'mapfile'} );
+            $self->debug( sprintf( "Führe Kommando aus: '%s'", join( " ", @Args ) ) );
+            unless ( system(@Args) == 0 ) {
+                $self->error( sprintf( "Fehler beim Ausführen von '%s'.", join( " ", @Args ) ) );
+                return undef;
+            }
+        }
+
+        $self->restart_postfix(1) if $map->{'restart_postfix'};
+
+    }
+
     return 1;
 
 }
 
+#--------------------------------------------------------------------------------------
+
+=head2 _diff_files( $file1, $file2, $map_type )
+
+=cut
+
+sub _diff_files {
+
+    my $self  = shift;
+    my $file1 = shift;
+    my $file2 = shift;
+    my $map_type = shift;
+
+    unless ( $file1 and $file2 ) {
+        $self->error("Keine Dateinamen zum Überprüfen übergeben.");
+        exit 9;
+    }
+    $self->debug( sprintf( "Vergleiche Inhalte der Dateien '%s' und '%s' ...", $file1, $file2 ) ) if $self->verbose >= 2;
+    return 1 unless -f $file1;
+    return 1 unless -f $file2;
+
+    my $content1 = $self->_read_map_file( $file1, $map_type );
+    my $content2 = $self->_read_map_file( $file2, $map_type );
+
+    return 1 unless $content1 and ref($content1) and ref($content1) eq 'ARRAY';
+    return 1 unless $content2 and ref($content2) and ref($content2) eq 'ARRAY';
+
+    return 1 unless scalar(@$content1) == scalar(@$content2);
+    my $length = scalar(@$content1);
+
+    my $i = 0;
+    my $they_are_different = 0;
+
+    for ( $i = 0; $i < $length; $i++ ) {
+
+        my $row1 = $content1->[$i];
+        my $row2 = $content2->[$i];
+
+        unless ( $row1 and ref($row1) and ref($row1) eq 'ARRAY' ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        unless ( $row2 and ref($row2) and ref($row2) eq 'ARRAY' ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        unless ( scalar(@$row1) == scalar(@$row2) ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        if ( defined( $row1->[0] ) ) {
+            unless ( defined( $row2->[0] ) ) {
+                $they_are_different = 1;
+                last;
+            }
+        }
+        elsif ( defined( $row2->[0] ) ) {
+            $they_are_different = 1;
+            last;
+        }
+        else {
+            next;
+        }
+
+        unless ( $row1->[0] eq $row2->[0] ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        my $values1 = $row1->[1];
+        my $values2 = $row2->[1];
+
+        if ( defined($values1) ) {
+            unless ( defined($values2) ) {
+                $they_are_different = 1;
+                last;
+            }
+        }
+        elsif ( defined($values2) ) {
+            $they_are_different = 1;
+            last;
+        }
+        else {
+            next;
+        }
+
+        unless ( $values1 and ref($values1) and ref($values1) eq 'ARRAY' ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        unless ( $values2 and ref($values2) and ref($values2) eq 'ARRAY' ) {
+            $they_are_different = 1;
+            last;
+        }
+
+        unless ( scalar(@$values1) == scalar(@$values2) ) {
+            $they_are_different = 1;
+            last;
+        }
+        next unless scalar(@$values1);
+
+        my $vals_diff = 0;
+        VALUES: for ( my $j = 0; $j < scalar(@$values1); $j++ ) {
+
+            my $v1 = $values1->[$j];
+            my $v2 = $values2->[$j];
+
+            if ( defined($v1) ) {
+                unless ( defined($v2) ) {
+                    $vals_diff = 1;
+                    last VALUES;
+                }
+            }
+            elsif ( defined($v2) ) {
+                $vals_diff = 1;
+                last VALUES;
+            }
+            else {
+                next VALUES;
+            }
+
+            if ( $v1 ne $v2 ) {
+                $vals_diff = 1;
+                last VALUES;
+            }
+
+        }
+
+        if ( $vals_diff ) {
+            $they_are_different = 1;
+            last;
+        }
+
+    }
+
+    return $they_are_different;
+
+}
+
+#---------------------------------
+
+=head2 _read_map_file( $file, $type )
+
+Liest eine Postfix-Mapdatei aus und liefert eine Datenstruktur zurück
+
+=cut
+
+sub _read_map_file {
+
+    my $self = shift;
+    my $file = shift;
+    my $type = shift;
+
+    $type ||= 'map';
+
+    unless ( $file ) {
+        $self->error( "Kein Dateiname zum Einlesen übergeben." );
+        return undef;
+    }
+
+    unless ( -f $file ) {
+        $self->warn( sprintf( "Datei '%s' existiert nicht.", $file ) );
+        return undef;
+    }
+
+    my $content = [];
+    my $line = '';
+
+    $self->debug( sprintf( "Lese Datei '%s' ein ...", $file ) ) if $self->verbose >= 3;
+    unless ( open FILE, "<", $file ) {
+        $self->error( sprintf( "Konnte Datei '%s' nicht zum Lesen öffnen: %s", $file, $! ) );
+        return undef;
+    }
+
+    while ( <FILE> ) {
+        next if /^\s*#/;
+        if ( /^\s*$/ ) {
+            push @$content, $self->_parse_line( $line, $type ) if $line;
+            $line = '';
+            next;
+        }
+        if ( /^\s/ ) {
+            if ( $line ) {
+                s/\s+$//;
+                $line .= $_;
+                next;
+            }
+            push @$content, $self->_parse_line( $_, $type );
+            next;
+        }
+        push @$content, $self->_parse_line( $line, $type ) if $line;
+        $line = $_;
+    }
+    push @$content, $self->_parse_line( $line, $type ) if $line;
+
+    close FILE;
+
+    $self->debug( "Gelesener Dateiinhalt: ", $content ) if $self->verbose >= 4;
+    return $content;
+
+}
+
+#--------------------------------------------------------------------------------------
+
+=head2 _parse_line( $line, $map_type )
+
+=cut
+
+sub _parse_line {
+
+    my $self = shift;
+    my $line = shift;
+    my $map_type = shift;
+    return [] unless $line;
+
+    $self->debug( sprintf( "Parse Zeile '%s' ...", $line ) ) if $self->verbose >= 4;
+    $line =~ s/^\s+//;
+    $line =~ s/\s+$//;
+
+    my $res = [];
+
+    return [] if $line =~ /^\s*$/;
+
+    my ( $key, $rest );
+    my $match = $map_type eq 'aliases' ? '^(\\S+)\\s*:\\s*(\\S.*)' : '^(\\S+)\\s+(\\S.*)';
+    $self->debug( sprintf( "Match-RegEx: '%s'.", $match ) ) if $self->verbose >= 4;
+
+    unless ( ( $key, $rest ) = $line =~ /$match/ismx ) {
+        return [];
+    }
+
+    push @$res, $key;
+
+    my $targets = [];
+    @$targets = split /\s*,\s*/, $rest;
+    push @$res, ( scalar( @$targets ) ? $targets : $rest );
+
+    $self->debug( "Geparste Zeile: ", $res ) if $self->verbose >= 4;
+    return $res;
+
+}
+
+
 #---------------------------------
 
 __PACKAGE__->meta->make_immutable;