On Wed, 9 Jul 2003, Jason R. Mastaler wrote:
> Tim Rice <[EMAIL PROTECTED]> writes:
>
> > Perhaps a :
>
> OK with me unless anyone else sees a problem with it?
See if you like this mmdf patch.
It's against 9 July 2003 CVS.
--
Tim Rice Multitalents (707) 887-1469
[EMAIL PROTECTED]
--- tmda/TMDA/Deliver.py.old 2003-07-01 13:11:46.000000000 -0700
+++ tmda/TMDA/Deliver.py 2003-07-09 15:24:28.247200016 -0700
@@ -84,6 +84,11 @@
self.delivery_dest = self.option
if firstchar == '&':
self.delivery_dest = self.delivery_dest[1:].strip()
+ # An mmdf line begins with a :
+ elif firstchar == ':':
+ self.delivery_type = 'mmdf'
+ self.delivery_dest = self.option
+ self.delivery_dest = self.delivery_dest[1:].strip()
# An mbox line begins with a slash or tilde, and does not end
# with a slash.
elif (firstchar == '/' or firstchar == '~') and (lastchar != '/'):
@@ -116,6 +121,20 @@
elif type == 'forward':
# don't wrap headers, don't escape From, don't add From_ line
self.__deliver_forward(Util.msg_as_string(self.msg), dest)
+ elif type == 'mmdf':
+ # Ensure destination path exists.
+ if not os.path.exists(dest):
+ raise Errors.DeliveryError, \
+ 'Destination "%s" does not exist!' % dest
+ # Refuse to deliver to an mmdf if it's a symlink, to
+ # prevent symlink attacks.
+ elif os.path.islink(dest):
+ raise Errors.DeliveryError, \
+ 'Destination "%s" is a symlink!' % dest
+ else:
+ # don't wrap headers, escape From, add From_ line
+ self.__deliver_mmdf(Util.msg_as_string(self.msg, 0, 1, 1),
+ dest)
elif type == 'mbox':
# Ensure destination path exists.
if not os.path.exists(dest):
@@ -147,6 +166,61 @@
"""Forward message to address, preserving the existing Return-Path."""
Util.sendmail(message, address, self.env_sender)
+ def __deliver_mmdf(self, message, mmdf):
+ """Reliably deliver a mail message into an mmdf file.
+
+ Basicly a copy of __deliver_mbox():
+ Just make sure each message is surrounded by "\1\1\1\1\n"
+ """
+ try:
+ # When orig_length is None, we haven't opened the file yet.
+ orig_length = None
+ # Open the mmdf file.
+ fp = open(mmdf, 'rb+')
+ lock_file(fp)
+ status_old = os.fstat(fp.fileno())
+ # Check if it _is_ an mmdf file; mmdf files must start
+ # with "\1\1\1\1\n" in their first line, or are 0-length files.
+ fp.seek(0, 0) # seek to start
+ first_line = fp.readline()
+ if first_line != '' and first_line[:5] != '\1\1\1\1\n':
+ # Not an mmdf file; abort here.
+ unlock_file(fp)
+ fp.close()
+ raise Errors.DeliveryError, \
+ 'Destination "%s" is not an mmdf file!' % mmdf
+ fp.seek(0, 2) # seek to end
+ orig_length = fp.tell() # save original length
+ fp.write('\1\1\1\1\n')
+ # Add a trailing newline if last line incomplete.
+ if message[-1] != '\n':
+ message = message + '\n'
+ # Write the message.
+ fp.write(message)
+ # Add a trailing blank line.
+ fp.write('\n')
+ fp.write('\1\1\1\1\n')
+ fp.flush()
+ os.fsync(fp.fileno())
+ # Unlock and close the file.
+ status_new = os.fstat(fp.fileno())
+ unlock_file(fp)
+ fp.close()
+ # Reset atime.
+ os.utime(mmdf, (status_old[stat.ST_ATIME], status_new[stat.ST_MTIME]))
+ except IOError, txt:
+ try:
+ if not fp.closed and not orig_length is None:
+ # If the file was opened and we know how long it was,
+ # try to truncate it back to that length.
+ fp.truncate(orig_length)
+ unlock_file(fp)
+ fp.close()
+ except:
+ pass
+ raise Errors.DeliveryError, \
+ 'Failure writing message to mmdf file "%s" (%s)' % (mmdf, txt)
+
def __deliver_mbox(self, message, mbox):
"""Reliably deliver a mail message into an mboxrd-format mbox file.
--- tmda/TMDA/Defaults.py.old 2003-07-09 14:04:01.252560001 -0700
+++ tmda/TMDA/Defaults.py 2003-07-09 16:53:07.811760006 -0700
@@ -150,6 +150,7 @@
# DELIVERY = "|/usr/bin/maildrop"
# DELIVERY = "|/usr/bin/procmail ~/.procmailrc-tmda"
# DELIVERY = "[EMAIL PROTECTED]"
+# DELIVERY = ":/var/spool/mail/jasonrm"
#
# No default for non-qmail users.
if not vars().has_key('DELIVERY'):
@@ -163,7 +164,7 @@
# A single character which specifies the separator between user names
# and address extensions (e.g, user-ext).
# The default under qmail is `-', while the default for Sendmail and
-# friends is likely `+'.
+# friends is likely `+'. The default for MMDF is '='.
#
# Default is "-"
if not vars().has_key('RECIPIENT_DELIMITER'):
--- tmda/htdocs/config-vars.ht.old 2003-07-09 14:04:34.892560001 -0700
+++ tmda/htdocs/config-vars.ht 2003-07-09 16:50:06.266800026 -0700
@@ -1259,7 +1259,7 @@
A single character which specifies the separator between user names
and address extensions (e.g, user-ext).
The default under qmail is `-', while the default for Sendmail and
-friends is likely `+'.
+friends is likely `+'. The default for MMDF is '='.
<br><br>
Default is "-"
<dt><hr>
--- tmda/htdocs/config-filter.ht.old 2003-07-01 13:12:24.000000000 -0700
+++ tmda/htdocs/config-filter.ht 2003-07-09 15:32:39.792160019 -0700
@@ -182,6 +182,19 @@
</tr>
<tr>
+<td>mmdf</td>
+<td>
+An mmdf instruction begins with a colon.
+Please note the following restrictions below.
+</td>
+<td>
+<code>
+deliver=:/home/jason/Mailbox<br>
+</code>
+</td>
+</tr>
+
+<tr>
<td>mbox</td>
<td>
An mbox instruction begins with a slash or tilde, and does not end with a
@@ -212,11 +225,11 @@
</table>
<br>
-<u>Please note the following restrictions to mbox and Maildir delivery:</u><br>
+<u>Please note the following restrictions to mmdf, mbox and Maildir delivery:</u><br>
<ul>
<li>
-TMDA will not create Maildirs or mbox files if they do not exist. You
+TMDA will not create Maildirs, mmdf or mbox files if they do not exist. You
must create them prior to having TMDA deliver mail to them with
commands like
<a href="http://www.qmail.org/man/man1/maildirmake.html" TARGET="Resource Window">
@@ -225,17 +238,17 @@
<br><br>
<li>
-TMDA requires write access to any Maildir or mbox file you wish to
+TMDA requires write access to any Maildir, mmdf or mbox file you wish to
deliver mail to.
<br><br>
<li>
-TMDA will not deliver to an mbox symlink. Specify the path to the
+TMDA will not deliver to an mmdf or mbox symlink. Specify the path to the
actual mbox file instead.
<br><br>
<li>
-Do not deliver to mbox files located on an NFS filesystem. This is
+Do not deliver to mmdf or mbox files located on an NFS filesystem. This is
unsafe and can corrupt your mbox file -- this applies to all MDAs, not
just TMDA. Use Maildir instead as it is immune to such
problems.