MAKEMIME(1)

๐ŸŽ€ MAKEMIME(1) ๐ŸŽ€

makemime โ€” the S. Varshavchik classic โ€” this is your girl for making MIME-formatted messages, bestie. No cap.


โœจ NAME โœจ

makemime โ€” create MIME-formatted messages ๐Ÿ’Œ


๐Ÿ’… SYNOPSIS ๐Ÿ’…

makemime [options...]
makemime [@filename]

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

okay so. makemime creates MIME-formatted messages of arbitrary complexity. Like, however extra you want it, she can do it. ๐Ÿ’–

Here's the vibe: makemime reads one or more individual files, MIME-encodes them, adds basic MIME headers, and then adds any additional headers you told it about via command line options. The result gets saved to another file or to standard output.

And the way you build complex MIME messages? You pipe together multiple instances of makemime. ๐ŸŒˆ Stacked. Iconic. The advanced options will literally tell makemime to fork() itself and handle all the details of setting up all the pipelines for you. main character energy fr.

Most of the time, the options for makemime come straight off the command line. But @filename reads options from a file. And @&n reads options from a pipe on file descriptor #n. And @- is just the shortcut life-hack version of @&0, which reads options from standard input. ๐Ÿซถ

When options are read from a file or a pipe, each option has to be on a line by itself. If an option needs an argument, the argument goes on the next line. Periodt.

For readability, leading whitespace gets deleted when options come from a file or a pipe. Empty lines are ignored too, along with any lines that begin with the # character. ๐Ÿ’€ (so you can leave yourself lil comments, go off)

Options and their arguments may contain characters that are special to the shell, like ( and ). Those characters must be backslashed when you specify them on the command line, so the shell doesn't get any weird ideas. But those same characters MUST NOT be backslashed when options are read from a file or a pipe. Noted. Similarly, the contents of most headers nearly always include spaces. So they have to be quoted when specified on the command line. And header contents MUST NOT be quoted when options come from a file or a pipe. Swapped rules, don't mix them up bestie ๐Ÿ˜ญ

makemime reads the content to be formatted as a MIME message from some other file. And the files can also be a pipe. โœจ Here's the cute part: it's possible to supply both the options and a file from the same pipe, by terminating the options list with a line containing the single character -. The remainder of the pipe will then be available to be used as an input file (which you must explicitly specify with one of the options, ok?). And of course, only one input file can come from a single pipe. ๐ŸŒธ

For this to work, the file with the options gets opened with a specific file descriptor, and then the options are read from that file descriptor:

# Open options.txt on file descriptor 3,
# then specify that options
# are read from file descriptor 3.
# Quote special shell character "&"

makemime "@&3" 3<options.txt

With options.txt contents:

-c
auto

-C
utf-8

-N
text8bit

# options.txt is opened on file descriptor 3, read this MIME
# section starting after the - terminator

&3
-
[contents of the MIME section]

๐ŸŒธ MIME overview ๐ŸŒธ

A MIME-formatted message contains one or several MIME sections. MIME headers specify how multiple MIME sections are to be interpreted as a whole โ€” whether they're attached together, whether they're alternative representations of the same content, or something even more esoteric. ๐Ÿ”ฎ

This manual page gives a very brief, terse, overview of basic MIME concepts. The description is biased towards describing the functionality of the makemime utility. See RFC 2045[1], RFC 2046[2], RFC 2047[3], RFC 2048[4], and RFC 2049[4] for a formal definition of MIME-formatted messages. ๐Ÿ“š

Each file in a MIME message is encoded as a single MIME section. A MIME section consists of at least one header line, Content-Type:. That Content-Type: header gives the type of the data contained in the file. Other header lines may also be present, and their relative order does not matter. MIME headers are followed by a blank line, then the contents of the file, encoded appropriately. โœจ

All MIME sections generated by makemime will always contain another header, Content-Transfer-Encoding:. This header gives the encoding method used for the file; it's an optional header, but makemime always creates it. She's thorough like that. ๐Ÿ’…

