File: feedmail.el.html

A replacement for parts of sendmail.el (specifically, it's what handles your outgoing mail after you hit C-c C-c in mail mode). See below for a list of additional features, including the ability to queue messages for later sending. This replaces the standalone fakemail program that used to be distributed with Emacs.

Sorry, no manual yet in this release. Look for one with the next release. Or the one after that. Or maybe later.

As far as I'm concerned, anyone can do anything they want with this specific piece of code. No warranty or promise of support is offered. This code is hereby released into the public domain.

Thanks: My thanks to the many people who have sent me suggestions
   and fixes over time, as well as those who have tested many beta
   iterations. Some are cited in comments in code fragments below,
   but that doesn't correlate well with the list of folks who have
   actually helped me along the way.

If you use feedmail, I invite you to send me some email about it. I appreciate feedback about problems you find or suggestions for improvements or added features (even though I can't predict when I'll incorporate changes). It's also OK with me if you send me a note along the lines of "I use feedmail and find it useful" or "I tried feedmail and didn't find it useful, so I stopped using it".

It is most useful, when sending a bug report, if you tell me what version of Emacs you are using, what version of feedmail you are using, and what versions of other email-related elisp packages you are using. If in doubt about any of that, send the bug report anyhow.

=====
A NOTE TO THOSE WHO WOULD CHANGE THIS CODE... Since it is PD, you're within your rights to do whatever you want. If you do publish a new version with your changes in it, please (1) insert Lisp comments describing the changes, (2) insert Lisp comments that clearly delimit where your changes are, (3) email me a copy
(I can't always consistently follow the relevant usenet groups),
and (4) use a version number that is based on the version you're changing along with something that indicates you changed it. For example,

       (defconst feedmail-patch-level "123")
       (defconst feedmail-patch-level "123-XYZ-mods")

The point of the last item, of course, is to try to minimize confusion. Odds are good that if your idea makes sense to me that it will show up in some future version of feedmail, though it's hard to say when releases will tumble out.
=====

This file requires the mail-utils library.

This file requires the smtpmail library if you use feedmail-buffer-to-smtpmail. It requires the smtp library if you use feedmail-buffer-smtp.

This file requires the custom library. Unfortunately, there are two incompatible versions of the custom library. If you don't have custom or you have the old version, this file will still load and work properly. If you don't know what custom is all about and want to edit your user option elisp variables the old fashioned way, just imagine that all the "defcustom" stuff you see below is really
"defvar", and ignore everything else. For info about custom, see
<URL:http://www.dina.kvl.dk/~abraham/custom/>.

This code does in elisp a superset of the stuff that used to be done by the separate program "fakemail" for processing outbound email. In other words, it takes over after you hit "C-c C-c" in mail mode. By appropriate setting of options, you can even revert to sendmail
(which is not too popular locally). See the variables at the top
of the elisp for how to achieve these effects (there are more features than in this bullet list, so trolling through the variable and function doc strings may be worth your while):

   --- you can park outgoing messages into a disk-based queue and
       stimulate sending them all later (handy for laptop users);
       there is also a queue for draft messages

   --- you can get one last look at the prepped outbound message and
       be prompted for confirmation

   --- removes Bcc:/Resent-Bcc: headers after getting address info

   --- does smart filling of address headers

   --- calls a routine to process Fcc: lines and removes them

   --- empty headers are removed

   --- can force From: or Sender: line

   --- can generate a Message-Id: line

   --- can generate a Date: line; the date can be the time the
       message was written or the time it is being sent

   --- strips comments from address info (both "()" and "<>" are
       handled via a call to mail-strip-quoted-names); the
       comments are stripped in the simplified address list given
       to a subprocess, not in the headers in the mail itself
       (they are left unchanged, modulo smart filling)

   --- error info is pumped into a normal buffer instead of the
       minibuffer

   --- just before the optional prompt for confirmation, lets you
       run a hook on the prepped message and simplified address
       list

   --- you can specify something other than /bin/mail for the
       subprocess

   --- you can generate/modify an X-Mailer: message header

After a long list of options below, you will find the function feedmail-send-it. Hers's the best way to use the stuff in this file:

Save this file as feedmail.el somewhere on your elisp loadpath; byte-compile it. Put the following lines in your init file:

    (setq send-mail-function 'feedmail-send-it)
    (autoload 'feedmail-send-it "feedmail")

If you plan to use the queue stuff, also use this:

    (setq feedmail-enable-queue t)
    (autoload 'feedmail-run-the-queue "feedmail")
    (autoload 'feedmail-run-the-queue-no-prompts "feedmail")
    (setq auto-mode-alist (cons '("\\\\.fqm$" . mail-mode) auto-mode-alist))

though VM users might find it more comfortable to use this instead of the above example's last line:

    (setq auto-mode-alist (cons '("\\\\.fqm$" . feedmail-vm-mail-mode) auto-mode-alist))

If you end up getting asked about killing modified buffers all the time you are probably being prompted from outside feedmail. You can probably get cured by doing the defadvice stuff described in the documentation for the variable feedmail-queue-buffer-file-name below.

If you are wondering how to send your messages to some SMTP server
(which is not really a feedmail-specific issue), you are probably
looking for smtpmail.el, and it is probably already present in your Emacs installation. Look at smtpmail.el for how to set that up, and then do this to hook it into feedmail:

    (autoload 'feedmail-buffer-to-smtpmail "feedmail" nil t)
    (setq feedmail-buffer-eating-function 'feedmail-buffer-to-smtpmail)

Alternatively, the FLIM <https://www.m17n.org/FLIM/> project provides a library called smtp.el. If you want to use that, the above lines would be:

    (autoload 'feedmail-buffer-to-smtp "feedmail" nil t)
    (setq feedmail-buffer-eating-function 'feedmail-buffer-to-smtp)

If you are using the desktop.el library to restore your sessions, you might like to add the suffix ".fqm" to the list of non-saved things via the variable desktop-files-not-to-save.

If you are planning to call feedmail-queue-reminder from your .emacs or something similar, you might need this:

    (autoload 'feedmail-queue-reminder "feedmail")

If you ever use rmail-resend and queue messages, you should do this:

    (setq feedmail-queue-alternative-mail-header-separator "")

If you want to automatically spell-check messages, but not when sending them from the queue, you could do something like this:

    (autoload 'feedmail-mail-send-hook-splitter "feedmail")
    (add-hook 'mail-send-hook 'feedmail-mail-send-hook-splitter)
    (add-hook 'feedmail-mail-send-hook 'ispell-message)

If you are using message-mode to compose and send mail, feedmail will probably work fine with that (someone else tested it and told me it worked). Follow the directions above, but make these adjustments instead:

    (setq message-send-mail-function 'feedmail-send-it)
    (add-hook 'message-mail-send-hook 'feedmail-mail-send-hook-splitter)

If you use message-mode and you make use of feedmail's queueing stuff, you might also like to adjust these variables to appropriate values for message-mode:

    feedmail-queue-runner-mode-setter
    feedmail-queue-runner-message-sender

If you are using the "cmail" email package, there is some built-in support for feedmail in recent versions. To enable it, you should:

    (setq cmail-use-feedmail t)

;;;;;;

I think the LCD is no longer being updated, but if it were, this would be a proper LCD record. There is an old version of feedmail.el in the LCD archive. It works but is missing a lot of features.

LCD record: feedmail|WJCarpenter|bill-feedmail@carpenter.ORG|Outbound mail queue handling|01-??-??|11-beta-??|feedmail.el

Change log:
original, 31 March 1991
patchlevel 1, 5 April 1991
patchlevel 2, 24 May 1991
5-may-92 jwz Conditionalized calling expand-mail-aliases, since that
function doesn't exist in Lucid Emacs or when using
mail-abbrevs.el.
patchlevel 3, 3 October 1996
        added queue stuff; still works in v18
patchlevel 4, issued by someone else patchlevel 5, issued by someone else patchlevel 6, not issued as far as I know
patchlevel 7, 20 May 1997
        abandon futile support of Emacs 18 (sorry if that hurts you)
        provide a Date: header by default
        provide a default for generating Message-Id: header contents
           and use it by default (slightly changed API)
        return value from feedmail-run-the-queue
        new wrapper function feedmail-run-the-queue-no-prompts
        user-mail-address as default for From:
        properly deal with Resent-{To,Cc,Bcc}
        Bcc and Resent-* now included in smart filling
        limited support for a "drafts" directory
        user-configurable default message action
        allow timeout for confirmation prompt (where available)
        move Fcc handling to as late as possible to get max
           header munging in the saved file
        work around sendmail.el's prompts when working from queue
        more reliably detect voluntary user bailouts
        offer to save modified buffers visiting queue files
        offer to delete old file copies of messages being queued
        offer to delete queue files when sending immediately
        queue filename convention preserves queue order
        default queue and draft directory names that work on VMS
        deduced address list now really a list, not a string (API change)
        no more address buffer
        when sending immediately, brief reminder of queue/draft counts
        copy trace of smtpmail stuff to feedmail error buffer on no-go
        more granularity on when to confirm sending
        pause a bit for errors while running queue
        try to clean up some pesky auto-save files from the
           queue/draft directories
        feedmail-force-expand-mail-aliases in case you can't figure
           any other way
        cleanup some of my sloppiness about case-fold-search (a strange
           variable)
        best effort following coding conventions from Emacs
           elisp manual appendix
        "customize" (see custom.el)
        when user selects "immediate send", clear action prompt since
           hooks may take a while to operate, and user may think the
           response didn't take
        fixes to the argument conventions for the
           feedmail-queue-runner-* functions; allows
           feedmail-run-the-queue[-no-prompts] to properly be called
           non-interactively
        eliminate reliance on directory-sep-char and feedmail-sep-thing
        tweak smart filling (reminded of comma problem by levitte@lp.se)
        option to control writing in text vs binary mode
patchlevel 8, 15 June 1998
        reliable re-editing of text-mode (vs binary) queued messages
        user option to keep Bcc: in Fcc: copy (keep by default)
        user option to delete body from Fcc: copy (keep by default)
        feedmail-deduce-bcc-where for envelope (API change for
          feedmail-deduce-address list)
        feedmail-queue-alternative-mail-header-separator
        at message action prompt, "I"/"S" bypass message confirmation prompt
        feedmail-mail-send-hook-splitter, feedmail-mail-send-hook,
          feedmail-mail-send-hook-queued
        user can supply stuff for message action prompt
        variable feedmail-queue-runner-confirm-global, function feedmail-run-the-queue-global-prompt
        bugfix: absolute argument to directory-files (tracked down for me
          by gray@austin.apc.slb.com (Douglas Gray Stephens)); relative
          pathnames can tickle stuff in ange-ftp remote directories
          (perhaps because feedmail is careless about its working
          directory)
        feedmail-deduce-envelope-from
        always supply envelope "from" (user-mail-address) to sendmail
        feedmail-message-id-suffix
        feedmail-queue-reminder, feedmail-queue-reminder-alist (after suggestions
          and/or code fragments from tonyl@Eng.Sun.COM (Tony Lam) and
          burge@newvision.com (Shane Burgess); bumped up the default value of
          feedmail-queue-chatty-sit-for since info is more complex sometimes
        feedmail-enable-spray (individual transmissions, crude mailmerge)
        blank Subject: no longer a special case; see feedmail-nuke-empty-headers
        fiddle-plexes data structure used lots of places; see feedmail-fiddle-plex-blurb
        feedmail-fiddle-plex-user-list
        feedmail-is-a-resend
        honor mail-from-style in constructing default for feedmail-from-line
        re-implement feedmail-from-line and feedmail-sender-line with
          fiddle-plexes; slightly modified semantics for feedmail-sender-line
        feedmail-queue-default-file-slug; tidy up some other slug details
        feedmail-queue-auto-file-nuke
        feedmail-queue-express-to-queue and feedmail-queue-express-to-draft
        strong versions of "q"ueue and "d"raft answers (always make a new file)
patchlevel 9, 23 March 2001
        feedmail-queue-buffer-file-name to work around undesirable mail-send prompt
        at message action prompt, can scroll message buffer with "<" and ">";
          C-v no longer scrolls help buffer
        conditionalize (discard-input) in message action prompt to avoid killing
          define-kbd-macro
        fixed error if feedmail-x-mailer-line was nil
        feedmail-binmail-template only uses /bin/rmail if it exists
        relocate feedmail-queue-alternative-mail-header-separator stuff
        added feedmail-vm-mail-mode, which make a good auto-mode-alist entry
          for FQM files if you're a VM user
        change buffer-substring calls to buffer-substring-no-properties for
          speed-up (suggested by Howard Melman <howard@silverstream.com>)
        feedmail-sendmail-f-doesnt-sell-me-out to control "-f" in call to sendmail
          in feedmail-buffer-to-sendmail
        better trapping of odd conditions during the running of the queue;
          thanks to Yigal Hochberg for helping me test much of this by remote
          control
        feedmail-debug and feedmail-debug-sit-for
        feedmail-display-full-frame
        feedmail-queue-express-hook
        added example function feedmail-spray-via-bbdb
        use expand-file-name for setting default directory names
        define feedmail-binmail-gnulinuxish-template as a suggestion for
          the value of feedmail-binmail-template on GNU/Linux and maybe other
          systems with non-classic /bin/[r]mail behavior
        guard against nil user-mail-address in generating MESSAGE-ID:
        feedmail-queue-slug-suspect-regexp is now a variable to
          accommodate non-ASCII environments (thanks to
          Makoto.Nakagawa@jp.compaq.com for this suggestion)
        feedmail-buffer-to-smtp, to parallel feedmail-buffer-to-smtpmail
patchlevel 10, 22 April 2001
        DATE: and MESSAGE-ID stuff now forces system-time-locale to "C"
          (brought to my attention by Makoto.Nakagawa@jp.compaq.com)
patchlevel 11
        tweak default FROM: calculation to look at mail-host-address
          (suggested by "Jason Eisner" <jason@cs.jhu.edu>)

todo:
        write texinfo manual
        maybe partition into multiple files, including files of examples

Defined variables (69)

feedmail-ask-before-queueIf non-nil, feedmail will ask what you want to do with the message.
feedmail-ask-before-queue-defaultMeaning if user hits return in response to the message action prompt.
feedmail-ask-before-queue-promptA string which will be used for the message action prompt.
feedmail-ask-before-queue-repromptA string which will be used for reprompting after invalid input.
feedmail-ask-for-queue-slugIf non-nil, prompt user for part of the queue file name.
feedmail-before-fcc-hookUser’s last opportunity to modify the message before Fcc action.
feedmail-binmail-gnulinuxish-templateGood candidate for GNU/Linux systems and maybe others.
feedmail-binmail-templateCommand template for the subprocess which will get rid of the mail.
feedmail-buffer-eating-functionFunction used to send the prepped buffer to a subprocess.
feedmail-confirm-outgoingIf non-nil, give a y-or-n confirmation prompt before sending mail.
feedmail-confirm-outgoing-timeoutIf non-nil, a timeout in seconds at the send confirmation prompt.
feedmail-date-generatorSpecifies the creation of a Date: header field.
feedmail-debugIf non-nil, blat a debug messages and such in the mini-buffer.
feedmail-debug-sit-forDuration of pause after feedmail-debug messages.
feedmail-deduce-bcc-whereWhere Bcc:/Resent-Bcc: addresses should appear in the envelope list.
feedmail-deduce-envelope-fromIf non-nil, deduce message envelope "from" from header From: or Sender:.
feedmail-display-full-frameIf non-nil, show prepped messages in a full frame.
feedmail-enable-queueIf non-nil, provide for stashing outgoing messages in a queue.
feedmail-enable-sprayIf non-nil, transmit message separately to each addressee.
feedmail-fiddle-headers-upwardlyNon-nil means fiddled header fields should go at the top of the header.
feedmail-fiddle-plex-blurbA fiddle-plex is a concise way of specifying header field fiddling.
feedmail-fiddle-plex-user-listIf non-nil, should be a list of one or more fiddle-plexes.
feedmail-fill-to-ccIf non-nil do smart filling of addressee header lines.
feedmail-fill-to-cc-fill-columnFill column used by ‘feedmail-fill-to-cc’.
feedmail-force-binary-writeIf non-nil, force writing file as binary (this applies to queues and Fcc:).
feedmail-force-expand-mail-aliasesIf non-nil, force the calling of ‘expand-mail-aliases’.
feedmail-from-lineIf non-nil and the email has no From: header, use this value.
feedmail-is-a-resendNon-nil means the message is a Resend (in the RFC-822-or-later sense).
feedmail-last-chance-hookUser’s last opportunity to modify the message on its way out.
feedmail-mail-send-hookHook run by ‘feedmail-mail-send-hook-splitter’ for immediate mail.
feedmail-mail-send-hook-queuedHook run by ‘feedmail-mail-send-hook-splitter’ for queued mail.
feedmail-message-id-generatorSpecifies the creation of a Message-Id: header field.
feedmail-message-id-suffixIf non-nil, used as a suffix for generating unique Message-Id: headers.
feedmail-nuke-bccIf non-nil remove Bcc: lines from the message headers.
feedmail-nuke-bcc-in-fccIf non-nil remove [Resent-]Bcc: lines in message copies saved via Fcc:.
feedmail-nuke-body-in-fccIf non-nil remove body of message in copies saved via Fcc:.
feedmail-nuke-buffer-after-queueIf non-nil, silently kill the buffer after a message is queued.
feedmail-nuke-empty-headersIf non-nil, remove header lines which have no contents.
feedmail-nuke-resent-bccIf non-nil remove Resent-Bcc: lines from the message headers.
feedmail-prompt-before-queue-help-supplementUser-provided supplementary help string for the message action prompt.
feedmail-prompt-before-queue-standard-alistAn alist of choices for the message action prompt.
feedmail-prompt-before-queue-user-alistSee ‘feedmail-prompt-before-queue-standard-alist’.
feedmail-queue-alternative-mail-header-separatorAlternative header demarcation for queued messages.
feedmail-queue-auto-file-nukeIf non-nil, automatically delete queue files when a message is sent.
feedmail-queue-buffer-file-nameIf non-nil, has the value normally expected of ‘buffer-file-name’.
feedmail-queue-chattyIf non-nil, blat a few status messages and such in the mini-buffer.
feedmail-queue-chatty-sit-forDuration of pause after most queue-related messages.
feedmail-queue-default-file-slugIndicates what to use for subject-less messages when forming a file name.
feedmail-queue-directoryName of a directory where messages will be queued.
feedmail-queue-draft-directoryName of a directory where draft messages will be queued.
feedmail-queue-express-hookChance to modify a message being sent directly to a queue.
feedmail-queue-fqm-suffixThe FQM suffix used to distinguish feedmail queued message files.
feedmail-queue-reminder-alistSee ‘feedmail-queue-reminder’.
feedmail-queue-run-ordererIf non-nil, name a function which will sort the queued messages.
feedmail-queue-runner-cleaner-upperFunction that will be called after a message has been sent.
feedmail-queue-runner-confirm-globalIf non-nil, give a y-or-n confirmation prompt before running the queue.
feedmail-queue-runner-is-activeNon-nil means we’re inside the logic of the queue-running loop.
feedmail-queue-runner-message-senderFunction to initiate sending a message file.
feedmail-queue-runner-mode-setterA function to set the proper mode of a message file.
feedmail-queue-slug-makerIf non-nil, a function which creates part of the queued file name.
feedmail-queue-slug-suspect-regexpRegular expression for characters/substrings to be replaced.
feedmail-queue-use-send-time-for-dateIf non-nil, use send time for the Date: header value.
feedmail-queue-use-send-time-for-message-idIf non-nil, use send time for the Message-Id: header value.
feedmail-sender-lineIf non-nil and the email has no Sender: header, use this value.
feedmail-sendmail-f-doesnt-sell-me-outWhether sendmail should issue a warning header if called with "-f".
feedmail-spray-address-fiddle-plex-listUser-supplied specification for a crude form of mailmerge capability.
feedmail-spray-this-addressDo not set this variable, except via ‘feedmail-spray-address-fiddle-plex-list’.
feedmail-x-mailer-lineControl the form of an X-Mailer: header in an outgoing message.
feedmail-x-mailer-line-user-appendageSee feedmail-x-mailer-line.

Defined functions (52)

feedmail-accume-n-nuke-header(HEADER-END HEADER-REGEXP)
feedmail-buffer-to-binmail(PREPPED ERRORS-TO ADDR-LISTOID)
feedmail-buffer-to-sendmail(PREPPED ERRORS-TO ADDR-LISTOID)
feedmail-buffer-to-smtp(PREPPED ERRORS-TO ADDR-LISTOID)
feedmail-buffer-to-smtpmail(PREPPED ERRORS-TO ADDR-LISTOID)
feedmail-confirm-addresses-hook-example()
feedmail-create-queue-filename(QUEUE-DIRECTORY)
feedmail-deduce-address-list(MESSAGE-BUFFER HEADER-START HEADER-END ADDR-REGEXP ADDRESS-LIST)
feedmail-default-date-generator(MAYBE-FILE)
feedmail-default-message-id-generator(MAYBE-FILE)
feedmail-default-x-mailer-generator()
feedmail-dump-message-to-queue(QUEUE-DIRECTORY WHAT-EVENT)
feedmail-envelope-deducer(EOH-MARKER)
feedmail-fiddle-date(MAYBE-FILE)
feedmail-fiddle-from()
feedmail-fiddle-header(NAME VALUE &optional ACTION FOLDING)
feedmail-fiddle-list-of-fiddle-plexes(LIST-OF-FIDDLE-PLEXES)
feedmail-fiddle-list-of-spray-fiddle-plexes(LIST-OF-FIDDLE-PLEXES)
feedmail-fiddle-message-id(MAYBE-FILE)
feedmail-fiddle-sender()
feedmail-fiddle-spray-address(ADDY-PLEX)
feedmail-fiddle-x-mailer()
feedmail-fill-this-one(THIS-LINE THIS-LINE-END)
feedmail-fill-to-cc-function(HEADER-END)
feedmail-find-eoh(&optional NOERROR)
feedmail-fqm-p(MIGHT-BE)
feedmail-look-at-queue-directory(QUEUE-DIRECTORY)
feedmail-mail-send-hook-splitter()
feedmail-message-action-help-blat(D-STRING)
feedmail-one-last-look(BUFFER)
feedmail-queue-express-to-draft()
feedmail-queue-express-to-queue()
feedmail-queue-reminder(&optional WHAT-EVENT)
feedmail-queue-reminder-brief()
feedmail-queue-reminder-medium()
feedmail-queue-send-edit-prompt()
feedmail-queue-send-edit-prompt-inner(DEFAULT PROMPT REPROMPT HELPER STANDARD-ALIST USER-ALIST)
feedmail-queue-subject-slug-maker(&optional QUEUE-DIRECTORY)
feedmail-rfc822-date(ARG-TIME)
feedmail-rfc822-time-zone(TIME)
feedmail-run-the-queue(&optional ARG)
feedmail-run-the-queue-global-prompt(&optional ARG)
feedmail-run-the-queue-no-prompts(&optional ARG)
feedmail-say-chatter(FORMAT &optional A1 A2 A3 A4 A5 A6 A7 A8 A9)
feedmail-say-debug(FORMAT &optional A1 A2 A3 A4 A5 A6 A7 A8 A9)
feedmail-scroll-buffer(DIRECTION &optional BUFFY)
feedmail-send-it()
feedmail-send-it-immediately()
feedmail-send-it-immediately-wrapper()
feedmail-spray-via-bbdb()
feedmail-tidy-up-slug(SLUG)
feedmail-vm-mail-mode(&optional _)

Defined faces (0)