-Jon Steinhart's (jon@fourwinds.com) Attachment Handling Mods
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A bunch of changes have been made to improve the nmh user interface for
-handling MIME attachments.
-
-Why Did I Do This?
-~~~~~~~~~~~~~~~~~~
-
-Although nmh contains the necessary functionality for MIME message handing,
-the interface to this functionality is pretty obtuse. There's no way that
-I'm ever going to convince my partner to write mhbuild composition files!
-And even though I know how to write them, I often screw up when sending a
-message that contains a shell script because I forget that I have to double
-any # at the start of a line, which shell scripts have galore.
-
-These changes simplify the task of managing attachments on draft files.
-They allow attachments to be added, listed, and deleted. MIME messages are
-automatically created when drafts with attachments are sent.
-
-The Simple Setup
-~~~~~~~~~~~~~~~~
-
-The gory details are all given below. Here's how to set things up simply. This
-only works if you're using the "standard" interface, i.e., whatnow. Life is more
-complicated if you run mh-e.
-
-Add the following to your .mh_profile:
-
- send: -attach X-MH-Attachment
- whatnow: -attach X-MH-Attachment
-
-You may already have send and whatnow lines in your .mh_profile; if you do, just add
-the new stuff to the end of the line. For example, mine looks like:
-
- send: -alias aliases -attach X-MH-Attachment
- whatnow: -attach X-MH-Attachment
-
-That's it. Next time you want to send an attachment, say "attach filename" at the
-whatnow prompt and you're done. You can check your attachments by saying "alist".
-
-Did I Do This Correctly?
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Hard to say. Despite lots of time looking at the nmh code, I can't say that
-I get the philosophy behind its structure.
-
-I am aware of two deviations from what I saw in the nmh code.
-
- 1. I commented my changes.
-
- 2. It's been years since I've used a VT-100, so I don't try to make code
- fit into 80 columns anymore. Seems silly to me.
-
-What Did I Do?
-~~~~~~~~~~~~~~
-
-I made changes to the following files:
-
- h/
- prototypes.h
- man/
- anno.man
- send.man
- whatnow.man
- uip/
- Makefile.in
- anno.c
- annosbr.c
- send.c
- sendsbr.c
- viamail.c (needed change for new sendsbr argument)
- whatnowsbr.c
-
-Attachments are associated with messages using header fields. For example, a
-draft that looks like this
-
- To: jon
- Subject: test of attachments
- X-MH-Attachment: /export/home/jon/foo
- X-MH-Attachment: /export/home/jon/bar
- X-MH-Attachment: /export/home/jon/test/foo
- --------
-
-has the files "foo", "bar", and foo as attachments.
-
-Although I use the header field name "X-MH-Attachment" to indicate
-attachments, the implementation allows any header field name.
-
-The advantage of using header fields is that the list of attachments
-travels with the draft so it remains valid across editing sessions.
-
-Note that the header fields for attachments are removed from the message
-before it is sent.
-
-Since I was adding header fields to messages, it seemed sensible to use the
-existing anno program to do this for me. This required several changes to
-generalize anno:
-
- o I added a -draft option that permits annotations (header fields) to
- be added to the draft instead of a message sequence.
-
- o I added a -delete option that allows annotations to be deleted.
-
- o I added a -list option that allows annotations to be listed.
-
- o I added a -number option that modifies the behavior of -delete and -list.
-
- o I added a -append option so that annotations are appended to the headers
- instead of the default prepend. Without this, attachments come out in
- reverse order.
-
-Using the modified anno, the example above could be created (assuming that the
-draft exists) by
-
- prompt% anno -draft -comp X-MH-Attachment -text /export/home/jon/foo -nodate -append
- prompt% anno -draft -comp X-MH-Attachment -text /export/home/jon/bar -nodate -append
- prompt% anno -draft -comp X-MH-Attachment -text /export/home/jon/test/foo -nodate -append
-
-One can quite easily make an "attach" command using shell scripts, aliases or functions.
-For example, here's a bash function that does the job:
-
- function attach() { for i in $*; do anno -append -nodate -draft -comp X-MH-Attachment -text "$i"; done; }
-
-The following examples show the different ways in which attachments can be
-listed.
-
- prompt% anno -list -draft -comp X-MH-Attachment
- foo
- bar
- foo
-
- prompt% anno -list -draft -comp X-MH-Attachment -text /
- /export/home/jon/foo
- /export/home/jon/bar
- /export/home/jon/test/foo
-
- prompt% anno -list -draft -comp X-MH-Attachment -number
- 1 foo
- 2 bar
- 3 foo
-
- prompt% anno -list -draft -comp X-MH-Attachment -text / -number
- 1 /export/home/jon/foo
- 2 /export/home/jon/bar
- 3 /export/home/jon/test/foo
-
- prompt%
-
-Why all these listing options?
-
-I feel that the listing as produced by the first example is what most people
-would want most of the time.
-
-The listing as produced by the second example seemed necessary for situations
-where there were several attachments with the same file name in different
-directories.
-
-I included the numbering option so that attachments could be deleted by number
-which might be easier in situations where there were several attachments with
-the same file name in different directories, as in the above example.
-
-Attachments are deleted using the -delete option.
-
- prompt% anno -delete -draft -comp X-MH-Attachment -text foo
-
-deletes the first attachment since the foo matches the basename of the attachment
-name.
-
- prompt% anno -delete -draft -comp X-MH-Attachment -text /export/home/jon/test/foo
-
-deletes the third attachment since the text is a full path name and matches.
-
- prompt% anno -delete -draft -comp X-MH-Attachment -number 2
-
-deletes the second attachment.
-
-The attachment annotations are converted to a MIME message by send. I'm not
-completely sure that this is the right place to do it, as opposed to doing
-it in post, but both would work. It seemed to me to make more sense to do
-it in send so that all of the various post options would apply to the MIME
-message instead of the original draft file.
-
-I added an -attach option to send that specifies the header field name used
-for attachments. Send performs the following additional steps if this option
-is set:
-
- o It scans the header of the draft for attachments. Normal behavior applies
- if none exist.
-
- o A temporary mhbuild composition file is created if there are attachments.
-
- o All non-attachment headers are copied from the draft file to the
- composition file.
-
- o The body of the draft is copied to a temporary body file if it contains at
- least one non-whitespace character. A mhbuild directive for this file is
- appended to the composition file. Note that this eliminates the problem
- of lines beginning with the # character in the message body.
-
- o A mhbuild directive is appended to the composition file for each attachment
- header.
-
- o mhbuild is run on the composition file, converting it to a MIME message.
-
- o The converted composition file is substituted for the original draft file
- and run through the rest of send.
-
- o The original draft file is renamed instead of the converted composition
- file. This preserves the original message instead of the composition file
- which is really what a user would want.
-
- o The ,file.orig file created by mhbuild is removed as it's a nuisance.
-
-The mhbuild directives appended to the composition file are constructed as
-follows:
-
- o The content-type a file with a dot-suffix is obtained from the list of
- mhshow-suffix- entries in the profile.
-
- o A file with no dot-suffix or no entry in the profile is assigned a
- content-type of application/octet-stream if it contains any non-ASCII
- characters.
-
- o A file with no dot-suffix or no entry in the profile is assigned a
- content-type of text/plain if it contains only ASCII characters.
-
- o The directive is of the form:
-
- #content-type; name="basename"; x-unix-mode=mode [ description ] filename
-
- The content type is derived as discussed above. The basename is the
- last component of the pathname given in the body of the attachment header
- field. The mode is file permissions. The description is obtained by
- running the file command on the attachment file. The filename is the
- field body from the attachment header field.
-
-I added an -attach option to whatnow that specifies the header field name for
-attachments.
-
-I added to the commands available at the whatnow prompt to provide an interface
-to the attachment mechanism.
-
-I'm not completely happy with some of these additions because they duplicate
-shell functionality. I'm not sure that there's a good way around it other than
-to not use whatnow.
-
-The first three additions (the ones I'm not happy with) are cd, ls, and pwd.
-These do the same thing as their system counterparts. As a matter of fact,
-these are implemented by running the commands in a subshell. I did this because
-I wanted proper interpretation of shell-specific things like ~ and wildcard
-expansion.
-
-The next command is attach. This takes a list of files and adds them to the draft
-as attachments using the same code as the modified anno. The list of files is
-run through ls using the user's shell, so wildcard expansion and all that works.
-
-The alist command lists the attachments on the current draft using listing function
-that I added to anno. It takes two optional options, -l for a long listing meaning
-full path names, and -n for a numbered listing.
-
-The detach command removes attachments from the current draft, again using the
-modified anno. The arguments are interpreted as numbers if the -n option is used,
-otherwise they're interpreted as file names. File names are shoveled through ls
-using the user's shell in the directory containing the file for wildcard expansion
-and such. File names are matched against the last pathname component unless they
-begin with a / in which case they're matched against the entire name.
-
-What's Left To Do?
-~~~~~~~~~~~~~~~~~~
-
-Nothing on this stuff. When I get time I'd like to improve the interface
-for reading messages with attachments. It's my opinion that, because of the
-command line nature of nmh, it makes the most sense to treat attachments as
-separate messages. In other words one should be able to read the next
-attachment using next, and the previous one using prev. One should be able
-to show and scan attachments. This would probably involve a major change
-in the message numbering scheme to allow something like 123.4 to indicate
-attachment 4 on message 123.
-
- Jon Steinhart