1;;; mime-tnef.el --- mime-view content filter for ms-tnef  -*- lexical-binding: t -*-
2
3;; Copyright (C) 2015 Kazuhiro Ito
4
5;; Author: Kazuhiro Ito <kzhr@d1.dion.ne.jp>
6;; Keywords: MIME, multimedia, mail, news
7
8;; This file is part of SEMI (Suite of Emacs MIME Interfaces).
9
10;; This program is free software; you can redistribute it and/or
11;; modify it under the terms of the GNU General Public License as
12;; published by the Free Software Foundation; either version 2, or (at
13;; your option) any later version.
14
15;; This program is distributed in the hope that it will be useful, but
16;; WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18;; General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING.  If not, write to the
22;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, USA.
24
25;;; Commentary:
26
27;; mime-tnef.el can handle an application/ms-tnef attachment, usually
28;; named winmail.dat.  At present, mime-tnef.el provides access to
29;; only attached files, not text.  Most of algorithms, constants are
30;; derived from TNEF, C program available at
31;; https://github.com/verdammelt/tnef .
32
33
34;;; Code:
35
36(require 'mime)
37(require 'mime-edit)
38
39
40;;; Customizable variables
41
42(defcustom mime-tnef-unicode-coding-system
43  (catch :found
44    (dolist (coding '(utf-16le utf-16-le-no-signature) nil)
45      (when (coding-system-p coding)
46	(throw :found coding))))
47  "Coding system for Windows uniode string."
48  :group 'mime-view
49  :type 'coding-system)
50
51
52;;; Internal constants
53
54(defconst mime-tnef-lvl-types-table
55  '((1 . message)
56    (2 . attachment)))
57
58(defconst mime-tnef-names-table
59  '((0 . OWNER) ;; #x0000
60    (1 . SENTFOR) ;; #x0001
61    (2 . DELEGATE) ;; #x0002
62    (6 . DATESTART) ;; #x0006
63    (7 . DATEEND) ;; #x0007
64    (8 . AIDOWNER) ;; #x0008
65    (9 . REQUESTRES) ;; #x0009
66    (32768 . FROM) ;; #x8000
67    (32772 . SUBJECT) ;; #x8004
68    (32773 . DATESENT) ;; #x8005
69    (32774 . DATERECD) ;; #x8006
70    (32775 . MESSAGESTATUS) ;; #x8007
71    (32776 . MESSAGECLASS) ;; #x8008
72    (32777 . MESSAGEID) ;; #x8009
73    (32778 . PARENTID) ;; #x800a
74    (32779 . CONVERSATIONID) ;; #x800b
75    (32780 . BODY) ;; #x800c
76    (32781 . PRIORITY) ;; #x800d
77    (32783 . ATTACHDATA) ;; #x800f
78    (32784 . ATTACHTITLE) ;; #x8010
79    (32785 . ATTACHMETAFILE) ;; #x8011
80    (32786 . ATTACHCREATEDATE) ;; #x8012
81    (32787 . ATTACHMODIFYDATE) ;; #x8013
82    (32800 . DATEMODIFY) ;; #x8020
83    (36865 . ATTACHTRANSPORTFILENAME) ;; #x9001
84    (36866 . ATTACHRENDDATA) ;; #x9002
85    (36867 . MAPIPROPS) ;; #x9003
86    (36868 . RECIPTABLE) ;; #x9004
87    (36869 . ATTACHMENT) ;; #x9005
88    (36870 . TNEFVERSION) ;; #x9006
89    (36871 . OEMCODEPAGE) ;; #x9007
90    (36872 . ORIGNINALMESSAGECLASS) ;; #x9008
91    ))
92
93(defconst mime-tnef-types-table
94  '((0 . TRIPLES) ;; #x0000
95    (1 . STRING) ;; #x0001
96    (2 . TEXT) ;; #x0002
97    (3 . DATE) ;; #x0003
98    (4 . SHORT) ;; #x0004
99    (5 . LONG) ;; #x0005
100    (6 . BYTE) ;; #x0006
101    (7 . WORD) ;; #x0007
102    (8 . DWORD) ;; #x0008
103    (9 . MAX) ;; #x0009
104    ))
105
106(defconst mime-tnef-mapi-names-table
107  '((1 . ACKNOWLEDGEMENT_MODE) ;; #x0001
108    (2 . ALTERNATE_RECIPIENT_ALLOWED) ;; #x0002
109    (3 . AUTHORIZING_USERS) ;; #x0003
110    (4 . AUTO_FORWARD_COMMENT) ;; #x0004
111    (5 . AUTO_FORWARDED) ;; #x0005
112    (6 . CONTENT_CONFIDENTIALITY_ALGORITHM_ID) ;; #x0006
113    (7 . CONTENT_CORRELATOR) ;; #x0007
114    (8 . CONTENT_IDENTIFIER) ;; #x0008
115    (9 . CONTENT_LENGTH) ;; #x0009
116    (10 . CONTENT_RETURN_REQUESTED) ;; #x000A
117    (11 . CONVERSATION_KEY) ;; #x000B
118    (12 . CONVERSION_EITS) ;; #x000C
119    (13 . CONVERSION_WITH_LOSS_PROHIBITED) ;; #x000D
120    (14 . CONVERTED_EITS) ;; #x000E
121    (15 . DEFERRED_DELIVERY_TIME) ;; #x000F
122    (16 . DELIVER_TIME) ;; #x0010
123    (17 . DISCARD_REASON) ;; #x0011
124    (18 . DISCLOSURE_OF_RECIPIENTS) ;; #x0012
125    (19 . DL_EXPANSION_HISTORY) ;; #x0013
126    (20 . DL_EXPANSION_PROHIBITED) ;; #x0014
127    (21 . EXPIRY_TIME) ;; #x0015
128    (22 . IMPLICIT_CONVERSION_PROHIBITED) ;; #x0016
129    (23 . IMPORTANCE) ;; #x0017
130    (24 . IPM_ID) ;; #x0018
131    (25 . LATEST_DELIVERY_TIME) ;; #x0019
132    (26 . MESSAGE_CLASS) ;; #x001A
133    (27 . MESSAGE_DELIVERY_ID) ;; #x001B
134    (30 . MESSAGE_SECURITY_LABEL) ;; #x001E
135    (31 . OBSOLETED_IPMS) ;; #x001F
136    (32 . ORIGINALLY_INTENDED_RECIPIENT_NAME) ;; #x0020
137    (33 . ORIGINAL_EITS) ;; #x0021
138    (34 . ORIGINATOR_CERTIFICATE) ;; #x0022
139    (35 . ORIGINATOR_DELIVERY_REPORT_REQUESTED) ;; #x0023
140    (36 . ORIGINATOR_RETURN_ADDRESS) ;; #x0024
141    (37 . PARENT_KEY) ;; #x0025
142    (38 . PRIORITY) ;; #x0026
143    (39 . ORIGIN_CHECK) ;; #x0027
144    (40 . PROOF_OF_SUBMISSION_REQUESTED) ;; #x0028
145    (41 . READ_RECEIPT_REQUESTED) ;; #x0029
146    (42 . RECEIPT_TIME) ;; #x002A
147    (43 . RECIPIENT_REASSIGNMENT_PROHIBITED) ;; #x002B
148    (44 . REDIRECTION_HISTORY) ;; #x002C
149    (45 . RELATED_IPMS) ;; #x002D
150    (46 . ORIGINAL_SENSITIVITY) ;; #x002E
151    (47 . LANGUAGES) ;; #x002F
152    (48 . REPLY_TIME) ;; #x0030
153    (49 . REPORT_TAG) ;; #x0031
154    (50 . REPORT_TIME) ;; #x0032
155    (51 . RETURNED_IPM) ;; #x0033
156    (52 . SECURITY) ;; #x0034
157    (53 . INCOMPLETE_COPY) ;; #x0035
158    (54 . SENSITIVITY) ;; #x0036
159    (55 . SUBJECT) ;; #x0037
160    (56 . SUBJECT_IPM) ;; #x0038
161    (57 . CLIENT_SUBMIT_TIME) ;; #x0039
162    (58 . REPORT_NAME) ;; #x003A
163    (59 . SENT_REPRESENTING_SEARCH_KEY) ;; #x003B
164    (60 . X400_CONTENT_TYPE) ;; #x003C
165    (61 . SUBJECT_PREFIX) ;; #x003D
166    (62 . NON_RECEIPT_REASON) ;; #x003E
167    (63 . RECEIVED_BY_ENTRYID) ;; #x003F
168    (64 . RECEIVED_BY_NAME) ;; #x0040
169    (65 . SENT_REPRESENTING_ENTRYID) ;; #x0041
170    (66 . SENT_REPRESENTING_NAME) ;; #x0042
171    (67 . RCVD_REPRESENTING_ENTRYID) ;; #x0043
172    (68 . RCVD_REPRESENTING_NAME) ;; #x0044
173    (69 . REPORT_ENTRYID) ;; #x0045
174    (70 . READ_RECEIPT_ENTRYID) ;; #x0046
175    (71 . MESSAGE_SUBMISSION_ID) ;; #x0047
176    (72 . PROVIDER_SUBMIT_TIME) ;; #x0048
177    (73 . ORIGINAL_SUBJECT) ;; #x0049
178    (74 . DISC_VAL) ;; #x004A
179    (75 . ORIG_MESSAGE_CLASS) ;; #x004B
180    (76 . ORIGINAL_AUTHOR_ENTRYID) ;; #x004C
181    (77 . ORIGINAL_AUTHOR_NAME) ;; #x004D
182    (78 . ORIGINAL_SUBMIT_TIME) ;; #x004E
183    (79 . REPLY_RECIPIENT_ENTRIES) ;; #x004F
184    (80 . REPLY_RECIPIENT_NAMES) ;; #x0050
185    (81 . RECEIVED_BY_SEARCH_KEY) ;; #x0051
186    (82 . RCVD_REPRESENTING_SEARCH_KEY) ;; #x0052
187    (83 . READ_RECEIPT_SEARCH_KEY) ;; #x0053
188    (84 . REPORT_SEARCH_KEY) ;; #x0054
189    (85 . ORIGINAL_DELIVERY_TIME) ;; #x0055
190    (86 . ORIGINAL_AUTHOR_SEARCH_KEY) ;; #x0056
191    (87 . MESSAGE_TO_ME) ;; #x0057
192    (88 . MESSAGE_CC_ME) ;; #x0058
193    (89 . MESSAGE_RECIP_ME) ;; #x0059
194    (90 . ORIGINAL_SENDER_NAME) ;; #x005A
195    (91 . ORIGINAL_SENDER_ENTRYID) ;; #x005B
196    (92 . ORIGINAL_SENDER_SEARCH_KEY) ;; #x005C
197    (93 . ORIGINAL_SENT_REPRESENTING_NAME) ;; #x005D
198    (94 . ORIGINAL_SENT_REPRESENTING_ENTRYID) ;; #x005E
199    (95 . ORIGINAL_SENT_REPRESENTING_SEARCH_KEY) ;; #x005F
200    (96 . START_DATE) ;; #x0060
201    (97 . END_DATE) ;; #x0061
202    (98 . OWNER_APPT_ID) ;; #x0062
203    (99 . RESPONSE_REQUESTED) ;; #x0063
204    (100 . SENT_REPRESENTING_ADDRTYPE) ;; #x0064
205    (101 . SENT_REPRESENTING_EMAIL_ADDRESS) ;; #x0065
206    (102 . ORIGINAL_SENDER_ADDRTYPE) ;; #x0066
207    (103 . ORIGINAL_SENDER_EMAIL_ADDRESS) ;; #x0067
208    (104 . ORIGINAL_SENT_REPRESENTING_ADDRTYPE) ;; #x0068
209    (105 . ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS) ;; #x0069
210    (112 . CONVERSATION_TOPIC) ;; #x0070
211    (113 . CONVERSATION_INDEX) ;; #x0071
212    (114 . ORIGINAL_DISPLAY_BCC) ;; #x0072
213    (115 . ORIGINAL_DISPLAY_CC) ;; #x0073
214    (116 . ORIGINAL_DISPLAY_TO) ;; #x0074
215    (117 . RECEIVED_BY_ADDRTYPE) ;; #x0075
216    (118 . RECEIVED_BY_EMAIL_ADDRESS) ;; #x0076
217    (119 . RCVD_REPRESENTING_ADDRTYPE) ;; #x0077
218    (120 . RCVD_REPRESENTING_EMAIL_ADDRESS) ;; #x0078
219    (121 . ORIGINAL_AUTHOR_ADDRTYPE) ;; #x0079
220    (122 . ORIGINAL_AUTHOR_EMAIL_ADDRESS) ;; #x007A
221    (123 . ORIGINALLY_INTENDED_RECIP_ADDRTYPE) ;; #x007B
222    (124 . ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS) ;; #x007C
223    (125 . TRANSPORT_MESSAGE_HEADERS) ;; #x007D
224    (126 . DELEGATION) ;; #x007E
225    (127 . TNEF_CORRELATION_KEY) ;; #x007F
226    (4096 . BODY) ;; #x1000
227    (4097 . REPORT_TEXT) ;; #x1001
228    (4098 . ORIGINATOR_AND_DL_EXPANSION_HISTORY) ;; #x1002
229    (4099 . REPORTING_DL_NAME) ;; #x1003
230    (4100 . REPORTING_MTA_CERTIFICATE) ;; #x1004
231    (4102 . RTF_SYNC_BODY_CRC) ;; #x1006
232    (4103 . RTF_SYNC_BODY_COUNT) ;; #x1007
233    (4104 . RTF_SYNC_BODY_TAG) ;; #x1008
234    (4105 . RTF_COMPRESSED) ;; #x1009
235    (4112 . RTF_SYNC_PREFIX_COUNT) ;; #x1010
236    (4113 . RTF_SYNC_TRAILING_COUNT) ;; #x1011
237    (4114 . ORIGINALLY_INTENDED_RECIP_ENTRYID) ;; #x1012
238    (4115 . BODY_HTML) ;; #x1013
239    (4149 . SMTP_MESSAGE_ID) ;; #x1035
240    (3072 . CONTENT_INTEGRITY_CHECK) ;; #x0C00
241    (3073 . EXPLICIT_CONVERSION) ;; #x0C01
242    (3074 . IPM_RETURN_REQUESTED) ;; #x0C02
243    (3075 . MESSAGE_TOKEN) ;; #x0C03
244    (3076 . NDR_REASON_CODE) ;; #x0C04
245    (3077 . NDR_DIAG_CODE) ;; #x0C05
246    (3078 . NON_RECEIPT_NOTIFICATION_REQUESTED) ;; #x0C06
247    (3079 . DELIVERY_POINT) ;; #x0C07
248    (3080 . ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED) ;; #x0C08
249    (3081 . ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT) ;; #x0C09
250    (3082 . PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY) ;; #x0C0A
251    (3083 . PHYSICAL_DELIVERY_MODE) ;; #x0C0B
252    (3084 . PHYSICAL_DELIVERY_REPORT_REQUEST) ;; #x0C0C
253    (3085 . PHYSICAL_FORWARDING_ADDRESS) ;; #x0C0D
254    (3086 . PHYSICAL_FORWARDING_ADDRESS_REQUESTED) ;; #x0C0E
255    (3087 . PHYSICAL_FORWARDING_PROHIBITED) ;; #x0C0F
256    (3088 . PHYSICAL_RENDITION_ATTRIBUTES) ;; #x0C10
257    (3089 . PROOF_OF_DELIVERY) ;; #x0C11
258    (3090 . PROOF_OF_DELIVERY_REQUESTED) ;; #x0C12
259    (3091 . RECIPIENT_CERTIFICATE) ;; #x0C13
260    (3092 . RECIPIENT_NUMBER_FOR_ADVICE) ;; #x0C14
261    (3093 . RECIPIENT_TYPE) ;; #x0C15
262    (3094 . REGISTERED_MAIL_TYPE) ;; #x0C16
263    (3095 . REPLY_REQUESTED) ;; #x0C17
264    (3096 . REQUESTED_DELIVERY_METHOD) ;; #x0C18
265    (3097 . SENDER_ENTRYID) ;; #x0C19
266    (3098 . SENDER_NAME) ;; #x0C1A
267    (3099 . SUPPLEMENTARY_INFO) ;; #x0C1B
268    (3100 . TYPE_OF_MTS_USER) ;; #x0C1C
269    (3101 . SENDER_SEARCH_KEY) ;; #x0C1D
270    (3102 . SENDER_ADDRTYPE) ;; #x0C1E
271    (3103 . SENDER_EMAIL_ADDRESS) ;; #x0C1F
272    (3584 . CURRENT_VERSION) ;; #x0E00
273    (3585 . DELETE_AFTER_SUBMIT) ;; #x0E01
274    (3586 . DISPLAY_BCC) ;; #x0E02
275    (3587 . DISPLAY_CC) ;; #x0E03
276    (3588 . DISPLAY_TO) ;; #x0E04
277    (3589 . PARENT_DISPLAY) ;; #x0E05
278    (3590 . MESSAGE_DELIVERY_TIME) ;; #x0E06
279    (3591 . MESSAGE_FLAGS) ;; #x0E07
280    (3592 . MESSAGE_SIZE) ;; #x0E08
281    (3593 . PARENT_ENTRYID) ;; #x0E09
282    (3594 . SENTMAIL_ENTRYID) ;; #x0E0A
283    (3596 . CORRELATE) ;; #x0E0C
284    (3597 . CORRELATE_MTSID) ;; #x0E0D
285    (3598 . DISCRETE_VALUES) ;; #x0E0E
286    (3599 . RESPONSIBILITY) ;; #x0E0F
287    (3600 . SPOOLER_STATUS) ;; #x0E10
288    (3601 . TRANSPORT_STATUS) ;; #x0E11
289    (3602 . MESSAGE_RECIPIENTS) ;; #x0E12
290    (3603 . MESSAGE_ATTACHMENTS) ;; #x0E13
291    (3604 . SUBMIT_FLAGS) ;; #x0E14
292    (3605 . RECIPIENT_STATUS) ;; #x0E15
293    (3606 . TRANSPORT_KEY) ;; #x0E16
294    (3607 . MSG_STATUS) ;; #x0E17
295    (3608 . MESSAGE_DOWNLOAD_TIME) ;; #x0E18
296    (3609 . CREATION_VERSION) ;; #x0E19
297    (3610 . MODIFY_VERSION) ;; #x0E1A
298    (3611 . HASATTACH) ;; #x0E1B
299    (3612 . BODY_CRC) ;; #x0E1C
300    (3613 . NORMALIZED_SUBJECT) ;; #x0E1D
301    (3615 . RTF_IN_SYNC) ;; #x0E1F
302    (3616 . ATTACH_SIZE) ;; #x0E20
303    (3617 . ATTACH_NUM) ;; #x0E21
304    (3618 . PREPROCESS) ;; #x0E22
305    (3621 . ORIGINATING_MTA_CERTIFICATE) ;; #x0E25
306    (3622 . PROOF_OF_SUBMISSION) ;; #x0E26
307    (4095 . ENTRYID) ;; #x0FFF
308    (4094 . OBJECT_TYPE) ;; #x0FFE
309    (4093 . ICON) ;; #x0FFD
310    (4092 . MINI_ICON) ;; #x0FFC
311    (4091 . STORE_ENTRYID) ;; #x0FFB
312    (4090 . STORE_RECORD_KEY) ;; #x0FFA
313    (4089 . RECORD_KEY) ;; #x0FF9
314    (4088 . MAPPING_SIGNATURE) ;; #x0FF8
315    (4087 . ACCESS_LEVEL) ;; #x0FF7
316    (4086 . INSTANCE_KEY) ;; #x0FF6
317    (4085 . ROW_TYPE) ;; #x0FF5
318    (4084 . ACCESS) ;; #x0FF4
319    (12288 . ROWID) ;; #x3000
320    (12289 . DISPLAY_NAME) ;; #x3001
321    (12290 . ADDRTYPE) ;; #x3002
322    (12291 . EMAIL_ADDRESS) ;; #x3003
323    (12292 . COMMENT) ;; #x3004
324    (12293 . DEPTH) ;; #x3005
325    (12294 . PROVIDER_DISPLAY) ;; #x3006
326    (12295 . CREATION_TIME) ;; #x3007
327    (12296 . LAST_MODIFICATION_TIME) ;; #x3008
328    (12297 . RESOURCE_FLAGS) ;; #x3009
329    (12298 . PROVIDER_DLL_NAME) ;; #x300A
330    (12299 . SEARCH_KEY) ;; #x300B
331    (12300 . PROVIDER_UID) ;; #x300C
332    (12301 . PROVIDER_ORDINAL) ;; #x300D
333    (13057 . FORM_VERSION) ;; #x3301
334    (13058 . FORM_CLSID) ;; #x3302
335    (13059 . FORM_CONTACT_NAME) ;; #x3303
336    (13060 . FORM_CATEGORY) ;; #x3304
337    (13061 . FORM_CATEGORY_SUB) ;; #x3305
338    (13062 . FORM_HOST_MAP) ;; #x3306
339    (13063 . FORM_HIDDEN) ;; #x3307
340    (13064 . FORM_DESIGNER_NAME) ;; #x3308
341    (13065 . FORM_DESIGNER_GUID) ;; #x3309
342    (13066 . FORM_MESSAGE_BEHAVIOR) ;; #x330A
343    (13312 . DEFAULT_STORE) ;; #x3400
344    (13325 . STORE_SUPPORT_MASK) ;; #x340D
345    (13326 . STORE_STATE) ;; #x340E
346    (13328 . IPM_SUBTREE_SEARCH_KEY) ;; #x3410
347    (13329 . IPM_OUTBOX_SEARCH_KEY) ;; #x3411
348    (13330 . IPM_WASTEBASKET_SEARCH_KEY) ;; #x3412
349    (13331 . IPM_SENTMAIL_SEARCH_KEY) ;; #x3413
350    (13332 . MDB_PROVIDER) ;; #x3414
351    (13333 . RECEIVE_FOLDER_SETTINGS) ;; #x3415
352    (13791 . VALID_FOLDER_MASK) ;; #x35DF
353    (13792 . IPM_SUBTREE_ENTRYID) ;; #x35E0
354    (13794 . IPM_OUTBOX_ENTRYID) ;; #x35E2
355    (13795 . IPM_WASTEBASKET_ENTRYID) ;; #x35E3
356    (13796 . IPM_SENTMAIL_ENTRYID) ;; #x35E4
357    (13797 . VIEWS_ENTRYID) ;; #x35E5
358    (13798 . COMMON_VIEWS_ENTRYID) ;; #x35E6
359    (13799 . FINDER_ENTRYID) ;; #x35E7
360    (13824 . CONTAINER_FLAGS) ;; #x3600
361    (13825 . FOLDER_TYPE) ;; #x3601
362    (13826 . CONTENT_COUNT) ;; #x3602
363    (13827 . CONTENT_UNREAD) ;; #x3603
364    (13828 . CREATE_TEMPLATES) ;; #x3604
365    (13829 . DETAILS_TABLE) ;; #x3605
366    (13831 . SEARCH) ;; #x3607
367    (13833 . SELECTABLE) ;; #x3609
368    (13834 . SUBFOLDERS) ;; #x360A
369    (13835 . STATUS) ;; #x360B
370    (13836 . ANR) ;; #x360C
371    (13837 . CONTENTS_SORT_ORDER) ;; #x360D
372    (13838 . CONTAINER_HIERARCHY) ;; #x360E
373    (13839 . CONTAINER_CONTENTS) ;; #x360F
374    (13840 . FOLDER_ASSOCIATED_CONTENTS) ;; #x3610
375    (13841 . DEF_CREATE_DL) ;; #x3611
376    (13842 . DEF_CREATE_MAILUSER) ;; #x3612
377    (13843 . CONTAINER_CLASS) ;; #x3613
378    (13844 . CONTAINER_MODIFY_VERSION) ;; #x3614
379    (13845 . AB_PROVIDER_ID) ;; #x3615
380    (13846 . DEFAULT_VIEW_ENTRYID) ;; #x3616
381    (13847 . ASSOC_CONTENT_COUNT) ;; #x3617
382    (14080 . ATTACHMENT_X400_PARAMETERS) ;; #x3700
383    (14081 . ATTACH_DATA_OBJ) ;; #x3701
384    (14082 . ATTACH_ENCODING) ;; #x3702
385    (14083 . ATTACH_EXTENSION) ;; #x3703
386    (14084 . ATTACH_FILENAME) ;; #x3704
387    (14085 . ATTACH_METHOD) ;; #x3705
388    (14087 . ATTACH_LONG_FILENAME) ;; #x3707
389    (14088 . ATTACH_PATHNAME) ;; #x3708
390    (14089 . ATTACH_RENDERING) ;; #x3709
391    (14090 . ATTACH_TAG) ;; #x370A
392    (14091 . RENDERING_POSITION) ;; #x370B
393    (14092 . ATTACH_TRANSPORT_NAME) ;; #x370C
394    (14093 . ATTACH_LONG_PATHNAME) ;; #x370D
395    (14094 . ATTACH_MIME_TAG) ;; #x370E
396    (14095 . ATTACH_ADDITIONAL_INFO) ;; #x370F
397    (14096 . ATTACH_MIME_SEQUENCE) ;; #x3710
398    (14098 . ATTACH_CONTENT_ID) ;; #x3712
399    (14099 . ATTACH_CONTENT_LOCATION) ;; #x3713
400    (14100 . ATTACH_FLAGS) ;; #x3714
401    (14592 . DISPLAY_TYPE) ;; #x3900
402    (14594 . TEMPLATEID) ;; #x3902
403    (14596 . PRIMARY_CAPABILITY) ;; #x3904
404    (14847 . 7BIT_DISPLAY_NAME) ;; #x39FF
405    (14848 . ACCOUNT) ;; #x3A00
406    (14849 . ALTERNATE_RECIPIENT) ;; #x3A01
407    (14850 . CALLBACK_TELEPHONE_NUMBER) ;; #x3A02
408    (14851 . CONVERSION_PROHIBITED) ;; #x3A03
409    (14852 . DISCLOSE_RECIPIENTS) ;; #x3A04
410    (14853 . GENERATION) ;; #x3A05
411    (14854 . GIVEN_NAME) ;; #x3A06
412    (14855 . GOVERNMENT_ID_NUMBER) ;; #x3A07
413    (14856 . BUSINESS_TELEPHONE_NUMBER) ;; #x3A08
414    (14857 . HOME_TELEPHONE_NUMBER) ;; #x3A09
415    (14858 . INITIALS) ;; #x3A0A
416    (14859 . KEYWORD) ;; #x3A0B
417    (14860 . LANGUAGE) ;; #x3A0C
418    (14861 . LOCATION) ;; #x3A0D
419    (14862 . MAIL_PERMISSION) ;; #x3A0E
420    (14863 . MHS_COMMON_NAME) ;; #x3A0F
421    (14864 . ORGANIZATIONAL_ID_NUMBER) ;; #x3A10
422    (14865 . SURNAME) ;; #x3A11
423    (14866 . ORIGINAL_ENTRYID) ;; #x3A12
424    (14867 . ORIGINAL_DISPLAY_NAME) ;; #x3A13
425    (14868 . ORIGINAL_SEARCH_KEY) ;; #x3A14
426    (14869 . POSTAL_ADDRESS) ;; #x3A15
427    (14870 . COMPANY_NAME) ;; #x3A16
428    (14871 . TITLE) ;; #x3A17
429    (14872 . DEPARTMENT_NAME) ;; #x3A18
430    (14873 . OFFICE_LOCATION) ;; #x3A19
431    (14874 . PRIMARY_TELEPHONE_NUMBER) ;; #x3A1A
432    (14875 . BUSINESS2_TELEPHONE_NUMBER) ;; #x3A1B
433    (14876 . MOBILE_TELEPHONE_NUMBER) ;; #x3A1C
434    (14877 . RADIO_TELEPHONE_NUMBER) ;; #x3A1D
435    (14878 . CAR_TELEPHONE_NUMBER) ;; #x3A1E
436    (14879 . OTHER_TELEPHONE_NUMBER) ;; #x3A1F
437    (14880 . TRANSMITABLE_DISPLAY_NAME) ;; #x3A20
438    (14881 . PAGER_TELEPHONE_NUMBER) ;; #x3A21
439    (14882 . USER_CERTIFICATE) ;; #x3A22
440    (14883 . PRIMARY_FAX_NUMBER) ;; #x3A23
441    (14884 . BUSINESS_FAX_NUMBER) ;; #x3A24
442    (14885 . HOME_FAX_NUMBER) ;; #x3A25
443    (14886 . COUNTRY) ;; #x3A26
444    (14887 . LOCALITY) ;; #x3A27
445    (14888 . STATE_OR_PROVINCE) ;; #x3A28
446    (14889 . STREET_ADDRESS) ;; #x3A29
447    (14890 . POSTAL_CODE) ;; #x3A2A
448    (14891 . POST_OFFICE_BOX) ;; #x3A2B
449    (14892 . TELEX_NUMBER) ;; #x3A2C
450    (14893 . ISDN_NUMBER) ;; #x3A2D
451    (14894 . ASSISTANT_TELEPHONE_NUMBER) ;; #x3A2E
452    (14895 . HOME2_TELEPHONE_NUMBER) ;; #x3A2F
453    (14896 . ASSISTANT) ;; #x3A30
454    (14912 . SEND_RICH_INFO) ;; #x3A40
455    (14913 . WEDDING_ANNIVERSARY) ;; #x3A41
456    (14914 . BIRTHDAY) ;; #x3A42
457    (14915 . HOBBIES) ;; #x3A43
458    (14916 . MIDDLE_NAME) ;; #x3A44
459    (14917 . DISPLAY_NAME_PREFIX) ;; #x3A45
460    (14918 . PROFESSION) ;; #x3A46
461    (14919 . PREFERRED_BY_NAME) ;; #x3A47
462    (14920 . SPOUSE_NAME) ;; #x3A48
463    (14921 . COMPUTER_NETWORK_NAME) ;; #x3A49
464    (14922 . CUSTOMER_ID) ;; #x3A4A
465    (14923 . TTYTDD_PHONE_NUMBER) ;; #x3A4B
466    (14924 . FTP_SITE) ;; #x3A4C
467    (14925 . GENDER) ;; #x3A4D
468    (14926 . MANAGER_NAME) ;; #x3A4E
469    (14927 . NICKNAME) ;; #x3A4F
470    (14928 . PERSONAL_HOME_PAGE) ;; #x3A50
471    (14929 . BUSINESS_HOME_PAGE) ;; #x3A51
472    (14930 . CONTACT_VERSION) ;; #x3A52
473    (14931 . CONTACT_ENTRYIDS) ;; #x3A53
474    (14932 . CONTACT_ADDRTYPES) ;; #x3A54
475    (14933 . CONTACT_DEFAULT_ADDRESS_INDEX) ;; #x3A55
476    (14934 . CONTACT_EMAIL_ADDRESSES) ;; #x3A56
477    (14935 . COMPANY_MAIN_PHONE_NUMBER) ;; #x3A57
478    (14936 . CHILDRENS_NAMES) ;; #x3A58
479    (14937 . HOME_ADDRESS_CITY) ;; #x3A59
480    (14938 . HOME_ADDRESS_COUNTRY) ;; #x3A5A
481    (14939 . HOME_ADDRESS_POSTAL_CODE) ;; #x3A5B
482    (14940 . HOME_ADDRESS_STATE_OR_PROVINCE) ;; #x3A5C
483    (14941 . HOME_ADDRESS_STREET) ;; #x3A5D
484    (14942 . HOME_ADDRESS_POST_OFFICE_BOX) ;; #x3A5E
485    (14943 . OTHER_ADDRESS_CITY) ;; #x3A5F
486    (14944 . OTHER_ADDRESS_COUNTRY) ;; #x3A60
487    (14945 . OTHER_ADDRESS_POSTAL_CODE) ;; #x3A61
488    (14946 . OTHER_ADDRESS_STATE_OR_PROVINCE) ;; #x3A62
489    (14947 . OTHER_ADDRESS_STREET) ;; #x3A63
490    (14948 . OTHER_ADDRESS_POST_OFFICE_BOX) ;; #x3A64
491    (15616 . STORE_PROVIDERS) ;; #x3D00
492    (15617 . AB_PROVIDERS) ;; #x3D01
493    (15618 . TRANSPORT_PROVIDERS) ;; #x3D02
494    (15620 . DEFAULT_PROFILE) ;; #x3D04
495    (15621 . AB_SEARCH_PATH) ;; #x3D05
496    (15622 . AB_DEFAULT_DIR) ;; #x3D06
497    (15623 . AB_DEFAULT_PAB) ;; #x3D07
498    (15624 . FILTERING_HOOKS) ;; #x3D08
499    (15625 . SERVICE_NAME) ;; #x3D09
500    (15626 . SERVICE_DLL_NAME) ;; #x3D0A
501    (15627 . SERVICE_ENTRY_NAME) ;; #x3D0B
502    (15628 . SERVICE_UID) ;; #x3D0C
503    (15629 . SERVICE_EXTRA_UIDS) ;; #x3D0D
504    (15630 . SERVICES) ;; #x3D0E
505    (15631 . SERVICE_SUPPORT_FILES) ;; #x3D0F
506    (15632 . SERVICE_DELETE_FILES) ;; #x3D10
507    (15633 . AB_SEARCH_PATH_UPDATE) ;; #x3D11
508    (15634 . PROFILE_NAME) ;; #x3D12
509    (15872 . IDENTITY_DISPLAY) ;; #x3E00
510    (15873 . IDENTITY_ENTRYID) ;; #x3E01
511    (15874 . RESOURCE_METHODS) ;; #x3E02
512    (15875 . RESOURCE_TYPE) ;; #x3E03
513    (15876 . STATUS_CODE) ;; #x3E04
514    (15877 . IDENTITY_SEARCH_KEY) ;; #x3E05
515    (15878 . OWN_STORE_ENTRYID) ;; #x3E06
516    (15879 . RESOURCE_PATH) ;; #x3E07
517    (15880 . STATUS_STRING) ;; #x3E08
518    (15881 . X400_DEFERRED_DELIVERY_CANCEL) ;; #x3E09
519    (15882 . HEADER_FOLDER_ENTRYID) ;; #x3E0A
520    (15883 . REMOTE_PROGRESS) ;; #x3E0B
521    (15884 . REMOTE_PROGRESS_TEXT) ;; #x3E0C
522    (15885 . REMOTE_VALIDATE_OK) ;; #x3E0D
523    (16128 . CONTROL_FLAGS) ;; #x3F00
524    (16129 . CONTROL_STRUCTURE) ;; #x3F01
525    (16130 . CONTROL_TYPE) ;; #x3F02
526    (16131 . DELTAX) ;; #x3F03
527    (16132 . DELTAY) ;; #x3F04
528    (16133 . XPOS) ;; #x3F05
529    (16134 . YPOS) ;; #x3F06
530    (16135 . CONTROL_ID) ;; #x3F07
531    (16136 . INITIAL_DETAILS_PANE) ;; #x3F08
532    (26608 . ID_SECURE_MIN) ;; #x67F0
533    (26623 . ID_SECURE_MAX) ;; #x67FF
534    ))
535
536(defconst mime-tnef-mapi-types-table
537  '((0 . UNSPECIFIED) ;; #x0000
538    (1 . NULL) ;; #x0001
539    (2 . SHORT) ;; #x0002
540    (3 . INT) ;; #x0003
541    (4 . FLOAT) ;; #x0004
542    (5 . DOUBLE) ;; #x0005
543    (6 . CURRENCY) ;; #x0006
544    (7 . APPTIME) ;; #x0007
545    (10 . ERROR) ;; #x000a
546    (11 . BOOLEAN) ;; #x000b
547    (13 . OBJECT) ;; #x000d
548    (20 . INT8BYTE) ;; #x0014
549    (30 . STRING) ;; #x001e
550    (31 . UNICODE_STRING) ;; #x001f
551    (64 . SYSTIME) ;; #x0040
552    (72 . CLSID) ;; #x0048
553    (258 . BINARY) ;; #x0102
554    ))
555
556
557;;; Internal functions
558
559(defmacro mime-tnef-byte (array idx)
560  `(logand (aref ,array ,idx) 255))
561
562(defmacro mime-tnef-padded-length (l)
563  ;; L must be integer.
564  `(* (/ (+ ,l 3) 4) 4))
565
566(eval-and-compile
567  (defsubst mime-tnef-2bytes (array idx)
568    (+ (mime-tnef-byte array idx)
569       (* (mime-tnef-byte array (1+ idx)) 256)))
570
571  (defsubst mime-tnef-4bytes (array idx)
572    (+ (mime-tnef-byte array idx)
573       (* (mime-tnef-byte array (1+ idx)) 256)
574       (* (mime-tnef-byte array (+ idx 2)) 65536)
575       (* (mime-tnef-byte array (+ idx 3)) 16777216))))
576
577
578;;; Debug
579
580(defvar mime-tnef-debug nil)
581
582(defun mime-tnef-debug (string &rest args)
583  (when mime-tnef-debug
584    (if args (apply #'message string args)
585      (message "%s" string))))
586
587
588;;; TNEF element
589
590(defun mime-tnef-element-start (element)
591  (cdr (assq 'start element)))
592
593(defun mime-tnef-element-end (element)
594  (cdr (assq 'end element)))
595
596(defun mime-tnef-element-name (element)
597  (cdr (assq 'name element)))
598
599(defun mime-tnef-element-type (element)
600  (cdr (assq 'type element)))
601
602
603;;; TNEF
604
605(defun mime-tnef-parse (string)
606  (catch :done
607    (unless (and (> (length string) 6)
608		 (equal (string-make-unibyte (substring string 0 4))
609			(string-make-unibyte "\x78\x9f\x3e\x22")))
610      (message "Input data does not seem to be MS-TNEF format")
611      (throw :done nil))
612    (mime-tnef-debug "TNEF Key: %04x\n" (mime-tnef-2bytes string 4))
613    (let ((length (length string))
614	  (read 6)
615	  result object
616	  lvl-type name type
617	  sum
618	  start end data-length)
619      (while (< read length)
620	(setq lvl-type (mime-tnef-byte string read)
621	      name (mime-tnef-2bytes string (1+ read))
622	      type (mime-tnef-2bytes string (+ read 3))
623	      data-length (mime-tnef-4bytes string (+ read 5))
624	      start (+ read 9)
625	      end (+ start data-length)
626	      object `(
627		       (lvl-type . ,(or (cdr (assq lvl-type
628		       				   mime-tnef-lvl-types-table))
629					lvl-type))
630		       (name . ,(or (cdr (assq name mime-tnef-names-table))
631				    name))
632		       (type . ,(or (cdr (assq type mime-tnef-types-table))
633				    type))
634		       (start . ,start)
635		       (end . ,end)
636		       ;; (length . ,(mime-tnef-4bytes string (+ read 5)))
637		       )
638	      read (+ read data-length 9 2)
639	      sum 0)
640	(dotimes (i data-length)
641	  (setq sum (+ sum (mime-tnef-byte string (- read 3 i)))))
642	(unless (eq (mime-tnef-2bytes string (- read 2)) (% sum 65536))
643	  (message "Checksum mismatch, TNEF may be corrupted"))
644	(setq result (cons object result)))
645      (cons (nreverse result) string))))
646
647(defun mime-tnef-codepage (tnef)
648  (let ((elements (car tnef))
649	codepage)
650    (while elements
651      (if (eq (mime-tnef-element-name (car elements)) 'OEMCODEPAGE)
652	  (setq codepage (mime-tnef-4bytes
653			  (cdr tnef) (mime-tnef-element-start (car elements)))
654		elements nil)
655	(setq elements (cdr elements))))
656    (mime-tnef-debug "TNEF codepage is %d" codepage)
657    codepage))
658
659(defun mime-tnef-coding-system (tnef)
660  (intern (format "cp%d" (mime-tnef-codepage tnef))))
661
662(defun mime-tnef-decode-string (string tnef)
663  (let ((coding (mime-tnef-coding-system tnef)))
664    (decode-coding-string string
665			  (if (coding-system-p coding)
666			      coding
667			    (detect-coding-string string t)))))
668
669(defun mime-tnef-decode-unicode-string (string)
670  (decode-coding-string string (and mime-tnef-unicode-coding-system
671				    (detect-coding-string string t))))
672
673
674;;; MAPI
675
676(defun mime-tnef-mapi-parse (element tnef)
677  (catch :done
678    (let* ((raw (cdr tnef))
679	   (read (mime-tnef-element-start element))
680	   (count (mime-tnef-4bytes raw read))
681	   result)
682      (setq read (+ read 4))
683      (mime-tnef-debug "MAPI count is %d" count)
684      (dotimes (_i count)
685	(let ((type (mime-tnef-2bytes raw read))
686	      (name (mime-tnef-2bytes raw (+ read 2)))
687	      (multi 1))
688	  (setq read (+ read 4))
689	  (when (> (logand name 32768) 0) ;; #x8000
690	    (mime-tnef-debug "MAPI element have GUID")
691	    (let ((num (mime-tnef-4bytes raw (+ read 16))))
692	      (mime-tnef-debug "MAPI number of GUID names is %d" num)
693	      (if (zerop num)
694		  (setq name (mime-tnef-2bytes raw (+ read 20))
695			read (+ read 24))
696		(setq read (+ read 20))
697		(dotimes (_i num)
698		  (setq read (+ read 4
699				(mime-tnef-padded-length
700				 (mime-tnef-4bytes raw (+ read)))))))))
701	  (when (or (> (logand type 4096) 0) ;; #x1000
702		    (memq (cdr (assq type mime-tnef-mapi-types-table))
703			  '(STRING UNICODE_STRING OBJECT BINARY)))
704	    (mime-tnef-debug "MAPI element have multi-values")
705	    (setq multi (prog1 (mime-tnef-4bytes raw read)
706			  (setq read (+ read 4)))
707		  type (logand type 61439))) ;; #xefff
708	  (setq type (or (cdr (assq type mime-tnef-mapi-types-table)) type)
709		name (or (cdr (assq name mime-tnef-mapi-names-table)) name))
710	  (mime-tnef-debug
711	   "MAPI %s (type %s), number of values is %d"
712	   (if (integerp name) (format "%x" name) name) type multi)
713	  (let (values)
714	    (dotimes (_i multi)
715	      (cond
716	       ((memq type '(SHORT BOOLEAN))
717		(setq values (cons (mime-tnef-2bytes raw read) values)
718		      ;; Padding 2 bytes.
719		      read (+ read 4)))
720	       ((memq type '(INT FLOAT))
721		(setq values (cons (substring raw read (+ read 4)) values)
722		      read (+ read 4)))
723	       ((memq type '(SYSTIME DOUBLE APPTIME CURRENCY INT8BYTE))
724		(setq values (cons (cons read (+ read 8)) values)
725		      read (+ read 8)))
726	       ((eq type 'CLSID)
727		(setq values (cons (cons read (+ read 16)) values)
728		      read (+ read 16)))
729	       ((memq type '(STRING UNICODE_STRING OBJECT BINARY))
730		(let ((length (mime-tnef-4bytes raw read)))
731		  (unless (zerop length)
732		    (setq values
733			  (cons (cons
734				 (+ read 4)
735				 (+ read 4 length
736				    (or (cdr (assq type
737						   '((STRING . -1)
738						     (UNICODE_STRING . -2))))
739					0)))
740				values)))
741		  (setq read (+ read 4 (mime-tnef-padded-length length)))))
742	       (t
743		(message "TNEF may be corrupted!!")
744		(throw :done (nreverse result)))))
745	    (setq result
746		  (cons `((name . ,name) (type . ,type) (values . ,values))
747			result)))))
748      (nreverse result))))
749
750(defun mime-tnef-mapi-string (mapi-element tnef)
751  (let* ((value (cadr (assq 'values mapi-element)))
752	 (string (substring (cdr tnef) (car value) (cdr value))))
753    (if (eq (cdr (assq 'type mapi-element)) 'UNICODE_STRING)
754	(mime-tnef-decode-unicode-string string)
755      (mime-tnef-decode-string string tnef))))
756
757
758;;; files
759
760(defun mime-tnef-files (tnef)
761  (let ((elements (car tnef))
762	files file type)
763    (while elements
764      (setq type (mime-tnef-element-name (car elements)))
765      (cond
766       ((eq type 'ATTACHRENDDATA)
767	(when file
768	  (setq files (cons file files)
769		file nil)))
770       ((eq type 'ATTACHDATA)
771	(when (assq 'start file)
772	  (mime-tnef-debug "Multiple ATTACHDATA for single ATTACHRENDDATA"))
773	(setq file (append
774		    `(,(assq 'start (car elements))
775		      ,(assq 'end (car elements)))
776		    (delq (assq 'start file)
777			  (delq (assq 'end file) file)))))
778       ((eq type 'ATTACHTITLE)
779	(unless (assq 'name file)
780	  (let ((start (mime-tnef-element-start (car elements)))
781		(end (mime-tnef-element-end (car elements))))
782	    (setq file
783		  (cons `(name . ,(mime-tnef-decode-string
784				   (substring (cdr tnef) start end) tnef))
785			file)))))
786       ((eq type 'ATTACHMENT)
787	(let ((mapi (mime-tnef-mapi-parse (car elements) tnef)))
788	  (while mapi
789	    (let* ((elt (car mapi))
790		   (name (cdr (assq 'name elt))))
791	      (cond
792	       ((eq name 'ATTACH_LONG_FILENAME)
793		(setq file (append `((name . ,(mime-tnef-mapi-string elt tnef))
794				    (longname . t))
795				  (delq (assq 'longname file)
796					(delq (assq 'name file) file)))))
797	       ((eq name 'DISPLAY_NAME)
798		;; ATTACH_LONG_FILENAME is preferred.
799		(unless (assq 'longname file)
800		  (setq file (cons `(name . ,(mime-tnef-mapi-string elt tnef))
801				   (delq (assq 'name file) file)))))))
802	    (setq mapi (cdr mapi))))))
803      (setq elements (cdr elements)))
804    (delq nil (nreverse (cons file files)))))
805
806
807;;; MIME-view
808
809(defun mime-tnef-insert-file-parameters (params file data)
810  (let (charset
811	result)
812    (dolist (elt params)
813      (setq result
814	    (cons
815	     (cons
816	      (car elt)
817	      (if (eq (cdr elt) 'charset)
818		  (or charset
819		      (let ((codings (detect-coding-string data)))
820			(while (and (null charset) codings)
821			  (setq charset (coding-system-to-mime-charset
822					 (car codings)))
823			  (when charset
824			    (setq charset (symbol-name charset)))
825			  (setq codings (cdr codings)))
826			charset))
827		(cdr elt)))
828	     result)))
829    (mime-edit-insert-file-parameters (nreverse result) file)))
830
831(defun mime-tnef-insert-file (file data)
832  (let*  ((guess (mime-find-file-type file))
833	  (type (nth 0 guess))
834	  (subtype (nth 1 guess))
835	  (parameters (nth 2 guess))
836	  (encoding "8bit")
837	  (disposition-type (nth 4 guess))
838	  (disposition-params (nth 5 guess)))
839    (setq parameters
840	  (concat
841	   (when (consp parameters)
842	     (mime-tnef-insert-file-parameters parameters file data))
843	   (when disposition-type
844	     (concat "\n" "Content-Disposition: " disposition-type
845		     (mime-edit-insert-file-parameters
846		      disposition-params file)))))
847    (insert
848     ;; multibyte buffer is needed for non-ASCII filename.
849     (with-temp-buffer
850       (mime-edit-insert-tag type subtype parameters)
851       (mime-edit-define-encoding encoding)
852       (goto-char (point-min))
853       (mime-tnef-translate-single-part-tag)
854       (buffer-string)))
855    (insert data "\n")))
856
857(defun mime-tnef-translate-single-part-tag ()
858  (if (re-search-forward mime-edit-single-part-tag-regexp nil t)
859      (let* ((beg (match-beginning 0))
860	     (end (match-end 0))
861	     (tag (buffer-substring beg end)))
862	(delete-region beg end)
863	(let ((contype (mime-edit-get-contype tag))
864	      (encoding (mime-edit-get-encoding tag)))
865	  (save-restriction
866	    (narrow-to-region (point)(point))
867	    (insert "Content-Type: " contype "\n")
868	    (if encoding
869		(insert "Content-Transfer-Encoding: " encoding "\n"))
870	    (mime-encode-header-in-buffer))
871	  (cons (and contype
872		     (downcase contype))
873		(and encoding
874		     (downcase encoding)))))))
875
876(defvar mime-tnef-buffers nil)
877
878(defun mime-tnef-kill-buffers ()
879  (mapc (lambda (buffer)
880	  (when (bufferp buffer)
881	    (kill-buffer buffer)))
882	mime-tnef-buffers))
883
884(eval-when-compile (require 'mmgeneric))
885
886(defun mime-display-application/ms-tnef (entity _situation)
887  (let ((tnef (mime-tnef-parse (mime-entity-content entity)))
888	files p buffer tnef-entity)
889    (setq files (and (car tnef) (mime-tnef-files tnef)))
890    (if (null files)
891	(insert (if (car tnef)
892		    "No attachment.\n"
893		  "Data may be corrupted.\n"))
894      (goto-char (setq p (point-max)))
895      (save-restriction
896      	(narrow-to-region p p)
897      	(setq buffer (generate-new-buffer
898		      (concat mime-temp-buffer-name "TNEF*")))
899      	(with-current-buffer buffer
900	  (require 'mmbuffer)
901	  (set-buffer-multibyte nil)
902	  (let ((boundary (concat "TNEF-" (mime-edit-make-boundary))))
903	    (insert "Content-Type: multipart/mixed;\n"
904		    " boundary=\"" boundary "\"\n"
905		    "Content-Transfer-Encoding: 7bit\n\n")
906	    ;; (mime-encode-header-in-buffer)
907	    ;; (goto-char (point-max))
908	    (while files
909	      (narrow-to-region (point) (point))
910	      (insert "--" boundary "\n")
911	      (mime-tnef-insert-file (cdr (assq 'name (car files)))
912				     (substring
913				      (cdr tnef)
914				      (cdr (assq 'start (car files)))
915				      (cdr (assq 'end (car files)))))
916	      (goto-char (point-max))
917	      (setq files (cdr files)))
918	    (widen)
919	    (insert "--" boundary "--" "\n")
920	    (setq tnef-entity
921	 	  (mime-parse-message
922      	 	   (mm-expand-class-name 'buffer)
923      	 	   nil entity (mime-entity-node-id entity))
924      	 	  buffer-read-only t)))
925	(add-hook 'kill-buffer-hook 'mime-tnef-kill-buffers nil t)
926	(make-local-variable 'mime-tnef-buffers)
927	(add-to-list 'mime-tnef-buffers buffer)
928	(mime-display-entity
929	 tnef-entity nil '((header . invisible)
930			   (body . visible)
931			   (entity-button . invisible)))))))
932
933;;; @ end
934;;;
935
936(provide 'mime-tnef)
937
938;;; mime-tnef.el ends here
939