The MIME encoding method defaults to "7bit" if this header is absent. 7bit encoding is only suitable for plain text messages in the US-ASCII character set. The "8bit" encoding method is used by plain text messages in other character sets that use octets with the high bit set. An alternative to 8bit encoding is "quoted-printable". And the "base64" encoding method is used for files containing binary data (anything other than plain text). ๐Ÿงš

MIME sections that contain text messages have their Content-Type: header set to text/plain; or text/html for HTML messages. There are also several other, rare, content types that can be used. MIME sections that contain other kinds of data will use some other, appropriate Content-Type: header, such as image/gif, or audio/x-wav. ๐ŸŽจ

MIME sections that contain textual content may also use the base64 encoding method โ€” they are not required to use 7bit, 8bit, or quoted-printable. text/pdf sections, that contain PDF files, typically contain binary data and must use the base64 encoding. Consequently, MIME sections that typically contain binary data, such as image/gif and audio/x-wav, are free to use encodings other than base64, as long as all the data can be represented by printable characters (but, in practice, that never happens ๐Ÿ˜ญ).

MIME sections may also contain other, optional, headers such as Content-Disposition:, Content-ID:, and Content-Name:. Consult the appropriate RFCs for the specific usage of these headers. These headers can be added by makemime by using the -a option, as described below. These headers play no part in creating the overall structure of a MIME-encoded message, and makemime does not care much about these headers. She simply includes them, and their content, upon request. ๐Ÿ’–

Multiple files are formatted as a single MIME message in two steps: first, by creating a MIME section for each file; and then creating a single MIME section that contains other MIME sections. A multipart/mixed MIME section contains a collection of MIME sections that represent different objects, attached together. A multipart/alternative MIME section contains a collection of MIME sections which are alternative representations of the same object, such as an HTML and a plain text version of the same message. Other multipart MIME sections also exist, and their usage is defined by their respective RFCs. ๐ŸŒˆ


๐Ÿ‘‘ Creating a single MIME section ๐Ÿ‘‘

makemime {-c "type"} [-e "encoding"] [-o outputfile] [-C "charset"]
         [-N "name"] [-a "header: value"...] {filename}

The -c option reads filename, encodes it appropriately, adds the Content-Type: type and Content-Transfer-Encoding: MIME headers, then writes the result to standard output. โœจ type can be any valid MIME type, except for multipart. Setting filename to - reads from standard input. Setting filename to &n reads from file descriptor #n.

The -C option sets the MIME charset attribute for text/plain content. The -N option sets the name attribute for Content-Type:.

Your encoding argument should be specified. It's more efficient to do so, fr fr. encoding must be one of the following: 7bit, 8bit, quoted-printable, or base64.

If encoding is not specified, makemime reads filename twice โ€” once to figure out the best encoding method, and the second time to encode filename. And if filename is a pipe, makemime creates a temporary file, which is not very efficient if filename is large. ๐Ÿ˜ญ However, letting makemime pick the encoding method is more convenient if filename is relatively small. Trade-offs, bestie.

Another possibility is to omit encoding and set type to auto. This combination sets Content-Type: to either text/plain, or application/octet-stream, based on the selected encoding. ๐Ÿ’…

By default the encoded MIME section is written to standard output. The -o option writes the MIME section to outputfile. outputfile may be &n, which writes the MIME section to a pipe on file descriptor #n. ๐ŸŽ€

makemime does not generate any other headers. Particularly, the Mime-Version: header is required for MIME-formatted E-mail messages. Additional headers are specified by the -a option, which may be used multiple times to insert multiple headers. makemime doesn't do anything with them except insert the headers into the generated MIME section. She's just the messenger ๐Ÿซถ

Note that Mime-Version: is only required for the top level MIME section. This header is not required for individual MIME sections that are later combined into a multipart MIME collection.

Note ๐Ÿšจ The -c option must occur listed first. The remaining options must follow the -c option. No exceptions, babe.

๐Ÿ’œ Creating a multipart MIME collection ๐Ÿ’œ

makemime {-m "multipart/type"} [-o outputfile] [-a "header: value"...]
         {filename}

