• Home
  • History
  • Annotate
  • only in this directory
NameDateSize

..14-Nov-2013104

badmail1.txtH A D25-Jun-2003301

badmail2.txtH A D25-Jun-20031.4 KiB

ChangeLogH A D06-Jul-201027 KiB

mime.benchH A D10-Jan-20061.6 KiB

mime.manH A D28-Jan-20099.8 KiB

mime.tclH A D21-May-2008110.1 KiB

mime.testH A D21-May-200820.5 KiB

pkgIndex.tclH A D07-Oct-2008198

README.htmlH A D04-Sep-200027.5 KiB

README.txtH A D04-Sep-200018.5 KiB

README.xmlH A D04-Sep-200019 KiB

rfc2629.dtdH A D01-Mar-20005.3 KiB

smtp.manH A D06-Jul-20105.6 KiB

smtp.tclH A D07-Oct-200846.4 KiB

README.html

1<html><head><title>The README file: Tcl MIME</title>
2<meta http-equiv="Expires" content="Wed, 23 Feb 2000 04:36:30 +0000">
3<STYLE type='text/css'>
4    .title { color: #990000; font-size: 22px; line-height: 22px; font-weight: bold; text-align: right;
5             font-family: helvetica, arial, sans-serif }
6    .filename { color: #666666; font-size: 18px; line-height: 28px; font-weight: bold; text-align: right;
7                  font-family: helvetica, arial, sans-serif }
8    p.copyright { color: #000000; font-size: 10px;
9                  font-family: verdana, charcoal, helvetica, arial, sans-serif }
10    p { margin-left: 2em; margin-right: 2em; }
11    ol { margin-left: 2em; margin-right: 2em; }
12    ul.text { margin-left: 2em; margin-right: 2em; }
13    pre { margin-left: 3em; color: #333333 }
14    ul.toc { color: #000000; line-height: 16px;
15             font-family: verdana, charcoal, helvetica, arial, sans-serif }
16    H3 { color: #333333; font-size: 16px; line-height: 16px; font-family: helvetica, arial, sans-serif }
17    H4 { color: #000000; font-size: 14px; font-family: helvetica, arial, sans-serif }
18    TD.header { color: #ffffff; font-size: 10px; font-family: arial, helvetica, san-serif; valign: top }
19    TD.author-text { color: #000000; font-size: 10px;
20                     font-family: verdana, charcoal, helvetica, arial, sans-serif }
21    TD.author { color: #000000; font-weight: bold; margin-left: 4em; font-size: 10px; font-family: verdana, charcoal, helvetica, arial, sans-serif }
22    A:link { color: #990000; font-size: 10px; text-transform: uppercase; font-weight: bold;
23             font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
24    A:visited { color: #333333; font-weight: bold; font-size: 10px; text-transform: uppercase;
25                font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
26    A:name { color: #333333; font-weight: bold; font-size: 10px; text-transform: uppercase;
27             font-family: MS Sans Serif, verdana, charcoal, helvetica, arial, sans-serif }
28    .link2 { color:#ffffff; font-weight: bold; text-decoration: none;
29             font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
30             font-size: 9px }
31    .RFC { color:#666666; font-weight: bold; text-decoration: none;
32           font-family: monaco, charcoal, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
33           font-size: 9px }
34    .hotText { color:#ffffff; font-weight: normal; text-decoration: none;
35               font-family: charcoal, monaco, geneva, MS Sans Serif, helvetica, monotype, verdana, sans-serif;
36               font-size: 9px }
37</style>
38</head>
39<body bgcolor="#ffffff"alink="#000000" vlink="#666666" link="#990000">
40<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
41<table width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table width="100%" border="0" cellpadding="2" cellspacing="1">
42<tr valign="top"><td width="33%" bgcolor="#666666" class="header">The README file</td><td width="33%" bgcolor="#666666" class="header">M.T. Rose</td></tr>
43<tr valign="top"><td width="33%" bgcolor="#666666" class="header">&nbsp;</td><td width="33%" bgcolor="#666666" class="header">Dover Beach Consulting, Inc.</td></tr>
44<tr valign="top"><td width="33%" bgcolor="#666666" class="header">&nbsp;</td><td width="33%" bgcolor="#666666" class="header">February 22, 2000</td></tr>
45</table></td></tr></table>
46<div align="right"><font face="monaco, MS Sans Serif" color="#990000" size="+3"><b><br><span class="title">Tcl MIME</span></b></font></div>
47<font face="verdana, helvetica, arial, sans-serif" size="2">
48
49<h3>Abstract</h3>
50
51<p>
52Tcl MIME generates and parses MIME body parts.
53</p>
54<a name="toc"><br><hr size="1" shade="0"></a>
55<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
56<h3>Table of Contents</h3>
57<ul compact class="toc">
58<b><a href="#anchor1">1.</a>&nbsp;
59SYNOPSIS<br></b>
60<b><a href="#anchor2">1.1</a>&nbsp;
61Requirements<br></b>
62<b><a href="#anchor3">1.2</a>&nbsp;
63Copyrights<br></b>
64<b><a href="#anchor4">2.</a>&nbsp;
65SYNTAX<br></b>
66<b><a href="#anchor5">3.</a>&nbsp;
67SEMANTICS<br></b>
68<b><a href="#mime_initialize">3.1</a>&nbsp;
69mime::initialize<br></b>
70<b><a href="#mime_finalize">3.2</a>&nbsp;
71mime::finalize<br></b>
72<b><a href="#mime_getproperty">3.3</a>&nbsp;
73mime::getproperty<br></b>
74<b><a href="#mime_getheader">3.4</a>&nbsp;
75mime::getheader<br></b>
76<b><a href="#mime_setheader">3.5</a>&nbsp;
77mime::setheader<br></b>
78<b><a href="#mime_getbody">3.6</a>&nbsp;
79mime::getbody<br></b>
80<b><a href="#mime_copymessage">3.7</a>&nbsp;
81mime::copymessage<br></b>
82<b><a href="#mime_buildmessage">3.7</a>&nbsp;
83mime::buildmessage<br></b>
84<b><a href="#smtp_sendmessage">3.8</a>&nbsp;
85smtp::sendmessage<br></b>
86<b><a href="#mime_parseaddress">3.9</a>&nbsp;
87mime::parseaddress<br></b>
88<b><a href="#mime_parsedatetime">3.10</a>&nbsp;
89mime::parsedatetime<br></b>
90<b><a href="#mime_mapencoding">3.10</a>&nbsp;
91mime::mapencoding<br></b>
92<b><a href="#mime_reversemapencoding">3.10</a>&nbsp;
93mime::reversemapencoding<br></b>
94
95<b><a href="#anchor6">4.</a>&nbsp;
96EXAMPLES<br></b>
97<b><a href="#rfc.references">&#167;</a>&nbsp;
98References<br></b>
99<b><a href="#rfc.authors">&#167;</a>&nbsp;
100Author's Address<br></b>
101<b><a href="#anchor7">A.</a>&nbsp;
102TODO List<br></b>
103<b><a href="#anchor8">B.</a>&nbsp;
104Acknowledgements<br></b>
105</ul>
106<br clear="all">
107
108<a name="anchor1"><br><hr size="1" shade="0"></a>
109<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
110<h3>1.&nbsp;SYNOPSIS</h3>
111</font><pre>
112    package provide mime 1.2
113    package provide smtp 1.2
114</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
115
116<p>
117Tcl MIME is an implementation of a Tcl package that generates and
118parses <a href="#RFC2045">MIME</a>[1] body parts.
119</p>
120
121<p>
122Each MIME part consists of a header
123(zero or more key/value pairs), 
124an empty line,
125and a structured body.
126A MIME part is either a "leaf" or has (zero or more) subordinates.
127</p>
128
129<p>
130MIME defines four keys that may appear in the headers:
131
132<blockquote class="text"><dl>
133
134<dt>   Content-Type:</dt>
135<dd>
136describes the data contained in the body
137("the content");
138</dd>
139
140<dt>   Content-Transfer-Encoding:</dt>
141<dd>
142describes how the content is
143encoded for transmission in an ASCII stream;
144</dd>
145
146<dt>   Content-Description:</dt>
147<dd>
148a textual description of the
149content; and,
150</dd>
151
152<dt>   Content-ID:</dt>
153<dd>
154a globally-unique identifier for the
155content.
156</dd>
157
158</dl></blockquote>
159
160</p>
161
162<p>
163Consult <a href="#RFC2046">[2]</a> for a list of standard content types.
164Further,
165consult <a href="#RFC822">[3]</a> for a list of several other header keys
166(e.g., "To", "cc", etc.)
167</p>
168
169<p>
170A simple example might be:
171</p>
172</font><pre>
173    Date: Sun, 04 July 1999 10:38:25 -0600
174    From: Marshall Rose &lt;mrose@dbc.mtview.ca.us>
175    To: Andreas Kupries &lt;a.kupries@westend.com>
176    cc: dnew@messagemedia.com (Darren New)
177    MIME-Version: 1.0
178    Content-Type: text/plain; charset="us-ascii"
179    Content-Description: a simple example
180    Content-ID: &lt;4294407315.931384918.1@dbc.mtview.ca.us>
181    
182    Here is the body. In this case, simply plain text.
183</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
184
185<p>
186In addition to an implementation of the mime package,
187Tcl MIME includes an implementation of the smtp package.
188</p>
189
190<h4><a name="anchor2">1.1</a>&nbsp;Requirements</h4>
191
192<p>
193This package requires:
194
195<ul class="text">
196
197<li>
198<a href="http://www.scriptics.com/software/8.1.html">Tcl/Tk version 8.0.3</a>
199or later
200</li>
201</ul>
202</p>
203<p>
204In addition, this package requires one of the following:
205
206<ul class="text">
207<li>
208<a href="http://www.oche.de/~akupries/soft/trf/">Trf version 2.0p5</a> or later
209</li>
210<li>
211<a href="http://dev.ajubasolutions.com/software/tcllib/">base 64
212version 2.0</a> or later (included with tcllib)
213</li>
214</ul>
215</p>
216<p>
217If it is available, Trf will be used to provide better performance;
218if not, Tcl-only equivalent functions, based on the base64 package, are used.
219</p>
220
221<h4><a name="anchor3">1.2</a>&nbsp;Copyrights</h4>
222
223<p>
224(c) 1999-2000 Marshall T. Rose
225</p>
226
227<p>
228Hold harmless the author, and any lawful use is allowed.
229</p>
230
231<a name="anchor4"><br><hr size="1" shade="0"></a>
232<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
233<h3>2.&nbsp;SYNTAX</h3>
234
235<p>
236<a href="#mime_initialize">mime::initialize</a>
237returns a token.
238Parameters:
239</p>
240</font><pre>    ?-canonical type/subtype
241        ?-param    {key value}?...
242        ?-encoding value?
243        ?-header   {key value}?... ?
244    (-file name | -string value | -parts {token1 ... tokenN})
245</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
246
247<p>
248<a href="#mime_finalize">mime::finalize</a> returns
249an empty string.
250Parameters:
251</p>
252</font><pre>    token ?-subordinates "all" | "dynamic" | "none"?
253</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
254
255<p>
256<a href="#mime_getproperty">mime::getproperty</a>
257returns a string or a list of strings.
258Parameters:
259</p>
260</font><pre>    token ?property | -names?
261</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
262
263<p>
264<a href="#mime_getheader">mime::getheader</a> returns
265a list of strings.
266Parameters:
267</p>
268</font><pre>    token ?key | -names?
269</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
270
271<p>
272<a href="#mime_setheader">mime::setheader</a> returns
273a list of strings.
274Parameters:
275</p>
276</font><pre>    token key value ?-mode "write" | "append" | "delete"?
277</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
278
279<p>
280<a href="#mime_getbody">mime::getbody</a> returns a string.
281Parameters:
282</p>
283</font><pre>    ?-command callback ?-blocksize octets? ?
284</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
285
286<p>
287<a href="#mime_copymessage">mime::copymessage</a>
288returns an empty string.
289Parameters:
290</p>
291</font><pre>    token channel
292</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
293
294<p>
295<a href="#mime_buildmessage">mime::buildmessage</a>
296returns a string.
297Parameters:
298</p>
299</font><pre>    token
300</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
301
302<p>
303<a href="#smtp_sendmessage">smtp::sendmessage</a>
304returns a list.
305Parameters:
306</p>
307</font><pre>    token ?-servers list? ?-ports list?
308          ?-queue boolean?     ?-atleastone boolean?
309          ?-originator string? ?-recipients string?
310          ?-header {key value}?...
311</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
312
313<p>
314<a href="#mime_parseaddress">mime::parseaddress</a>
315returns a list of serialized arrays.
316Parameters:
317</p>
318</font><pre>    string
319</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
320
321<p>
322<a href="#mime_parsedatetime">mime::parsedatetime</a>
323returns a string.
324Parameters:
325</p>
326</font><pre>    [string | -now] property
327</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
328
329<p>
330<a href="#mime_mapencoding">mime::mapencoding</a>
331returns a string.
332Parameters:
333</p>
334</font><pre>    encoding_name
335</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
336
337<p>
338<a href="#mime_reversemapencoding">mime::reversemapencoding</a>
339returns a string.
340Parameters:
341</p>
342</font><pre>    mime_charset
343</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
344
345<a name="anchor5"><br><hr size="1" shade="0"></a>
346<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
347<h3>3.&nbsp;SEMANTICS</h3>
348
349<h4><a name="mime_initialize">3.1</a>&nbsp;mime::initialize</h4>
350
351<p>
352mime::initialize creates a MIME part:
353
354<ul class="text">
355
356<li>
357If the -canonical option is present,
358then the body is in canonical (raw) form and is found by consulting
359either the -file, -string, or -part option.
360<br>
361<br>
362
363In addition,
364both the -param and -header options may occur zero or more times to
365specify "Content-Type" parameters (e.g., "charset")
366and header keyword/values (e.g., "Content-Disposition"),
367respectively.
368<br>
369<br>
370
371Also, -encoding, if present,
372specifies the "Content-Transfer-Encoding" when copying the body.
373</li>
374
375<li>
376If the -canonical option is not present,
377then the MIME part contained in either the -file or the -string option
378is parsed,
379dynamically generating subordinates as appropriate.
380</li>
381
382</ul>
383
384</p>
385
386<h4><a name="mime_finalize">3.2</a>&nbsp;mime::finalize</h4>
387
388<p>
389mime::finalize destroys a MIME part.
390</p>
391
392<p>
393If the -subordinates option is present,
394it specifies which subordinates should also be destroyed.
395The default value is "dynamic".
396</p>
397
398<h4><a name="mime_getproperty">3.3</a>&nbsp;mime::getproperty</h4>
399
400<p>
401mime::getproperty returns the properties of a MIME part.
402</p>
403
404<p>
405The properties are:
406</p>
407</font><pre>
408    property    value
409    ========    =====
410    content     the type/subtype describing the content
411    encoding    the "Content-Transfer-Encoding"
412    params      a list of "Content-Type" parameters
413    parts       a list of tokens for the part's subordinates
414    size        the approximate size of the content (unencoded)
415</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
416
417<p>
418The "parts" property is present only if the MIME part has
419subordinates.
420</p>
421
422<p>
423If mime::getproperty is invoked with the name of a specific property,
424then the corresponding value is returned;
425instead,
426if -names is specified,
427a list of all properties is returned;
428otherwise,
429a serialized array of properties and values is returned.
430</p>
431
432<h4><a name="mime_getheader">3.4</a>&nbsp;mime::getheader</h4>
433
434<p>
435mime::getheader returns the header of a MIME part.
436</p>
437
438<p>
439A header consists of zero or more key/value pairs.
440Each value is a list containing one or more strings.
441</p>
442
443<p>
444If mime::getheader is invoked with the name of a specific key,
445then a list containing the corresponding value(s) is returned;
446instead,
447if -names is specified,
448a list of all keys is returned;
449otherwise,
450a serialized array of keys and values is returned.
451Note that when a key is specified (e.g., "Subject"),
452the list returned usually contains exactly one string;
453however,
454some keys (e.g., "Received") often occur more than once in the header,
455accordingly the list returned usually contains more than one string.
456</p>
457
458<h4><a name="mime_setheader">3.5</a>&nbsp;mime::setheader</h4>
459
460<p>
461mime::setheader writes, appends to, or deletes the value associated
462with a key in the header.
463</p>
464
465<p>
466The value for -mode is one of:
467
468<blockquote class="text"><dl>
469
470<dt>   write:</dt>
471<dd>
472 the key/value is either created or
473overwritten (the default);
474</dd>
475
476<dt>   append:</dt>
477<dd>
478 a new value is appended for the key
479(creating it as necessary); or,
480</dd>
481
482<dt>   delete:</dt>
483<dd>
484 all values associated with the key are removed
485(the "value" parameter is ignored).
486</dd>
487
488</dl></blockquote>
489
490</p>
491
492<p>
493Regardless,
494mime::setheader returns the previous value associated with the key.
495</p>
496
497<h4><a name="mime_getbody">3.6</a>&nbsp;mime::getbody</h4>
498
499<p>
500mime::getbody returns the body of a leaf MIME part in canonical form.
501</p>
502
503<p>
504If the -command option is present,
505then it is repeatedly invoked with a fragment of the body as this:
506</p>
507</font><pre>
508    uplevel #0 $callback [list "data" $fragment]
509</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
510
511<p>
512(The -blocksize option,
513if present,
514specifies the maximum size of each fragment passed to the
515callback.)
516</p>
517
518<p>
519When the end of the body is reached,
520the callback is invoked as:
521</p>
522</font><pre>
523    uplevel #0 $callback "end"
524</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
525
526<p>
527Alternatively,
528if an error occurs,
529the callback is invoked as:
530</p>
531</font><pre>
532    uplevel #0 $callback [list "error" reason]
533</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
534
535<p>
536Regardless,
537the return value of the final invocation of the callback is propagated
538upwards by mime::getbody.
539</p>
540
541<p>
542If the -command option is absent,
543then the return value of mime::getbody is a string containing the MIME
544part's entire body.
545</p>
546
547<h4><a name="mime_copymessage">3.7</a>&nbsp;mime::copymessage</h4>
548
549<p>
550mime::copymessage copies the MIME part to the specified channel.
551</p>
552
553<p>
554mime::copymessage operates synchronously,
555and uses fileevent to allow asynchronous operations to proceed
556independently.
557</p>
558
559<h4><a name="mime_buildmessage">3.7</a>&nbsp;mime::buildmessage</h4>
560
561<p>
562mime::buildmessage returns the MIME part as a string.  It is similar
563to mime::copymessage, only it returns the data as a return string
564instead of writing to a channel.
565</p>
566
567
568<h4><a name="smtp_sendmessage">3.8</a>&nbsp;smtp::sendmessage</h4>
569
570<p>
571smtp::sendmessage sends a MIME part to an SMTP server.
572(Note that this procedure is in the "smtp" package,
573not the "mime" package.)
574</p>
575
576<p>
577The options are:
578
579<blockquote class="text"><dl>
580
581<dt>   -servers:</dt>
582<dd>
583a list of SMTP servers
584(the default is "localhost");
585</dd>
586
587<dt>   -ports:</dt>
588<dd>
589a list of SMTP ports
590(the default is 25);
591</dd>
592
593<dt>   -queue:</dt>
594<dd>
595indicates that the SMTP server should be
596asked to queue the message for later processing;
597</dd>
598
599<dt>   -atleastone:</dt>
600<dd>
601indicates that the SMTP server must find
602at least one recipient acceptable for the message to be sent;
603</dd>
604
605<dt>   -originator:</dt>
606<dd>
607a string containing an 822-style address
608specification
609(if present the header isn't examined for an originator address);
610</dd>
611
612<dt>   -recipients:</dt>
613<dd>
614a string containing one or more 822-style
615address specifications
616(if present the header isn't examined for recipient addresses); and,
617</dd>
618
619<dt>   -header:</dt>
620<dd>
621a keyword/value pairing
622(may occur zero or more times).
623</dd>
624
625</dl></blockquote>
626
627</p>
628
629<p>
630If the -originator option is not present,
631the originator address is taken from "From" (or "Resent-From");
632similarly,
633if the -recipients option is not present,
634recipient addresses are taken from "To", "cc", and "Bcc" (or
635"Resent-To", and so on).
636Note that the header key/values supplied by the "-header" option
637(not those present in the MIME part)
638are consulted.
639Regardless,
640header key/values are added to the outgoing message as necessary to
641ensure that a valid 822-style message is sent.
642</p>
643
644<p>
645smtp::sendmessage returns a list indicating which recipients were
646unacceptable to the SMTP server.
647Each element of the list is another list,
648containing the address, an SMTP error code, and a textual diagnostic.
649Depending on the -atleastone option and the intended recipients,,
650a non-empty list may still indicate that the message was accepted by
651the server.
652</p>
653
654<h4><a name="mime_parseaddress">3.9</a>&nbsp;mime::parseaddress</h4>
655
656<p>
657mime::parseaddr takes a string containing one or more 822-style
658address specifications and returns a list of serialized arrays,
659one element for each address specified in the argument.
660</p>
661
662<p>
663Each serialized array contains these properties:
664</p>
665</font><pre>
666    property    value
667    ========    =====
668    address     local@domain
669    comment     822-style comment
670    domain      the domain part (rhs)
671    error       non-empty on a parse error 
672    group       this address begins a group
673    friendly    user-friendly rendering
674    local       the local part (lhs)
675    memberP     this address belongs to a group
676    phrase      the phrase part
677    proper      822-style address specification
678    route       822-style route specification (obsolete)
679</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
680
681<p>
682Note that one or more of these properties may be empty.
683</p>
684
685<h4><a name="mime_parsedatetime">3.10</a>&nbsp;mime::parsedatetime</h4>
686
687<p>
688mime::parsedatetime takes a string containing an 822-style
689date-time specification and returns the specified property.
690</p>
691
692<p>
693The list of properties and their ranges are:
694</p>
695</font><pre>
696    property     range
697    ========     =====
698    hour         0 .. 23
699    lmonth       January, February, ..., December
700    lweekday     Sunday, Monday, ... Saturday
701    mday         1 .. 31
702    min          0 .. 59
703    mon          1 .. 12
704    month        Jan, Feb, ..., Dec
705    proper       822-style date-time specification
706    rclock       elapsed seconds between then and now
707    sec          0 .. 59
708    wday         0 .. 6 (Sun .. Mon)
709    weekday      Sun, Mon, ..., Sat
710    yday         1 .. 366
711    year         1900 ...
712    zone         -720 .. 720 (minutes east of GMT)
713</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
714
715<h4><a name="mime_mapencoding">3.10</a>&nbsp;mime::mapencoding</h4>
716
717<p>
718mime::mapencoding takes a string containing the name of a
719tcl encoding (see [encoding names]) and returns the MIME
720charset name for that encoding (or "" if the charset name
721is unknown).
722</p>
723
724<h4><a name="mime_reversemapencoding">3.10</a>&nbsp;mime::reversemapencoding</h4>
725
726<p>
727mime::reversemapencoding takes a string containing the name of a
728MIME charset tcl encoding (see [encoding names]) and returns the MIME
729charset name for that encoding (or "" if no known tcl encoding maps to
730the mime charset type).
731</p>
732
733<a name="anchor6"><br><hr size="1" shade="0"></a>
734<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
735<h3>4.&nbsp;EXAMPLES</h3>
736</font><pre>
737package require mime 1.0
738package require smtp 1.0
739
740
741# create an image
742
743set imageT [mime::initialize -canonical image/gif \
744                             -file logo.gif]
745
746
747# parse a message
748
749set messageT [mime::initialize -file example.msg]
750
751
752# recursively traverse a message looking for primary recipients
753
754proc traverse {token} {
755    set result ""
756
757# depth-first search
758    if {![catch { mime::getproperty $token parts } parts]} {
759        foreach part $parts {
760            set result [concat $result [traverse $part]]
761        }
762    }
763
764# one value for each line occuring in the header
765    foreach value [mime::getheader $token To] {
766        foreach addr [mime::parseaddress $value] {
767            catch { unset aprops }
768            array set aprops $addr
769            lappend result $aprops(address)
770        }
771    }
772
773    return $result
774}
775
776
777# create a multipart containing both, and a timestamp
778
779set multiT [mime::initialize -canonical multipart/mixed
780                             -parts [list $imageT $messageT]]
781
782
783
784
785# send it to some friends
786
787smtp::sendmessage $multiT \
788      -header [list From "Marshall Rose &lt;mrose@dbc.mtview.ca.us>"] \
789      -header [list To "Andreas Kupries &lt;a.kupries@westend.com>"] \
790      -header [list cc "dnew@messagemedia.com (Darren New)"] \
791      -header [list Subject "test message..."]
792
793
794# clean everything up
795
796mime::finalize $multiT -subordinates all
797</pre><font face="verdana, helvetica, arial, sans-serif" size="2">
798<a name="rfc.references"><br><hr size="1" shade="0"></a>
799<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
800<h3>
801References</h3>
802<table width="99%" border="0">
803<tr><td class="author-text" valign="top"><b><a name="RFC2045">[1]</a></b></td>
804<td class="author-text"><a href="mailto:ned@innosoft.com">Freed, N.</a> and <a href="mailto:nsb@messagemedia.com">N.S. Borenstein</a>, "<a href="http://info.internet.isi.edu/in-notes/rfc/files/rfc2045.txt">Multipurpose Internet Mail Extensions (MIME)
805Part One: Format of Internet Message Bodies</a>", RFC 2045, November 1996.</td></tr>
806<tr><td class="author-text" valign="top"><b><a name="RFC2046">[2]</a></b></td>
807<td class="author-text"><a href="mailto:ned@innosoft.com">Freed, N.</a> and <a href="mailto:nsb@messagemedia.com">N.S. Borenstein</a>, "<a href="http://info.internet.isi.edu/in-notes/rfc/files/rfc2046.txt">Multipurpose Internet Mail Extensions (MIME)
808Part Two: Media Types</a>", RFC 2046, November 1995.</td></tr>
809<tr><td class="author-text" valign="top"><b><a name="RFC822">[3]</a></b></td>
810<td class="author-text"><a href="mailto:DCrocker@UDel-Relay">Crocker, D.</a>, "<a href="http://info.internet.isi.edu/in-notes/rfc/files/rfc822.txt">Standard for the format of ARPA Internet Text Messages</a>", RFC 822, STD 11, August 1982.</td></tr>
811</table>
812
813<a name="rfc.authors"><br><hr size="1" shade="0"></a>
814<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
815<h3>Author's Address</h3>
816<table width="99%" border="0" cellpadding="0" cellspacing="0">
817<tr><td class="author-text">&nbsp;</td>
818<td class="author-text">Marshall T. Rose</td></tr>
819<tr><td class="author-text">&nbsp;</td>
820<td class="author-text">Dover Beach Consulting, Inc.</td></tr>
821<tr><td class="author-text">&nbsp;</td>
822<td class="author-text">POB 255268</td></tr>
823<tr><td class="author-text">&nbsp;</td>
824<td class="author-text">Sacramento, CA  95865-5268</td></tr>
825<tr><td class="author-text">&nbsp;</td>
826<td class="author-text">US</td></tr>
827<tr><td class="author" align="right">Phone:&nbsp;</td>
828<td class="author-text">+1 916 483 8878</td></tr>
829<tr><td class="author" align="right">Fax:&nbsp;</td>
830<td class="author-text">+1 916 483 8848</td></tr>
831<tr><td class="author" align="right">EMail:&nbsp;</td>
832<td class="author-text"><a href="mailto:mrose@dbc.mtview.ca.us">mrose@dbc.mtview.ca.us</a></td></tr>
833</table>
834
835<a name="anchor7"><br><hr size="1" shade="0"></a>
836<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
837<h3>Appendix A.&nbsp;TODO List</h3>
838
839<p>
840
841<blockquote class="text"><dl>
842
843<dt>mime::initialize</dt>
844<dd>
845
846<ul class="text">
847
848<li>
849well-defined errorCode values
850</li>
851
852<li>
853catch nested errors when processing a multipart
854</li>
855
856</ul>
857
858</dd>
859
860</dl></blockquote>
861
862</p>
863
864<a name="anchor8"><br><hr size="1" shade="0"></a>
865<table border="0" cellpadding="0" cellspacing="2" width="30" height="15" align="right"><tr><td bgcolor="#990000" align="center" width="30" height="15"><a href="#toc" CLASS="link2"><font face="monaco, MS Sans Serif" color="#ffffff" size="1"><b>&nbsp;TOC&nbsp;</b></font></a><br></td></tr></table>
866<h3>Appendix B.&nbsp;Acknowledgements</h3>
867
868<p>
869This package is influenced by the safe-tcl package
870(Borenstein and Rose, circa 1993),
871and also by <a href="mailto:dnew@messagemedia.com">Darren New</a>'s
872unpublished package of 1999.
873</p>
874
875<p>
876This package makes use of 
877<a href="mailto:a.kupries@westend.com">Andreas Kupries</a>'s
878excellent Trf package.
879</p>
880</font></body></html>
881

README.txt

1
2
3The README file                                                M.T. Rose
4                                            Dover Beach Consulting, Inc.
5                                                       February 22, 2000
6
7
8                                Tcl MIME
9
10
11Abstract
12
13   Tcl MIME generates and parses MIME body parts.
14
15Table of Contents
16
17   1.   SYNOPSIS . . . . . . . . . . . . . . . . . . . . . . . . . .   2
18   1.1  Requirements . . . . . . . . . . . . . . . . . . . . . . . .   3
19   1.2  Copyrights . . . . . . . . . . . . . . . . . . . . . . . . .   3
20   2.   SYNTAX . . . . . . . . . . . . . . . . . . . . . . . . . . .   4
21   3.   SEMANTICS  . . . . . . . . . . . . . . . . . . . . . . . . .   5
22   3.1  mime::initialize . . . . . . . . . . . . . . . . . . . . . .   5
23   3.2  mime::finalize . . . . . . . . . . . . . . . . . . . . . . .   5
24   3.3  mime::getproperty  . . . . . . . . . . . . . . . . . . . . .   5
25   3.4  mime::getheader  . . . . . . . . . . . . . . . . . . . . . .   6
26   3.5  mime::setheader  . . . . . . . . . . . . . . . . . . . . . .   6
27   3.6  mime::getbody  . . . . . . . . . . . . . . . . . . . . . . .   6
28   3.7  mime::copymessage  . . . . . . . . . . . . . . . . . . . . .   7
29   3.8  mime::buildmessage . . . . . . . . . . . . . . . . . . . . .   7
30   3.9  smtp::sendmessage  . . . . . . . . . . . . . . . . . . . . .   7
31   3.10 mime::parseaddress . . . . . . . . . . . . . . . . . . . . .   8
32   3.11 mime::parsedatetime  . . . . . . . . . . . . . . . . . . . .   9
33   3.12 mime::mapencoding  . . . . . . . . . . . . . . . . . . . . .   9
34   3.13 mime::reversemapencoding . . . . . . . . . . . . . . . . . .   9
35
36   4.   EXAMPLES . . . . . . . . . . . . . . . . . . . . . . . . . .  10
37        References . . . . . . . . . . . . . . . . . . . . . . . . .  12
38        Author's Address . . . . . . . . . . . . . . . . . . . . . .  12
39   A.   TODO List  . . . . . . . . . . . . . . . . . . . . . . . . .  13
40   B.   Acknowledgements . . . . . . . . . . . . . . . . . . . . . .  14
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59Rose                                                            [Page 1]
60
61README                          Tcl MIME                   February 2000
62
63
641. SYNOPSIS
65
66       package provide mime 1.2
67       package provide smtp 1.2
68
69   Tcl MIME is an implementation of a Tcl package that generates and
70   parses MIME[1] body parts.
71
72   Each MIME part consists of a header (zero or more key/value pairs),
73   an empty line, and a structured body. A MIME part is either a "leaf"
74   or has (zero or more) subordinates.
75
76   MIME defines four keys that may appear in the headers: 
77
78      Content-Type: describes the data contained in the body ("the
79      content");
80
81      Content-Transfer-Encoding: describes how the content is encoded
82      for transmission in an ASCII stream;
83
84      Content-Description: a textual description of the content; and,
85
86      Content-ID: a globally-unique identifier for the content.
87
88   Consult [2] for a list of standard content types. Further, consult
89   [3] for a list of several other header keys (e.g., "To", "cc", etc.)
90
91   A simple example might be:
92
93       Date: Sun, 04 July 1999 10:38:25 -0600
94       From: Marshall Rose <mrose@dbc.mtview.ca.us>
95       To: Andreas Kupries <a.kupries@westend.com>
96       cc: dnew@messagemedia.com (Darren New)
97       MIME-Version: 1.0
98       Content-Type: text/plain; charset="us-ascii"
99       Content-Description: a simple example
100       Content-ID: <4294407315.931384918.1@dbc.mtview.ca.us>
101
102       Here is the body. In this case, simply plain text.
103
104   In addition to an implementation of the mime package, Tcl MIME
105   includes an implementation of the smtp package.
106
107
108
109
110
111
112
113
114
115Rose                                                            [Page 2]
116
117README                          Tcl MIME                   February 2000
118
119
1201.1 Requirements
121
122   This package requires: 
123
124   o  Tcl/Tk version 8.0.3[4] or later
125
126   In addition, this package requires one of the following:
127
128   o  Trf version 2.0p5[5] or later
129
130   o  base64 version 2.0 or later (included with tcllib)
131
132   If it is available, Trf will be used to provide better performance;
133   if not, Tcl-only equivalent functions, based on the base64 package,
134   are used.
135
1361.2 Copyrights
137
138   (c) 1999-2000 Marshall T. Rose
139
140   Hold harmless the author, and any lawful use is allowed.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179Rose                                                            [Page 3]
180
181README                          Tcl MIME                   February 2000
182
183
1842. SYNTAX
185
186   mime::initialize (Section 3.1) returns a token. Parameters:
187       ?-canonical type/subtype
188           ?-param    {key value}?...
189           ?-encoding value?
190           ?-header   {key value}?... ?
191       (-file name | -string value | -parts {token1 ... tokenN})
192
193   mime::finalize (Section 3.2) returns an empty string. Parameters:
194       token ?-subordinates "all" | "dynamic" | "none"?
195
196   mime::getproperty (Section 3.3) returns a string or a list of
197   strings. Parameters:
198       token ?property | -names?
199
200   mime::getheader (Section 3.4) returns a list of strings. Parameters:
201       token ?key | -names?
202
203   mime::setheader (Section 3.5) returns a list of strings. Parameters:
204       token key value ?-mode "write" | "append" | "delete"?
205
206   mime::getbody (Section 3.6) returns a string. Parameters:
207       ?-command callback ?-blocksize octets? ?
208
209   mime::copymessage (Section 3.7) returns an empty string. Parameters:
210       token channel
211
212   mime::buildmessage (Section 3.7) returns a string. Parameters:
213       token
214
215   smtp::sendmessage (Section 3.8) returns a list. Parameters:
216       token ?-servers list? ?-ports list?
217             ?-queue boolean?     ?-atleastone boolean?
218             ?-originator string? ?-recipients string?
219             ?-header {key value}?...
220
221   mime::parseaddress (Section 3.9) returns a list of serialized
222   arrays. Parameters:
223       string
224
225   mime::parsedatetime (Section 3.10) returns a string. Parameters:
226       [string | -now] property
227
228   mime::mapencoding (Section 3.10) returns a string. Parameters:
229       encoding_name
230
231   mime::reversemapencoding (Section 3.10) returns a string. Parameters:
232       charset_type
233
234
235
236Rose                                                            [Page 4]
237
238README                          Tcl MIME                   February 2000
239
240
2413. SEMANTICS
242
2433.1 mime::initialize
244
245   mime::initialize creates a MIME part: 
246
247   o  If the -canonical option is present, then the body is in
248      canonical (raw) form and is found by consulting either the -file,
249      -string, or -part option. 
250
251      In addition, both the -param and -header options may occur zero
252      or more times to specify "Content-Type" parameters (e.g.,
253      "charset") and header keyword/values (e.g.,
254      "Content-Disposition"), respectively. 
255
256      Also, -encoding, if present, specifies the
257      "Content-Transfer-Encoding" when copying the body.
258
259   o  If the -canonical option is not present, then the MIME part
260      contained in either the -file or the -string option is parsed,
261      dynamically generating subordinates as appropriate.
262
2633.2 mime::finalize
264
265   mime::finalize destroys a MIME part.
266
267   If the -subordinates option is present, it specifies which
268   subordinates should also be destroyed. The default value is
269   "dynamic".
270
2713.3 mime::getproperty
272
273   mime::getproperty returns the properties of a MIME part.
274
275   The properties are:
276
277       property    value
278       ========    =====
279       content     the type/subtype describing the content
280       encoding    the "Content-Transfer-Encoding"
281       params      a list of "Content-Type" parameters
282       parts       a list of tokens for the part's subordinates
283       size        the approximate size of the content (unencoded)
284
285   The "parts" property is present only if the MIME part has
286   subordinates.
287
288   If mime::getproperty is invoked with the name of a specific
289   property, then the corresponding value is returned; instead, if
290
291
292Rose                                                            [Page 5]
293
294README                          Tcl MIME                   February 2000
295
296
297   -names is specified, a list of all properties is returned;
298   otherwise, a serialized array of properties and values is returned.
299
3003.4 mime::getheader
301
302   mime::getheader returns the header of a MIME part.
303
304   A header consists of zero or more key/value pairs. Each value is a
305   list containing one or more strings.
306
307   If mime::getheader is invoked with the name of a specific key, then
308   a list containing the corresponding value(s) is returned; instead,
309   if -names is specified, a list of all keys is returned; otherwise, a
310   serialized array of keys and values is returned. Note that when a
311   key is specified (e.g., "Subject"), the list returned usually
312   contains exactly one string; however, some keys (e.g., "Received")
313   often occur more than once in the header, accordingly the list
314   returned usually contains more than one string.
315
3163.5 mime::setheader
317
318   mime::setheader writes, appends to, or deletes the value associated
319   with a key in the header.
320
321   The value for -mode is one of: 
322
323      write: the key/value is either created or overwritten (the
324      default);
325
326      append: a new value is appended for the key (creating it as
327      necessary); or,
328
329      delete: all values associated with the key are removed (the
330      "value" parameter is ignored).
331
332   Regardless, mime::setheader returns the previous value associated
333   with the key.
334
3353.6 mime::getbody
336
337   mime::getbody returns the body of a leaf MIME part in canonical form.
338
339   If the -command option is present, then it is repeatedly invoked
340   with a fragment of the body as this:
341
342       uplevel #0 $callback [list "data" $fragment]
343
344   (The -blocksize option, if present, specifies the maximum size of
345   each fragment passed to the callback.)
346
347
348Rose                                                            [Page 6]
349
350README                          Tcl MIME                   February 2000
351
352
353   When the end of the body is reached, the callback is invoked as:
354
355       uplevel #0 $callback "end"
356
357   Alternatively, if an error occurs, the callback is invoked as:
358
359       uplevel #0 $callback [list "error" reason]
360
361   Regardless, the return value of the final invocation of the callback
362   is propagated upwards by mime::getbody.
363
364   If the -command option is absent, then the return value of
365   mime::getbody is a string containing the MIME part's entire body.
366
3673.7 mime::copymessage
368
369   mime::copymessage copies the MIME part to the specified channel.
370
371   mime::copymessage operates synchronously, and uses fileevent to
372   allow asynchronous operations to proceed independently.
373
3743.7 mime::buildmessage
375
376   mime::buildmessage returns the MIME part as a string.  It is similar
377   to mime::copymessage, only it returns the data as a return string
378   instead of writing to a channel.
379
3803.8 smtp::sendmessage
381
382   smtp::sendmessage sends a MIME part to an SMTP server. (Note that
383   this procedure is in the "smtp" package, not the "mime" package.)
384
385   The options are: 
386
387      -servers: a list of SMTP servers (the default is "localhost");
388
389      -ports: a list of SMTP ports (the default is 25)
390
391      -queue: indicates that the SMTP server should be asked to queue
392      the message for later processing;
393
394      -atleastone: indicates that the SMTP server must find at least
395      one recipient acceptable for the message to be sent;
396
397      -originator: a string containing an 822-style address
398      specification (if present the header isn't examined for an
399      originator address);
400
401      -recipients: a string containing one or more 822-style address
402      specifications (if present the header isn't examined for
403      recipient addresses); and,
404
405      -header: a keyword/value pairing (may occur zero or more times).
406
407   If the -originator option is not present, the originator address is
408   taken from "From" (or "Resent-From"); similarly, if the -recipients
409   option is not present, recipient addresses are taken from "To",
410
411
412Rose                                                            [Page 7]
413
414README                          Tcl MIME                   February 2000
415
416
417   "cc", and "Bcc" (or "Resent-To", and so on). Note that the header
418   key/values supplied by the "-header" option (not those present in
419   the MIME part) are consulted. Regardless, header key/values are
420   added to the outgoing message as necessary to ensure that a valid
421   822-style message is sent.
422
423   smtp::sendmessage returns a list indicating which recipients were
424   unacceptable to the SMTP server. Each element of the list is another
425   list, containing the address, an SMTP error code, and a textual
426   diagnostic. Depending on the -atleastone option and the intended
427   recipients,, a non-empty list may still indicate that the message
428   was accepted by the server.
429
4303.9 mime::parseaddress
431
432   mime::parseaddr takes a string containing one or more 822-style
433   address specifications and returns a list of serialized arrays, one
434   element for each address specified in the argument.
435
436   Each serialized array contains these properties:
437
438       property    value
439       ========    =====
440       address     local@domain
441       comment     822-style comment
442       domain      the domain part (rhs)
443       error       non-empty on a parse error
444       group       this address begins a group
445       friendly    user-friendly rendering
446       local       the local part (lhs)
447       memberP     this address belongs to a group
448       phrase      the phrase part
449       proper      822-style address specification
450       route       822-style route specification (obsolete)
451
452   Note that one or more of these properties may be empty.
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467Rose                                                            [Page 8]
468
469README                          Tcl MIME                   February 2000
470
471
4723.10 mime::parsedatetime
473
474   mime::parsedatetime takes a string containing an 822-style date-time
475   specification and returns the specified property.
476
477   The list of properties and their ranges are:
478
479       property     range
480       ========     =====
481       hour         0 .. 23
482       lmonth       January, February, ..., December
483       lweekday     Sunday, Monday, ... Saturday
484       mday         1 .. 31
485       min          0 .. 59
486       mon          1 .. 12
487       month        Jan, Feb, ..., Dec
488       proper       822-style date-time specification
489       rclock       elapsed seconds between then and now
490       sec          0 .. 59
491       wday         0 .. 6 (Sun .. Mon)
492       weekday      Sun, Mon, ..., Sat
493       yday         1 .. 366
494       year         1900 ...
495       zone         -720 .. 720 (minutes east of GMT)
496
4973.10 mime::mapencoding
498
499   mime::mapencodings maps tcl encodings onto the proper names for their
500   MIME charset type.  This is only done for encodings whose charset types
501   were known.  The remaining encodings return "" for now.
502
5033.10 mime::reversemapencoding
504
505   mime::reversemapencoding maps MIME charset types onto tcl encoding names.
506   Those that are unknown return "".
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523Rose                                                            [Page 9]
524
525README                          Tcl MIME                   February 2000
526
527
5284. EXAMPLES
529
530   package require mime 1.0
531   package require smtp 1.0
532
533
534   # create an image
535
536   set imageT [mime::initialize -canonical image/gif \
537                                -file logo.gif]
538
539
540   # parse a message
541
542   set messageT [mime::initialize -file example.msg]
543
544
545   # recursively traverse a message looking for primary recipients
546
547   proc traverse {token} {
548       set result ""
549
550   # depth-first search
551       if {![catch { mime::getproperty $token parts } parts]} {
552           foreach part $parts {
553               set result [concat $result [traverse $part]]
554           }
555       }
556
557   # one value for each line occuring in the header
558       foreach value [mime::getheader $token To] {
559           foreach addr [mime::parseaddress $value] {
560               catch { unset aprops }
561               array set aprops $addr
562               lappend result $aprops(address)
563           }
564       }
565
566       return $result
567   }
568
569
570   # create a multipart containing both, and a timestamp
571
572   set multiT [mime::initialize -canonical multipart/mixed
573                                -parts [list $imageT $messageT]]
574
575
576
577
578
579Rose                                                           [Page 10]
580
581README                          Tcl MIME                   February 2000
582
583
584   # send it to some friends
585
586   smtp::sendmessage $multiT \
587         -header [list From "Marshall Rose <mrose@dbc.mtview.ca.us>"] \
588         -header [list To "Andreas Kupries <a.kupries@westend.com>"] \
589         -header [list cc "dnew@messagemedia.com (Darren New)"] \
590         -header [list Subject "test message..."]
591
592
593   # clean everything up
594
595   mime::finalize $multiT -subordinates all
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635Rose                                                           [Page 11]
636
637README                          Tcl MIME                   February 2000
638
639
640References
641
642   [1]  Freed, N. and N.S. Borenstein, "Multipurpose Internet Mail
643        Extensions (MIME) Part One: Format of Internet Message Bodies",
644        RFC 2045, November 1996.
645
646   [2]  Freed, N. and N.S. Borenstein, "Multipurpose Internet Mail
647        Extensions (MIME) Part Two: Media Types", RFC 2046, November
648        1995.
649
650   [3]  Crocker, D., "Standard for the format of ARPA Internet Text
651        Messages", RFC 822, STD 11, August 1982.
652
653   [4]  http://www.scriptics.com/software/8.1.html
654
655   [5]  http://www.oche.de/~akupries/soft/trf/
656
657   [6]  mailto:dnew@messagemedia.com
658
659   [7]  mailto:a.kupries@westend.com
660
661
662Author's Address
663
664   Marshall T. Rose
665   Dover Beach Consulting, Inc.
666   POB 255268
667   Sacramento, CA  95865-5268
668   US
669
670   Phone: +1 916 483 8878
671   Fax:   +1 916 483 8848
672   EMail: mrose@dbc.mtview.ca.us
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691Rose                                                           [Page 12]
692
693README                          Tcl MIME                   February 2000
694
695
696Appendix A. TODO List
697
698   mime::initialize 
699
700      *  well-defined errorCode values
701
702      *  catch nested errors when processing a multipart
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747Rose                                                           [Page 13]
748
749README                          Tcl MIME                   February 2000
750
751
752Appendix B. Acknowledgements
753
754   This package is influenced by the safe-tcl package (Borenstein and
755   Rose, circa 1993), and also by Darren New[6]'s unpublished package
756   of 1999.
757
758   This package makes use of Andreas Kupries[7]'s excellent Trf package.
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803Rose                                                           [Page 14]
804
805

README.xml

1<?xml version="1.0"?>
2<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
3
4<?rfc compact="no"?>
5<?rfc toc="yes"?>
6<?rfc private="The README file"?>
7<?rfc header="README"?>
8
9<rfc>
10<front>
11<title>Tcl MIME</title>
12
13<author initials="M.T." surname="Rose" fullname="Marshall T. Rose">
14<organization>Dover Beach Consulting, Inc.</organization>
15<address>
16<postal>
17<street>POB 255268</street>
18<city>Sacramento</city> <region>CA</region> <code>95865-5268</code>
19<country>US</country>
20</postal>
21<phone>+1 916 483 8878</phone>
22<facsimile>+1 916 483 8848</facsimile>
23<email>mrose@dbc.mtview.ca.us</email>
24</address>
25</author>
26
27<date month="February" year="2000" />
28
29<abstract><t>Tcl MIME generates and parses MIME body parts.</t></abstract>
30</front>
31
32<middle>
33
34<section title="SYNOPSIS">
35<figure><artwork><![CDATA[
36    package provide mime 1.2
37    package provide smtp 1.2
38]]></artwork></figure>
39
40<t>Tcl MIME is an implementation of a Tcl package that generates and
41parses <xref target="RFC2045">MIME</xref> body parts.</t>
42
43<t>Each MIME part consists of a header
44(zero or more key/value pairs), 
45an empty line,
46and a structured body.
47A MIME part is either a "leaf" or has (zero or more) subordinates.</t>
48
49<t>MIME defines four keys that may appear in the headers:
50<list style="hanging">
51<t hangText="   Content-Type:">describes the data contained in the body
52("the content");</t>
53
54<t hangText="   Content-Transfer-Encoding:">describes how the content is
55encoded for transmission in an ASCII stream;</t>
56
57<t hangText="   Content-Description:">a textual description of the
58content; and,</t>
59
60<t hangText="   Content-ID:">a globally-unique identifier for the
61content.</t> 
62</list></t>
63
64<t>Consult <xref target="RFC2046" /> for a list of standard content types.
65Further,
66consult <xref target="RFC822" /> for a list of several other header keys
67(e.g., "To", "cc", etc.)</t>
68
69<figure>
70<preamble>A simple example might be:</preamble>
71<artwork><![CDATA[
72    Date: Sun, 04 July 1999 10:38:25 -0600
73    From: Marshall Rose <mrose@dbc.mtview.ca.us>
74    To: Andreas Kupries <a.kupries@westend.com>
75    cc: dnew@messagemedia.com (Darren New)
76    MIME-Version: 1.0
77    Content-Type: text/plain; charset="us-ascii"
78    Content-Description: a simple example
79    Content-ID: <4294407315.931384918.1@dbc.mtview.ca.us>
80    
81    Here is the body. In this case, simply plain text.
82]]></artwork>
83</figure>
84
85<t>In addition to an implementation of the mime package,
86Tcl MIME includes an implementation of the smtp package.</t>
87
88<vspace blankLines="1000" />
89
90<section title="Requirements">
91<t>This package requires:
92<list style="symbols">
93<t><eref target="http://www.scriptics.com/software/8.1.html">Tcl/Tk version 8.0.3</eref>
94</list>
95or later</t>
96<t>In addition, this package requires one of the following:</t>
97<list style="symbols">
98<t><eref target="http://www.oche.de/~akupries/soft/trf/">Trf version 2.0p5</eref>
99or later</t>
100<t><eref target="http://dev.ajubasolutions.com/software/tcllib/">base 64 version 2.0</eref> or later (included with tcllib)</t>
101</list></t>
102<t>If it is available, Trf will be used to provide better performance;
103if not, Tcl-only equivalent functions, based on the base64 package,
104are used.</t>
105</section>
106
107<section title="Copyrights">
108<t>(c) 1999-2000 Marshall T. Rose</t>
109
110<t>Hold harmless the author, and any lawful use is allowed.</t>
111</section>
112</section>
113
114<section title="SYNTAX">
115<figure>
116<preamble><xref target="mime_initialize">mime::initialize</xref>
117returns a token.
118Parameters:</preamble>
119<artwork><![CDATA[    ?-canonical type/subtype
120        ?-param    {key value}?...
121        ?-encoding value?
122        ?-header   {key value}?... ?
123    (-file name | -string value | -parts {token1 ... tokenN})
124]]></artwork>
125</figure>
126
127<figure>
128<preamble><xref target="mime_finalize">mime::finalize</xref> returns
129an empty string.
130Parameters:</preamble>
131<artwork><![CDATA[    token ?-subordinates "all" | "dynamic" | "none"?
132]]></artwork>
133</figure>
134
135<figure>
136<preamble><xref target="mime_getproperty">mime::getproperty</xref>
137returns a string or a list of strings.
138Parameters:</preamble>
139<artwork><![CDATA[    token ?property | -names?
140]]></artwork>
141</figure>
142
143<figure>
144<preamble><xref target="mime_getheader">mime::getheader</xref> returns
145a list of strings.
146Parameters:</preamble>
147<artwork><![CDATA[    token ?key | -names?
148]]></artwork>
149</figure>
150
151<figure>
152<preamble><xref target="mime_setheader">mime::setheader</xref> returns
153a list of strings.
154Parameters:</preamble>
155<artwork><![CDATA[    token key value ?-mode "write" | "append" | "delete"?
156]]></artwork>
157</figure>
158
159<figure>
160<preamble><xref target="mime_getbody">mime::getbody</xref> returns a string.
161Parameters:</preamble>
162<artwork><![CDATA[    ?-command callback ?-blocksize octets? ?
163]]></artwork>
164</figure>
165
166<figure>
167<preamble><xref target="mime_copymessage">mime::copymessage</xref>
168returns an empty string.
169Parameters:</preamble>
170<artwork><![CDATA[    token channel
171]]></artwork>
172</figure>
173
174<figure>
175<preamble><xref target="mime_buildmessage">mime::buildmessage</xref>
176returns an empty string.
177Parameters:</preamble>
178<artwork><![CDATA[    token
179]]></artwork>
180</figure>
181
182<figure>
183<preamble><xref target="smtp_sendmessage">smtp::sendmessage</xref>
184returns a list.
185Parameters:</preamble>
186<artwork><![CDATA[    token ?-servers list? ?-ports list?
187          ?-queue boolean?     ?-atleastone boolean?
188          ?-originator string? ?-recipients string?
189          ?-header {key value}?...
190]]></artwork>
191</figure>
192
193<figure>
194<preamble><xref target="mime_parseaddress">mime::parseaddress</xref>
195returns a list of serialized arrays.
196Parameters:</preamble>
197<artwork><![CDATA[    string
198]]></artwork>
199</figure>
200
201<figure>
202<preamble><xref target="mime_parsedatetime">mime::parsedatetime</xref>
203returns a string.
204Parameters:</preamble>
205<artwork><![CDATA[    [string | -now] property
206]]></artwork>
207</figure>
208
209<figure>
210<preamble><xref target="mime_mapencoding">mime::mapencoding</xref>
211returns a string.
212Parameters:</preamble>
213<artwork><![CDATA[    encoding_name
214]]></artwork>
215</figure>
216
217<figure>
218<preamble><xref target="mime_reversemapencoding">mime::reversemapencoding</xref>
219returns a string.
220Parameters:</preamble>
221<artwork><![CDATA[    content_type
222]]></artwork>
223</figure>
224
225</section>
226
227<section title="SEMANTICS">
228
229<section anchor="mime_initialize" title="mime::initialize">
230<t>mime::initialize creates a MIME part:
231<list style="symbols">
232<t>If the -canonical option is present,
233then the body is in canonical (raw) form and is found by consulting
234either the -file, -string, or -part option.
235<vspace blankLines="1" />
236In addition,
237both the -param and -header options may occur zero or more times to
238specify "Content-Type" parameters (e.g., "charset")
239and header keyword/values (e.g., "Content-Disposition"),
240respectively.
241<vspace blankLines="1" />
242Also, -encoding, if present,
243specifies the "Content-Transfer-Encoding" when copying the body.</t>
244    
245<t>If the -canonical option is not present,
246then the MIME part contained in either the -file or the -string option
247is parsed,
248dynamically generating subordinates as appropriate.</t>
249</list></t>
250</section>
251
252<section anchor="mime_finalize" title="mime::finalize">
253<t>mime::finalize destroys a MIME part.</t>
254
255<t>If the -subordinates option is present,
256it specifies which subordinates should also be destroyed.
257The default value is "dynamic".</t>    
258</section>
259
260<section anchor="mime_getproperty" title="mime::getproperty">
261<t>mime::getproperty returns the properties of a MIME part.</t>
262
263<figure>
264<preamble>The properties are:</preamble>
265<artwork><![CDATA[
266    property    value
267    ========    =====
268    content     the type/subtype describing the content
269    encoding    the "Content-Transfer-Encoding"
270    params      a list of "Content-Type" parameters
271    parts       a list of tokens for the part's subordinates
272    size        the approximate size of the content (unencoded)
273]]></artwork>
274<postamble>The "parts" property is present only if the MIME part has
275subordinates.</postamble>
276</figure>
277
278<t>If mime::getproperty is invoked with the name of a specific property,
279then the corresponding value is returned;
280instead,
281if -names is specified,
282a list of all properties is returned;
283otherwise,
284a serialized array of properties and values is returned.</t>    
285</section>
286
287<section anchor="mime_getheader" title="mime::getheader">
288<t>mime::getheader returns the header of a MIME part.</t>
289
290<t>A header consists of zero or more key/value pairs.
291Each value is a list containing one or more strings.</t>
292
293<t>If mime::getheader is invoked with the name of a specific key,
294then a list containing the corresponding value(s) is returned;
295instead,
296if -names is specified,
297a list of all keys is returned;
298otherwise,
299a serialized array of keys and values is returned.
300Note that when a key is specified (e.g., "Subject"),
301the list returned usually contains exactly one string;
302however,
303some keys (e.g., "Received") often occur more than once in the header,
304accordingly the list returned usually contains more than one string.</t>
305</section>
306
307<section anchor="mime_setheader" title="mime::setheader">
308<t>mime::setheader writes, appends to, or deletes the value associated
309with a key in the header.</t>
310
311<t>The value for -mode is one of:
312<list style="hanging">
313<t hangText="   write:"> the key/value is either created or
314overwritten (the default);</t>
315
316<t hangText="   append:"> a new value is appended for the key
317(creating it as necessary); or,</t>
318
319<t hangText="   delete:"> all values associated with the key are removed
320(the "value" parameter is ignored).</t>
321</list></t>
322
323<t>Regardless,
324mime::setheader returns the previous value associated with the key.</t>
325</section>
326
327<section anchor="mime_getbody" title="mime::getbody">
328<t>mime::getbody returns the body of a leaf MIME part in canonical form.</t>
329
330<figure>
331<preamble>If the -command option is present,
332then it is repeatedly invoked with a fragment of the body as this:</preamble>
333<artwork><![CDATA[
334    uplevel #0 $callback [list "data" $fragment]
335]]></artwork>
336<postamble>(The -blocksize option,
337if present,
338specifies the maximum size of each fragment passed to the
339callback.)</postamble>
340</figure>
341
342<figure>
343<preamble>When the end of the body is reached,
344the callback is invoked as:</preamble>
345<artwork><![CDATA[
346    uplevel #0 $callback "end"
347]]></artwork>
348</figure>
349
350<figure>
351<preamble>Alternatively,
352if an error occurs,
353the callback is invoked as:</preamble>
354<artwork><![CDATA[
355    uplevel #0 $callback [list "error" reason]
356]]></artwork>
357</figure>
358
359<t>Regardless,
360the return value of the final invocation of the callback is propagated
361upwards by mime::getbody.</t>
362
363<t>If the -command option is absent,
364then the return value of mime::getbody is a string containing the MIME
365part's entire body.</t>    
366</section>
367
368<section anchor="mime_copymessage" title="mime::copymessage">
369<t>mime::copymessage copies the MIME part to the specified channel.</t>
370
371<t>mime::copymessage operates synchronously,
372and uses fileevent to allow asynchronous operations to proceed
373independently.</t>
374</section>
375
376<section anchor="mime_buildmessage" title="mime::buildmessage">
377<t>mime::buildmessage returns the MIME part as a string.  It is similar
378to mime::copymessage, only it returns the data as a return string
379instead of writing to a channel.</t>
380</section>
381
382<section anchor="smtp_sendmessage" title="smtp::sendmessage">
383<t>smtp::sendmessage sends a MIME part to an SMTP server.
384(Note that this procedure is in the "smtp" package,
385not the "mime" package.)</t>
386
387<t>The options are:
388<list style="hanging">
389<t hangText="   -servers:">a list of SMTP servers
390(the default is "localhost");</t>
391
392<t hangText="   -ports:">a list of SMTP ports
393(the default is 25);</t>
394
395<t hangText="   -queue:">indicates that the SMTP server should be
396asked to queue the message for later processing;</t>
397
398<t hangText="   -atleastone:">indicates that the SMTP server must find
399at least one recipient acceptable for the message to be sent;</t>
400
401<t hangText="   -originator:">a string containing an 822-style address
402specification
403(if present the header isn't examined for an originator address);</t>
404
405<t hangText="   -recipients:">a string containing one or more 822-style
406address specifications
407(if present the header isn't examined for recipient addresses); and,</t>
408
409<t hangText="   -header:">a keyword/value pairing
410(may occur zero or more times).</t> 
411</list></t>
412
413<t>If the -originator option is not present,
414the originator address is taken from "From" (or "Resent-From");
415similarly,
416if the -recipients option is not present,
417recipient addresses are taken from "To", "cc", and "Bcc" (or
418"Resent-To", and so on).
419Note that the header key/values supplied by the "-header" option
420(not those present in the MIME part)
421are consulted.
422Regardless,
423header key/values are added to the outgoing message as necessary to
424ensure that a valid 822-style message is sent.</t>
425
426<t>smtp::sendmessage returns a list indicating which recipients were
427unacceptable to the SMTP server.
428Each element of the list is another list,
429containing the address, an SMTP error code, and a textual diagnostic.
430Depending on the -atleastone option and the intended recipients,,
431a non-empty list may still indicate that the message was accepted by
432the server.</t>
433</section>
434
435<section anchor="mime_parseaddress" title="mime::parseaddress">
436<t>mime::parseaddr takes a string containing one or more 822-style
437address specifications and returns a list of serialized arrays,
438one element for each address specified in the argument.</t>
439
440<figure>
441<preamble>Each serialized array contains these properties:</preamble>
442<artwork><![CDATA[
443    property    value
444    ========    =====
445    address     local@domain
446    comment     822-style comment
447    domain      the domain part (rhs)
448    error       non-empty on a parse error 
449    group       this address begins a group
450    friendly    user-friendly rendering
451    local       the local part (lhs)
452    memberP     this address belongs to a group
453    phrase      the phrase part
454    proper      822-style address specification
455    route       822-style route specification (obsolete)
456]]></artwork>
457<postamble>Note that one or more of these properties may be empty.</postamble>
458</figure>
459</section>
460
461<vspace blankLines="10000" />
462
463<section anchor="mime_parsedatetime" title="mime::parsedatetime">
464<t>mime::parsedatetime takes a string containing an 822-style
465date-time specification and returns the specified property.</t>
466
467<figure>
468<preamble>The list of properties and their ranges are:</preamble>
469<artwork><![CDATA[
470    property     range
471    ========     =====
472    hour         0 .. 23
473    lmonth       January, February, ..., December
474    lweekday     Sunday, Monday, ... Saturday
475    mday         1 .. 31
476    min          0 .. 59
477    mon          1 .. 12
478    month        Jan, Feb, ..., Dec
479    proper       822-style date-time specification
480    rclock       elapsed seconds between then and now
481    sec          0 .. 59
482    wday         0 .. 6 (Sun .. Mon)
483    weekday      Sun, Mon, ..., Sat
484    yday         1 .. 366
485    year         1900 ...
486    zone         -720 .. 720 (minutes east of GMT)
487]]></artwork>
488</figure>
489</section>
490
491<section anchor="mime_mapencoding" title="mime::mapencoding">
492<t>mime::mapencoding maps tcl encodings onto the proper names for their
493MIME charset type.  This is only done for encodings whose charset types
494were known.  The remaining encodings return "" for now.</t>
495</section>
496
497<section anchor="mime_reversemapencoding" title="mime::reversemapencoding">
498<t>mime::reversemapencoding maps MIME charset types onto tcl encoding names.
499Those that are unknown return "".</t>
500</section>
501
502</section>
503
504<section title="EXAMPLES">
505<figure>
506<artwork><![CDATA[
507package require mime 1.0
508package require smtp 1.0
509
510
511# create an image
512
513set imageT [mime::initialize -canonical image/gif \
514                             -file logo.gif]
515
516
517# parse a message
518
519set messageT [mime::initialize -file example.msg]
520
521
522# recursively traverse a message looking for primary recipients
523
524proc traverse {token} {
525    set result ""
526
527# depth-first search
528    if {![catch { mime::getproperty $token parts } parts]} {
529        foreach part $parts {
530            set result [concat $result [traverse $part]]
531        }
532    }
533
534# one value for each line occuring in the header
535    foreach value [mime::getheader $token To] {
536        foreach addr [mime::parseaddress $value] {
537            catch { unset aprops }
538            array set aprops $addr
539            lappend result $aprops(address)
540        }
541    }
542
543    return $result
544}
545
546
547# create a multipart containing both, and a timestamp
548
549set multiT [mime::initialize -canonical multipart/mixed
550                             -parts [list $imageT $messageT]]
551
552
553
554
555# send it to some friends
556
557smtp::sendmessage $multiT \
558      -header [list From "Marshall Rose <mrose@dbc.mtview.ca.us>"] \
559      -header [list To "Andreas Kupries <a.kupries@westend.com>"] \
560      -header [list cc "dnew@messagemedia.com (Darren New)"] \
561      -header [list Subject "test message..."]
562
563
564# clean everything up
565
566mime::finalize $multiT -subordinates all
567]]></artwork>
568</figure>
569</section>
570
571</middle>
572
573<back>
574<references>
575<reference anchor="RFC2045">
576<front>
577<title>Multipurpose Internet Mail Extensions (MIME)
578Part One: Format of Internet Message Bodies</title>
579<author initials="N." surname="Freed" fullname="Ned Freed">
580<organization>Innosoft International, Inc.</organization>
581<address>
582<email>ned@innosoft.com</email>
583</address>
584</author>
585<author initials="N.S." surname="Borenstein"
586        fullname="Nathaniel S. Borenstein">
587<organization>First Virtual Holdings, Incorporated</organization>
588<address>
589<email>nsb@messagemedia.com</email>
590</address>
591</author>
592<date month="November" year="1996"/>
593</front>
594<seriesInfo name="RFC" value="2045" />
595</reference>
596
597<reference anchor="RFC2046">
598<front>
599<title>Multipurpose Internet Mail Extensions (MIME)
600Part Two: Media Types</title>
601<author initials="N." surname="Freed" fullname="Ned Freed">
602<organization>Innosoft International, Inc.</organization>
603<address>
604<email>ned@innosoft.com</email>
605</address>
606</author>
607<author initials="N.S." surname="Borenstein"
608        fullname="Nathaniel S. Borenstein">
609<organization>First Virtual Holdings, Incorporated</organization>
610<address>
611<email>nsb@messagemedia.com</email>
612</address>
613</author>
614<date month="November" year="1995"/>
615</front>
616<seriesInfo name="RFC" value="2046" />
617</reference>
618
619<reference anchor="RFC822">
620<front>
621<title>Standard for the format of ARPA Internet Text Messages</title>
622<author initials="D." surname="Crocker" fullname="Dave Crocker">
623<organization abbrev="UDEL">University of Delaware</organization>
624<address>
625<email>DCrocker@UDel-Relay</email>
626</address>
627</author>
628<date month="August" year="1982"/>
629</front>
630<seriesInfo name="RFC" value="822" />
631<seriesInfo name="STD" value="11" />
632</reference>
633
634</references>
635
636<section title="TODO List">
637<t><list style="hanging">
638<t hangText="mime::initialize">
639<list style="symbols">
640<t>well-defined errorCode values</t>
641
642<t>catch nested errors when processing a multipart</t>
643</list></t>
644
645</list></t>
646</section>
647
648<section title="Acknowledgements">
649<t>This package is influenced by the safe-tcl package
650(Borenstein and Rose, circa 1993),
651and also by <eref target="mailto:dnew@messagemedia.com">Darren New</eref>'s
652unpublished package of 1999.</t>
653
654<t>This package makes use of 
655<eref target="mailto:a.kupries@westend.com">Andreas Kupries</eref>'s
656excellent Trf package.</t>
657</section>
658
659</back>
660</rfc>
661