Function: rmail-retry-failure
rmail-retry-failure is an interactive and byte-compiled function
defined in rmail.el.gz.
Signature
(rmail-retry-failure)
Documentation
Edit a mail message which is based on the contents of the current message.
For a message rejected by the mail system, extract the interesting headers and
the body of the original message.
If the failed message is a MIME multipart message, it is searched for a
body part with a header which matches the variable mail-mime-unsent-header.
Otherwise, the variable mail-unsent-separator should match the string that
delimits the returned original message.
The variable rmail-retry-ignored-headers is a regular expression
specifying headers which should not be copied into the new message.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/mail/rmail.el.gz
(defun rmail-retry-failure ()
"Edit a mail message which is based on the contents of the current message.
For a message rejected by the mail system, extract the interesting headers and
the body of the original message.
If the failed message is a MIME multipart message, it is searched for a
body part with a header which matches the variable `mail-mime-unsent-header'.
Otherwise, the variable `mail-unsent-separator' should match the string that
delimits the returned original message.
The variable `rmail-retry-ignored-headers' is a regular expression
specifying headers which should not be copied into the new message."
(interactive)
(require 'mail-utils)
(let (bounce-buffer ;; Buffer we found it in
bounce-start ;; Position of start of failed message in that buffer
bounce-end ;; Position of end of failed message in that buffer
bounce-indent ;; Number of columns we need to de-indent it.
(msgnum rmail-current-message)
resending
(content-type (rmail-get-header "Content-Type")))
(save-excursion
(goto-char (point-min))
(let ((case-fold-search t))
(if (and content-type
(string-match
";[\n\t ]*boundary=\"?\\([-0-9a-z'()+_,./:=? ]+\\)\"?"
content-type))
;; Handle a MIME multipart bounce message
;; by scanning the raw buffer.
(let ((codestring
(concat "\n--"
(substring content-type (match-beginning 1)
(match-end 1))))
(beg (rmail-msgbeg msgnum))
(end (rmail-msgend msgnum)))
(with-current-buffer rmail-view-buffer
(save-restriction
(narrow-to-region beg end)
(goto-char (point-min))
(unless (re-search-forward mail-mime-unsent-header nil t)
(error "Cannot find beginning of header in failed message"))
(unless (search-forward "\n\n" nil t)
(error "Cannot find start of Mime data in failed message"))
(setq bounce-start (point))
(setq bounce-buffer (current-buffer))
(if (search-forward codestring nil t)
(setq bounce-end (match-beginning 0))
(setq bounce-end (point-max))))))
;; Non-MIME bounce.
(or (re-search-forward mail-unsent-separator nil t)
(error "Cannot parse this as a failure message"))
(skip-chars-forward "\n")
;; Support a style of failure message in which the original
;; message is indented, and included within lines saying
;; `Start of returned message' and `End of returned message'.
(if (looking-at " +Received:")
(progn
(setq bounce-start (point))
(skip-chars-forward " ")
(setq bounce-indent (- (current-column)))
(goto-char (point-max))
(re-search-backward "^End of returned message$" nil t)
(setq bounce-buffer (current-buffer))
(setq bounce-end (point)))
;; One message contained a few random lines before
;; the old message header. The first line of the
;; message started with two hyphens. A blank line
;; followed these random lines. The same line
;; beginning with two hyphens was possibly marking
;; the end of the message.
(if (looking-at "^--")
(let ((boundary (buffer-substring-no-properties
(point)
(progn (end-of-line) (point)))))
(search-forward "\n\n")
(skip-chars-forward "\n")
(setq bounce-start (point))
(goto-char (point-max))
(search-backward (concat "\n\n" boundary) bounce-start t)
(setq bounce-buffer (current-buffer))
(setq bounce-end (point)))
(setq bounce-start (point)
bounce-buffer (current-buffer)
bounce-end (point-max)))
(unless (search-forward "\n\n" nil t)
(error "Cannot find end of header in failed message"))))))
;; We have found the message that bounced, within the current message.
;; Now start sending new message; default header fields from original.
;; Turn off the usual actions for initializing the message body
;; because we want to get only the text from the failure message.
(let (mail-signature mail-setup-hook)
(if (rmail-start-mail nil nil nil nil nil rmail-buffer
(list (list 'rmail-mark-message
rmail-buffer
(aref rmail-msgref-vector msgnum)
rmail-retried-attr-index)))
;; Insert original text as initial text of new draft message.
;; Bind inhibit-read-only since the header delimiter
;; of the previous message was probably read-only.
(let ((inhibit-read-only t)
eoh)
(erase-buffer)
(insert-buffer-substring bounce-buffer
bounce-start bounce-end)
(goto-char (point-min))
(if bounce-indent
(indent-rigidly (point-min) (point-max) bounce-indent))
(rfc822-goto-eoh)
(setq eoh (point))
(insert mail-header-separator)
(save-restriction
(narrow-to-region (point-min) eoh)
(rmail-delete-headers rmail-retry-ignored-headers)
(rmail-delete-headers "^\\(sender\\|return-path\\|received\\):")
(setq resending (mail-fetch-field "resent-to"))
(if mail-self-blind
(if resending
(insert "Resent-Bcc: " (user-login-name) "\n")
(insert "Bcc: " (user-login-name) "\n"))))
(goto-char (point-min))
(mail-position-on-field (if resending "Resent-To" "To") t))))))