2 ;;; $Id: tm-body.el,v 0.14 1994/08/03 05:31:33 morioka Exp $
11 (defun replace-as-filename (str)
13 (i 0)(len (length str))
16 (setq chr (elt str i))
17 (if (or (and (<= ?+ chr)(<= chr ?.))
18 (and (<= ?0 chr)(<= chr ?:))
20 (and (<= ?@ chr)(<= chr ?\[))
21 (and (<= ?\] chr)(<= chr ?_))
22 (and (<= ?a chr)(<= chr ?{))
23 (and (<= ?} chr)(<= chr ?~))
25 (setq dest (concat dest
26 (char-to-string chr)))
32 (defconst mime/tspecials "\000-\040()<>@,;:\\\"/[\093?.=")
33 (defconst mime/token-regexp
34 (concat "[^" mime/tspecials "]*"))
35 (defconst mime/content-type-subtype-regexp
36 (concat mime/token-regexp "/" mime/token-regexp))
37 (defconst mime/content-parameter-value-regexp
39 message/quoted-string-regexp
42 (defconst mime/output-buffer-name "*MIME-out*")
43 (defconst mime/decoding-buffer-name "*MIME-decoding*")
45 (defvar mime/content-decoding-method-alist
46 '(("text/plain" . "tm-plain")
47 ("text/x-latex" . "tm-latex")
48 ("audio/basic" . "tm-au")
49 ("image/gif" . "tm-image")
50 ("image/jpeg" . "tm-image")
51 ("image/tiff" . "tm-image")
52 ("image/x-tiff" . "tm-image")
53 ("image/x-pic" . "tm-image")
54 ("video/mpeg" . "tm-mpeg")
55 ("application/octet-stream" . "tm-file")
57 ;;; (setq mime/content-decoding-method-alist
58 ;;; '(("audio/basic" . "tm-au")
59 ;;; ("image/gif" . "tm-image")
60 ;;; ("image/jpeg" . "tm-image")
61 ;;; ("image/x-pic" . "tm-image")
62 ;;; ("video/mpeg" . "tm-mpeg")
63 ;;; ("application/octet-stream" . "tm-file")
65 (defvar mime/use-internal-decoder nil)
66 ;;; (setq mime/use-internal-decoder t)
68 (defun mime/decode-body ()
70 (if (get-buffer mime/output-buffer-name)
71 (kill-buffer mime/output-buffer-name))
74 (goto-char (point-min))
75 (let ((ctype (mime/Content-Type "^$"))
76 (encoding (mime/Content-Transfer-Encoding "^$" "7bit"))
79 (cond ((equal (car ctype) "multipart/mixed")
80 (mime/decode-multipart/mixed ctype encoding)
82 ((equal (car ctype) "message/partial")
83 (mime/decode-message/partial ctype encoding)
86 (mime/decode-content nil (car ctype) encoding
87 (mime/get-name ctype))
91 (defun mime/decode-multipart/mixed (ctype default-encoding)
92 (let ((boundary (cdr (assoc "boundary" (cdr ctype))))
94 (if (eq (elt boundary 0) ?\")
96 (substring boundary 1 (- (length boundary) 1))
98 (setq boundary (concat "^--" (regexp-quote boundary) "\\(--\\)?$"))
99 (while (re-search-forward boundary nil t)
100 (goto-char (point-min))
101 (setq b (+ (match-end 0) 1))
103 (and (setq ctype (mime/Content-Type))
105 (mime/Content-Transfer-Encoding boundary
107 (mime/decode-content boundary
109 (mime/get-name ctype))
113 (defun mime/decode-message/partial (ctype default-encoding)
114 (let ((root-dir (concat "/tmp/m-prts-" (user-login-name)))
115 (id (cdr (assoc "id" (cdr ctype))))
116 (number (cdr (assoc "number" (cdr ctype))))
117 (total (cdr (assoc "total" (cdr ctype))))
119 (the-buf (current-buffer))
121 (if (not (file-exists-p root-dir))
122 (shell-command (concat "mkdir " root-dir))
124 (setq id (replace-as-filename id))
125 (setq root-dir (concat root-dir "/" id))
126 (if (not (file-exists-p root-dir))
127 (shell-command (concat "mkdir " root-dir))
129 (setq file (concat root-dir "/FULL"))
130 (if (not (file-exists-p file))
132 (setq file (concat root-dir "/CT"))
133 (if (not (file-exists-p file))
135 (if (get-buffer "*MIME-temp*")
136 (kill-buffer "*MIME-temp*")
138 (switch-to-buffer "*MIME-temp*")
139 (insert (concat total "\n"))
141 (switch-to-buffer the-buf)
143 (re-search-forward "^$")
144 (goto-char (+ (match-end 0) 1))
145 (setq file (concat root-dir "/" number))
146 (write-region (point)
149 (if (get-buffer "*MIME-temp*")
150 (kill-buffer "*MIME-temp*")
152 (switch-to-buffer "*MIME-temp*")
154 (max (string-to-int total))
158 (setq file (concat root-dir "/"
161 (if (not (file-exists-p file))
163 (insert-file-contents file)
164 (goto-char (point-max))
167 (write-file (concat root-dir "/FULL"))
171 (switch-to-buffer the-buf)
180 (defun mime/get-name (ctype)
182 (or (cdr (assoc "name" (cdr ctype)))
183 (cdr (assoc "x-name" (cdr ctype)))
184 (message/get-field-body "Content-Description")
187 (defun mime/narrow-to-content (boundary)
190 (narrow-to-region (point)
192 (re-search-forward boundary nil t)
195 (goto-char (point-min))
198 (defun mime/Content-Type (&optional boundary)
201 (mime/narrow-to-content boundary)
202 (if (and (re-search-forward "^Content-Type:[ \t]*" nil t)
206 (and (re-search-forward ".*\\(\n[ \t].*\\)*" nil t)
209 (goto-char (point-min))
210 (re-search-forward mime/content-type-subtype-regexp nil t)
214 (buffer-substring (match-beginning 0) (match-end 0))
216 dest attribute value)
217 (while (and (re-search-forward "[ \t\n]*;[ \t\n]*" nil t)
218 (re-search-forward mime/token-regexp nil t)
222 (buffer-substring (match-beginning 0) (match-end 0))
224 (if (and (re-search-forward "=[ \t\n]*" nil t)
225 (re-search-forward mime/content-parameter-value-regexp
230 (buffer-substring (match-beginning 0)
238 (defun mime/Content-Transfer-Encoding (&optional boundary default-encoding)
241 (mime/narrow-to-content boundary)
243 (if (and (re-search-forward "^Content-Transfer-Encoding:[ \t]*" nil t)
244 (re-search-forward mime/token-regexp nil t)
246 (downcase (buffer-substring (match-beginning 0) (match-end 0)))
251 (defun mime/base64-decode-region (beg end &optional buf filename)
252 (let ((the-buf (current-buffer)) ret)
254 (setq buf (get-buffer-create mime/decoding-buffer-name))
258 (switch-to-buffer buf)
260 (switch-to-buffer the-buf)
261 (narrow-to-region beg end)
262 (goto-char (point-min))
263 (while (re-search-forward
265 mime/Base64-encoded-text-regexp
267 (setq ret (mime/base64-decode-string
268 (buffer-substring (match-beginning 0)
271 (switch-to-buffer buf)
273 (switch-to-buffer the-buf)
277 (switch-to-buffer buf)
278 (let ((kanji-flag nil)
281 (if (featurep 'mule) *noconv*))
283 (write-file filename)
285 (switch-to-buffer the-buf)
289 (defun mime/decode-content (boundary ctype encoding name)
290 (let ((method (cdr (assoc ctype mime/content-decoding-method-alist))))
294 (re-search-forward "^$")
295 (goto-char (+ (match-end 0) 1))
296 (let ((file (make-temp-name "/tmp/TM"))
300 (and (re-search-forward boundary nil t)
304 (if (and (string= encoding "base64")
305 mime/use-internal-decoder)
307 (mime/base64-decode-region b e nil file)
308 (setq encoding "binary")
310 (write-region b e file)
312 (start-process method mime/output-buffer-name method file
316 (if mime/body-decoding-mode
317 mime/body-decoding-mode
319 (replace-as-filename name))
322 (defun mime/show-body-decoded-result ()
324 (if (get-buffer mime/output-buffer-name)
325 (set-window-buffer (get-largest-window)
326 mime/output-buffer-name)