'\" t .\" .\" .\" Title: makemime .\" Author: Sam Varshavchik .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 08/25/2013 .\" Manual: Double Precision, Inc. .\" Source: Courier Mail Server .\" Language: English .\" .TH "MAKEMIME" "1" "08/25/2013" "Courier Mail Server" "Double Precision, Inc\&." .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" makemime \- Create MIME\-formatted messages .SH "SYNOPSIS" .HP \w'\fBmakemime\fR\ 'u \fBmakemime\fR [\fIoptions\fR...] .HP \w'\fBmakemime\fR\ 'u \fBmakemime\fR [@\fIfilename\fR] .SH "DESCRIPTION" .PP \fBmakemime\fR creates MIME\-formatted messages of arbitrary complexity\&. \fBmakemime\fR 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 \fBmakemime\fR\&. Advanced options direct \fBmakemime\fR to \fBfork\fR() itself, and handle the details of setting up all the pipelines\&. .PP In most cases, options for \fBmakemime\fR come directly from the command line\&. @filename reads the options from a file\&. "@&\fIn\fR" reads options from a pipe on file descriptor #\fIn\fR\&. "@\-" is a shortcut for "@&0", which reads options from standard input\&. .PP 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\&. .PP 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 \*(Aq#\*(Aq character\&. .PP Options and their arguments may contain characters that are special characters to the shell, such as \*(Aq(\*(Aq and \*(Aq)\*(Aq\&. 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\&. .PP \fBmakemime\fR 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\&. .SS "MIME overview" .PP 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 \fBmakemime\fR utility\&. See \m[blue]\fBRFC 2045\fR\m[]\&\s-2\u[1]\d\s+2, \m[blue]\fBRFC 2046\fR\m[]\&\s-2\u[2]\d\s+2, \m[blue]\fBRFC 2047\fR\m[]\&\s-2\u[3]\d\s+2, \m[blue]\fBRFC 2048\fR\m[]\&\s-2\u[4]\d\s+2, and \m[blue]\fBRFC 2049\fR\m[]\&\s-2\u[4]\d\s+2 for a formal definition of MIME\-formatted messages\&. .PP 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 \fBmakemime\fR will always contain another header, "Content\-Transfer\-Encoding:"\&. This header gives the encoding method used for the file; it is an optional header, but \fBmakemime\fR always creates it\&. .PP 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)\&. .PP 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"\&. .PP 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)\&. .PP 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 \fBmakemime\fR by using the \fB\-a\fR option, as described below\&. These headers play no part in creating the overall structure of a MIME\-encoded message, and \fBmakemime\fR does not care much about these headers\&. It simply includes them, and their content, upon request\&. .PP 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\&. .SS "Creating a single MIME section" .HP \w'\fBmakemime\fR\ 'u \fBmakemime\fR {\-c\ "\fItype\fR"} [\-e\ "\fIencoding\fR"] [\-o\ \fIoutputfile\fR] [\-C\ "\fIcharset\fR"] [\-N\ "\fIname"\fR] [\-a\ "\fIheader:\ value"\fR...] {\fIfilename\fR} .PP The \fB\-c\fR option reads filename, encodes it appropriately, adds the "Content\-Type: \fItype\fR" 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 "&\fIn\fR" reads from file descriptor #\fIn\fR\&. .PP The \fB\-C\fR option sets the MIME charset attribute for text/plain content\&. The \fB\-N\fR option sets the name attribute for Content\-Type:\&. .PP \fIencoding\fR argument should be specified\&. It\*(Aqs more efficient to do so\&. \fIencoding\fR must be one of the following: 7bit, 8bit, quoted\-printable, or base64\&. .PP If \fIencoding\fR is not specified, \fBmakemime\fR reads the filename twice \- once to figure out the best encoding method, and the second time to encode filename\&. If filename is a pipe \fBmakemime\fR creates a temporary file, which is not very efficient if filename is large\&. However letting \fBmakemime\fR pick the encoding method is more convenient if filename is relatively small\&. .PP Another possibility is to omit \fIencoding\fR and set \fItype\fR to auto\&. This combination sets "Content\-Type:" to either text/plain, or application/octet\-stream, based on the selected \fIencoding\fR\&. .PP By default the encoded MIME section is written to standard output\&. The \fB\-o\fR option writes the MIME section to \fIoutputfile\fR\&. \fIoutputfile\fR may be "&\fIn\fR", which writes the MIME section to a pipe on file descriptor #\fIn\fR\&. .PP \fBmakemime\fR 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 \fB\-a\fR option, which may be used multiple times to insert multiple headers\&. \fBmakemime\fR doesn\*(Aqt do anything with them except to insert the headers into the generated MIME section\&. .PP 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\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP The \fB\-c\fR option must occur listed first, the remaining options must follow the \fB\-c\fR option\&. .sp .5v .RE .SS "Creating a multipart MIME collection" .HP \w'\fBmakemime\fR\ 'u \fBmakemime\fR {\-m\ "multipart/\fItype\fR"} [\-e\ "\fIencoding\fR"] [\-o\ \fIoutputfile\fR] [\-a\ "\fIheader:\ value"\fR...] {\fIfilename\fR} .PP The \fB\-m\fR option is identical to the \fB\-c\fR option, except for three differences\&. .PP \fItype\fR must be either "multipart/mixed", "multipart/alternative", or some other MIME multipart content type\&. Additionally, "\fIencoding\fR" 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 \fBmakemime\fR (it can also be a pipe, like the \fB\-c\fR option), but it can be created via any other means\&. .PP The \fB\-m\fR 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 \fIoutputfile\fR\&. .SS "Creating a multipart MIME section" .HP \w'\fBmakemime\fR\ 'u \fBmakemime\fR {\-j\ \fIfile1\fR"} [\-o\ \fIoutputfile\fR] {\fIfile2\fR} .PP This option adds a MIME section to an existing MIME collection\&. \fIfile1\fR must be a MIME collection that was previously created by the \fB\-m\fR option\&. \fIfile2\fR must be a MIME section that was previously created by the \fB\-c\fR option\&. The \fB\-j\fR options adds the MIME section in \fIfile2\fR to the MIME collection in \fIfile1\fR\&. The result is written to standard output or to \fIoutputfile\fR\&. .PP \fIfile1\fR and/or \fIfile2\fR may be "@&\fIn\fR" which reads from file descriptor #\fIn\fR\&. The \fIoutputfile\fR may also specify a file descriptor\&. .PP \fIfile1\fR and \fIfile2\fR should ideally be created by \fBmakemime\fR as well\&. It\*(Aqs also possible to use MIME\-formatted files created by other software, but with some degree of care\&. \fBmakemime\fR 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\&. \fBmakemime\fR\*(Aqs 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 \fBmakemime\fR, and it may not be able to handle them\&. .SS "Recursive MIME collections" .PP MIME collection may contain other MIME collections as well as MIME sections\&. The \fB\-m\fR and the \fB\-j\fR 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: .PP 1\&. Create a MIME collection that has a text/plain and a text/html MIME section\&. .PP 2\&. Create a MIME collection consisting of the MIME section generated in step one, plus additional MIME sections containing other attachments\&. .PP For example: .sp .if n \{\ .RS 4 .\} .nf # 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" \e \-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" \e \-o tmp2\&.gif attachment\&.gif # Create the final multipart/mixed collection makemime \-m "multipart/mixed" \-a "Mime\-Version: 1\&.0" \e \-o tmp\&.mm1 tmp\&.ma2 makemime \-j tmp\&.mm1 \-o output\&.msg tmp2\&.gif .fi .if n \{\ .RE .\} .PP output\&.msg now contains the complete MIME collection\&. Just add the Subject:, From:, and To: headers (can also be done by additional \fB\-a\fR options, of course), and send it on its way\&. .SS "Building complex MIME encodings" .PP 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\&. .PP This can be done manually, by hand\&. It is also possible to have \fBmakemime\fR do this automatically\&. \fBmakemime\fR 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\*(Aqs limit on the maximum number of open files and pipes\&. .PP Any file that\*(Aqs read by the \fB\-c\fR, \fB\-m\fR, and \fB\-j\fR options ( \fB\-o\fR specifies a file to create, and doesn\*(Aqt 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 \fBmakemime\fR can only use one \fB\-c\fR, \fB\-m\fR, or \fB\-j\fR option\&. However, another \fB\-c\fR, \fB\-m\fR, or \fB\-j\fR 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 \fBmakemime\fR can be replaced with the following command: .sp .if n \{\ .RS 4 .\} .nf makemime \-j \e( \e \-m "multipart/alternative" \e \-a "Content\-Disposition: inline" tmp1\&.txt \e \e) \-o tmp\&.ma2 \e tmp1\&.html .fi .if n \{\ .RE .\} .PP Note that the parenthesis must be backslashed, to avoid their special meaning to the shell\&. An equivalent argument file would have the following contents: .sp .if n \{\ .RS 4 .\} .nf \-j ( \-m multipart/alternative \-a Content\-Disposition: inline tmp1\&.txt ) \-o tmp\&.ma2 tmp1\&.html .fi .if n \{\ .RE .\} .PP 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: .sp .if n \{\ .RS 4 .\} .nf makemime \-j \e \e( \e \-m "multipart/mixed" \e \-a "Mime\-Version: 1\&.0" \e \e( \e \-j \e \e( \e \-m "multipart/alternative" \e \-a "Content\-Disposition: inline" \e \e( \e \-c "text/plain; charset=iso\-8859\-1" \e msg\&.txt \e \e) \e \e) \e \e( \e \-c "text/html; charset=iso\-8859\-1" \e msg\&.html \e \e) \e \e) \e \e) \e \-o output\&.msg \e \e( \e \-c "image/gif" \e \-a "Content\-Disposition: attachment" \e attachment\&.gif \e \e) .fi .if n \{\ .RE .\} .PP An equivalent argument file would be: .sp .if n \{\ .RS 4 .\} .nf \-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 ) .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP \m[blue]\fB\fBmaildrop\fR(1)\fR\m[]\&\s-2\u[5]\d\s+2, \m[blue]\fB\fBmaildropfilter\fR(5)\fR\m[]\&\s-2\u[6]\d\s+2, \m[blue]\fB\fBreformail\fR(1)\fR\m[]\&\s-2\u[7]\d\s+2, \m[blue]\fB\fBreformime\fR(1)\fR\m[]\&\s-2\u[8]\d\s+2, \fBegrep\fR(1), \fBgrep\fR(1), \m[blue]\fB\fBcourier\fR(8)\fR\m[]\&\s-2\u[9]\d\s+2, \fBsendmail\fR(8), \m[blue]\fBRFC 2045\fR\m[]\&\s-2\u[1]\d\s+2, \m[blue]\fBRFC 2046\fR\m[]\&\s-2\u[2]\d\s+2, \m[blue]\fBRFC 2047\fR\m[]\&\s-2\u[3]\d\s+2, \m[blue]\fBRFC 2048\fR\m[]\&\s-2\u[4]\d\s+2, \m[blue]\fBRFC 2049\fR\m[]\&\s-2\u[4]\d\s+2\&. .SH "AUTHOR" .PP \fBSam Varshavchik\fR .RS 4 Author .RE .SH "NOTES" .IP " 1." 4 RFC 2045 .RS 4 \%http://www.rfc-editor.org/rfc/rfc2045.txt .RE .IP " 2." 4 RFC 2046 .RS 4 \%http://www.rfc-editor.org/rfc/rfc2046.txt .RE .IP " 3." 4 RFC 2047 .RS 4 \%http://www.rfc-editor.org/rfc/rfc2047.txt .RE .IP " 4." 4 RFC 2048 .RS 4 \%http://www.rfc-editor.org/rfc/rfc2048.txt .RE .IP " 5." 4 \fBmaildrop\fR(1) .RS 4 \%[set $man.base.url.for.relative.links]/maildrop.html .RE .IP " 6." 4 \fBmaildropfilter\fR(5) .RS 4 \%[set $man.base.url.for.relative.links]/maildropfilter.html .RE .IP " 7." 4 \fBreformail\fR(1) .RS 4 \%[set $man.base.url.for.relative.links]/reformail.html .RE .IP " 8." 4 \fBreformime\fR(1) .RS 4 \%[set $man.base.url.for.relative.links]/reformime.html .RE .IP " 9." 4 \fBcourier\fR(8) .RS 4 \%[set $man.base.url.for.relative.links]/courier.html .RE