2 ;;; $Id: tm-tar.el,v 1.1 1995/09/18 17:09:19 H.Ueno Exp $
6 ;;; Internal viewer for
7 ;;; - application/x-tar
8 ;;; - application/x-gzip, type="tar"
9 ;;; - aplication/octet-stream, type="tar"
10 ;;; - aplication/octet-stream, type="tar+gzip"
12 ;;; by Hiroshi Ueno <zodiac@ibm.net>
15 ;;; @ required modules
24 (defconst tm-tar/list-buffer "*tm-tar/List*")
25 (defconst tm-tar/view-buffer "*tm-tar/View*")
26 (defconst tm-tar/file-search-regexp "[0-9]+\:[0-9\:]+[ ]+[0-9]+[ ]+")
31 (defvar tm-tar/tar-program "gtar")
32 (defvar tm-tar/tar-compress-arg '("-z"))
33 (defvar tm-tar/gzip-program "gzip")
34 (defvar tm-tar/mmencode-program "mmencode")
35 (defvar tm-tar/uudecode-program "uudecode")
37 (defvar mime/tm-tar-mode-map nil)
38 (if mime/tm-tar-mode-map
40 (setq mime/tm-tar-mode-map (make-keymap))
41 (suppress-keymap mime/tm-tar-mode-map)
42 (define-key mime/tm-tar-mode-map "\C-c" 'exit-recursive-edit)
43 (define-key mime/tm-tar-mode-map "q" 'exit-recursive-edit)
44 (define-key mime/tm-tar-mode-map "n" 'mime/tm-tar/next-line)
45 (define-key mime/tm-tar-mode-map " " 'mime/tm-tar/next-line)
46 (define-key mime/tm-tar-mode-map "\C-m" 'mime/tm-tar/next-line)
47 (define-key mime/tm-tar-mode-map "p" 'mime/tm-tar/previous-line)
48 (define-key mime/tm-tar-mode-map "\177" 'mime/tm-tar/previous-line)
49 (define-key mime/tm-tar-mode-map "\C-\M-m" 'mime/tm-tar/previous-line)
50 (define-key mime/tm-tar-mode-map "v" 'mime/tm-tar/view-file)
51 (define-key mime/tm-tar-mode-map "\C-h" 'Helper-help)
52 (define-key mime/tm-tar-mode-map "?" 'mime/tm-tar/helpful-message)
53 (cond ((string-match "XEmacs\\|Lucid" emacs-version)
54 (define-key mime/tm-tar-mode-map
55 'button2 'mime/tm-tar/view-file-mouse)
57 ((> emacs-major-version 18)
58 (define-key mime/tm-tar-mode-map
59 [mouse-2] 'mime/tm-tar/view-file-mouse)
63 ;;; @@ tm-tar mode functions
66 (defun mime/tm-tar-mode (&optional prev-buf)
67 "Major mode for listing the contents of a tar archive file."
69 (let ((buffer-read-only t)
71 (mode-line-buffer-identification '("%17b"))
73 (goto-char (point-min))
74 (mime/tm-tar/move-to-filename)
75 (catch 'mime/tm-tar-mode (mime/tm-tar-mode/command-loop))
78 (switch-to-buffer prev-buf)
82 (defun mime/tm-tar-mode/command-loop ()
83 (let ((old-local-map (current-local-map))
87 (use-local-map mime/tm-tar-mode-map)
88 (mime/tm-tar/helpful-message)
92 (use-local-map old-local-map)
96 (defun mime/tm-tar/next-line ()
99 (mime/tm-tar/move-to-filename)
102 (defun mime/tm-tar/previous-line ()
105 (mime/tm-tar/move-to-filename)
108 (defun mime/tm-tar/view-file ()
110 (let ((name (mime/tm-tar/get-filename))
113 (switch-to-buffer tm-tar/view-buffer)
114 (setq buffer-read-only nil)
116 (message "Reading a file from the archive. Please wait...")
117 (apply 'call-process tm-tar/tar-program
118 nil t nil (append tm-tar/view-args (list name)))
119 (goto-char (point-min))
121 (view-buffer tm-tar/view-buffer)
124 (defun mime/tm-tar/view-file-mouse (e)
127 (mime/tm-tar/view-file)
130 (defun mime/tm-tar/get-filename ()
137 (if (re-search-forward "^d" eol t)
138 (error "Cannot view a directory"))
140 (if (re-search-forward tm-tar/file-search-regexp eol t)
141 (progn (let ((beg (point))
143 (skip-chars-forward "^ \n")
144 (buffer-substring beg (point))
146 (error "No file on this line")
150 (defun mime/tm-tar/move-to-filename ()
151 (let ((eol (progn (end-of-line) (point)))
154 (re-search-forward tm-tar/file-search-regexp eol t)
157 (defun mime/tm-tar/set-properties ()
158 (if (> emacs-major-version 18)
159 (let ((beg (point-min))
164 (while (re-search-forward tm-tar/file-search-regexp end t)
165 (put-text-property (point)
169 'mouse-face 'highlight)
173 (defun mime/tm-tar/helpful-message ()
175 (message "Type %s, %s, %s, %s, %s, %s."
176 (substitute-command-keys "\\[Helper-help] for help")
177 (substitute-command-keys "\\[mime/tm-tar/helpful-message] for key")
178 (substitute-command-keys "\\[mime/tm-tar/next-line] to next")
179 (substitute-command-keys "\\[mime/tm-tar/previous-line] to prev")
180 (substitute-command-keys "\\[mime/tm-tar/view-file] to view")
181 (substitute-command-keys "\\[exit-recursive-edit] to quit")
184 ;;; @@ tar message decoder
187 (defun mime/decode-message/tar (beg end cal)
188 (let ((coding (cdr (assoc 'encoding cal)))
189 (cur-buf (current-buffer))
190 (tm-tar/tar-file-name (expand-file-name (concat (make-temp-name
191 (expand-file-name "tm" mime/tmp-dir)) ".tar")))
192 (tm-tar/tmp-file-name (expand-file-name (make-temp-name
193 (expand-file-name "tm" mime/tmp-dir))))
196 (find-file tm-tar/tmp-file-name)
197 (setq new-buf (current-buffer))
198 (setq buffer-read-only nil)
203 (re-search-forward "^$")
204 (append-to-buffer new-buf (+ (match-end 0) 1) end)
206 (if (member coding mime-viewer/uuencode-encoding-name-list)
208 (goto-char (point-min))
209 (if (re-search-forward "^begin [0-9]+ " nil t)
212 (insert tm-tar/tar-file-name)
215 (set-buffer-modified-p nil)
216 (kill-buffer new-buf)
217 (error "uuencode file signature was not found")
220 (kill-buffer new-buf)
221 (message "Listing the contents of archive. Please wait...")
222 (cond ((string-equal coding "base64")
223 (call-process tm-tar/mmencode-program nil nil nil "-u"
224 "-o" tm-tar/tar-file-name tm-tar/tmp-file-name)
226 ((string-equal coding "quoted-printable")
227 (call-process tm-tar/mmencode-program nil nil nil "-u" "-q"
228 "-o" tm-tar/tar-file-name tm-tar/tmp-file-name)
230 ((member coding mime-viewer/uuencode-encoding-name-list)
231 (call-process tm-tar/uudecode-program nil nil nil
232 tm-tar/tmp-file-name)
235 (copy-file tm-tar/tmp-file-name tm-tar/tar-file-name t)
237 (delete-file tm-tar/tmp-file-name)
238 (setq tm-tar/list-args (list "-tvf" tm-tar/tar-file-name))
239 (setq tm-tar/view-args (list "-xOf" tm-tar/tar-file-name))
240 (if (eq 0 (call-process tm-tar/gzip-program
241 nil nil nil "-t" tm-tar/tar-file-name))
243 (setq tm-tar/list-args
244 (append tm-tar/tar-compress-arg tm-tar/list-args))
245 (setq tm-tar/view-args
246 (append tm-tar/tar-compress-arg tm-tar/view-args))
248 (switch-to-buffer tm-tar/view-buffer)
249 (switch-to-buffer tm-tar/list-buffer)
250 (setq buffer-read-only nil)
252 (apply 'call-process tm-tar/tar-program
253 nil t nil tm-tar/list-args)
254 (mime/tm-tar/set-properties)
255 (mime/tm-tar-mode cur-buf)
256 (kill-buffer tm-tar/view-buffer)
257 (kill-buffer tm-tar/list-buffer)
258 (delete-file tm-tar/tar-file-name)
261 ;;; @@ program/buffer coding system
264 (cond ((boundp 'MULE)
265 (define-program-coding-system tm-tar/view-buffer nil *autoconv*)
268 (define-program-kanji-code tm-tar/view-buffer nil 1)
271 ;;; @@ message types to use tm-tar
274 (set-atype 'mime/content-decoding-condition
275 '((type . "application/octet-stream")
276 (method . mime/decode-message/tar)
277 (mode . "play") ("type" . "tar")
280 (set-atype 'mime/content-decoding-condition
281 '((type . "application/octet-stream")
282 (method . mime/decode-message/tar)
283 (mode . "play") ("type" . "tar+gzip")
286 (set-atype 'mime/content-decoding-condition
287 '((type . "application/x-gzip")
288 (method . mime/decode-message/tar)
289 (mode . "play") ("type" . "tar")
292 (set-atype 'mime/content-decoding-condition
293 '((type . "application/x-tar")
294 (method . mime/decode-message/tar)