Mail via qmail-queue weiterleiten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

ich schlage mich gerade mit einem in Python geschriebenen Mailfilter herum, der via qmail-qfilter aufgerufen wird. Muss eine Mail an ein anderes Postfach weitergeleitet werden, benutzen wir zurzeit qmail-inject, um die Mail in die Queue einzustellen.

Jetzt gibt es ein Problem bei Mails, die von MS-Outlook 12 erstellt wurden: Dort kann es vorkommen, dass im To-header folgendes steht:
To: =?iso-8859-1?Q?Test:H=E4sin?= <foo@bar.de>
qmail-inject stört sich nun an dem Doppelpunkt und bricht mit der Meldung "qmail-inject: fatal: unable to parse this line:" ab. Das Problem wollen wir dadurch beheben, dass wir qmail-queue direkt verwenden, weil diesem die Header egal sind.

Soweit die Vorgeschichte :-).

Hier steht, dass man qmail-queue erst über den file descriptor 0 mit der Mail füttern muss, dann diesen descriptor schließen soll und dann den envelope über descriptor 1 schreiben muss.

Jetzt bastel ich schon ziemlich lange herum und komme nicht weiter:

Code: Alles auswählen

import os
from subprocess import Popen, PIPE

def main_subprocess():
    qmail_queue = Popen('/var/qmail/bin/qmail-queue',
                        stdin=PIPE, stdout=PIPE, stderr=PIPE)
    mail_fd = os.fdopen(0, 'wb')
    mail = open('mailfile.eml')
    try:
        data = mail.read()
    finally:
        mail.close()
    mail_fd.write(data)
    mail_fd.flush()
    mail_fd.close()

    env_fd = os.fdopen(1, 'wb')
    env_fd.write("mail from: me@mydomain.de\n"
                 "rcpt to: you@yourdomain.de\n")
    env_fd.flush()
    qmail_queue.communicate()
    print qmail_queue.wait()


if __name__ == '__main__':
    main_subprocess()
Als return code erhalte ich die 54, was zeigt, dass qmail-queue entweder die Mail oder den Envelope nicht lesen konnte.

Ich habe auch schon alles (?) mögliche versucht: Die Deskriptoren zu beginn öffnen und diese Popen übergeben. Die File-Objekte, die communicate() zurückgibt, gelesen und geschlossen, communicate() die mail übergeben, anstatt direkt auf mail_fd zu schreiben, die Descriptoren explizit geschlossen, auch mal nicht etc., etc...

Was mache ich hier falsch? Ich steh total auf dem Schlauch :cry: .

Gruß,
Manuel
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Ich verstehe nicht wieso du gerade die fd 0 und 1 oeffnest? Sind die nicht normalerweise stdin und stdout?
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

name hat geschrieben:Ich verstehe nicht wieso du gerade die fd 0 und 1 oeffnest? Sind die nicht normalerweise stdin und stdout?
Ha! Jetzt hab ich's. Danke, du hast mir den nötigen Anstoß gegeben. Den stdout iin Popen ersetze ich durch os.tmpfile() und schreibe dort den Envelope rein (der binär ist, wie ich gerade gelesen habe). Ich dachte, ich müsse stdout (fd 1) selbst schreibend öffnen und diesen übergeben :-/.

Folgender Code funktioniert:

Code: Alles auswählen

import os
from subprocess import Popen, PIPE

def main_subprocess():
    env_fd = os.tmpfile()

    qmail_queue = Popen('/var/qmail/bin/qmail-queue',
                        stdin=PIPE, stdout=env_fd, stderr=PIPE)
    mail = open('mailfile.eml')
    data = mail.read()
    mail_fd = qmail_queue.stdin
    mail_fd.write(data)
    mail_fd.flush()
    mail_fd.close()

    env_fd.write("Fme@mydomain.de\0Tyou.yourdomain.de\0\0")
    env_fd.flush()
    env_fd.seek(0)
    env_fd.close()
    print qmail_queue.wait()


if __name__ == '__main__':
    main_subprocess()
Gruß,
Manuel
Antworten