1 ;;; mew-decode.el --- MIME syntax decoder for Mew
3 ;; Author: Kazu Yamamoto <Kazu@Mew.org>
4 ;; Created: Oct 2, 1996
5 ;; Revised: Aug 31, 1999
9 (defconst mew-decode-version "mew-decode.el version 0.26")
13 (defvar mew-prog-mime-decode-switch
14 (list (cons mew-b64 '("-b"))
16 (cons mew-xg '("-g"))))
18 (defvar mew-prog-mime-decode-text-switch
19 (list (cons mew-b64 '("-b" "-t"))
21 (cons mew-xg '("-g" "-t"))))
23 (defvar mew-decode-multipart-encrypted-switch
24 '(("application/pgp-encrypted" mew-pgp-decrypt mew-pgp-ver mew-prog-pgp)))
26 (defvar mew-decode-multipart-signed-switch
27 '(("application/pgp-signature" mew-pgp-verify mew-pgp-ver mew-prog-pgp)))
29 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 (defmacro mew-decode-error (error-msg)
35 (` (progn (setq mew-decode-error (, error-msg)) (error ""))))
37 (defmacro mew-decode-narrow-to-header (&rest body)
39 (if (re-search-forward mew-eoh nil t)
41 (goto-char (point-max))
43 (if (and (integerp mew-header-max-length)
44 (> (count-lines (point-min) (point)) mew-header-max-length))
46 (substitute-command-keys
47 "Too long header. To see the message, type '\\<mew-summary-mode-map>\\[mew-summary-display-command]'")))
49 (narrow-to-region (point-min) (point))
50 (goto-char (point-min))
53 (defun mew-header-arrange (beg end)
55 (narrow-to-region beg end)
57 (let (ch-beg ch-end vs-beg vs-end contents cbeg)
58 (setq ch-beg (next-single-property-change (point-min) 'mew-noncontents))
61 (setq vs-beg (next-single-property-change (point-min) 'mew-visible))
63 (setq vs-end (next-single-property-change vs-beg 'mew-visible))
64 (if mew-field-other-visible
66 (setq vs-beg (next-single-property-change (point-min)
69 (setq vs-end (next-single-property-change vs-beg
72 (setq vs-end ch-beg)))
74 (setq vs-end ch-beg)))
75 (setq ch-end (point-max))
76 (if (null vs-end) (setq vs-end (point-max)))
77 (mew-decode-header-property-region ch-beg ch-end)
78 (setq contents (buffer-substring ch-beg ch-end))
79 (delete-region ch-beg ch-end)
80 (if (nth 1 (mew-assoc-match2 "Content-" mew-field-spec 0))
86 (put-text-property cbeg (point) 'mew-visible t)) ;; used later
91 (put-text-property cbeg (point) 'mew-visible nil)) ;; for XEmacs
92 (goto-char (point-max)))
93 (mew-decode-syntax-insert-privacy)
94 (goto-char (if (get-text-property (point-min) 'mew-visible)
96 (or (next-single-property-change (point-min) 'mew-visible)
99 (save-excursion (mew-highlight-x-face (point-min) (point-max))))))
100 (mew-header-goto-end)
102 (mew-header-set "\n") ;; analyzed
103 (mew-header-set nil))) ;; asis
105 (defun mew-decode-header-property-region (BEG END)
106 ;; see also mew-highlight-header
107 (if (and (or window-system mew-xemacs-p) mew-use-highlight-header)
109 (let ((defkey (intern-soft "mew-highlight-header-face-key"))
110 (defval (intern-soft "mew-highlight-header-face-marginal"))
111 key beg med N-spec key-face val-face)
113 (narrow-to-region BEG END)
114 (goto-char (point-min))
116 (if (not (looking-at mew-keyval))
118 (setq key (mew-match 1))
119 (setq beg (match-beginning 0))
120 (setq med (match-end 0))
122 (mew-header-goto-next)
123 (setq N-spec (mew-assoc-match3 key mew-field-spec 0))
124 (setq key-face (or (nth 3 N-spec) defkey))
125 (setq val-face (or (nth 4 N-spec) defval))
126 (put-text-property beg med 'face key-face)
127 (put-text-property med (point) 'face val-face))))))))
129 (defun mew-decode-rfc822-header (&optional no-property)
130 "A function to handle RFC822 header.
131 Called on the beginning of the header in the narrowed region.
132 - Decode and highlight RFC822 fields excluding MIME fields.
133 - Delete X-Mew: fields.
134 - Arrange decoded-RFC822-fields, mew-mv:, MIME fields in order.
135 The cursor moves between mew-mv: and MIME fields.
136 Return the existence MIME-Version: and the value of Subject:."
137 (setq no-property (or no-property
138 (not (and (or window-system mew-xemacs-p)
139 mew-use-highlight-header))))
140 (let* ((case-fold-search t)
141 (visibles (make-list (length mew-field-spec) nil))
142 (defkey (intern-soft "mew-highlight-header-face-key"))
143 (defval (intern-soft "mew-highlight-header-face-marginal"))
144 key beg med subj from contents others
145 key-face val-face N N-spec visiblep mimep)
146 (mew-decode-narrow-to-header
148 (if (not (looking-at mew-keyval))
150 (setq key (capitalize (mew-match 1)))
151 (setq beg (match-beginning 0))
152 (setq med (match-end 0))
154 (mew-header-goto-next)
155 (setq N-spec (mew-assoc-match3 key mew-field-spec 0))
156 (setq N (nth 0 N-spec))
157 (setq visiblep (nth 2 N-spec))
159 ((mew-case-equal key mew-x-mew:)
160 ;; deleting X-Mew: on the RFC822 header
161 (delete-region beg (point)))
162 ((string-match "^Content-" key)
163 ;; Due to PGP/MIME, properties are not put here.
164 (setq contents (cons (buffer-substring beg (point)) contents))
165 (delete-region beg (point)))
167 (mew-header-decode-region
168 (mew-field-type-for-decoding key) med (point))
170 ((mew-case-equal key mew-from:)
171 (setq from (mew-addrstr-parse-address
172 (buffer-substring med (1- (point))))))
173 ((mew-case-equal key mew-subj:)
174 (setq subj (buffer-substring med (1- (point)))))
175 ((mew-case-equal key mew-mv:)
177 (setq mimep (string-match
179 (mew-addrstr-parse-value
180 (buffer-substring med (point)))))))
183 (setq key-face (or (nth 3 N-spec) defkey))
184 (setq val-face (or (nth 4 N-spec) defval))
185 (put-text-property beg med 'face key-face)
186 (put-text-property med (point) 'face val-face))
188 ((null N-spec) ;; others
189 (setq others (cons (buffer-substring beg (point)) others))
190 (delete-region beg (point)))
192 (setcar (nthcdr N visibles)
193 (concat (nth N visibles)
194 (buffer-substring beg (point))))
195 (delete-region beg (point)))
198 (put-text-property (point-min) (point) 'mew-invisible t)
199 (put-text-property (point-min) (point) 'mew-noncontents t)
200 (if mew-field-other-visible
203 (mapcar (function insert) (nreverse others))
204 (put-text-property beg (point) 'mew-others t)
205 (put-text-property beg (point) 'mew-noncontents t))
207 (mapcar (function (lambda (x) (and (stringp x) (insert x)))) visibles)
208 ;; for recenter in Message mode
209 (put-text-property beg (point) 'mew-visible t)
210 (put-text-property beg (point) 'mew-noncontents t)
211 (if mew-field-other-visible
214 (mapcar (function insert) (nreverse others))
215 (put-text-property beg (point) 'mew-others t)
216 (put-text-property beg (point) 'mew-noncontents t)))
217 ;; the beginning of the content header
218 (save-excursion (mapcar (function insert) (nreverse contents)))
219 ;; 'mew-contents doesn't work due to PGP/MIME
220 (list mimep subj from)))
222 (defun mew-decode-mime-header (&optional dct)
223 "A function to handle content header.
224 Called on the beginning of the content header in the narrowed region
225 Return a part syntax after moving the beginning of the content body."
226 (let ((case-fold-search t)
227 (vec (make-vector (length mew-mime-fields) nil))
228 key med attr n act value syntax)
229 (mew-decode-narrow-to-header
231 (if (not (looking-at mew-keyval))
233 (setq key (capitalize (mew-match 1)))
234 (setq med (match-end 0))
236 (mew-header-goto-next)
237 (setq attr (assoc key mew-mime-fields))
240 (setq n (nth 1 attr))
241 (setq act (nth 2 attr))
244 (setq value (mew-param-decode
245 (buffer-substring med (1- (point))))))
247 (setq value (mew-addrstr-parse-value
248 (buffer-substring med (1- (point))))))
250 (if mew-decode-DECODE
251 (mew-header-decode-region 'text med (point) t))
252 ;; mew-header-decode-region goes to the max point in
253 ;; the narrowed region. So, this must be (point).
254 (setq value (buffer-substring med (1- (point))))))
255 (aset vec n value)))))
259 ;; the beginning of the content body
260 (setq syntax (vconcat (list 'single (point) nil nil) vec))
261 (or (mew-syntax-get-ct syntax)
262 (mew-syntax-set-ct syntax (or dct mew-type-txt)))
265 (defun mew-decode-mime-body (ctl cte &optional tocs)
266 ;; ((point), (point-max)) (not point-min)
267 ;; If tocs is t, don't decode fromcs, don't encode tocs, no post-conv
268 (let* ((ct (mew-syntax-get-value ctl 'cap))
269 (textp (string-match "^Text/" ct))
270 (linebasep (or textp (mew-ct-linebasep ct)))
271 (switch (if linebasep
272 mew-prog-mime-decode-text-switch
273 mew-prog-mime-decode-switch))
275 opt file charset post-conv fromcs)
276 (if (or (null cte) (mew-member-case-equal cte mew-decode-composite-value))
279 ((and (mew-case-equal cte mew-b64)
280 (fboundp 'base64-decode-region))
281 (base64-decode-region beg (point-max))
285 (while (search-forward "\r\n" nil t) (replace-match "\n")))))
286 ((mew-which mew-prog-mime-decode exec-path)
287 (setq opt (cdr (mew-assoc-case-equal cte switch 0)))
289 ;; Treated as Application/Octet-Stream.
290 ;; Never reach here when decoding.
291 (mew-decode-error (concat "Unknown CTE: " cte))
292 (setq file (mew-make-temp-name))
294 mew-cs-dummy mew-cs-text-for-write
295 ;; NEVER use call-process-region for privacy reasons
296 (write-region beg (point-max) file nil 'no-msg))
297 (delete-region beg (point-max))
299 mew-cs-binary mew-cs-dummy
300 ;; mew-prog-mime-decode converts CRLF to LF, so
301 ;; read input as binary.
302 (apply (function call-process) mew-prog-mime-decode
304 (if (file-exists-p file) (delete-file file))))
306 (mew-decode-error (concat mew-prog-mime-decode " doesn't exist")))))
307 ;; charset conversion
310 (setq charset (mew-syntax-get-param ctl "charset")))
312 (setq fromcs (mew-charset-to-cs charset))
313 (mew-cs-decode-region beg (point-max) fromcs)
316 (mew-cs-encode-region beg (point-max) tocs))
317 ((setq post-conv (mew-cs-post-conv fromcs))
319 (funcall post-conv beg (point-max)))))))
323 ;; Kick start function
326 (defvar mew-decode-LIMIT nil)
327 (defvar mew-decode-DECODE t)
329 (defun mew-decode (fld msg)
332 (goto-char (point-min))
333 (setq mew-decode-error nil)
334 (setq mew-decode-not-decrypted nil)
335 (mew-decode-syntax-clear)
336 (mew-insert-message fld msg mew-cs-text-for-read nil)
337 ;; afer reading the file
341 (setq mc-flag nil)) ;; for re-search-forward
342 ((fboundp 'set-buffer-multibyte)
343 (set-buffer-multibyte t))))
344 ;; Illegal messages may not have end-of-header.
345 ;; Truncated messages may not have end-of-header.
346 (if (re-search-forward mew-eoh nil t)
348 (setq mew-decode-error "No end-of-header(null line) in the top level")
349 (goto-char (point-max))
350 (if (not (bolp)) (insert "\n"))
352 (goto-char (point-min))
353 (setq mew-decode-LIMIT nil)
354 (setq mew-decode-DECODE t)
356 (let ((debug-on-error t))
357 (setq mew-decode-syntax
358 (mew-decode-message (mew-decode-syntax-rfc822-head) 0))
359 (mew-decode-syntax-set))
362 (setq mew-decode-syntax
364 ;; Call internalform with VIRTUAL content header
365 ;; CT: message/rfc822 (virtual)
367 ;; Header(RFC822 header + content header)
369 ;; Body(content body)
370 (mew-decode-syntax-rfc822-head) 0))
371 (mew-decode-syntax-set))
374 (mew-header-goto-body)
375 ;; min, point - 1, point, point-max
376 (setq mew-decode-syntax (mew-decode-syntax-rfc822))))))
380 ;; the function "m":: for message
383 (defun mew-decode-message (syntax cnt)
384 ;; Called on the beginning of the RFC822 header in the narrowed region
385 ;; hbeg is certainly the beginning of the VIRTUAL content body(i.e. min).
386 ;; hend will have to set to the end of PHYSICAL content header(i.e. end)
387 ;; after analyzing the physical content header and body since CD:'s
388 ;; length in the physical content header will change(no need to say
389 ;; about the end of the physical content header).
391 ;; Content-Type: Message/Rfc822 == virtual content header
393 ;;(min)Decoded RFC822 fields == virtual content body
395 ;;(cur)MIME fields == physical content header
397 ;; Content-Body == physical content body
399 (let* (msf mimep subj mew-inherit-from part)
400 (if (and mew-decode-LIMIT (>= cnt mew-decode-LIMIT))
401 ;; don't recurse anyway. don't decode the header
403 ;; even if mew-decode-DECODE is nil, we can and must
404 ;; decode the header here.
405 (setq msf (mew-decode-rfc822-header)) ;; on the physical
406 (setq mimep (nth 0 msf))
407 (setq subj (nth 1 msf))
408 (setq mew-inherit-from (nth 2 msf)))
410 ;; the beginning of the physical content header (cur)
414 (narrow-to-region (point) (point-max))
415 (setq part (mew-decode-singlepart cnt nil 'message))
416 ;; hend is always 1 char smaller than the beginning of
417 ;; the physical content body
418 (mew-syntax-set-key syntax 'message)
419 (mew-syntax-set-end syntax (1- (mew-syntax-get-begin part)))
420 (or (mew-syntax-get-cd syntax) (mew-syntax-set-cd syntax subj))
421 (mew-syntax-cat syntax part))) ;; return value
423 ;; the beginning of the meaningless physical content header
424 (if (re-search-forward mew-eoh nil t)
426 (mew-decode-error "No end-of-header(null line) in RFC822 message"))
427 ;; the beginning of the BODY(i.e. the physical content body)
428 (if mew-decode-DECODE
429 (mew-cs-decode-region (point) (point-max) mew-cs-rfc822-trans))
430 (mew-syntax-set-key syntax 'message)
431 (mew-syntax-set-end syntax (1- (point)))
432 (or (mew-syntax-get-cd syntax) (mew-syntax-set-cd syntax subj))
433 (mew-decode-syntax-rfc822 syntax)
434 ;; (point-min), (point) - 1, (point), (point-max)
438 ;; the function "S":: for singlepart
441 (defun mew-decode-singlepart (cnt &optional dct parent)
442 ;; Called on the beginning of the content header in the narrowed region
443 (let* ((case-fold-search t) (begin (point))
444 (syntax (mew-decode-mime-header dct))
445 (ctl (mew-syntax-get-ct syntax))
446 (ct (mew-syntax-get-value ctl 'cap))
447 (cte (or (mew-syntax-get-cte syntax) mew-7bit))
449 ;; the beginning of the content body
451 ((not (mew-member-case-equal cte mew-decode-value))
452 (mew-syntax-set-ct syntax mew-type-apo))
453 ((string-match "^Message/" ct)
454 (if (not (mew-member-case-equal cte mew-decode-composite-value))
455 (mew-syntax-set-ct syntax mew-type-apo)
457 ((mew-case-equal mew-ct-msg ct)
458 (if (equal parent 'message) (setq encap t))
460 (narrow-to-region (point) (point-max))
461 (setq syntax (mew-decode-message syntax cnt))))
462 ((mew-case-equal mew-ct-ext ct)
463 (let* ((at (mew-syntax-get-param ctl "access-type"))
464 (func (cdr (mew-assoc-case-equal at mew-ext-include-switch 0))))
465 (if (not (and func (fboundp func)))
468 (goto-char (point-max)) ;; phantom body
470 (delete-region begin (point))
471 (setq syntax (mew-decode-singlepart cnt)))))
472 ((mew-case-equal mew-ct-sts ct)
476 ;; xxx how about message/partinal?
477 (mew-syntax-set-ct syntax mew-type-apo)
479 ;; Multipart, decoding is not required
480 ((string-match "^Multipart/" ct)
481 (if (not (mew-member-case-equal cte mew-decode-composite-value))
482 (mew-syntax-set-ct syntax mew-type-apo)
484 ((mew-case-equal mew-ct-mld ct)
485 ;; semantics into digest
486 (setq syntax (mew-decode-multipart syntax cnt mew-type-msg)))
487 ((mew-case-equal mew-ct-mls ct)
488 (setq syntax (mew-decode-multipart-signed syntax cnt)))
489 ((mew-case-equal mew-ct-mle ct)
490 (if (boundp 'mew-inherit-prefetching) ;; xxx
492 (setq syntax (mew-decode-multipart-encrypted syntax cnt))))
494 (setq syntax (mew-decode-multipart syntax cnt nil))))))
497 (if (and (equal parent 'message) (not (mew-case-equal mew-ct-txt ct)))
499 ;; even if cte is nil, call mew-decode-mime-body for charset conversion
500 (if mew-decode-DECODE (mew-decode-mime-body ctl cte))))
501 ;; ct may be changed to apo
502 (if (not (mew-case-equal mew-ct-msg (car (mew-syntax-get-ct syntax))))
503 (mew-syntax-set-end syntax (point-max)))
505 ;; Mew allows text/plain and multipart/* for body.
506 ;; If other CT: is embedded under message, it should be
507 ;; encapsulated in multipart/mixed.
508 (let ((head mew-encode-syntax-multi-head))
509 ;; begin for multipart syntax is important because
510 ;; the begin will be used by the parent to set hend
511 (mew-syntax-set-begin head (mew-syntax-get-begin syntax))
512 (mew-syntax-set-end head (point-max))
513 (mew-syntax-cat head syntax)) ;; return value
514 syntax))) ;; return value
517 ;; the function "M":: for multipart
520 (defun mew-decode-multipart (syntax cnt &optional dct)
521 (let* ((case-fold-search nil) ;; boundary is case sensitive
522 (ctl (mew-syntax-get-ct syntax))
523 (ct (mew-syntax-get-value ctl 'cap))
524 (boundary (regexp-quote (mew-syntax-get-param ctl "boundary")))
526 obound ebound bregex start break)
528 (mew-decode-error "No boundary parameter for multipart"))
529 (mew-syntax-set-key syntax 'multi)
530 (setq obound (concat "--" boundary))
531 (setq ebound (concat "--" boundary "--"))
532 (setq bregex (concat "^--" boundary "\\(\\|--\\)$"))
533 (if (not (re-search-forward (concat "^" obound "$") nil t))
534 (mew-decode-error (format "No first boundary for %s" ct)))
536 (setq start (point)) ;; the beginning of the part
539 (if (not (re-search-forward bregex nil t))
540 (mew-decode-error (format "No last boundary for %s" ct)))
541 (setq break (string= (regexp-quote (mew-match 0)) ebound))
542 (forward-line) ;; the beginning of the next part
545 (beginning-of-line) ;; just in case
546 (forward-char -1) ;; skip the preceding CRLF
547 ;; the end of the part
549 (narrow-to-region start (point))
550 (goto-char (point-min))
551 ;; the beginning of the part
552 (setq part (mew-decode-singlepart cnt dct nil))
553 (setq parts (vconcat parts (vector part)))))
554 (setq start (point)) ;; the beginning of the part
556 (throw 'multipart (vconcat syntax parts)))))))
559 ;; the function "D":: for decryption
562 (defun mew-decode-multipart-encrypted (syntax cnt)
563 ;; called in narrowed region
565 ;; CT: M/E; proto; bound;
570 ;; (the encrypted part)
572 (let* ((case-fold-search nil) ;; boundary is case sensitive
573 (ctl (mew-syntax-get-ct syntax))
574 (boundary (regexp-quote (mew-syntax-get-param ctl "boundary")))
575 (switch mew-decode-multipart-encrypted-switch)
576 file1 file2 file3 syntax1 syntax3 func unknown existp proto
577 start result file3result privacy
580 (mew-decode-error "No boundary parameter for multipart"))
581 (setq oregex (concat "^--" boundary "$"))
582 (setq eregex (concat "^--" boundary "--$"))
584 (if (not (re-search-forward oregex nil t))
585 (mew-decode-error "No first boundary for Multipart/Encrypted"))
586 (forward-line) ;; the beginning of the key part
589 (if (not (re-search-forward oregex nil t))
590 (mew-decode-error "No second boundary for Multipart/Encrypted"))
592 (setq syntax1 (mew-decode-security-singlepart start (1- (point))))
593 (setq proto (car (mew-syntax-get-ct syntax1)))
594 (setq func (mew-decode-get-security-func proto switch))
595 (setq existp (mew-decode-get-security-existence proto switch))
598 (setq file1 (mew-save-decode-form syntax1)))
600 (forward-line) ;; the beginning of the encrypted part
603 (if (not (re-search-forward eregex nil t))
604 (mew-decode-error "No third boundary for Multipart/Encrypted"))
606 (if (and func existp)
607 (setq file2 (mew-save-decode-form
608 (mew-decode-security-singlepart start (1- (point))))))
610 (delete-region (point-min) (point-max))
612 ;; Call protocol function
615 (setq result (concat "unknown protocol " proto)))
617 (setq result (concat (mew-decode-get-security-prog proto switch)
620 (setq file3result (funcall func file1 file2))
621 (setq file3 (nth 0 file3result) result (nth 1 file3result))))
623 (if (and func existp (file-exists-p file3))
625 (insert-file-contents file3)
626 (put-text-property (point-min) (point-max) 'mew-noncontents nil)
627 ;; because of RICH functionality of RFC1847... Gee dirty!
628 (mew-decode-crlf-magic))
629 (insert "\n") ;; CT: text/plain; charset=us-ascii
630 (insert "Multipart/Encrypted could not be decrypted.\n")
631 (setq mew-decode-not-decrypted t))
632 ;; Throw away garbage
633 (and file1 (file-exists-p file1) (delete-file file1))
634 (and file2 (file-exists-p file2) (delete-file file2))
635 (and file3 (file-exists-p file3) (delete-file file3))
636 ;; Analyze the decrypted part
637 (goto-char (point-min))
638 (setq syntax3 (mew-decode-singlepart cnt nil nil))
639 (setq privacy (mew-syntax-get-privacy syntax3))
640 (if privacy (setq result (concat result "\n\t")))
641 (mew-syntax-set-privacy
642 syntax3 (cons (list mew-ct-mle proto result) privacy))
646 ;; the function "V":: for verification
649 (defun mew-decode-multipart-signed (syntax cnt)
650 ;; called in narrowed region
652 ;; CT: M/S; proto; bound; micalg;
659 (let* ((case-fold-search nil) ;; boundary is case sensitive
660 (ctl (mew-syntax-get-ct syntax))
661 (boundary (regexp-quote (mew-syntax-get-param ctl "boundary")))
662 (switch mew-decode-multipart-signed-switch)
663 file1 file2 syntax2 syntax3 func unknown existp proto
664 end1 start2 result privacy
667 (mew-decode-error "No boundary parameter for multipart"))
668 (setq oregex (concat "^--" boundary "$"))
669 (setq eregex (concat "^--" boundary "--$"))
671 (if (not (re-search-forward oregex nil t))
672 (mew-decode-error "No first boundary for Multipart/Signed"))
674 ;; the beginning of the signed part
675 (delete-region (point-min) (point)) ;; deleting content-header
676 (goto-char (point-min)) ;; just in case
678 (if (not (re-search-forward oregex nil t))
679 (mew-decode-error "No second boundary for Multipart/Signed"))
681 (setq end1 (1- (point))) ;; the end of the signed part
682 (forward-line) ;; the beginning of the key part
683 (setq start2 (point))
685 (if (not (re-search-forward eregex nil t))
686 (mew-decode-error "No third boundary for Multipart/Signed"))
687 (beginning-of-line) ;; the end of the encrypted part + 1
688 (setq syntax2 (mew-decode-security-singlepart start2 (1- (point))))
689 (setq proto (car (mew-syntax-get-ct syntax2)))
690 (setq func (mew-decode-get-security-func proto switch))
691 (setq existp (mew-decode-get-security-existence proto switch))
695 (setq file1 (mew-save-transfer-form (point-min) end1 'retain))
696 (setq file2 (mew-save-decode-form syntax2))))
699 (delete-region end1 (point-max))
700 ;; Now the signed part only
701 ;; Call protocl function
704 (setq result (concat "unknown protocol " proto)))
706 (setq result (concat (mew-decode-get-security-prog proto switch)
709 (setq result (funcall func file1 file2))))
710 ;; Throw away garbage
711 (and file1 (file-exists-p file1) (delete-file file1))
712 (and file2 (file-exists-p file2) (delete-file file2))
713 ;; Analyze the signed part
714 (goto-char (point-min))
715 (setq syntax3 (mew-decode-singlepart cnt nil nil))
716 (setq privacy (mew-syntax-get-privacy syntax3))
717 (if privacy (setq result (concat result "\n\t")))
718 (mew-syntax-set-privacy
719 syntax3 (cons (list mew-ct-mls proto result) privacy))
722 (defmacro mew-decode-get-security-func (proto switch)
723 (` (nth 1 (mew-assoc-case-equal (, proto) (, switch) 0))))
725 (defmacro mew-decode-get-security-existence (proto switch)
726 (` (symbol-value (nth 2 (mew-assoc-case-equal (, proto) (, switch) 0)))))
728 (defmacro mew-decode-get-security-prog (proto switch)
729 (` (symbol-value (nth 3 (mew-assoc-case-equal (, proto) (, switch) 0)))))
731 (defun mew-decode-security-singlepart (beg end)
734 (narrow-to-region beg end)
735 (goto-char (point-min))
736 (mew-decode-singlepart 0)))) ;; 0 is dummy
738 (defun mew-save-decode-form (syntax)
740 (let ((file (mew-make-temp-name)))
741 (write-region (mew-syntax-get-begin syntax)
742 (mew-syntax-get-end syntax)
746 (defun mew-decode-crlf-magic ()
747 (let ((case-fold-search t)
751 (goto-char (point-min))
753 (while (re-search-forward
754 "^\r?$\\|^Content-Transfer-Encoding:[ \t]*" nil t)
755 (setq key (mew-match 0))
756 (setq start (match-end 0))
757 (if (string-match "^\r?$" key)
760 (if (string-match mew-bin cte)
761 (narrow-to-region (point-min) (1+ start))
762 (narrow-to-region (point-min) (point-max)))
763 (goto-char (point-min))
764 (while (search-forward "\r\n" nil t)
765 (replace-match "\n" nil t)))
766 (throw 'header nil)))
768 (mew-header-goto-next)
769 (setq match (mew-buffer-substring start (1- (point))))
770 (setq cte (mew-addrstr-parse-value match)))))))
772 (provide 'mew-decode)
774 ;;; Copyright Notice:
776 ;; Copyright (C) 1996, 1997, 1998, 1999 Mew developing team.
777 ;; All rights reserved.
779 ;; Redistribution and use in source and binary forms, with or without
780 ;; modification, are permitted provided that the following conditions
783 ;; 1. Redistributions of source code must retain the above copyright
784 ;; notice, this list of conditions and the following disclaimer.
785 ;; 2. Redistributions in binary form must reproduce the above copyright
786 ;; notice, this list of conditions and the following disclaimer in the
787 ;; documentation and/or other materials provided with the distribution.
788 ;; 3. Neither the name of the team nor the names of its contributors
789 ;; may be used to endorse or promote products derived from this software
790 ;; without specific prior written permission.
792 ;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
793 ;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
794 ;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
795 ;; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
796 ;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
797 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
798 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
799 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
800 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
801 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
802 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
804 ;;; mew-decode.el ends here