RFC 1524

A User Agent Configuration Mechanism For Multimedia Mail Format Information

πŸ“… published September 1993, from ietf

A User Agent Configuration Mechanism For Multimedia Mail Format Information πŸ“¬βœ¨

okay bestie, this is RFC 1524 πŸŽ€ (part 1 of 3)

It's written by N. Borenstein from Bellcore πŸ’… and it's dated September 1993. The category is Informational, so it's shared for the community's info and it is not an Internet standard. The title block doesn't list anything it obsoletes or updates, so it's kind of a standalone vibe πŸ¦‹

Status of This Memo 🌸

This memo gives info to the Internet community. It does not specify an Internet standard. Distribution of this memo is unlimited πŸ’œ

Abstract 🧚

This memo suggests a file format so that a bunch of mail reading user agent programs can all know about the locally installed facilities for handling mail in various formats πŸ“¬ The mechanism is explicitly designed to work with Internet mail systems based on RFCs 821 (STD 10), 822 (STD 11), 934, 1049 (STD 11), 1113, and the Multipurpose Internet Mail Extensions, known as MIME πŸŽ€

However, with some extensions it could probably be made to work for X.400-based mail systems as well 🌈

The format and mechanism are proposed in a way that is generally operating-system independent ✨ However, certain implementation details will inevitably reflect operating system differences, and some of those will have to be handled in a uniform manner for each operating system πŸ™ˆ This memo makes those situations explicit, and, in an appendix, suggests a standard behavior under the UNIX operating system πŸ‘‘

Introduction πŸ¦‹

The electronic mail world is in the middle of a glow-up from single-part, text-only mail to multi-part, multi-media mail πŸ’– To support that, various extensions to RFC 821 and RFC 822 have been proposed and/or adopted, most notably MIME [RFC-1521] 🫢 People have shown off super high-functionality multimedia mail, but mail interchange between different user agents has been a total mess 😭 In general, only text messages have been shared between user agents that weren't explicitly designed to work together. That limit is not compatible with a smooth transition to a multi-media mail world πŸ’€

One approach to this transition is to modify a bunch of different mail reading user agents so that, when they need to display mail of an unfamiliar (non-text) type, they check an external file for info on how to display that file 🧚 That file might say, for example, that if the content-type of a message is "foo", it can be displayed to the user via the "displayfoo" program πŸ“

This approach means that, with a one-time modification, a wide variety of mail reading programs can be given the ability to display a wide variety of message types 🌸 Plus, extending the set of media types supported at a site becomes a simple matter of installing a binary and adding a single line to a configuration file πŸŽ€ The crucial part, though, is that all of the user agents agree on a common representation and source for the configuration file. This memo proposes exactly that common representation πŸ‘‘

Location of Configuration Information πŸ—ΊοΈ

Each user agent must clearly obtain the configuration information from a common location, if the same information is going to be used to configure all user agents πŸ’… But individual users should be able to override or augment a site's configuration ✨ So the configuration information should be obtained from a designated set of locations πŸ¦‹ The overall configuration comes from the virtual concatenation of several individual configuration files known as mailcap files πŸ“¬

The configuration information is obtained from the FIRST matching entry in a mailcap file πŸ’– "Matching" depends on three things: a matching content-type specification, an entry containing sufficient information for the purposes of the application doing the searching, and the success of any test in the test= field, if one is present 🫢

The precise location of the mailcap files is operating-system dependent 🌈 A standard location for UNIX is specified in Appendix A 🧚

Overall Format of a Mailcap File πŸ“

Each mailcap file is made up of a set of entries, and each entry describes the proper handling of one media type at the local site πŸ’œ

