[Mew-dist 1393] Re: Content-Disposition
gotoh at example.com
gotoh at example.com
1997年 7月 31日 (木) 10:28:23 JST
後藤@太陽計測です
# Mew 1.87 on Win32 で書いています。 いまのところ快適です
>>>>> From: Kazu Yamamoto (山本和彦) <Kazu at example.com>
kazu> Content-Disposition が Standards track にのるようです。サポートを考えな
kazu> くては。
Content-Disposition:のうち、すくなくともファイル名に関する部分は、
是非欲しいです。仕事でも私用でもファイル添付はよく使うため、
その都度ファイル名の扱いに困っていました。
特に相手が不慣れな人だったりすると、「ファイル名のない添付ファイル
なんておかしい!」と言い出したりします。
結局こちらで考慮しなければならず、手で Content-Disposition: を加えて
いました。
この機能は自分でも欲しかったので、以前mew-1.70のころいじって実装して
試していました。mewのalpha&betaの間はそのへんに手を出すのを控えていた
のですが、このたび、話題も出たことだし、現実逃避の一環としてmew-1.87
用に直してみました。参考までに添付させていただきます。
(mew-1.87のオリジナルからの差分)
このパッチは mew-syntax を追加するので悪影響もあるかと思い、自分だけ
でテスト運用していて、しばらくほったらかしていたもの+αです。
もし試してみる勇気がある人は、パッチを当てて、一度全ての.elcを消して
再makeしてください。defmacroな部分を変更しているので、部分コンパイル
はエラーの元になります。
...more...
このパッチは色々な部分に手を入れているのでわかりにくいと思いますです。
すみません。
パッチの内容(仕様)としては、以下の通りです。
1. Content-Disposition: として mew-cdp: を定義し、
syntaxの8番目の要素としてCDP:を使う。
2. マルチパートメール作成時、'c'(mew-attach-copy) によりファイルを
添付する際はその情報(オリジナルファイル名)をCDP:に保存し、
パートヘッダを作成時に使用する。
3. マルチパートメール作成時にパートのファイル名を指定できるように
'N'キーのアクション(mew-attach-filename)を定義し、ファイル名の
付加/削除が行える。(空文字列またはC-u N で削除)
4. メール閲覧ではMIME解析によってCDP:を保存し、summaryバッファにて
マルチパート展開した際に、CDP: filename= があれば、CD:の位置に
(File: fielname.ext)と表示する。ただし、CDがあればそれを優先して
表示する。
5. 'y' (mew-summary-save) によるセーブ時のファイル名候補として、
(1) CDP:のfilename=メンバ
(2) CT:のname=メンバ
(3) CD:そのもの
(4) 候補なし
という優先順位で決定し、プロンプトによってユーザ確認を行う。
6. ファイル名にパスが含まれている場合は、これを削除する。
7. ファイル名に漢字が含まれている場合はエンコードを行う。
ついでに、*.lzh, *.zipはapplication/octet-streamでBエンコード
を使用するように mew-mime-content-typeに追加してたりします。
(Winな世界ではよくつかわれるもので)
あと気になったのは、パートヘッダではfoldingは必要なのか否か、です。
現在のMewはとっても長い CD:を付けた場合、そのまんま折り返さずに付加
されていますね。 CDP: のファイル名は折り返すべきなのかなぁと悩み、
とりあえずCDP:のfilename=だけは折り返してます。
もし、元気のある方はお試しください。
--- Regards,
Shun-ichi Goto <gotoh at example.com>
R&D Group, TAIYO Corp., Tokyo, JAPAN
-------------- next part --------------
Only in mew-1.87: lp.el
diff -ru mew-1.87-orig/mew-attach.el mew-1.87/mew-attach.el
--- mew-1.87-orig/mew-attach.el Wed Jul 30 11:11:15 1997
+++ mew-1.87/mew-attach.el Wed Jul 30 14:51:30 1997
@@ -41,6 +41,7 @@
(define-key mew-draft-attach-map "F" 'mew-attach-find-new-file)
(define-key mew-draft-attach-map "l" 'mew-attach-link)
(define-key mew-draft-attach-map "m" 'mew-attach-multipart)
+ (define-key mew-draft-attach-map "N" 'mew-attach-filename)
(define-key mew-draft-attach-map "T" 'mew-attach-type)
(define-key mew-draft-attach-map "G" 'mew-attach-gzip64)
(define-key mew-draft-attach-map "B" 'mew-attach-base64)
@@ -378,6 +379,29 @@
(mew-encode-syntax-print mew-encode-syntax))
)))
+(defun mew-attach-filename (&optional arg)
+ "Assign filename with-in Content-Disposition:"
+ (interactive "P")
+ (if (not (mew-attach-not-line0-1-dot))
+ (message "Can't assign filename here")
+ (let* ((nums (mew-attach-nums))
+ (syntax (mew-syntax-get-entry mew-encode-syntax nums))
+ (cdp (mew-syntax-get-cdp syntax))
+ (fn nil)
+ (case-fold-search t))
+ (if arg
+ ()
+ (setq fn (or (mew-syntax-get-cdp-filename cdp)
+ (mew-syntax-get-file syntax)
+ ""))
+ (setq fn (read-string "Filename: " fn)))
+ (if (or (null fn) (equal fn ""))
+ (mew-syntax-set-cdp syntax nil)
+ (mew-syntax-set-cdp syntax
+ (list (car cdp) (format "filename=\"%s\"" fn))))
+ (mew-encode-syntax-print mew-encode-syntax)
+ )))
+
(defun mew-attach-link (&optional from to)
"Link a file with a symbolic link on \".\" in attachments."
(interactive)
@@ -423,7 +447,8 @@
(tofile (or to
(mew-input-string "Copy to %s(%s): " subdir
(file-name-nondirectory fromfile))))
- (efile nil))
+ (efile nil)
+ single)
(setq efile (if (equal subdir "") tofile (concat subdir tofile)))
(if (and (file-exists-p (expand-file-name efile mimedir))
(not (mew-y-or-n-p "%s exists. Overwrite it? " efile)))
@@ -435,11 +460,16 @@
(write-region (point-min) (point-max)
(expand-file-name efile mimedir))
))
+ (setq single (mew-encode-syntax-single tofile))
+ (mew-syntax-set-cdp single
+ (list nil
+ (concat "filename="
+ (mew-quote (file-name-nondirectory fromfile)))))
(setq mew-encode-syntax
(mew-syntax-insert-entry
mew-encode-syntax
nums
- (mew-encode-syntax-single tofile)))
+ single))
(mew-encode-syntax-print mew-encode-syntax)
))
))
diff -ru mew-1.87-orig/mew-decode.el mew-1.87/mew-decode.el
--- mew-1.87-orig/mew-decode.el Wed Jul 30 11:11:15 1997
+++ mew-1.87/mew-decode.el Wed Jul 30 04:17:52 1997
@@ -220,7 +220,8 @@
(setq value (mew-buffer-substring val (point)))
(cond
((equal attr 'analyze)
- (setq value (mew-header-syntax-list value))) ;; list
+ (setq value (mew-header-syntax-list
+ (mew-header-decode value t)))) ;; list
((equal attr 'extract)
(setq value (mew-header-syntax value)))
((equal attr 'decode)
diff -ru mew-1.87-orig/mew-encode.el mew-1.87/mew-encode.el
--- mew-1.87-orig/mew-encode.el Wed Jul 30 11:11:16 1997
+++ mew-1.87/mew-encode.el Wed Jul 30 13:37:48 1997
@@ -51,6 +51,10 @@
("application/moss-signature" . mew-moss-sign))
)
+(defvar mew-default-cdp-type-alist
+ (list (cons "^Text/" 'inline)
+ (cons "^Message/" 'inline)
+ ))
;;;
;;;
;;;
@@ -156,6 +160,20 @@
(list file charset cte encopts)
)))
+(defun mew-encode-guess-cdp-type (ct)
+ "Guess CDP: type with CT: and mew-default-cdp-type"
+ (let ((alist mew-default-cdp-type-alist))
+ (setq type (catch 'loop
+ (while alist
+ (if (string-match (car (car alist)) ct)
+ (throw 'loop (cdr (car alist))))
+ (setq alist (cdr alist)))
+ 'attachment))
+ (cond ((eq type 'inline) "inline")
+ ((eq type 'attachment) "attachment")
+ (t "attachment"))
+ ))
+
(defun mew-encode-singlepart (syntax &optional path depth buffered)
;; path is nil if called make-single or security multipart
;; buffered is t if called make-single
@@ -165,6 +183,7 @@
(params (cdr ctl))
(cte (mew-syntax-get-cte syntax))
(cd (mew-syntax-get-cd syntax))
+ (cdp (mew-syntax-get-cdp syntax))
(privacy (mew-syntax-get-privacy syntax))
(beg (point))
(text-sw mew-prog-mime-encode-text-switch)
@@ -201,6 +220,28 @@
(mew-header-insert-here mew-cte: cte) ;; cte is never nil here
;; Insert cd.
(if cd (mew-header-insert-here mew-cd: (mew-header-encode cd "B")))
+ ;; Insert cdp.
+ (if (null cdp)
+ ()
+ (let ((fn (mew-quote (mew-syntax-get-cdp-filename cdp)))
+ (fn2 nil)
+ (prefix " filename=")
+ len line)
+ (mew-header-insert-here mew-cdp: (or (car cdp)
+ (mew-encode-guess-cdp-type ct)) 'noret)
+ (if fn (insert "; \n"))
+ ;; make folded filename
+ (while fn
+ (setq line (concat prefix (mew-header-encode fn "B")))
+ (if (< 74 (length line))
+ (setq len (string-match ".$" fn)
+ fn2 (concat (substring fn len) fn2)
+ fn (substring fn 0 len))
+ (insert (concat line "\n"))
+ (setq prefix " "
+ fn fn2
+ fn2 nil)))
+ ))
;; Terminate content-header.
(insert "\n")
;; header "\n" (cur) [text]
diff -ru mew-1.87-orig/mew-func.el mew-1.87/mew-func.el
--- mew-1.87-orig/mew-func.el Wed Jul 30 11:11:17 1997
+++ mew-1.87/mew-func.el Wed Jul 30 03:08:58 1997
@@ -398,4 +398,12 @@
(erase-buffer)
)
+(defun mew-quote (str)
+ (concat "\"" str "\""))
+
+(defun mew-unquote (str)
+ (if (string-match "^\"\\(.*\\)\"$" str)
+ (mew-match 1 str)
+ str))
+
(provide 'mew-func)
diff -ru mew-1.87-orig/mew-mime.el mew-1.87/mew-mime.el
--- mew-1.87-orig/mew-mime.el Wed Jul 30 11:11:18 1997
+++ mew-1.87/mew-mime.el Wed Jul 30 12:46:46 1997
@@ -51,8 +51,7 @@
"Candidate of Content-Type: when CT: is changed in draft buffer."
)
-(defvar
- mew-mime-content-type
+(defvar mew-mime-content-type
(list
(list
"multipart/*"
@@ -159,6 +158,22 @@
(list
"application/octet-stream"
"\\.Z$"
+ "base64"
+ '(mew-mime-application/octet-stream () nil)
+ (if (boundp 'mew-icon-application/octet-stream)
+ mew-icon-application/octet-stream)
+ )
+ (list
+ "application/octet-stream"
+ "\\.[Zz][Ii][Pp]$"
+ "base64"
+ '(mew-mime-application/octet-stream () nil)
+ (if (boundp 'mew-icon-application/octet-stream)
+ mew-icon-application/octet-stream)
+ )
+ (list
+ "application/octet-stream"
+ "\\.[Ll][Zz][Hh]$"
"base64"
'(mew-mime-application/octet-stream () nil)
(if (boundp 'mew-icon-application/octet-stream)
diff -ru mew-1.87-orig/mew-summary.el mew-1.87/mew-summary.el
--- mew-1.87-orig/mew-summary.el Wed Jul 30 11:11:20 1997
+++ mew-1.87/mew-summary.el Wed Jul 30 13:35:58 1997
@@ -1649,7 +1649,30 @@
file)
(if (not (or msg part))
(message "No message or part here")
- (setq file (mew-input-file-name))
+ ;; (setq file (mew-input-file-name))
+ (let* ((ent (mew-syntax-get-entry-strnum
+ (mew-cache-decode-syntax
+ (mew-current-get 'cache)) part))
+ (ct (mew-syntax-get-ct ent))
+ (cd (mew-syntax-get-cd ent))
+ (cdp (mew-syntax-get-cdp ent))
+ (fn nil))
+ ;; get filename from CDP: filename=
+ ;; or get filename from CT: name=
+ ;; or treat CD: as filename
+ ;; or no-name
+ (or (and cdp
+ (setq fn (mew-syntax-get-cdp-filename cdp))
+ (setq fn (mew-header-decode fn t)))
+ (and (setq fn (mew-syntax-get-ct-filename ct))
+ (setq fn (mew-header-decode fn t)))
+ (and cd
+ (setq fn (mew-header-decode cd))
+ (string-match "^\"\\(.*\\)\"$" fn)
+ (setq fn (mew-match 1 fn)))
+ (setq fn "")
+ )
+ (setq file (mew-input-file-name nil (file-name-nondirectory fn))))
(if (not (file-exists-p file))
(setq doit t)
(if (null mew-file-append-p)
diff -ru mew-1.87-orig/mew-syntax.el mew-1.87/mew-syntax.el
--- mew-1.87-orig/mew-syntax.el Wed Jul 30 11:11:20 1997
+++ mew-1.87/mew-syntax.el Wed Jul 30 13:33:22 1997
@@ -18,16 +18,16 @@
;;
;; mew-encode-syntax
;;
-;; <single> = [ 'single file (dcr) (<pri>) (CT:) CTE: CD: nil ]
-;; <multi> = [ 'multi dir/ (dcr) (<pri>) ("mul") CTE: CD: nil 1*<part> ]
+;; <single> = [ 'single file (dcr) (<pri>) (CT:) CTE: CD: nil nil ]
+;; <multi> = [ 'multi dir/ (dcr) (<pri>) ("mul") CTE: CD: nil nil 1*<part> ]
;; <part> = <single> | <multi>
;; <pri> = ("Multipart/Encrypted" "application/pgp-signature")
;;
;; mew-decode-syntax
;;
-;; <message> = [ 'message hbeg hend (<pri>) ("msg") CTE: CD: CI: <part> ]
-;; <single> = [ 'single beg end (<pri>) (CT:) CTE: CD: CI: ]
-;; <multi> = [ 'multi beg end (<pri>) ("mul") CTE: CD: CI: 1*<part> ]
+;; <message> = [ 'message hbeg hend (<pri>) ("msg") CTE: CD: CI: CDP: <part> ]
+;; <single> = [ 'single beg end (<pri>) (CT:) CTE: CD: CI: CDP: ]
+;; <multi> = [ 'multi beg end (<pri>) ("mul") CTE: CD: CI: CDP: 1*<part> ]
;; <part> = <message> | <single> | <multi>
;; <pri> = results of decryption and/or verification
@@ -37,6 +37,7 @@
(defconst mew-cte: "Content-Transfer-Encoding:")
(defconst mew-cd: "Content-Description:")
(defconst mew-cid: "Content-ID:")
+(defconst mew-cdp: "Content-Disposition:")
(defconst mew-mime-fields
(list (cons mew-ct: 'analyze)
@@ -43,6 +44,7 @@
(cons mew-cte: 'extract)
(cons mew-cd: 'decode)
(cons mew-cid: nil)
+ (cons mew-cdp: 'analyze)
))
;; See also mew-rfc822-fields
@@ -116,12 +118,18 @@
(defmacro mew-syntax-set-ci (syntax ci)
(` (aset (, syntax) 7 (, ci))))
-(defmacro mew-syntax-get-part (syntax)
+(defmacro mew-syntax-get-cdp (syntax)
(` (aref (, syntax) 8)))
-(defmacro mew-syntax-set-part (syntax part)
+(defmacro mew-syntax-set-cdp (syntax part)
(` (aset (, syntax) 8 (, part))))
+(defmacro mew-syntax-get-part (syntax)
+ (` (aref (, syntax) 9)))
+
+(defmacro mew-syntax-set-part (syntax part)
+ (` (aset (, syntax) 9 (, part))))
+
;; alias for draft syntax
(defmacro mew-syntax-get-file (syntax)
@@ -143,7 +151,8 @@
(regex (concat "^" member "=\"?\\([^\"]*\\)\"?$"))) ;; xxx
(catch 'loop
(while ctl
- (if (string-match regex (car ctl))
+ (if (and (stringp (car ctl))
+ (string-match regex (car ctl)))
(throw 'loop (mew-match 1 (car ctl))))
(setq ctl (cdr ctl))
)
@@ -150,6 +159,17 @@
)
))
+(defun mew-syntax-get-cdp-filename (cdp)
+ (if (and cdp (listp cdp))
+ (mew-syntax-get-member cdp "filename")
+ nil))
+
+(defun mew-syntax-get-ct-filename (ct)
+ (if (and ct (listp ct))
+ (mew-syntax-get-member ct "name")
+ nil))
+
+
;; need to setq
(defmacro mew-syntax-cat (syntax part)
(` (vconcat (, syntax) (vector (, part)))))
@@ -293,13 +313,13 @@
(ct (mew-file-content attr)))
(or cte (setq cte (mew-file-encoding attr)))
(if (null ctl) (setq ctl (list ct)))
- (vconcat [single] (list file decrypters privacy ctl cte cd) [nil])
+ (vconcat [single] (list file decrypters privacy ctl cte cd) [nil nil])
))
(defun mew-encode-syntax-multi (dir ct)
(if (not (string-match (concat mew-path-separator "$") dir))
(setq dir (concat dir mew-path-separator)))
- (vconcat [multi] (list dir) [nil nil] (list ct) [nil nil nil])
+ (vconcat [multi] (list dir) [nil nil] (list ct) [nil nil nil nil])
)
(defun mew-encode-syntax-initial (dir)
@@ -380,7 +400,7 @@
(int-to-string num) nlevel)
(setq cnt (1+ cnt))
(setq num (1+ num)))
- (insert (mew-encode-syntax-format [nil "." nil nil ("") nil nil nil]
+ (insert (mew-encode-syntax-format [nil "." nil nil ("") nil nil nil nil]
(int-to-string num) nlevel)))
(t
(while (< cnt len)
@@ -391,7 +411,7 @@
(setq cnt (1+ cnt))
(setq num (1+ num)))
(insert (mew-encode-syntax-format
- [nil "." nil nil ("") nil nil nil]
+ [nil "." nil nil ("") nil nil nil nil]
(concat number "." (int-to-string num))
nlevel)))
)
@@ -415,6 +435,7 @@
(char (mew-syntax-get-member ctl "charset"))
(cte (mew-syntax-get-cte syntax))
(cd (mew-syntax-get-cd syntax))
+ (cdp (mew-syntax-get-cdp syntax))
(decrypters (mew-syntax-get-decrypters syntax))
(privacy (mew-syntax-get-privacy syntax)) ctm ctp
(space " ") (space-char 32)
@@ -431,29 +452,30 @@
(setq ct (concat ct "(" char ")"))
(setq ct (concat ct "(guess)"))))
- (if (null privacy)
- (if (null cte)
- (setq marks " ")
+ (if privacy
+ (while privacy
+ (setq ctm (nth 0 (car privacy)))
+ (setq ctp (nth 1 (car privacy)))
+ (setq privacy (cdr privacy))
+ (cond
+ ((string-match "pgp" ctp) (setq marks (concat marks "P")))
+ ((string-match "moss" ctp) (setq marks (concat marks "M")))
+ )
+ (cond
+ ((string-match mew-ct-mle ctm) (setq marks (concat marks "E")))
+ ((string-match mew-ct-mls ctm) (setq marks (concat marks "S")))
+ )
+ )
+ (if cte
(cond
- ((equal cte mew-b64) (setq marks "B "))
- ((equal cte mew-qp) (setq marks "Q "))
- ((equal cte mew-xg) (setq marks "G "))
+ ((equal cte mew-b64) (setq marks "B"))
+ ((equal cte mew-qp) (setq marks "Q"))
+ ((equal cte mew-xg) (setq marks "G"))
))
- (while privacy
- (setq ctm (nth 0 (car privacy)))
- (setq ctp (nth 1 (car privacy)))
- (setq privacy (cdr privacy))
- (cond
- ((string-match "pgp" ctp) (setq marks (concat marks "P")))
- ((string-match "moss" ctp) (setq marks (concat marks "M")))
- )
- (cond
- ((string-match mew-ct-mle ctm) (setq marks (concat marks "E")))
- ((string-match mew-ct-mls ctm) (setq marks (concat marks "S")))
- )
- )
- (setq marks (concat marks " "))
+ (if (mew-syntax-get-cdp-filename cdp)
+ (setq marks (concat marks "N")))
)
+ (setq marks (concat marks " "))
(setq marks (substring marks 0 lm))
(concat
@@ -571,13 +593,13 @@
(defun mew-decode-syntax-rfc822-head ()
;; hend may be 0 since (point-min) is 1
- (vector 'message (point-min) (1- (point)) nil mew-type-msg nil nil nil))
+ (vector 'message (point-min) (1- (point)) nil mew-type-msg nil nil nil nil))
(defun mew-decode-syntax-text ()
- (vector 'single (point) (point-max) nil mew-type-txt nil nil nil))
+ (vector 'single (point) (point-max) nil mew-type-txt nil nil nil nil))
(defconst mew-encode-syntax-multi-head
- (vector 'multi nil nil nil mew-type-mlm nil nil nil))
+ (vector 'multi nil nil nil mew-type-mlm nil nil nil nil))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
@@ -633,10 +655,13 @@
))
(defun mew-decode-syntax-print-loop (syntax pref)
- (let ((po (point))
- (ct (capitalize (car (mew-syntax-get-ct syntax))))
- (cd (or (mew-syntax-get-cd syntax) ""))
- (privacy (mew-syntax-get-privacy syntax)))
+ (let* ((po (point))
+ (ct (capitalize (car (mew-syntax-get-ct syntax))))
+ (desc (mew-syntax-get-cd syntax))
+ (ctfn (mew-syntax-get-ct-filename (mew-syntax-get-ct syntax)))
+ (cdpfn (mew-syntax-get-cdp-filename (mew-syntax-get-cdp syntax)))
+ (privacy (mew-syntax-get-privacy syntax))
+ (fn (or cdpfn ctfn)))
(if privacy
(setq mew-decode-result
(concat mew-decode-result
@@ -645,9 +670,13 @@
(mew-match 0 pref)))
privacy
"\n")))
+ (setq desc (or desc
+ (and fn (format "(File: \"%s\")"
+ (mew-header-decode fn t)))
+ ""))
(cond
((mew-syntax-message-p syntax)
- (insert (format "%s\t%s\t%s\n" pref ct cd))
+ (insert (format "%s\t%s\t%s\n" pref ct desc))
(mew-summary-highlight-lines-region po (point) t)
(if (mew-syntax-multipart-p (mew-syntax-get-part syntax))
(mew-decode-syntax-print-loop
@@ -654,7 +683,7 @@
(mew-syntax-get-part syntax)
(concat "\t" pref))))
((mew-syntax-singlepart-p syntax)
- (insert (format "%s\t%s\t%s\n" pref ct cd))
+ (insert (format "%s\t%s\t%s\n" pref ct desc))
(mew-summary-highlight-lines-region po (point) t))
((mew-syntax-multipart-p syntax)
(let ((cnt mew-syntax-magic)
-------------- next part --------------
ちなみに summary-modeでの表示はこんな感じになります。
----------------------------------------------------------------------------------
106 M06/25 <@gotoh at example.com Test for attach 2n This is test 2nd UEsDBBQAAAAIAMSrpCK
107 M06/25 <@gotoh at example.com Test for sending m Win95でMewの使うにあたって、以前少し
108 06/25 gotoh at example.com From: のテスト テストです Shun-ichi Goto <gotoh at example.com
109 M06/26 gotoh at example.com new mewencode test 山口さんのパッチを当てた mewencode.e
1 Text/Plain
2 Application/Octet-Stream (File: "33b24536.bin")
110 M06/26 秋山 日出夫 <a advance list 太陽計測株式会社 志賀 安 様 いつもお
111 06/26 後藤俊一 <goto ちょっと長いサブジ 本文は特になし! ヘッダのMIMEの折り
[--]J.:--%%-Mule: +inbox 4:02pm (Summary)--[348 more]-----------------
Mew-dist メーリングリストの案内