dsn.c:dsnuser_worstcase_list(...) should return the worst case. With the
current solution, if there are two deliveries (A with DSN_CLASS_OK and B
with DSN_CLASS_FAIL), there will be no delivery to A because of the
failure with B. Maybe a better solution would be to make
pipe.c:insert_messages(...) respect the individual status of the entries
of dsnusers?
The delivery to A is not thrown away, but may be duplicated when the MTA
retries B.
Maybe I don't understand completely how dsnusers gets filled, but the
current check
if (dsnuser_worstcase_list(&dsnusers) == DSN_CLASS_FAIL) {
trace(TRACE_DEBUG, "main(): [...]");
exitcode = EX_NOUSER;
goto freeall;
}
will *skip any* insertion, if at least *one* DSN_CLASS_FAIL occurs.
And the exitcode EX_NOUSER will prevent the MTA to retry (after all,
this is exactly what all this fuss is about).
This will not trouble me, because I call dbmail-smtp -d with only one
address. But won't this cause loss of mail, if you call it with several
addresses or let dbmail parse the headers itself?
This is correct; the status is changed in the event of an error or
over-quota situation. Lots of people have been saying that over-quota
should do a full bounce, and I think we should look into that after 2.0.1.
Of course, it is completely valid to change the status from OK to
TEMP_FAIL or FAIL, if an error occurs. But my problem is, that
insert_messages may also change the status from FAIL to TEMP_FAIL. Imho,
this is invalid behaviour (it may be the cause for duplicated mail).
I think, insert_messages should check each entry of dsnusers if its
status is OK and only then try to insert. This would make FAILs
permanent, but won't cause mail loss.
Best regards,
Michael