diff --git a/Milter/dsn.py b/Milter/dsn.py
index 4407b8422c3f191c1f0fb8e2a382296abf85f31f..723d3a07687da7a80041cd7f68b3f0f443897dfe 100644
--- a/Milter/dsn.py
+++ b/Milter/dsn.py
@@ -5,6 +5,9 @@
 # Send DSNs, do call back verification,
 # and generate DSN messages from a template
 # $Log$
+# Revision 1.12  2006/07/26 16:37:35  customdesigned
+# Support timeout.
+#
 # Revision 1.11  2006/06/21 21:07:11  customdesigned
 # Include header fields in DSN template.
 #
@@ -79,6 +82,8 @@ def send_dsn(mailfrom,receiver,msg=None,timeout=600):
 
 def create_msg(q,rcptlist,origmsg=None,template=None):
   "Create a DSN message from a template.  Template must be '\n' separated."
+  if not template:
+    return None
   heloname = q.h
   sender = q.s
   connectip = q.i
@@ -98,11 +103,6 @@ def create_msg(q,rcptlist,origmsg=None,template=None):
   msg.add_header('X-Mailer','PyMilter-'+Milter.__version__)
   msg.set_type('text/plain')
 
-  if not template:
-    if spf_result and spf_result.startswith('softfail'):
-      template = softfail_msg
-    else:
-      template = nospf_msg
   hdrs,body = template.split('\n\n',1)
   for ln in hdrs.splitlines():
     name,val = ln.split(':',1)
diff --git a/bms.py b/bms.py
index fdd711d8c72605388b3076921f8b2ce7800bd659..248f7aac6e7e42deb6fa909af2f2ba0257b0fa4c 100644
--- a/bms.py
+++ b/bms.py
@@ -1,6 +1,9 @@
 #!/usr/bin/env python
 # A simple milter that has grown quite a bit.
 # $Log$
+# Revision 1.77  2006/12/31 03:07:20  customdesigned
+# Use HELO identity if good when MAILFROM is bad.
+#
 # Revision 1.76  2006/12/30 18:58:53  customdesigned
 # Skip reputation/whitelist/blacklist when rejecting on SPF.  Add X-Hello-SPF.
 #
@@ -81,7 +84,7 @@ subjpats = (
  r'^subjectbounce',
  r'^returned mail',
  r'^undeliver',
- r'^delivery\b.*\bfailure',
+ r'^delivery\b.*\bfail',
  r'^delivery problem',
  r'\buser unknown\b',
  r'^failed',
@@ -1683,24 +1686,29 @@ class bmsMilter(Milter.Milter):
       self.log('CBV:',sender,'(cached)')
       res = cbv_cache[sender]
     else:
-      self.log('CBV:',sender)
+      fname = template_name+'.txt'
       try:
 	template = file(template_name+'.txt').read()
-      except IOError: template = None
+	self.log('CBV:',sender,'Using:',fname)
+      except IOError:
+        template = None
+	self.log('CBV:',sender,'PLAIN')
       m = dsn.create_msg(q,self.recipients,msg,template)
-      if srs:
-        # Add SRS coded sender to various headers.  When (incorrectly)
-	# replying to our DSN, any of these which are preserved
-	# allow us to track the source.
-	msgid = srs.forward(sender,self.receiver)
-	m.add_header('Message-Id','<%s>'%msgid)
-	if 'x-mailer' in m:
-	  m.replace_header('x-mailer','"%s" <%s>' % (m['x-mailer'],msgid))
-	else:
-	  m.add_header('X-Mailer','"Python Milter" <%s>'%msgid)
-	m.add_header('Sender','"Python Milter" <%s>'%msgid)
-      m = m.as_string()
-      print >>open(template_name+'.last_dsn','w'),m
+      if m:
+	if srs:
+	  # Add SRS coded sender to various headers.  When (incorrectly)
+	  # replying to our DSN, any of these which are preserved
+	  # allow us to track the source.
+	  msgid = srs.forward(sender,self.receiver)
+	  m.add_header('Message-Id','<%s>'%msgid)
+	  if 'x-mailer' in m:
+	    m.replace_header('x-mailer','"%s" <%s>' % (m['x-mailer'],msgid))
+	  else:
+	    m.add_header('X-Mailer','"Python Milter" <%s>'%msgid)
+	  m.add_header('Sender','"Python Milter" <%s>'%msgid)
+	m = m.as_string()
+	print >>open(template_name+'.last_dsn','w'),m
+      # if missing template, do plain CBV
       res = dsn.send_dsn(sender,self.receiver,m,timeout=timeout)
     if res:
       desc = "CBV: %d %s" % res[:2]