mm-archive.el 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. ;;; mm-archive.el --- Functions for parsing archive files as MIME
  2. ;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
  3. ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is free software: you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; GNU Emacs is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;; Code:
  17. (require 'mm-decode)
  18. (autoload 'gnus-recursive-directory-files "gnus-util")
  19. (autoload 'mailcap-extension-to-mime "mailcap")
  20. (defvar mm-archive-decoders
  21. '(("application/ms-tnef" t "tnef" "-f" "-" "-C")
  22. ("application/zip" nil "unzip" "-j" "-x" "%f" "-d")
  23. ("application/x-gtar-compressed" nil "tar" "xzf" "-" "-C")
  24. ("application/x-tar" nil "tar" "xf" "-" "-C")))
  25. (defun mm-archive-decoders () mm-archive-decoders)
  26. (defun mm-dissect-archive (handle)
  27. (let ((decoder (cddr (assoc (car (mm-handle-type handle))
  28. mm-archive-decoders)))
  29. (dir (mm-make-temp-file
  30. (expand-file-name "emm." mm-tmp-directory) 'dir)))
  31. (set-file-modes dir #o700)
  32. (unwind-protect
  33. (progn
  34. (mm-with-unibyte-buffer
  35. (mm-insert-part handle)
  36. (if (member "%f" decoder)
  37. (let ((file (expand-file-name "mail.zip" dir)))
  38. (write-region (point-min) (point-max) file nil 'silent)
  39. (setq decoder (copy-sequence decoder))
  40. (setcar (member "%f" decoder) file)
  41. (apply 'call-process (car decoder) nil nil nil
  42. (append (cdr decoder) (list dir)))
  43. (delete-file file))
  44. (apply 'call-process-region (point-min) (point-max) (car decoder)
  45. nil (get-buffer-create "*tnef*")
  46. nil (append (cdr decoder) (list dir)))))
  47. `("multipart/mixed"
  48. ,handle
  49. ,@(mm-archive-list-files (gnus-recursive-directory-files dir))))
  50. (delete-directory dir t))))
  51. (defun mm-archive-list-files (files)
  52. (let ((handles nil)
  53. type disposition)
  54. (dolist (file files)
  55. (with-temp-buffer
  56. (when (string-match "\\.\\([^.]+\\)$" file)
  57. (setq type (mailcap-extension-to-mime (match-string 1 file))))
  58. (unless type
  59. (setq type "application/octet-stream"))
  60. (setq disposition
  61. (if (string-match "^image/\\|^text/" type)
  62. "inline"
  63. "attachment"))
  64. (insert (format "Content-type: %s\n" type))
  65. (insert "Content-Transfer-Encoding: 8bit\n\n")
  66. (insert-file-contents file)
  67. (push
  68. (mm-make-handle (mm-copy-to-buffer)
  69. (list type)
  70. '8bit nil
  71. `(,disposition (filename . ,file))
  72. nil nil nil)
  73. handles)))
  74. handles))
  75. (defun mm-archive-dissect-and-inline (handle)
  76. (let ((start (point-marker)))
  77. (save-restriction
  78. (narrow-to-region (point) (point))
  79. (dolist (handle (cddr (mm-dissect-archive handle)))
  80. (goto-char (point-max))
  81. (mm-display-inline handle))
  82. (goto-char (point-max))
  83. (mm-handle-set-undisplayer
  84. handle
  85. `(lambda ()
  86. (let ((inhibit-read-only t)
  87. (end ,(point-marker)))
  88. (remove-images ,start end)
  89. (delete-region ,start end)))))))
  90. (provide 'mm-archive)
  91. ;; mm-archive.el ends here