Anzeige:
Ergebnis 1 bis 13 von 13

Thema: Mail-Info Backup

  1. #1
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9

    Mail-Info Backup

    Moin zusammen,

    ich habe mal eine Frage an Euch. Ich mache hier von unseren Daten und natürlich auch von den E-Mail täglich ein Backup. Das ganze wird ordentlich geloggt damit ich nachschauen kann welche Daten auf dem Backup sind. Das habe ich bis jetzt aber nur für allgemeine Daten gemacht nicht aber für die Mails. Das Backup wird mit einem selbst geschriebenen Script gemacht welches über ein cronjob aufgerufen wird.
    Das Problem was ich habe ist Postfix scheibt die Mails an sich ja einfach als Datei(z.B. "154." ) auf die Platte, wenn ich mir davon ne liste ausgeben lasse bringt mich das ja nicht wirklich weiter, wenn ein user eine Speziele Mail wieder haben will. Also muss ich zumindest die Infos "From", "Subject", "Date" und "To" auslesen um überhaupt eine zuordnung machen zu können. Dazu noch die Dateiname und den Pfad.
    So die Sache ist ich bräuchte eine recht schlanke Lösung da das Backup an sich schon recht lange braucht. Hat da jemand ne Idee oder Erfahrung mit. Bin für jede Idee Dankbar.

    mfg

    mex

    System:
    SuSE 10
    Postfix, cyrus und spamd

  2. #2
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Starte vor dem Backup ein Perl-Script, das Dir die gewünschten Daten aus den Mailordnern zieht und in eine separate Liste (am besten pro User eine) schreibt. Damit hast Du zwar ein kleines Zeitloch (es können ja Mails eintrudeln zwischen dem Start des Scripts und dem Start des Backups), aber das sollte zu verschmerzen sein - Perl ist ziemlich fix.

    Wenn Du Dich mit Perl nicht auskennst, dann poste hier mal eine anonymisierte Postfix-Datei.

    Jan

    P.S.: Du kannst sowas natürlich mit fast jeder Programmiersprache machen, aber nach meinen Erfahrungen ist Perl bei Textanalyse immer noch am schnellsten.

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.09.2004
    Ort
    Mannheim
    Beiträge
    102
    Das ist nicht Postfix sondern Cyrus, der diese Dateien anlegt.
    Ich rate aber davon ab, dem Cyrus auf Dateisystemebene in seine Ablage reinzupfuschen. Suchen kannst du natürlich, aber beim Restore müsstest du schon einen reconstruct machen.

    Außerdem werden die Namen auch wiedervergeben, dass heisst ein 154. ist heute vlt. eine andere Mail als gestern.

    Als Viewer für diese Dateien eignen sich Konqueror, aber mit etwas Gebastel auch Maildir-fähige Mailclients.
    Greetz
    Thomas
    - Jabber-IM: tschloss-at-gmail.com -

  4. #4
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    Danke für die Antworten.
    Ne von Perl versteh ich nicht all zu viel . Also hier mal ein Beispiel wie so eine Datei aussieht. Ich hoffe ich habe die richtig verstanden. Nur was du mit einem configfile anfangen wolltest wüsst ich auch nicht

    Code:
    Return-Path: <sender-adresse>
    Received: from empfänger-domain.de ([unix socket])
             by empfänger-server (Cyrus v2.2.12) with LMTPA;
             Mon, 30 Jul 2007 10:41:24 +0200
    X-Sieve: CMU Sieve 2.2
    Received: from localhost (localhost [127.0.0.1])
            by empfänger-domain.de (Postfix) with ESMTP id 19E72114655
            for <empfänger-adresse>; Mon, 30 Jul 2007 10:41:24 +0200 (CEST)
    Received: from empfänger-domain.de ([127.0.0.1])
     by localhost (empfänger-domain.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP
     id 15472-05 for <xxx@localhost.empfänger-domain.de>;
     Mon, 30 Jul 2007 10:41:23 +0200 (CEST)
    Received: from localhost (localhost [127.0.0.1])
            by empfänger-domain.de (Postfix) with ESMTP id CD030114653
            for <xxx@localhost>; Mon, 30 Jul 2007 10:41:22 +0200 (CEST)
    Delivery-Date: Mon, 30 Jul 2007 10:40:34 +0200
    Received-SPF: none (mxeu24: 85.25.139.103 is neither permitted nor denied by domain of sender-domain.de) client-ip=85.
    Received: from imap.1und1.com [212.227.15.187]
            by localhost with IMAP (fetchmail-6.2.5.2)
            for xxx@localhost (single-drop); Mon, 30 Jul 2007 10:41:22 +0200 (CEST)
    Received: from [85.25.139.103] (helo=echo636.server4you.de)
            by mx.kundenserver.de (node=mxeu24) with ESMTP (Nemesis),
            id 0MKtd6-1IFQnp3ATk-0004Gg for xxx@empfänger-domain.de; Mon, 30 Jul 2007 10:40:33 +0200
    Received: by echo636.server4you.de (Postfix, from userid 65534)
            id 6A4DF434254; Mon, 30 Jul 2007 10:40:34 +0200 (CEST)
    Received: from [192.168.1.2] (p57B7B308.dip0.t-ipconnect.de [87.183.179.8])
            by echo636.server4you.de (Postfix) with ESMTP id 377C743424E;
            Mon, 30 Jul 2007 10:40:22 +0200 (CEST)
    Message-ID: <46ADA36B.6000602@sender-domain.de>
    Date: Mon, 30 Jul 2007 10:38:03 +0200
    From: "Sender." <xxx@sender-domain.de>
    User-Agent: Thunderbird 1.5.0.12 (Windows/20070509)
    MIME-Version: 1.0
    To: empfänger <xxx@empfänger-domain.de>,
     "CC-Empfänger" <xxx@CC-empfänger-domain.de>
    Subject: <Subject>
    Content-Type: text/plain; charset=ISO-8859-15; format=flowed
    Content-Transfer-Encoding: 8bit
    Envelope-To: xxx@empfänger-domain.de
    X-Virus-Scanned: amavisd-new at empfänger-domain.de
    
    moin,
    
    <Mailinhalt>
    Interessant sind wie gesagt nur die Vier sachen aus der Mail und der Dateiname:

    Code:
    Date: Mon, 30 Jul 2007 10:38:03 +0200
    Code:
    From: "Sender." <xxx@sender-domain.de>
    Code:
    To: empfänger <xxx@empfänger-domain.de>
    Code:
    Subject: <Subject>
    --------------------------------------------------------------------------
    aber beim Restore müsstest du schon einen reconstruct machen.

    Außerdem werden die Namen auch wiedervergeben, dass heisst ein 154. ist heute vlt. eine andere Mail als gestern.
    Das mit dem Restore ist klar, das mach ich ja bei Mails die der Virenscanner oder Spamfilter fälschlicherweise weg sotiert hat.
    Ändert sich der Name nicht nur wenn die Mail in ein anderes Verzeichnis gelegt wird? Wenn die Mail immer im gleichen Verzeichnis liegt sollte sich der Name doch nicht änder, hab das zwar noch nie getestet aber wäre für mich ziemlich unlogisch.


    mfg

    mex

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.09.2004
    Ort
    Mannheim
    Beiträge
    102
    Eine Mail-Datei zu finden ist mit egrep sicher nicht besonders schwer, mit einem Perl Progrämmchen (es gibt im CPAN Module, die das Mailformat mit allem drum und dran interpretieren können) kann man das leicht noch etwas aufpeppen.
    Schöner wird es, wenn du dir das Verzechnis etwas umbastelst bzw. deinen Backup in eine Maildir-Struktur hinein machst, damit es wie ein echtes Maildir aussieht und dann mit einem Client draufschaust. Das ist für Einzelfälle angenehm, aber um es für einen Regelbetrieb zu nutzen müßtest du den Ansatz noch verfeinern.

    Mit den Datenamen miente ich nur, dass wenn der User die 153. abgeholt / gelöscht hat, dass dann eine neue eingehende Mail auch wieder 153. heissen kann. Das heisst man muss beim Zurückspeichern auf Konfliktfreiheit achten.
    Greetz
    Thomas
    - Jabber-IM: tschloss-at-gmail.com -

  6. #6
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    nein, ich wollte tatsächlich nur ein Beispiel für eine Mail haben, keine Konfig. So könnte ein kleines Perl-Script aussehen, das Dir die benötigten Infos extrahiert:
    Code:
    #! /usr/bin/perl
    
    use strict;
    use warnings;
    use File::Basename;
    
    # Basis-Mailverzeichnis
    my $BASE_DIR  = "/home/jan/tmp/mail_info";
    
    # Daten aus einer Mail ziehen
    # Parameter: Dateiname mit absolutem Pfad
    sub extract_maildata {
      my ($fname) = @_;
      # Dateinamen und Verzeichnis trennen
      my ($dir, $file) = $fname =~ m#^(.+)/([^/]+)$#;
      if (open MFILE, $fname) {
        # benoetigte Daten initialisieren
        my $date = "";
        my $from = "";
        my $to   = "";
        my $subj = "";
        # Datei zeilenweise lesen
        foreach my $line (<MFILE>) {
          # Zeilenende \n entfernen
          chomp $line;
          # 1. Leerzeile in einer Mail ist Header-Ende
          last if $line =~ /^$/;
          # nach den Daten suchen, extrahieren
          ($date) = $line =~ m/^Date: (.+)$/ if $line =~ /^Date: /;
          ($from) = $line =~ m/^From: (.+)$/ if $line =~ /^From: /;
          ($to)   = $line =~ m/^To: (.+)$/ if $line =~ /^To: /;
          ($subj) = $line =~ m/^Subject: (.+)$/ if $line =~ /^Subject: /;
        }
        close MFILE;
        # CSV-Zeile nach STDOUT schreiben
        print "$dir|$file|$date|$from|$to|$subj\n";
      }
    }
    
    # rekursiv Verzeichnisse einlesen
    # Parameter: Verzeichnis (absoluter Pfad)
    sub read_dir {
      my ($dname) = @_;
      # Verzeichnis oeffnen und Inhalt in Array lesen
      if (opendir FDIR, $dname) {
        my @dlist = readdir FDIR;
        closedir FDIR;
        # Array durchlaufen
        foreach my $d (@dlist) {
          # . und .. interessieren nicht
          next if $d =~ /^\.{1,2}$/;
          # absoluter Pfad des Verzeichniseintrags
          my $p = $dname . "/" . $d;
          # wieder Verzeichnis? rekursiv read_dir aufrufen
          if (-d $p) {
            read_dir($p);
          }
          # Datei gefunden: Parsen
          elsif (-f $p) {
            extract_maildata($p);
          }
        }
      }
    }
    
    # MAIN
    # Header nach STDOUT schreiben
    print "Pfad|Dateiname|Datum|Absender|Empfaenger|Betreff\n";
    # Basisverzeichnis durchackern
    read_dir $BASE_DIR;
    exit 0;
    Das Script durchforstet ab dem mit $BASE_DIR definierten Verzeichnis rekursiv den ganzen Baum und parst jede gefundene Datei nach den angegebenen Daten. Die Erebnisse schreibt es im CSV-Format auf STDOUT (Feldtrenner ist |), die Datei kannst Du dann z. B. in OpenOffice Calc importieren, suchen, sortieren, ...

    Aufrufen kannst Du das Script z. B. so:
    Code:
    jan@jack:~/tmp> ./get_mailinfo.pl >mail_info.txt
    jan@jack:~/tmp> cat mail_info.txt
    Pfad|Dateiname|Datum|Absender|Empfaenger|Betreff
    /home/jan/tmp/mail_info|135|Mon, 30 Jul 2007 10:38:03 +0200|"Sender." <xxx@sender-domain.de>|empfänger <xxx@empfänger-domain.de>,|<Subject>
    /home/jan/tmp/mail_info/jan|144|Mon, 30 Jul 2007 10:38:03 +0200|"Sender." <xxx@sender-domain.de>|empfänger <xxx@empfänger-domain.de>,|<Subject>
    /home/jan/tmp/mail_info/jan61|222|Mon, 30 Jul 2007 10:38:03 +0200|"Sender." <xxx@sender-domain.de>|empfänger <xxx@empfänger-domain.de>,|<Subject>
    Das ist nat. nur ein grobes Beispiel. Wenn Du z. B. noch Dateien im Tree hast, die keine Mails sind, dann müssten diese noch abgefangen werden, Fehlerhandling ist auch eher rudimentär.

    HTH
    Jan

  7. #7
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    Super Danke euch Beiden ich werde das ganze heute gleich mal testen.

    mfg

    mex

  8. #8
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    Moin hat doch etwas gedauert mit dem testen ist bisschen viel los im moment . Also ich habe es jetzt mal an einem kleinen Datenbestand getestet. Es funktioniert soweit er liest das aus was er soll und schreib es auch in die Log-Datei. Es gibt nur ein kleines Problem für das ich aber keine Lösung gefunden habe. Die Formatierung in der Log- bzw. CVS-Datei stimmt irgendwie nicht ganz der mach dort ein paar Zeilenumbrüche die nicht seien dürften. Das hat zur folge das man die Daten leider nicht ordentlich in eine Calc-Tabelle importieren kann. Wenn ich von Hand die Zeilenumbrüche raus nehme gehts nur kann ich das bei ca. 800.000 Datensätzen nicht Händisch machen

    Code:
    /home/user/tdir/NeuerO|10524.|Wed, 20 Dec 2006 16:11:27 +0100
    |Absender <absender@domain.de>
    |Empfänger <empfänger@domain.de>
    |Re: Subject
    genau so ist die Formatierung und Sie Sollte so sein



    Code:
    /home/user/tdir/NeuerO|10524.|Wed, 20 Dec 2006 16:11:27 +0100|Absender <absender@domain.de>|Empfnger <empfnger@domain.de>|Re: Subject
    Ich hab schon versucht das zu ändern aber irgendwie find ich da keine Lösung. Wäre sehr dankbar wenn da wär ne Idee hätte. Ein Hinweis oder Schubs in die richtige Richtung wäre mir schon genug

    mfg

    mex

  9. #9
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    da bleiben offenbar noch ein paar Zeilenumbrüche übrig, allerdings ist mir nicht ganz klar, woher die kommen (in extract_maildata soll chomp $line; eigentlich genau das verhindern). Kann es sein, dass da DOS-Zeilenenden drinstehen? Mach mal
    Code:
    od -cx mail_info.txt | less
    und schau nach, ob da irgendwo das Zeichen \r auftaucht.

    Du solltest sie wegkriegen, wenn Du in der Funktion extract_maildata folgende Zeile einfügst (ungetestet):
    Code:
    ...
          # Zeilenende \n entfernen
          chomp $line;
          $line =~ s/[\r\n]//g;
    ...
    Gruß
    Jan

  10. #10
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    Super danke so gehts .

    Also das erstellen geht echt fix, hab das mal mit knapp 68000 mails getestet hat er so ca. eine minute für gebraucht da kann man nicht meckern . Nur das importieren nach Clac kann man glaub ich getrost vergessen. 1. sagt Calc bei ca. 64000 Zeilen hier ist meine maximal Grenze erreicht und die Daten die er dann hat irgendwie zu sortieren kann man komplett vergessen. Ich teste das ganze noch mal mit einer DB denke mal wird eine Postgres damit wird es wahrscheinlich besser gehen aber ist zuviel aufwand, das rechnet sich nicht. Dafür geht das öffnen der .txt recht gut mit einem vernüpfitgen Editor, denke auch mal das das mit der jetzt funktionierenden Formatierung übersichtlich genug ist.

    Ein kleines Problem gibts allerdings noch, ist aber nichts was mich wirklich stört.
    Beim ausführen des Skriptes wird ein Fehler ausgegeben.

    Code:
    Use of uninitialized value in concatenation (.) or string at ./get_mailinfo.pl line 37.

    Das liegt aber, so wie ich es sehe, an der neuen Zeile.

    line 37 ist die folgende:

    Code:
      print "$dir|$file|$date|$from|$to|$subj \n";
    Also das letzte war nur zu Info halt falls noch jemand das Skript benutzt. Daten gehen keine verloren.

    mfg

    mex

    Und nochmals vielen Dank

  11. #11
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von mex Beitrag anzeigen
    ...Also das erstellen geht echt fix, hab das mal mit knapp 68000 mails getestet hat er so ca. eine minute für gebraucht da kann man nicht meckern . Nur das importieren nach Clac kann man glaub ich getrost vergessen. 1. sagt Calc bei ca. 64000 Zeilen hier ist meine maximal Grenze erreicht und die Daten die er dann hat irgendwie zu sortieren kann man komplett vergessen....
    Vielleicht wäre eine Variante, das in kleinere Brocken aufzuteilen (z. B. nach Empfänger, das sollte doch Sinn machen?):
    Code:
    jan@jack:~/tmp> cat split_mailinfo.pl
    #! /usr/bin/perl
    
    use strict;
    use warnings;
    
    my $hdr     = "";
    my $prev_to = "";
    
    while (<STDIN>) {
      if ($hdr eq "") {
        $hdr = $_;
        next;
      }
      my @f = split /\|/;
      my ($to) = $f[4] =~ m/.*?([\wäöüß.-]+@[\wäöüß.-]+).*/i;
      if ($prev_to ne $to) {
        close OUT if $prev_to ne "";
        open OUT, ">mail_out/${to}.csv" or die "kann Ausgabedatei nicht oeffnen ($!)\n";
        print OUT $hdr;
      }
      print OUT $_;
      $prev_to = $to;
    }
    close OUT;
    
    exit 0;
    Das rufst Du dann wie folgt auf:
    Code:
    ./get_mailinfo.pl | sort -t '|' -k 5 | ./split_mailinfo.pl
    und hast im Verzeichnis mail_out je Empfänger 1 CSV-Datei liegen.

    Eine andere Variante wäre nach Tagen zu splitten:
    Code:
    jan@jack:~/tmp> cat split_mailinfo2.pl
    #! /usr/bin/perl
    
    use strict;
    use warnings;
    
    my $hdr     = "";
    my $prev_dt = "";
    
    while (<STDIN>) {
      if ($hdr eq "") {
        $hdr = $_;
        next;
      }
      my @f = split /\|/;
      my ($dt) = $f[2] =~ m/^[^ ]* (\d+ \w+ \d+) .*/i;
      if ($prev_dt ne $dt) {
        close OUT if $prev_dt ne "";
        open OUT, ">mail_out/${dt}.csv" or die "kann Ausgabedatei nicht oeffnen ($!)\n";
        print OUT $hdr;
      }
      print OUT $_;
      $prev_dt = $dt;
    }
    close OUT;
    
    exit 0;
    Aufruf analog:
    Code:
    ./get_mailinfo.pl | sort -t '|' -k 3 | ./split_mailinfo2.pl
    Das Prinzip könnte (und muss!) man noch ausbauen, die Regex für die Ermittlung des Empfängers z. B. ist eher rudimentär, da findet man im Netz bessere, das Ganze variabel machen (nach beliebigen Feldern sortieren), leere Felder abfangen, Fehler abfangen, nach Tag+Stunde splitten... Nur so eine Idee, wie man der Datenflut Herr werden könnte.

    Zitat Zitat von mex Beitrag anzeigen
    Ein kleines Problem gibts allerdings noch, ist aber nichts was mich wirklich stört.
    Beim ausführen des Skriptes wird ein Fehler ausgegeben.

    Code:
    Use of uninitialized value in concatenation (.) or string at ./get_mailinfo.pl line 37.
    ...
    Nein, an der neuen Zeile liegt das nicht. Das kann z. B. passieren, wenn das Subject leer ist (ist ja nicht ungewöhnlich). Das kannst Du einfach umgehen:
    Code:
        close MFILE;
        $date = "" unless $date;
        $from = "" unless $from;
        $to   = "" unless $to;
        $subj = "" unless $subj;
        print "$dir|$file|$date|$from|$to|$subj\n";
    Damit wird immer dann, wenn ein Wert nicht definiert ist, ein Leerstring gesetzt (kannst natürlich auch irgendeinen Wert wie "--UNBEKANNT--" oder "--LEER--" einsetzen).

    Jan

  12. #12
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    moin,
    ich teste das noch mal hab im moment nur leider keine Zeit dafür. Kann also noch ein bisschen dauern bis ich wieder was poste.

    Noch mal vielen Dank für deine Mühen

    mfg

    mex

  13. #13
    Junior Mitglied
    Registriert seit
    14.08.2006
    Beiträge
    9
    Da hab ich doch glatt vergessen noch was zu posten...das script ist echt super also zumindest bei den Tests. Hab das ganze mal mit meinem Postfach ausprobiert(ca 66000 mails) ist ech fix das ganze...Probleme gibts nur wenn man die Daten richtung Excel schieben will...da ist irgendwann schluss mit Daten hinzufügen höhö, naja nehm ich dann halt ne postgres für, wenn es mal nötig ist. Aber ansonsten echt schönes Script.

    Vielen Dank noch mal.

    mfg

    mex

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •