home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / misc / vm-hack.el < prev    next >
Encoding:
Text File  |  1990-07-22  |  17.5 KB  |  692 lines

  1. ;From ark1!uakari.primate.wisc.edu!brutus.cs.uiuc.edu!apple!motcsd!hpda!hpcuhb!hpsmtc1!hp-ses!hplabs!hp-sdd!ncr-sd!ncrcae!hubcap!mephisto!tut.cis.ohio-state.edu!cs.utexas.edu!sun-barr!decwrl!shelby!neon!yossi Fri Dec 15 12:42:59 1989
  2. ;Article 1070 of comp.emacs:
  3. ;Path: ark1!uakari.primate.wisc.edu!brutus.cs.uiuc.edu!apple!motcsd!hpda!hpcuhb!hpsmtc1!hp-ses!hplabs!hp-sdd!ncr-sd!ncrcae!hubcap!mephisto!tut.cis.ohio-state.edu!cs.utexas.edu!sun-barr!decwrl!shelby!neon!yossi
  4. ;From yossi@Neon.Stanford.EDU (Joseph Friedman)
  5. ;Newsgroups: comp.emacs
  6. ;Subject: vm-hack.el
  7. ;Message-ID: <1989Dec7.001819.26761@Neon.Stan>
  8. ;Date: 7 Dec 89 00:18:00 GMT
  9. ;Lines: 502
  10. ;
  11. ;Hi folks!
  12. ;
  13. ;I recently discovered GNU Emacs, and became pretty addicted to it
  14. ;(some people will do anything to avoid work...)  Anyway, I took
  15. ;Johan Vromans' summary mode and hacked it up.  I also added MM-style
  16. ;mail forwarding.  The result is this chunk of e-lisp code, which I
  17. ;am posting here.  Since this is my first serious attempt at programming
  18. ;in e-lisp, I would appreciate any comments.
  19. ;
  20. ;-yossi
  21. ;(Yossi@CS.Stanford.EDU)
  22. ;
  23. ;------------------------------- Cut Here ----------------------------------
  24.  
  25. ;
  26. ; A few enhancements to VM.  First off, I fixed some bugs in Johan Vromans'
  27. ; summary mode, and extended his stuff to cover %f in the format (NOTE: I
  28. ; changed the names of his variables from jv-... to vm-hack-...)
  29. ; I also added an MM-style message forwarding.
  30. ;
  31. ; Here's Johan Vromans' README, with the name changes:
  32. ;
  33. ; > Hi VM freaks,
  34. ; >
  35. ; > I've been using the following extension to VM's summary handling for
  36. ; > some time, and I like it. So I want to share it with you.
  37. ; >
  38. ; > Features:
  39. ; >
  40. ; >  - when a mail originates from me, the recipient is shown instead of
  41. ; >    the sender, e.g. "To info-vm@cs.odu.edu".
  42. ; >
  43. ; >  - when a mail was originally sent to a mailing list, the name of the
  44. ; >    mailing list is shown instead, e.g. "[info-vm]".
  45. ; >
  46. ; > A user-settable variable "vm-hack-summary-mode" determines whether this
  47. ; > is never done (value = nil), only for the primary mailbox folder
  48. ; > (value = t), or for all folders (other values).
  49. ; > The local key "%" is set up to switch between this modes: "%" will
  50. ; > show all sender names, while "C-u %" will enable the above processing.
  51. ; >
  52. ; > The user-variable "vm-hack-mailing-lists" holds a list of all mailing lists
  53. ; > I partcipate in, e.g.
  54. ; >
  55. ; > (setq vm-hack-mailing-lists 
  56. ; >       (list
  57. ; >         "perl-users"
  58. ; >         "info-vm" "bug-vm"
  59. ; >         .....))
  60. ; >
  61. ; > Happy hacking!
  62. ; > Johan
  63. ; > --                           jv@mh.nl via internet backbones
  64. ; > Johan Vromans                   uucp: ..!{uunet,hp4nl}!mh.nl!jv
  65. ; > Multihouse Automatisering bv           phone/fax: +31 1820 62944/62500
  66. ; > Doesburgweg 7, 2803 PL Gouda, The Netherlands
  67. ; > ------------------------ "Arms are made for hugging" ---------------------
  68. ;
  69. ; The variable vm-hack-mm-forward controls the MM-style mail forwarding.
  70. ; See the documentation of the variable for more details.  I have tested
  71. ; this code on GNU Emacs v18.55, running under ULTRIX v3.1A.  Since I
  72. ; hack on sendmail, it is possible that this code will not work on your
  73. ; system.  Please let me know if it breaks.
  74. ;
  75. ; NOTE: If you expect to receive MM-style forwarded messages, you'd probably
  76. ;       want to add Resent-From, Resent-To, and Resent-Date to your
  77. ;       vm-visible-headers.
  78. ;
  79. ; You'll need to add (require 'vm-hack) to your vm-mode-hooks.
  80. ;
  81.  
  82. (provide 'vm-hack)
  83. (load "vm-summary")
  84. (load "vm-reply")
  85.  
  86. (defvar vm-hack-summary-mode t "\
  87.   *Enables intelligent handling of From-addresses in VM summary list.
  88.    Values are 'nil' (no handling), 't' (primary mailbox only) or anything
  89.    else, which causes all mailboxes to be handled.")
  90.  
  91. (defvar vm-hack-mailing-lists nil "*List of mailing lists.")
  92.  
  93. (defvar vm-hack-mm-forward t "\
  94.   *Controls the forwarding style of messages in VM.  Values:
  95.  
  96.     t:   MM-style forwarding.  When you use VM's \"forward\" command to
  97.          forward a message from person A to person B, the header is
  98.          constructed in such a way that B will think he got it from A
  99.          directly, except that the subject is modified according to
  100.          vm-forwarding-subject-format (if it is non-nil); the header
  101.      also indicates that the message is \"Resent-From\" you.
  102.          The body of the message is left unchanged.
  103.  
  104.     nil: The old VM forwarding.")
  105.  
  106. (define-key vm-mode-map "%" 'vm-hack-summary-shownames)
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167. ; we need the host name
  168. (defvar vm-hack-hostname "**JUNK**" "\
  169. *Hostname used by vm-hack-summary for recognizing an outgoing message.")
  170.  
  171. (if (string= vm-hack-hostname "**JUNK**")
  172.     (let (vm-hack-hostname-process)
  173.       (setq vm-hack-hostname-process
  174.         (start-process "host-name" nil
  175.                "sh" "-c" "cat > /dev/null; hostname"))
  176.       (set-process-filter vm-hack-hostname-process
  177.               '(lambda (process string)
  178.                  (setq vm-hack-hostname string)))
  179.       (process-send-eof vm-hack-hostname-process)
  180.       (while (string= vm-hack-hostname "**JUNK**") (sleep-for 1))
  181.       (setq vm-hack-hostname (substring vm-hack-hostname
  182.                     0 (string-match "$"
  183.                             vm-hack-hostname)))))
  184.  
  185.  
  186. (defun vm-hack-subs-mailing-list (hdr)
  187.   "Return name of mailing list, if found in HDR."
  188.   (let ((ll vm-hack-mailing-lists) (case-fold-search t) el res)
  189.     (while (not (null ll))
  190.       (setq el (car-safe ll))
  191.       (setq ll (cdr-safe ll))
  192.       (if (string-match (regexp-quote el) hdr)
  193.       (progn
  194.         (setq ll nil)        ; terminate loop
  195.         (setq res (concat "[" el "]")))))
  196.     res))
  197.       
  198. (defun vm-su-full-name (m)
  199.   ;; modified version of vm's vm-su-full-name.
  200.   ;; Depending on the value of vm-hack-summary-mode, some post-processing
  201.   ;; is done on the name displayed.
  202.   ;;
  203.   ;; If the mail is from/to a mailing list, the name of the list is
  204.   ;; displayed.
  205.   ;; If the mail originates from me, the recipient is shown.
  206.   ;;
  207.   (let (temp temp-full-name)
  208.     (setq temp-full-name
  209.       (or (vm-full-name-of m)
  210.           (progn (vm-su-do-author m) (vm-full-name-of m))))
  211.     (cond
  212.      ;; return what we have if no postprocessing selected
  213.      ((null vm-hack-summary-mode)
  214.       temp-full-name)
  215.  
  216.      ;; idem, if only the primary mailbox must be handled
  217.      ((and (eq vm-hack-summary-mode 't)
  218.        (not vm-primary-inbox-p))
  219.       temp-full-name)
  220.  
  221.      ;; first, try mailing lists
  222.      ((vm-hack-subs-mailing-list
  223.        (concat (vm-get-header-contents m "To") " "
  224.            (vm-get-header-contents m "Cc"))))
  225.  
  226.      ;; if not, maybe recipient?
  227.      ((and (or
  228.           (equal temp-full-name (user-login-name))
  229.           (equal temp-full-name (user-full-name)))
  230.          (setq temp (vm-su-do-recipient-address m)))
  231.       (concat "To " temp))
  232.  
  233.      ;; nope - return the full name
  234.      (t temp-full-name))))
  235.       
  236. (defun vm-su-from (m)
  237.   ;; modified version of vm's vm-su-from
  238.   (let (temp temp-from)
  239.     (setq temp-from
  240.       (or (vm-from-of m)
  241.           (progn (vm-su-do-author m) (vm-from-of m))))
  242.     (cond
  243.      ;; return what we have if no postprocessing selected
  244.      ((null vm-hack-summary-mode)
  245.       temp-from)
  246.  
  247.      ;; idem, if only the primary mailbox must be handled
  248.      ((and (eq vm-hack-summary-mode 't)
  249.        (not vm-primary-inbox-p))
  250.       temp-from)
  251.  
  252.      ;; first, try mailing lists
  253.      ((vm-hack-subs-mailing-list
  254.        (concat (vm-get-header-contents m "To") " "
  255.            (vm-get-header-contents m "Cc"))))
  256.  
  257.      ;; if not, maybe recipient?
  258.      ((and (or
  259.           (equal temp-from (user-login-name))
  260.           (equal temp-from (concat (user-login-name)
  261.                        "@" vm-hack-hostname)))
  262.        (setq temp (vm-su-do-recipient-address m)))
  263.       (concat "To " temp))
  264.  
  265.      ;; nope - return the from
  266.      (t temp-from))))
  267.  
  268. (defun vm-su-do-recipient-address (m)
  269.   (let (to)
  270.     (setq to (or (vm-get-header-contents m "To")
  271.          (vm-get-header-contents m "Apparently-To")))
  272.     (cond ((null to)
  273.        (setq to "???"))
  274.       ((string-match "^\\(\\([^<,]+[^ \t\n]\\)[ \t\n]+\\)?<\\([^>]+\\)>"
  275.              to)
  276.        (setq to (substring to (match-beginning 3) (match-end 3))))
  277.       ((string-match "[^,]*(\\([^),]+\\))[^,]*" to)
  278.        (setq to
  279.          (concat
  280.           (substring to (match-beginning 0) (1- (match-beginning 1)))
  281.           (substring to (1+ (match-end 1)) (match-end 0))))))
  282.     ;; ewe ewe see pee...
  283.     (if (and vm-gargle-uucp (string-match
  284. "\\([^!@:.]+\\)\\(\\.[^!@:]+\\)?!\\([^!@: \t\n]+\\)\\(@\\([^!@:. \t\n]+\\)\\(.[^ \t\n]+\\)?\\)?[ \t\n]*$"
  285.                  to))
  286.     (setq to
  287.           (concat
  288.            (substring to (match-beginning 3) (match-end 3)) "@"
  289.            (if (and (match-beginning 5) (match-beginning 2)
  290.             (not (match-beginning 6)))
  291.            (concat (substring to (match-beginning 5) (match-end 5))
  292.                ".")
  293.          "")
  294.            (substring to (match-beginning 1)
  295.               (or (match-end 2) (match-end 1)))
  296.            (if (match-end 2) "" ".UUCP"))))
  297.     to))
  298.  
  299. (defun vm-hack-summary-shownames (&optional dont)
  300.   "Show full names in summary instead of mailing lists etc., or the
  301. other way around if prefix arg is supplied."
  302.   (interactive "P")
  303.   (let ((vm-hack-summary-mode dont))
  304.     (vm-summarize nil)))
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365. ;
  366. ; A slight change to vm-do-reply.  Need to turn off vm-hack-summary-mode
  367. ; when figuring out the vm-included-text-attribution-format, since some
  368. ; people out there may reply to themselves.
  369. ;
  370. (defun vm-do-reply (to-all include-text)
  371.   (vm-follow-summary-cursor)
  372.   (if vm-mail-buffer
  373.       (set-buffer vm-mail-buffer))
  374.   (vm-error-if-folder-empty)
  375.   (save-restriction
  376.     (widen)
  377.     (let ((mail-buffer (current-buffer))
  378.       (text-start (vm-text-of (car vm-message-pointer)))
  379.       (text-end (vm-text-end-of (car vm-message-pointer)))
  380.       (mp vm-message-pointer)
  381.       to cc subject message-id tmp)
  382.       (cond ((setq to (vm-get-header-contents (car mp) "Reply-To")))
  383.         ((setq to (vm-get-header-contents (car mp) "From")))
  384.         ((setq to (vm-grok-From_-author (car mp))))
  385.         (t (error "Cannot find a From: or Reply-To: header in message")))
  386.       (setq subject (vm-get-header-contents (car mp) "Subject")
  387.         message-id (and vm-in-reply-to-format
  388.                 (vm-sprintf 'vm-in-reply-to-format (car mp))))
  389.       (if to-all
  390.       (progn
  391.         (setq cc (vm-get-header-contents (car mp) "To"))
  392.         (setq tmp (vm-get-header-contents (car mp) "Cc"))
  393.         (if tmp
  394.         (if cc
  395.             (setq cc (concat cc ",\n\t" tmp))
  396.           (setq cc tmp)))))
  397.       (if vm-strip-reply-headers
  398.       (let ((mail-use-rfc822 t))
  399.         (require 'mail-utils)
  400.         (and to (setq to (mail-strip-quoted-names to)))
  401.         (and cc (setq cc (mail-strip-quoted-names cc)))))
  402.       (if (mail nil to subject message-id cc)
  403.       (progn
  404.         (use-local-map (copy-keymap (current-local-map)))
  405.         (local-set-key "\C-c\C-y" 'vm-yank-message)
  406.         (local-set-key "\C-c\C-s" 'vm-mail-send)
  407.         (local-set-key "\C-c\C-c" 'vm-mail-send-and-exit)
  408.         (local-set-key "\C-c\C-v" vm-mode-map)
  409.         (setq vm-mail-buffer mail-buffer
  410.           vm-message-pointer mp)
  411.         (cond (include-text
  412.            (goto-char (point-max))
  413.            (insert-buffer-substring mail-buffer text-start text-end)
  414.            (goto-char (- (point) (- text-end text-start)))
  415.            (save-excursion
  416.              (if vm-included-text-attribution-format
  417.              (let ((vm-hack-summary-mode nil))
  418.                (insert (vm-sprintf
  419.                     'vm-included-text-attribution-format
  420.                     (car mp)))))
  421.              (while (and (re-search-forward "^" nil t) (not (eobp)))
  422.                (replace-match vm-included-text-prefix t t))))))))))
  423.  
  424. ;
  425. ; A modified vm-forward-message.
  426. ;
  427. (defun vm-forward-message ()
  428.   "Forward the current message to one or more third parties.
  429. You will be placed in a *mail* buffer as is usual with replies, but you
  430. must fill in the To: or Resent-To: header manually." 
  431.   (interactive)
  432.   (vm-follow-summary-cursor)
  433.   (if vm-mail-buffer
  434.       (set-buffer vm-mail-buffer))
  435.   (vm-error-if-folder-empty)
  436.   (let ((b (current-buffer)) (m (car vm-message-pointer)) start)
  437.     (save-restriction
  438.       (widen)
  439.       (if vm-hack-mm-forward
  440.  
  441.       ; use MM-style forwarding
  442.       (cond ((mail nil nil nil)
  443.          (use-local-map (copy-keymap (current-local-map)))
  444.          (local-set-key "\C-c\C-y" 'vm-yank-message)
  445.          (local-set-key "\C-c\C-v" vm-mode-map)
  446.          (setq vm-mail-buffer b)
  447.  
  448.          ; reconstruct the whole thing
  449.          (erase-buffer)
  450.  
  451.              ; put header of old message
  452.          (insert-buffer-substring
  453.            b
  454.            (save-excursion
  455.              (set-buffer b)
  456.              (goto-char (vm-start-of m))
  457.              (forward-line 1)
  458.              (point))
  459.            (save-excursion
  460.              (set-buffer b)
  461.              (goto-char (vm-text-of m))
  462.              (forward-line -1)
  463.              (point)))
  464.          (set-window-start (get-buffer-window (current-buffer))
  465.                    (point))
  466.  
  467.              ; if diff't subject format, reformat subject line
  468.          (and
  469.            vm-forwarding-subject-format
  470.            (goto-char (point-min))
  471.            (re-search-forward
  472.              "^Subject:[ \t]+\\([^\n]*\n\\([ \t][^\n]*\n\\)*\\)"
  473.              (point-max) t)
  474.            (progn
  475.              (delete-region (match-beginning 0) (match-end 0))
  476.              (goto-char (point-max))
  477.              (insert "Subject: "
  478.                  (save-excursion
  479.                    (set-buffer b)
  480.                    (vm-sprintf 'vm-forwarding-subject-format m)))
  481.              (insert "\n")))
  482.  
  483.              ; add new header fields
  484.          (goto-char (point-max))
  485.          (insert "Resent-From: " (user-login-name) "\n")
  486.          (insert "Resent-To: ")
  487.          (save-excursion
  488.            (insert "\n")
  489.            (insert mail-header-separator "\n")
  490.          
  491.                ; include original message
  492.            (insert-buffer-substring b (goto-char (vm-text-of m))
  493.                         (vm-end-of m)))))
  494.  
  495.         ; nope. use old VM forwarding
  496.     (cond ((mail nil nil
  497.              (and vm-forwarding-subject-format
  498.               (vm-sprintf 'vm-forwarding-subject-format m)))
  499.            (use-local-map (copy-keymap (current-local-map)))
  500.            (local-set-key "\C-c\C-y" 'vm-yank-message)
  501.            (local-set-key "\C-c\C-v" vm-mode-map)
  502.            (setq vm-mail-buffer b)
  503.            (goto-char (point-max))
  504.            (insert "------- Start of forwarded message -------\n")
  505.            (setq start (point))
  506.            (insert-buffer-substring b
  507.                     (save-excursion
  508.                       (set-buffer b)
  509.                       (goto-char (vm-start-of m))
  510.                       (forward-line 1)
  511.                       (point))
  512.                     (vm-text-end-of m))
  513.            (if vm-rfc934-forwarding
  514.            (vm-rfc934-char-stuff-region start (point)))
  515.            (insert "------- End of forwarded message -------\n")
  516.            (goto-char (point-min))
  517.            (end-of-line)))))))
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578. ;
  579. ; A hacked-up version of sendmail-send-it that understands my forwarding
  580. ; mechanism
  581. ;
  582.  
  583. (defun vm-hack-sendmail-send-it ()
  584.   (let ((errbuf (if mail-interactive
  585.             (generate-new-buffer " sendmail errors")
  586.           0))
  587.     (tembuf (generate-new-buffer " sendmail temp"))
  588.     (case-fold-search nil)
  589.     (resent nil)
  590.     delimline
  591.     (mailbuf (current-buffer)))
  592.     (unwind-protect
  593.     (save-excursion
  594.       (set-buffer tembuf)
  595.       (erase-buffer)
  596.       (insert-buffer-substring mailbuf)
  597.       (goto-char (point-max))
  598.       ;; require one newline at the end.
  599.       (or (= (preceding-char) ?\n)
  600.           (insert ?\n))
  601.       ;; Change header-delimiter to be what sendmail expects.
  602.       (goto-char (point-min))
  603.       (re-search-forward
  604.         (concat "^" (regexp-quote mail-header-separator) "\n"))
  605.       (replace-match "\n")
  606.       (backward-char 2)
  607.       (setq delimline (point-marker))
  608.       (if mail-aliases
  609.           (expand-mail-aliases (point-min) delimline))
  610.       (goto-char (point-min))
  611.       ;; ignore any blank lines in the header
  612.       (while (and (re-search-forward "\n\n\n*" delimline t)
  613.               (< (point) delimline))
  614.         (replace-match "\n"))
  615.       (let ((case-fold-search t))
  616.         ;; Find and handle any FCC fields.
  617.         (goto-char (point-min))
  618.         (if (re-search-forward "^FCC:" delimline t)
  619.         (mail-do-fcc delimline))
  620.         ;; If there is a From and no Sender, put it a Sender.
  621.         (goto-char (point-min))
  622.         (and (re-search-forward "^From:"  delimline t)
  623.          (not (save-excursion
  624.             (goto-char (point-min))
  625.             (re-search-forward "^Sender:" delimline t)))
  626.          (progn
  627.            (forward-line 1)
  628.            (insert "Sender: " (user-login-name) "\n")))
  629.         ;; don't send out a blank subject line
  630.         (goto-char (point-min))
  631.         (if (re-search-forward "^Subject:[ \t]*\n" delimline t)
  632.         (replace-match ""))
  633.  
  634.         ;; if resent message, find out the real recipient
  635.         (save-excursion
  636.           (goto-char delimline)
  637.           (if (re-search-backward
  638.            "^Resent-To:[ \t]*\\([^\n]+\n\\(^[ \t]+[^ \t][^\n]*\n\\)*\\)"
  639.            (point-min) t)
  640.           (let ((s (buffer-substring (match-beginning 1) (match-end 1))))
  641.             (while (not (string= s ""))
  642.               (string-match "[^ ,\n]+" s)
  643.               (setq resent
  644.                 (append resent
  645.                     (list
  646.                       (substring
  647.                         s (match-beginning 0) (match-end 0)))))
  648.               (setq s (substring s (match-end 0) (length s)))
  649.               (and
  650.                 (string-match "[, \t\n][ \t\n]*" s)
  651.             (setq s (substring s (match-end 0) (length s))))))))
  652.  
  653.         (if mail-interactive
  654.         (save-excursion
  655.           (set-buffer errbuf)
  656.           (erase-buffer))))
  657.       (apply 'call-process-region
  658.          (append (list (point-min) (point-max)
  659.                    (if (boundp 'sendmail-program)
  660.                    sendmail-program
  661.                  "/usr/lib/sendmail")
  662.                    nil errbuf nil
  663.                    "-oi")
  664.              (if (null resent)
  665.                  (list "-t")
  666.                  resent)
  667.              ;; Always specify who from,
  668.              ;; since some systems have broken sendmails.
  669.              (list "-f" (user-login-name))
  670. ;;;             ;; Don't say "from root" if running under su.
  671. ;;;             (and (equal (user-real-login-name) "root")
  672. ;;;                  (list "-f" (user-login-name)))
  673.              ;; These mean "report errors by mail"
  674.              ;; and "deliver in background".
  675.              (if (null mail-interactive) '("-oem" "-odb"))))
  676.       (if mail-interactive
  677.           (save-excursion
  678.         (set-buffer errbuf)
  679.         (goto-char (point-min))
  680.         (while (re-search-forward "\n\n* *" nil t)
  681.           (replace-match "; "))
  682.         (if (not (zerop (buffer-size)))
  683.             (error "Sending...failed to %s"
  684.                (buffer-substring (point-min) (point-max)))))))
  685.       (kill-buffer tembuf)
  686.       (if (bufferp errbuf)
  687.       (kill-buffer errbuf)))))
  688.  
  689. (setq send-mail-function 'vm-hack-sendmail-send-it)
  690.  
  691.  
  692.