The -m option is similar to the -c option, except for three differences. ๐Ÿ‘€

type must be either multipart/mixed, multipart/alternative, or some other MIME multipart content type. There is no explicit encoding. Also: filename must be a MIME-formatted section โ€” NOT a regular file. ๐Ÿšจ Usually filename is created by a previous invocation of makemime (it can also be a pipe, just like the -c option), but it can be created via any other means.

The -m option creates an initial multipart MIME collection, that contains only one MIME section, taken from filename. The collection is written to standard output, or the pipe, or to outputfile. โœจ


๐Ÿฆ„ Creating a multipart MIME section ๐Ÿฆ„

makemime {-j file1} [-o outputfile] {file2}

This option adds a MIME section to an existing MIME collection. ๐Ÿ‘‘

file1 must be a MIME collection that was previously created by the -m option. file2 must be a MIME section that was previously created by the -c option. The -j option adds the MIME section in file2 to the MIME collection in file1. The result is written to standard output or to outputfile. ๐ŸŒธ

file1 and/or file2 may be @&n which reads from file descriptor #n. The outputfile may also specify a file descriptor.

file1 and file2 should ideally be created by makemime as well. It's also possible to use MIME-formatted files created by other software, but with some degree of care. โš ๏ธ makemime is not intended to be a MIME parser, but a MIME generator. However, some amount of MIME parsing is necessary to append a MIME section to an existing MIME collection. makemime's parsing is sufficient for appending a new section to a MIME collection, as long as the MIME headers in the MIME collections are straightforward. Very convoluted MIME headers may confuse makemime, and she may not be able to handle them. ๐Ÿ’€

๐ŸŒธ Recursive MIME collections ๐ŸŒธ

okay so here's the tea: a MIME collection can contain other MIME collections, not just plain MIME sections. And because a multipart MIME collection is literally just a special lil type of MIME section, the -m and -j options can slide a multipart MIME collection in wherever a MIME section would go. Automatic. No extra work. ๐Ÿ’…

The example below encodes a text message that can be alternatively represented as HTML or plain text, with some additional attachments. Two steps, bestie:

  1. Create a MIME collection that has a text/plain and a text/html MIME section.
  2. Create a MIME collection consisting of the MIME section generated in step one, plus additional MIME sections containing other attachments.

Here's how it looks:

# Take two files containing the text and the html version of a message, and
# add MIME headers to them.

makemime -c "text/plain; charset=iso-8859-1" -o tmp1.txt msg.txt
makemime -c "text/html; charset=iso-8859-1" -o tmp1.html msg.html

# Combine the result into a multipart/alternative collection

makemime -m "multipart/alternative" -a "Content-Disposition: inline" \
                                    -o tmp.ma1 tmp1.txt
makemime -j tmp.ma1 -o tmp.ma2 tmp1.html

# Add MIME headers to an image attachment.

makemime -c "image/gif" -a "Content-Disposition: attachment" \
                        -o tmp2.gif attachment.gif

# Create the final multipart/mixed collection

makemime -m "multipart/mixed" -a "Mime-Version: 1.0" \
                              -o tmp.mm1 tmp.ma2
makemime -j tmp.mm1 -o output.msg tmp2.gif

And boom โ€” output.msg now contains the complete MIME collection. All you gotta do is add the Subject:, From:, and To: headers (can also be done by additional -a options, of course), and send it on its way. ๐Ÿฆ‹โœจ

๐Ÿ› ๏ธ Building complex MIME encodings ๐Ÿ› ๏ธ

There are several different ways to build complete MIME encodings from multiple MIME sections, and honestly pick your fighter:

  • One way is to use temporary files to create MIME sections, then combine them together into a single MIME collection.
  • A slightly more complicated approach involves setting up pipes between multiple makemime processes, in order to avoid using temporary files.