Like, one line might tell you how to display a message in Group III fax format πŸ“  A mailcap file is a sequence of these individual entries, separated by newlines (according to the operating system's newline conventions) 🌸 Blank lines and lines that start with the # character (ASCII 35) are considered comments, and they get ignored πŸ™ˆ

Long entries can be continued on multiple lines, as long as each non-terminal line ends with a backslash character (\, ASCII 92) πŸŽ€ In that case, the multiple lines are treated as a single mailcap entry πŸ‘‘ Note that for these "continued" lines, the backslash must be the last character on the line to be continued πŸ’…

So the overall format of a mailcap file is given in the modified BNF of RFC 822 as:

      Mailcap-File = *Mailcap-Line

      Mailcap-Line = Comment / Mailcap-Entry

      Comment = NEWLINE  /  "#" *CHAR NEWLINE

      NEWLINE = <newline as defined by OS convention>

Note that the above specification implies that comments must appear on lines all to themselves, with a # character as the first character on each comment line 😭🫢

Format of a Mailcap Entry ✨

okay so every mailcap entry is a bunch of fields separated by semi-colons πŸ’… The first two fields are required, and must occur in the specified order. The rest are optional and can show up in any order, so lowkey super flexible πŸ¦‹

The first field is the content-type πŸŽ€ It tells you what kind of data this entry describes how to handle, and it gets matched against the type/subtype in the "Content-Type" header field of an Internet mail message. If the subtype is written as "*", it's meant to match all subtypes of that content-type, so it's giving wildcard energy ✨

The second field, view-command, says how the message or body part can be viewed at the local site πŸ‘€ The syntax is fully specified, but what running a program actually does is kinda operating-system dependent, so the UNIX version lives in Appendix A 🌸

The optional fields, which can go in any order, are these:

  • compose πŸ–ŠοΈ Used to specify a program that can compose a new body or body part in the given format. The whole point is to support mail composing agents that handle lots of mail types through external composing agents. Just like with the view-command, the semantics of program execution are operating system dependent, with UNIX semantics specified in Appendix A. The result of the composing program might be data that isn't ready for mail transport yet. That means a Content-Transfer-Encoding may need to be applied to the data.
  • composetyped 🎨 Similar to compose, but for when the composing program needs to specify the Content-type header field to be applied to the composed data. compose is simpler and is the preferred pick for existing (non-mail-oriented) programs that compose data in a given format. composetyped is necessary when the Content-type information has to include auxiliary parameters, and the composition program then has to know enough about mail formats to produce output that includes the mail type information.
  • edit ✏️ Used to specify a program that can edit a body or body part in the given format. In many cases it may be identical in content to the compose field, and it shares the operating-system dependent semantics for program execution.
  • print πŸ–¨οΈ Used to specify a program that can print a message or body part in the given format. As with the view-command, the semantics of program execution are operating system dependent, with UNIX semantics specified in Appendix A.
  • test πŸ§ͺ Used to test some external condition (like the machine architecture, or the window system in use) to figure out whether or not the mailcap line applies. It specifies a program to run to test that condition. The semantics of execution, and of the value the test program returns, are operating system dependent, with UNIX semantics specified in Appendix A. If the test fails, a subsequent mailcap entry should be sought. Multiple test fields are not permitted. Since a test can call a program, it can already be arbitrarily complex, so no need for more πŸ’€
  • needsterminal πŸ’» Indicates that the view-command must be run on an interactive terminal. This is needed to tell window-oriented user agents that an interactive terminal is needed. (The decision isn't left exclusively to the view-command, because in some circumstances those programs may not be able to tell whether or not they're on interactive terminals.) The needsterminal command should be assumed to apply to the compose and edit commands, too, if they exist. Note that this is NOT a test. It's a requirement for the environment the program will run in, and it should typically cause the creation of a terminal window when not executed on either a real terminal or a terminal window.
  • copiousoutput πŸ“œ Indicates that the output from the view-command will be an extended stream of output. It's to be read as advice to the UA (User Agent mail-reading program) that the output should be either paged or made scrollable. Note that it is probably a mistake if needsterminal and copiousoutput are both specified πŸ™ˆ
  • description πŸ“ Simply provides a textual description, optionally quoted, of the type of data. Mail readers can use it, optionally, to describe the data before offering to display it.
  • textualnewlines 🌈 If set to any non-zero value, indicates that this type of data is line-oriented and that, if encoded in base64, all newlines should be converted to canonical form (CRLF) before encoding. They'll be in that form after decoding. In general, this field is only needed if there's line-oriented data of some type other than text/* or non-line-oriented data that is a subtype of text.
  • x11-bitmap πŸ–ΌοΈ Names a file, in X11 bitmap (xbm) format, that points to an appropriate icon used to visually denote the presence of this kind of data.
  • nametemplate 🏷️ Gives a file name format, in which %s will be replaced by a short unique string to become the name of the temporary file passed to the viewing command. This is only expected to matter in environments where filename extensions are meaningful. For example, one could specify that a GIF file passed to a gif viewer should have a name ending in ".gif" by using nametemplate=%s.gif.

Any other fields beginning with "x-" may be included for local or mailer-specific extensions of this format. Implementations should simply ignore all such unrecognized fields so extensions can happen, and some of them might get standardized in a future version of this document πŸ¦„

Some of the fields above, like "needsterminal", apply to the actions of the view-command, edit-command, and compose-command, alike. In some unusual cases that might not be desirable, but you can get around it with separate mailcap entries. The trick is that subsequent mailcap entries get searched if an earlier one doesn't provide enough information 🧠

application/postscript; ps-to-terminal %s;\ needsterminal
application/postscript; ps-to-terminal %s; \compose=idraw %s

In RFC 822 modified BNF, the following grammar describes a mailcap entry:

Mailcap-Entry = typefield ; view-command
                    [";" 1#field]

typefield = propertype / implicit-wild

propertype = type "/" wildsubtype

implicitwild = type

wildsubtype = subtype / "*"

view-command = mtext

mtext = *mchar

mchar = schar / qchar

schar = * <any CHAR except ";","\", and CTLS>

qchar = "\" CHAR ; may quote any char

field = flag / namedfield

namedfield = fieldname "=" mtext

flag = "needsterminal"   ; All these literals are to
     / "copiousoutput"   ; be interpreted as
     / x-token           ; case-insensitive

fieldname =    / "compose"      ;Also all of these
               / "composetyped" ;are case-insensitive.
               / "print"
               / "edit"
               / "test"
               / "x11-bitmap"
               / "textualnewlines"
               / "description"
               / x-token

Note that "type", "subtype", and "x-token" are defined in MIME. Also, while the definition of "schar" includes the percent sign, "%", this character has a special meaning in at least the UNIX semantics. It will therefore need to be quoted as a qchar to be used literally πŸ”


Acknowledgements ✨

The author wishes to thank Malcolm Bjorn Gillies, Dan Heller, Olle Jaernefors, Keith Moore, Luc Rooijakkers, and the other members of the IETF task force on mail extensions for their comments on earlier versions of this draft. If other acknowledgements were neglected, please let me know, as it was surely accidental 🫢

Security Considerations

Security issues are not discussed in this memo. However, the use of the mechanisms described in this memo can make it easier for implementations to slip into the kind of security problems discussed in the MIME document. Implementors and mailcap administrators should be aware of these security considerations. In particular, they should exercise caution in the choice of programs to be listed in a mailcap file for automatic execution.

🚨 This one is serious, bestie. Programs listed in a mailcap file can run automatically, so be extremely careful about which ones you put in there. Choose wisely and don't let a sketchy program in just because it's convenient πŸ’€

Author's Address

Nathaniel S. Borenstein
MRE 2D-296, Bellcore
445 South St.
Morristown, NJ 07962-1910

EMail: nsb@bellcore.com
Phone: +1 201 829 4270
Fax:  +1 201 829 7019

Appendix A: Implementation Details for UNIX 🐧

Although this memo fully specifies a syntax for "mailcap" files, the semantics of the mailcap file are necessarily operating-system dependent in four respects. To clarify the intent, and to promote a standard usage, this appendix proposes UNIX semantics for these four cases. If a mailcap mechanism is implemented on non-UNIX systems, similar semantic decisions should be made and published πŸ“š

Location of the Mailcap File(s)

For UNIX, a path search of mailcap files is specified. The default path search is specified as including at least the following:

$HOME/.mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap

However, this path may itself be overridden by a path specified by the MAILCAPS environment variable 🌸

Semantics of executable commands πŸ’…

okay so a bunch of parts of a mailcap entry are commands that actually get run πŸ”₯. The mandatory second field, the view-command, takes a command to execute, and so do the optional print, edit, test, and compose fields.

On UNIX, each of those is a full shell command line, including the path to a program and its arguments. Shells differ from each other, and even the same shell can act differently from one system to another πŸ™ƒ, so the command line is meant to be input to the Bourne shell. That means it's implicitly preceded by /bin/sh -c on the command line.

The two characters %s, if used, get replaced by the name of a file holding the actual mail body data πŸ“„. For edit and the view-command, the body part is passed to the command as standard input, unless one or more instances of %s show up in the view-command. In that case, %s gets replaced by the name of a file containing the body part, and that file might have to be created before the view-command program runs. Those files can't be assumed to still exist after the view-command program exits, so a view-command that wants to exit and keep processing in the background should take care to save the data first πŸ’Ύ.

For the compose and composetyped commands, %s gets replaced by the name of a file where the programs named in those commands should write the composed data πŸ“. The calling program checks that file later to grab the composed data. If %s doesn't appear in the compose or composetyped commands, then the composing programs are assumed to write the composed data to standard output instead.

Also, any occurrence of %t gets replaced by the content-type and subtype spec. So if the content-type is text/plain, then %t becomes text/plain 🌸. A literal % character can be quoted as \%. Named parameters from the Content-type field can go into the command line using %{, followed by the parameter name and a closing }. The whole parameter should show up as a single command line argument, even if it has spaces inside 🧚.

Here's a vibe check example. If the message has this Content-type line:

Content-type:  multipart/mixed; boundary=42

and the mailcap file has this line:

multipart/*; /usr/local/bin/showmulti \
  %t %{boundary}

then the equivalent of this command should get executed:

/usr/local/bin/showmulti multipart/mixed 42

If the content-type is multipart (any subtype), then the two characters %n get replaced by an integer giving the number of sub-parts in the multipart entity πŸ”’. The two characters %F get replaced by a set of arguments. There are twice as many arguments as sub-parts, and they alternate between content-types and file names, one pair for each part in turn. So if a multipart entity has three parts, %F gets replaced by the equivalent of content-type1 file-name1 content-type2 file-name2 content-type3 file-name3 ✨.

Semantics of the "test" field πŸ§ͺ

The test field specifies a program that checks whether or not the current mailcap line applies. This is useful for things like having a mailcap line that only kicks in if the X window system is running, or if you're on a SPARCstation with a /dev/audio πŸ–₯️. The value of the test field is the program to run for that check. The exact program and its arguments are determined the same way as in the previous section. The test program should return an exit code of zero if the condition is true, and a non-zero code otherwise βœ….

Semantics of the "compose" field πŸŽ™οΈ

On UNIX, the composing program is expected to produce a data stream for that body part as its standard output. The program gets run with the command line arguments determined as specified above. The data returned through standard output gets a Content-Type field that has no supplementary parameters πŸ’œ.

For example, this mailcap entry:

audio/basic; /usr/local/bin/showaudio %t
  compose = /usr/local/bin/recordaudio

would tag the data composed by the recordaudio program as:

Content-Type: audio/basic

If that's not acceptable (for example, in multipart mail, where a boundary parameter is required), then the compose field can't be used πŸ™…β€β™€οΈ. Instead, you should use the composetyped field in the mailcap file.

Semantics of the "composetyped" field πŸŽ€

The composetyped field is pretty much like the compose field, except it names a composition program that doesn't produce raw data. Instead, it produces data that includes a MIME-conformant type specification πŸ“¦. The program gets run with the command line arguments determined as specified above. The data returned through standard output must begin with a Content-Type header, followed optionally by other Content-* headers, and then a blank line and the data.

For example, this mailcap entry:

multipart/mixed; /usr/local/bin/showmulti %t \
  %{boundary}; \
  composetyped = /usr/local/bin/makemulti

would run the makemulti program, which is expected to begin its output with a line of this form:

Content-Type: multipart/mixed; boundary=foobar

Quick note: a composition program doesn't need to encode binary data in base64 or quoted-printable πŸ™. It's still the responsibility of the software calling the composition program to encode that data as necessary. However, if a composing program does encode data (which isn't encouraged), it should announce that fact using a Content-Transfer-Encoding header, in the standard way defined by MIME. Because such encodings must be announced by that header, they're only an option for composetyped programs, not for compose programs 🫢.

Appendix B: Sample Mailcap File πŸ“

Here's an example of a mailcap file for UNIX that shows off most of the syntax above. It includes explanatory comments wherever they're needed πŸ“š.

# Mailcap file for Bellcore lab 214.
#
# The next line sends "richtext" to the richtext program
text/richtext; richtext %s; copiousoutput
#
# Next, basic u-law audio
audio/*; showaudio; test=/usr/local/bin/hasaudio
#
# Next, use the xview program to handle several image formats
image/*; xview %s; test=/usr/local/bin/RunningX
#
# The ATOMICMAIL interpreter uses curses, so needs a terminal
application/atomicmail; /usr/local/bin/atomicmail %s; \
    needsterminal
#
# The next line handles Andrew format,
#   if ez and ezview are installed
x-be2; /usr/andrew/bin/ezview %s; \
   print=/usr/andrew/bin/ezprint %s ; \
   compose=/usr/andrew/bin/ez -d %s \;
   edit=/usr/andrew/bin/ez -d %s; \;
   copiousoutput
#
# The next silly example demonstrates the use of quoting
application/*; echo "This is \"%t\" but \
   is 50 \% Greek to me" \; cat %s; copiousoutput

Appendix C: A Note on Format Translation πŸ”„

It has been suggested that another job for a mailcap-like mechanism could be specifying the locally available tools for document format translation. For example, the file could point to one program that translates format A to format B, another that translates format B to format C, and finally a mechanism for displaying format C. This would be somewhat richer than the current mailcap file, and it might even be useful at the message transport layer. But it would seriously complicate the processing effort for a user agent that just wants to display a message in format A 😩.

With the current, simpler mailcap scheme, a single line could tell that user agent to display A-format mail using a pipeline of translators and the C-format viewer. This memo resists the temptation to complicate the processing a user agent needs to pull that off πŸ™…β€β™€οΈ. With the mailcap format defined here, all you have to do is find the correct single line in a mailcap file and execute the command given in that line πŸ’œ.

References πŸ“š

[RFC-822] Crocker, D., "Standard for the format of ARPA Internet text messages", STD 11, RFC 822, UDEL, August 1982.

[RFC-1521] Borenstein, N., and N. Freed, "MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies", RFC 1521, Bellcore, Innosoft, September 1993.

πŸ“¦ where this page comes from