makemime — Create MIME-formatted messages
makemime
[options
...]
makemime
[@filename
]
makemime creates MIME-formatted messages of arbitrary
complexity.
makemime reads one or more individual files,
MIME-encodes them, adds basic MIME headers, and adds any additional headers
specified bye command line options. The result is saved to another file or
standard output. Complex MIME-formatted messages are created by piping together
multiple instances of makemime.
Advanced options direct makemime to
fork
() itself, and handle the details of setting up all
the pipelines.
In most cases, options for makemime come directly from the
command line. @filename
reads the options from a file.
"@&
" reads options from a pipe
on file descriptor #n
n
.
"@-
" is a shortcut for
"@&0
", which reads options from standard input.
When options are read from a file or a pipe, each option must be on a line by itself. If an option requires an argument, the argument must follow on the next line.
For readability, leading whitespace is deleted when options are read from a file or a pipe. Empty lines are also ignored, as well as lines that begin with the '#' character.
Options and their arguments may contain characters that are special characters to the shell, such as '(' and ')'. These characters must be backslashed when specified on the command line, to avoid their special meaning to the shell. These characters MUST NOT be backslashed when options are read from a file or a pipe. Similarly, the contents of most headers nearly always include spaces. Therefore they must be quoted when specified on the command line. Header contents MUST NOT be quoted when options come from a file or a pipe.
makemime reads the content to be formatted as a MIME message from some other file. The files can also be a pipe. It is 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 be available to be used as an input file (which must be explicitly specified by one of the options). Of course, only one input file can come from a single pipe.
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 are attached together; whether they are 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, RFC 2046, RFC 2047, RFC 2048, and RFC 2049 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:
".
The "Content-Type:
" header gives the type of the data
ontained in the file. Other header lines may also be present.
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 is an optional header, but
makemime always creates it.
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
". 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. It simply
includes them, and their content, upon request.
Multiple files are formatted as a single message 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.
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:
" and
"type
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:
.
encoding
argument should be specified. It's more
efficient to do so. encoding
must be one of the
following:
7bit
, 8bit
,
quoted-printable
, or base64
.
If encoding
is not specified,
makemime
reads the filename
twice - once to figure out the best
encoding method, and the second time to encode filename
.
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.
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 to insert the headers into the generated MIME section.
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.
The -c
option must occur listed first, the remaining
options must follow the -c
option.
makemime
{-m "multipart/type
"} [-e "encoding
"] [-o outputfile
] [-a "header: value"
...] {filename
}
The -m
option is identical to the -c
option,
except for three differences.
type
must be either
"multipart/mixed
",
"multipart/alternative
", or
some other MIME multipart content type. Additionally,
"encoding
" can only be
"7bit
" or "8bit
", and will default to "8bit
" if not specified. Finally,
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, 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
.
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
options 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
"@&
" which reads from
file descriptor #n
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 it may not be able to
handle them.
MIME collection may contain other MIME collections as well as MIME
sections. The -m
and the -j
options may use
a multipart MIME collection in place of a MIME section automatically
because a multipart MIME collection is just a special type of a MIME section.
The following example
encodes a text message that can be alternatively represented as HTML or plain
text, with some additional attachments:
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.
For example:
# 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
output.msg
now contains the complete MIME collection.
Just add the
Subject:
, From:
, and
To:
headers (can also be done by additional
-a
options, of
course), and send it on its way.
There are several different ways to build complete MIME encodings from multiple MIME sections. 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.
This can be done manually, by hand. It is 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.
Any file that's read by the
-c
,
-m
,
and
-j
options (
-o
specifies a file to
create, and doesn't count) 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. 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
Note that the parenthesis must be backslashed, to avoid their special meaning to the shell. 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 \ \)
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 )
maildrop(1), maildropfilter(5), reformail(1), reformime(1), egrep(1), grep(1), courier(8), sendmail(8), RFC 2045, RFC 2046, RFC 2047, RFC 2048, RFC 2049.