mm-decode.el (mm-dissect-buffer): Guess content-type if the first token is missing...
[gnus] / lisp / mm-decode.el
index f1e11a0..4a9007a 100644 (file)
@@ -607,19 +607,19 @@ files left at the next time."
                    (split-string (buffer-string) "\n" t))))
         fails)
     (dolist (temp (append cache mm-temp-files-to-be-deleted))
-      (unless (and (file-exists-p temp)
-                  (if (file-directory-p temp)
-                      ;; A parent directory left at the previous time.
+      (when (and (file-exists-p temp)
+                (if (file-directory-p temp)
+                    ;; A parent directory left at the previous time.
+                    (progn
+                      (ignore-errors (delete-directory temp))
+                      (file-exists-p temp))
+                  ;; Delete a temporary file and its parent directory.
+                  (ignore-errors (delete-file temp))
+                  (or (file-exists-p temp)
                       (progn
+                        (setq temp (file-name-directory temp))
                         (ignore-errors (delete-directory temp))
-                        (not (file-exists-p temp)))
-                    ;; Delete a temporary file and its parent directory.
-                    (ignore-errors (delete-file temp))
-                    (and (not (file-exists-p temp))
-                         (progn
-                           (setq temp (file-name-directory temp))
-                           (ignore-errors (delete-directory temp))
-                           (not (file-exists-p temp))))))
+                        (file-exists-p temp)))))
        (push temp fails)))
     (if fails
        ;; Schedule the deletion of the files left at the next time.
@@ -672,12 +672,39 @@ MIME-Version header before proceeding."
                                 description)))))
       (if (or (not ctl)
              (not (string-match "/" (car ctl))))
-         (mm-dissect-singlepart
-          (list mm-dissect-default-type)
-          (and cte (intern (downcase (mail-header-strip cte))))
-          no-strict-mime
-          (and cd (mail-header-parse-content-disposition cd))
-          description)
+         (let ((cdl (and cd (mail-header-parse-content-disposition cd))))
+           (mm-dissect-singlepart
+            ;; Guess Content-Type from the file name extention.
+            ;; Some mailer sends a part without type like this:
+            ;;  Content-Type: ; name="IMG_3156.JPG"
+            ;;  Content-Disposition: attachment; filename="IMG_3156.JPG"
+            (list (or
+                   (let ((tem
+                          (or (mail-content-type-get cdl 'filename)
+                              (and ct
+                                   (with-temp-buffer
+                                     (insert ct)
+                                     (goto-char (point-min))
+                                     (and (re-search-forward "\
+;[\t\n ]*name=\\([\"']\\|\\([^\t\n\r ]+\\)\\)" nil t)
+                                          (or (match-string 2)
+                                              (progn
+                                                (goto-char (match-beginning 1))
+                                                (condition-case nil
+                                                    (progn
+                                                      (forward-sexp 1)
+                                                      (buffer-substring
+                                                       (1+ (match-beginning 1))
+                                                       (1- (point))))
+                                                  (error nil))))))))))
+                     (and tem
+                          (setq tem (file-name-extension tem))
+                          (require 'mailcap)
+                          (cdr (assoc (concat "." (downcase tem))
+                                      mailcap-mime-extensions))))
+                   mm-dissect-default-type))
+            (and cte (intern (downcase (mail-header-strip cte))))
+            no-strict-mime cdl description))
        (setq type (split-string (car ctl) "/"))
        (setq subtype (cadr type)
              type (car type))
@@ -954,10 +981,20 @@ external if displayed external."
                            method file (mm-handle-type handle))))
              (unwind-protect
                  (if window-system
-                     (start-process "*display*" nil
-                                    mm-external-terminal-program
-                                    "-e" shell-file-name
-                                    shell-command-switch command)
+                     (set-process-sentinel
+                      (start-process "*display*" nil
+                                     mm-external-terminal-program
+                                     "-e" shell-file-name
+                                     shell-command-switch command)
+                      `(lambda (process state)
+                         (if (eq 'exit (process-status process))
+                             (run-at-time
+                              60.0 nil
+                              (lambda ()
+                                (ignore-errors (delete-file ,file))
+                                (ignore-errors (delete-directory
+                                                ,(file-name-directory
+                                                  file))))))))
                    (require 'term)
                    (require 'gnus-win)
                    (set-buffer
@@ -971,11 +1008,15 @@ external if displayed external."
                    (set-process-sentinel
                     (get-buffer-process buffer)
                     `(lambda (process state)
-                       (if (eq 'exit (process-status process))
-                           (gnus-configure-windows
-                            ',gnus-current-window-configuration))))
+                       (when (eq 'exit (process-status process))
+                         (ignore-errors (delete-file ,file))
+                         (ignore-errors
+                           (delete-directory ,(file-name-directory file)))
+                         (gnus-configure-windows
+                          ',gnus-current-window-configuration))))
                    (gnus-configure-windows 'display-term))
-               (mm-handle-set-external-undisplayer handle (cons file buffer)))
+               (mm-handle-set-external-undisplayer handle (cons file buffer))
+               (add-to-list 'mm-temp-files-to-be-deleted file t))
              (message "Displaying %s..." command))
            'external)
           (copiousoutput
@@ -1023,6 +1064,12 @@ external if displayed external."
                                   (handle handle))
                       (lambda (process state)
                         (when (eq (process-status process) 'exit)
+                          (run-at-time
+                           60.0 nil
+                           (lambda ()
+                             (ignore-errors (delete-file file))
+                             (ignore-errors (delete-directory
+                                             (file-name-directory file)))))
                           (when (buffer-live-p outbuf)
                             (with-current-buffer outbuf
                               (let ((buffer-read-only nil)
@@ -1395,7 +1442,7 @@ Return t if meta tag is added or replaced."
        (goto-char (point-min))
        (if (re-search-forward "\
 <meta\\s-+http-equiv=[\"']?content-type[\"']?\\s-+content=[\"']\
-text/\\(\\sw+\\)\\(?:\;\\s-*charset=\\(.+\\)\\)?[\"'][^>]*>" nil t)
+text/\\(\\sw+\\)\\(?:\;\\s-*charset=\\([^\"'>]+\\)\\)?[^>]*>" nil t)
            (if (and (not force-charset)
                     (match-beginning 2)
                     (string-match "\\`html\\'" (match-string 1)))