You can do this manually, by hand, like a โœจcraftโœจ. But it's also possible to have makemime do this automatically. makemime will set up these pipes and run multiple instances of itself to create a single MIME collection, with multiple attachments of complexity limited only by your system's limit on the maximum number of open files and pipes. (iykyk โ€” that's the ceiling, bestie.)

Any file that's read by the -c, -m, and -j options (-o specifies a file to create, and doesn't count, she's built different) may be replaced by a single argument containing a left parenthesis, additional options, then a single argument containing a right parenthesis.

A single invocation of makemime can only use one -c, -m, or -j option. However, another -c, -m, or -j option may be specified inside the left and the right parenthesis, and its output is used in place of the file it replaced. So in the previous example, the third and the fourth invocation of makemime can be replaced with the following command:

makemime -j \(                                           \
               -m "multipart/alternative"                \
               -a "Content-Disposition: inline" tmp1.txt \
             \) -o tmp.ma2                               \
             tmp1.html
โš ๏ธ heads up bestie: note that the parenthesis must be backslashed, to avoid their special meaning to the shell. The shell will absolutely eat them otherwise and it will be a whole thing. ๐Ÿ˜ญ

An equivalent argument file would have the following contents:

-j
   (
      -m
          multipart/alternative
      -a
          Content-Disposition: inline
      tmp1.txt
   )
   -o
      tmp.ma2
 tmp1.html

These constructs can be arbitrarily nested, and are limited by the amount of available memory and resources. ๐ŸŒˆ The entire sequence in the previous section is equivalent to the following command:

makemime -j                                                 \
         \(                                                 \
            -m "multipart/mixed"                            \
            -a "Mime-Version: 1.0"                          \
            \(                                              \
                -j                                          \
                \(                                          \
                   -m "multipart/alternative"               \
                   -a "Content-Disposition: inline"         \
                   \(                                       \
                      -c "text/plain; charset=iso-8859-1"   \
                      msg.txt                               \
                   \)                                       \
                \)                                          \
                \(                                          \
                    -c "text/html; charset=iso-8859-1"      \
                    msg.html                                \
                \)                                          \
            \)                                              \
         \)                                                 \
         -o output.msg                                      \
         \(                                                 \
            -c "image/gif"                                  \
            -a "Content-Disposition: attachment"            \
            attachment.gif                                  \
         \)

Look at that nesting. She's giving main character energy. ๐Ÿ‘‘

An equivalent argument file would be:

-j
(
   -m
       multipart/mixed
   -a
       Mime-Version: 1.0
   (
       -j
       (
           -m
               multipart/alternative
           -a
               Content-Disposition: inline
           (
               -c
                   text/plain; charset=iso-8859-1
               msg.txt
           )
       )
       (
           -c
               text/html; charset=iso-8859-1
           msg.html
       )
   )
)
-o
   output.msg
(
   -c
       image/gif
   -a
       Content-Disposition: attachment
   attachment.gif
)

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

๐Ÿ’– AUTHOR ๐Ÿ’–

Sam Varshavchik Author

๐Ÿ“Ž NOTES ๐Ÿ“Ž

  1. RFC 2045 http://www.rfc-editor.org/rfc/rfc2045.txt
  2. RFC 2046 http://www.rfc-editor.org/rfc/rfc2046.txt
  3. RFC 2047 http://www.rfc-editor.org/rfc/rfc2047.txt
  4. RFC 2048 http://www.rfc-editor.org/rfc/rfc2048.txt
  5. maildrop(1) http://www.courier-mta.org/maildrop/maildrop.html
  6. maildropfilter(5) http://www.courier-mta.org/maildrop/maildropfilter.html
  7. reformail(1) http://www.courier-mta.org/maildrop/reformail.html
  8. reformime(1) http://www.courier-mta.org/maildrop/reformime.html
  9. courier(8) http://www.courier-mta.org/maildrop/courier.html

and that's the whole page, bestie!! this one comes from the Courier Mail Server, dated 01/10/2026, and it's page MAKEMIME(1) โ€” go forth and build your MIME collections, you absolute icon ๐Ÿ’…๐ŸŒธโœจ

๐Ÿ“ฆ where this page comes from
  • ubuntu stonking: maildrop 4.0.4-1 ยท GPL-3~with-OpenSSL-exception
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms