Seite 1 von 1

Mail via qmail-queue weiterleiten

Verfasst: Freitag 7. November 2008, 13:17
von helduel
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

Verfasst: Freitag 7. November 2008, 13:46
von name
Ich verstehe nicht wieso du gerade die fd 0 und 1 oeffnest? Sind die nicht normalerweise stdin und stdout?

Verfasst: Freitag 7. November 2008, 14:34
von helduel
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