Menu

#268 mh-redistribute + identity is broken with nmh >= 1.5

mh-e-8.7
closed-fixed
None
9
2018-08-05
2012-08-15
Kevin Layer
No

I don't have a distcomps file. Never have. mh-redistribute always worked. I have an identity that fixed problems with the lack of From: with nmh 1.5. mh-redistribute doesn't work, however.

With this config:

'(mh-identity-default "Home")
'(mh-identity-list (quote (("Home" (("From" . "\"Kevin Layer\" <layer@known.net>"))))))

redist doesn't work. From strace'ing emacs, I see

15628 writev(2, [{"post", 4}, {": ", 2}, {"message has no Resent-From: head"..., 34}, {"\n", 1}], 4) = 41
15628 writev(2, [{"post", 4}, {": ", 2}, {"See default components files for"..., 41}, {"\n", 1}], 4) = 48
15628 writev(2, [{"post", 4}, {": ", 2}, {"re-format message and try again", 31}, {"\n", 1}], 4) = 38
15628 write(6, "Prev-Resent: Tue, 07 Aug 2012 15"..., 2582) = 2582
15628 exit_group(1) = ?
15628 +++ exited with 1 +++
...
15630 writev(2, [{"post", 4}, {": ", 2}, {"message has no From: header", 27}, {"\n", 1}], 4) = 34
19176 <... read resumed> "post: message has no From: heade"..., 16384) = 34
15630 writev(2, [{"post", 4}, {": ", 2}, {"See default components files for"..., 41}, {"\n", 1}], 4 <unfinished ...>
19176 read(28, <unfinished ...>

I think adding something like this is needed:

(defun mh-redistribute (to cc &optional message)
...
(mh-goto-header-end 0)
;;added:
(when (and mh-identity-default mh-identity-list)
(let* ((id-list (car (cdr (assoc mh-identity-default
mh-identity-list))))
(from (assoc "From" id-list)))
(when from
(insert "Resent-From: " (cdr from) "\n"))))
;;;...finish addition
(insert "Resent-To: " to "\n")
...)

It definitely seems like the new contract that nmh 1.5 is imposing has
been broken by mh-redistribute in that it's not adding a Resent-From:
header.

Discussion

  • Kevin Layer

    Kevin Layer - 2012-08-15

    This is a very serious problem, since not only does mh-redistribute not work, but use of it causes messages to be silently dropped (I will file another bug on that).

     
  • Kevin Layer

    Kevin Layer - 2012-08-15
    • priority: 5 --> 9
     
  • Bill Wohler

    Bill Wohler - 2012-08-18
    • milestone: --> mh-e-8.3
    • labels: --> General
    • status: open --> open-accepted
     
  • Bill Wohler

    Bill Wohler - 2012-08-18

    Thanks, Kevin.

    I'd suggest fixing #3558007 first so that we have a test case to recover gracefully if rdist fails. Then fix this one.

     
    • Mike Kupfer

      Mike Kupfer - 2015-06-16

      Is 3558007 now ticket #269?

       

      Last edit: Mike Kupfer 2015-06-16
  • Bill Wohler

    Bill Wohler - 2012-12-10
    • assigned_to: Bill Wohler
     
  • Bill Wohler

    Bill Wohler - 2013-02-23
    • labels: General -->
     
  • Bill Wohler

    Bill Wohler - 2013-02-23
    • Status: open-accepted --> open
     
  • Bill Wohler

    Bill Wohler - 2014-08-05
    • Milestone: mh-e-8.3 --> mh-e-8.6
     
  • Mike Kupfer

    Mike Kupfer - 2015-06-21
    • Milestone: mh-e-8.6 --> mh-e-8.7
     
  • Jeffrey Honig

    Jeffrey Honig - 2015-12-26

    I'm finally looking at this.

    I wrote some code to get this from the identity. However this does not work if you do not have an identity.

    In order to fix this we are going to need to figure out if we are running the version of nmh that has a problem. If we are, we'll need to get nmh to tell us what Resent-From needs to be from the distcomps file. That means doing a 'comp -build -form distcomps' and parsing out the Resent-From value. If it does not exist, that's going to be an error.

    I'll try to work on this over Xmas break.

     
  • Jeffrey Honig

    Jeffrey Honig - 2015-12-26

    Attached is my diff to fix this and inline here is annotation on this diff. Anyone care to weigh in on this?

    diff --git a/lisp/mh-e/mh-comp.el b/lisp/mh-e/mh-comp.el
    index 5875b41..3fede82 100644
    --- a/lisp/mh-e/mh-comp.el
    +++ b/lisp/mh-e/mh-comp.el
    @@ -77,6 +77,14 @@ Default is \"components\".
    If not an absolute file name, the file is searched for first in the
    user's MH directory, then in the system MH lib directory.")

    +(defvar mh-dist-formfile "distcomps"
    + "Name of file to be used as a skeleton for redistributing messages.
    +
    +Default is \"distcomps\".
    +
    +If not an absolute file name, the file is searched for first in the
    +user's MH directory, then in the system MH lib directory.")
    +
    (defvar mh-repl-formfile "replcomps"
    "Name of file to be used as a skeleton for replying to messages.

    @@ -411,7 +419,7 @@ See also `mh-send'."
    (interactive (list (mh-get-msg-num t)))
    (let* ((from-folder mh-current-folder)
    (config (current-window-configuration))
    - (components-file (mh-bare-components))
    + (components-file (mh-bare-components mh-comp-formfile))
    (draft
    (cond ((and mh-draft-folder (equal from-folder mh-draft-folder))
    (pop-to-buffer (find-file-noselect (mh-msg-filename message))

    %%
    %% I updated mh-bare-components to require a form file name
    %%

    @@ -647,7 +655,7 @@ Original message has headers FROM and SUBJECT."
    (format mh-forward-subject-format from subject))

    ;;;###mh-autoload
    -(defun mh-redistribute (to cc &optional message)
    +(defun mh-redistribute (to cc identity &optional message)
    "Redistribute a message.

    This command is similar in function to forwarding mail, but it

    %%
    %% mh-redistribute now takes an identity
    %%

    @@ -666,6 +674,9 @@ The hook `mh-annotate-msg-hook' is run after annotating the
    message and scan line."
    (interactive (list (mh-read-address "Redist-To: ")
    (mh-read-address "Redist-Cc: ")
    + (if mh-identity-list
    + (mh-select-identity mh-identity-default)
    + nil)
    (mh-get-msg-num t)))
    (or message
    (setq message (mh-get-msg-num t)))

    %%
    %% When identities are enabled mh-redistribute prompts for one
    %%

    @@ -674,15 +685,35 @@ message and scan line."
    (draft (mh-read-draft "redistribution"
    (if mh-redist-full-contents-flag
    (mh-msg-filename message)
    - nil)
    - nil)))
    - (mh-goto-header-end 0)
    - (insert "Resent-To: " to "\n")
    - (if (not (equal cc "")) (insert "Resent-cc: " cc "\n"))
    + (mh-bare-components mh-dist-formfile))
    + (not mh-redist-full-contents-flag)))

    %%
    %% When not redisting contents, get MH/nmh to give us the
    %% componenets file as our draft
    %%

    • (from (or
    • (mh-identity-field identity "From")
    • (mh-get-header-field "Resent-From:")
    • ))

    %%
    %% If an identity is specified and has a From, use that.
    %% Otherwise read the header field
    %%

    • (fcc (mh-get-header-field "Resent-fcc:")))

    %%
    %% Get value of Resent-fcc: from components file
    %%

    • ;; Read interesting fields from distcomps file
    • (if mh-redist-full-contents-flag
    • (let ((components-file (mh-bare-components mh-dist-formfile)))
    • (mh-mapc
    • (function
    • (lambda (header-field)
    • (let ((field (car header-field))
    • (value (cdr header-field))
    • (case-fold-search t))
    • (cond
    • ;; Address field
    • ((string-match field "^Resent-fcc$")
    • (setq fcc (or fcc value)))
    • ((string-match field "^Resent-From%")
    • (setq from (or from value)))))))
    • (mh-components-to-list components-file))
    • (delete-file components-file)))

    %%
    %% When we are redisting the full contents, we need to read the
    %% components file separately. Are we interested in any values
    %% other than Resent-From: and Resent-fcc:?
    %%

       (mh-clean-msg-header
        (point-min)
    
    • "^Message-Id:\|^Received:\|^Return-Path:\|^Sender:\|^Date:\|^From:"
    • "^Message-Id:\|^Received:\|^Return-Path:\|^Sender:\|^Date:\|^Resent-fcc:\|^Resent-From:"
      nil)
    • (mh-insert-fields "Resent-To:" to "Resent-cc:" cc "Resent-From:" from "Resent-fcc:" fcc)
      (save-buffer)
      (message "Redistributing...")
      (let ((env "mhdist=1"))

    @@ -700,7 +731,7 @@ message and scan line."
    ;; Annotate...
    (mh-annotate-msg message folder mh-note-dist
    "-component" "Resent:"
    - "-text" (format "\"%s %s\"" to cc)))
    + "-text" (format "\"To: %s cc: %s From: %s\"" to cc from)))
    (kill-buffer draft)
    (message "Redistributing...done"))))

    %%
    %% I think removing From was wrong.
    %% Remove the fields we are going to add back
    %%

    @@ -896,7 +927,7 @@ CONFIG is the window configuration before sending mail."
    (message "Composing a message...")
    (let ((draft (mh-read-draft
    "message"
    - (mh-bare-components)
    + (mh-bare-components mh-comp-formfile)
    t)))
    (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc)
    (goto-char (point-max))

    %%
    %% I updated mh-bare-components to require a form file name
    %%

    @@ -906,23 +937,25 @@ CONFIG is the window configuration before sending mail."
    (mh-letter-mode-message)
    (mh-letter-adjust-point))))

    -(defun mh-bare-components ()
    - "Generate a temporary, clean components file and return its path."
    - ;; Let comp(1) create the skeleton for us. This is particularly
    +(defun mh-bare-components (formfile)
    + "Generate a temporary, clean components file from FORMFILE
    +and return its path."
    + ;; Let comp(1) create the skeleton for us. This is particularly
    ;; important with nmh-1.5, because its default "components" needs
    - ;; some processing before it can be used. Unfortunately, comp(1)
    - ;; doesn't have a -build option. So, to avoid the possibility of
    - ;; clobbering an existing draft, create a temporary directory and
    - ;; use it as the drafts folder. Then copy the skeleton to a regular
    - ;; temp file, and return the regular temp file.
    + ;; some processing before it can be used. Unfortunately, comp(1)
    + ;; didnt't have a -build option until later versions of nmh. So, to
    + ;; avoid the possibility of clobbering an existing draft, create
    + ;; a temporary directory and use it as the drafts folder. Then
    + ;; copy the skeleton to a regular; temp file, and return the
    + ;; regular temp file.
    (let (new
    (temp-folder (mm-make-temp-file
    (concat mh-user-path "draftfolder.") t)))
    (mh-exec-cmd "comp" "-nowhatnowproc"
    "-draftfolder" (format "+%s"
    (file-name-nondirectory temp-folder))
    - (if (stringp mh-comp-formfile)
    - (list "-form" mh-comp-formfile)))
    + (if (stringp formfile)
    + (list "-form" formfile)))
    (setq new (mm-make-temp-file "comp."))
    (rename-file (concat temp-folder "/" "1") new t)
    (delete-file (concat temp-folder "/" ".mh_sequences"))

    %%
    %% Now require the name of a form file.
    %% Comments updated slightly.
    %%

     
  • Jeffrey Honig

    Jeffrey Honig - 2015-12-26
    • assigned_to: Bill Wohler --> Jeffrey Honig
     
  • Jeffrey Honig

    Jeffrey Honig - 2015-12-26

    Also needed is the patch to mh-identity to add (mh-select-identity) and (mh-identity-field).

     
  • Jeffrey Honig

    Jeffrey Honig - 2016-01-08

    Attached is the latest version of the patch which I believe addresses Mike's review comments.

     
  • Mike Kupfer

    Mike Kupfer - 2018-08-05

    This will be fixed in Emacs 27.1.

    commit e1646e1e2864d6eaf567f4fe77cc11d3e17dde51
    Author: Mike Kupfer mkupfer@alum.berkeley.edu
    Date: Sat Aug 4 18:06:37 2018 -0700

    Fix mh-redistribute to work with nmh 1.5 and identities (SF#268)
    
    Co-authored-by: Jeffrey C Honig <jch@honig.net>
    
    * lisp/mh-e/mh-comp.el (mh-redistribute): Add a non-optional
    identity parameter.  Use mh-bare-components to generate a draft,
    then apply identity-specific settings.  Add more details to the
    "Resent" annotation line.
    (mh-dist-formfile): New.
    (mh-bare-components): Add a formfile argument.
    (mh-edit-again, mh-send-sub): Track the change to
    mh-bare-components.
    * lisp/mh-e/mh-identity.el (mh-select-identity)
    (mh-identity-field): New.
    
     
  • Mike Kupfer

    Mike Kupfer - 2018-08-05
    • status: open --> closed-fixed
     

Log in to post a comment.