- (mm-with-unibyte-buffer
- (insert-buffer-substring (mm-handle-buffer handle))
- (mm-decode-content-transfer-encoding
- (mm-handle-encoding handle) (car (mm-handle-type handle)))
- (if (functionp method)
- (let ((cur (current-buffer)))
- (if (eq method 'mailcap-save-binary-file)
- (set-buffer (generate-new-buffer "*mm*"))
- (let ((win (get-buffer-window cur t)))
- (when win
- (select-window win)))
- (switch-to-buffer (generate-new-buffer "*mm*")))
- (buffer-disable-undo)
- (mm-set-buffer-file-coding-system 'no-conversion)
- (insert-buffer-substring cur)
- (funcall method)
- (mm-handle-set-undisplayer handle (current-buffer)))
- (let* ((dir (make-temp-name (expand-file-name "emm." mm-tmp-directory)))
- (filename (mail-content-type-get
- (mm-handle-disposition handle) 'filename))
- (needsterm (assoc "needsterm"
- (mailcap-mime-info
- (car (mm-handle-type handle)) t)))
- process file)
- ;; We create a private sub-directory where we store our files.
- (make-directory dir)
- (set-file-modes dir 448)
- (if filename
- (setq file (expand-file-name (file-name-nondirectory filename)
- dir))
- (setq file (make-temp-name (expand-file-name "mm." dir))))
- (write-region (point-min) (point-max)
- file nil 'nomesg nil 'no-conversion)
- (setq process
- (if needsterm
- (start-process "*display*" nil
- "xterm"
- "-e" shell-file-name "-c"
- (format method
- (mm-quote-arg file)))
- (start-process "*display*" (generate-new-buffer "*mm*")
- shell-file-name
- "-c" (format method
- (mm-quote-arg file)))))
- (mm-handle-set-undisplayer handle (cons file process))
- (message "Displaying %s..." (format method file))))))
-
+ (let ((outbuf (current-buffer)))
+ (mm-with-unibyte-buffer
+ (if (functionp method)
+ (let ((cur (current-buffer)))
+ (if (eq method 'mailcap-save-binary-file)
+ (progn
+ (set-buffer (generate-new-buffer "*mm*"))
+ (setq method nil))
+ (mm-insert-part handle)
+ (let ((win (get-buffer-window cur t)))
+ (when win
+ (select-window win)))
+ (switch-to-buffer (generate-new-buffer "*mm*")))
+ (buffer-disable-undo)
+ (mm-set-buffer-file-coding-system mm-binary-coding-system)
+ (insert-buffer-substring cur)
+ (goto-char (point-min))
+ (message "Viewing with %s" method)
+ (let ((mm (current-buffer))
+ (non-viewer (assq 'non-viewer
+ (mailcap-mime-info
+ (mm-handle-media-type handle) t))))
+ (unwind-protect
+ (if method
+ (funcall method)
+ (mm-save-part handle))
+ (when (and (not non-viewer)
+ method)
+ (mm-handle-set-undisplayer handle mm)))))
+ ;; The function is a string to be executed.
+ (mm-insert-part handle)
+ (let* ((dir (make-temp-name (expand-file-name "emm." mm-tmp-directory)))
+ (filename (mail-content-type-get
+ (mm-handle-disposition handle) 'filename))
+ (mime-info (mailcap-mime-info
+ (mm-handle-media-type handle) t))
+ (needsterm (or (assoc "needsterm" mime-info)
+ (assoc "needsterminal" mime-info)))
+ (copiousoutput (assoc "copiousoutput" mime-info))
+ file buffer)
+ ;; We create a private sub-directory where we store our files.
+ (make-directory dir)
+ (set-file-modes dir 448)
+ (if filename
+ (setq file (expand-file-name (file-name-nondirectory filename)
+ dir))
+ (setq file (make-temp-name (expand-file-name "mm." dir))))
+ (let ((coding-system-for-write mm-binary-coding-system))
+ (write-region (point-min) (point-max) file nil 'nomesg))
+ (message "Viewing with %s" method)
+ (cond (needsterm
+ (unwind-protect
+ (start-process "*display*" nil
+ "xterm"
+ "-e" shell-file-name
+ shell-command-switch
+ (mm-mailcap-command
+ method file (mm-handle-type handle)))
+ (mm-handle-set-undisplayer handle (cons file buffer)))
+ (message "Displaying %s..." (format method file))
+ 'external)
+ (copiousoutput
+ (with-current-buffer outbuf
+ (forward-line 1)
+ (mm-insert-inline
+ handle
+ (unwind-protect
+ (progn
+ (call-process shell-file-name nil
+ (setq buffer
+ (generate-new-buffer "*mm*"))
+ nil
+ shell-command-switch
+ (mm-mailcap-command
+ method file (mm-handle-type handle)))
+ (if (buffer-live-p buffer)
+ (save-excursion
+ (set-buffer buffer)
+ (buffer-string))))
+ (progn
+ (ignore-errors (delete-file file))
+ (ignore-errors (delete-directory
+ (file-name-directory file)))
+ (ignore-errors (kill-buffer buffer))))))
+ 'inline)
+ (t
+ (unwind-protect
+ (start-process "*display*"
+ (setq buffer
+ (generate-new-buffer "*mm*"))
+ shell-file-name
+ shell-command-switch
+ (mm-mailcap-command
+ method file (mm-handle-type handle)))
+ (mm-handle-set-undisplayer handle (cons file buffer)))
+ (message "Displaying %s..." (format method file))
+ 'external)))))))
+
+(defun mm-mailcap-command (method file type-list)
+ (let ((ctl (cdr type-list))
+ (beg 0)
+ (uses-stdin t)
+ out sub total)
+ (while (string-match "%{\\([^}]+\\)}\\|%s\\|%t\\|%%" method beg)
+ (push (substring method beg (match-beginning 0)) out)
+ (setq beg (match-end 0)
+ total (match-string 0 method)
+ sub (match-string 1 method))
+ (cond
+ ((string= total "%%")
+ (push "%" out))
+ ((string= total "%s")
+ (setq uses-stdin nil)
+ (push (mm-quote-arg file) out))
+ ((string= total "%t")
+ (push (mm-quote-arg (car type-list)) out))
+ (t
+ (push (mm-quote-arg (or (cdr (assq (intern sub) ctl)) "")) out))))
+ (push (substring method beg (length method)) out)
+ (if uses-stdin
+ (progn
+ (push "<" out)
+ (push (mm-quote-arg file) out)))
+ (mapconcat 'identity (nreverse out) "")))
+