comparison lisp/gnus/rfc2231.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents a26d9b55abb6
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; rfc2231.el --- functions for decoding rfc2231 headers 1 ;;; rfc2231.el --- Functions for decoding rfc2231 headers
2 2
3 ;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. 3 ;; Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004,
4 ;; 2005 Free Software Foundation, Inc.
4 5
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6 ;; This file is part of GNU Emacs. 7 ;; This file is part of GNU Emacs.
7 8
8 ;; GNU Emacs is free software; you can redistribute it and/or modify 9 ;; GNU Emacs is free software; you can redistribute it and/or modify
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details. 17 ;; GNU General Public License for more details.
17 18
18 ;; You should have received a copy of the GNU General Public License 19 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to the 20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
20 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02111-1307, USA. 22 ;; Boston, MA 02110-1301, USA.
22 23
23 ;;; Commentary: 24 ;;; Commentary:
24 25
25 ;;; Code: 26 ;;; Code:
26 27
27 (eval-when-compile (require 'cl)) 28 (eval-when-compile (require 'cl))
28 (require 'ietf-drums) 29 (require 'ietf-drums)
30 (require 'rfc2047)
31 (autoload 'mm-encode-body "mm-bodies")
32 (autoload 'mail-header-remove-whitespace "mail-parse")
33 (autoload 'mail-header-remove-comments "mail-parse")
29 34
30 (defun rfc2231-get-value (ct attribute) 35 (defun rfc2231-get-value (ct attribute)
31 "Return the value of ATTRIBUTE from CT." 36 "Return the value of ATTRIBUTE from CT."
32 (cdr (assq attribute (cdr ct)))) 37 (cdr (assq attribute (cdr ct))))
38
39 (defun rfc2231-parse-qp-string (string)
40 "Parse QP-encoded string using `rfc2231-parse-string'.
41 N.B. This is in violation with RFC2047, but it seem to be in common use."
42 (rfc2231-parse-string (rfc2047-decode-string string)))
33 43
34 (defun rfc2231-parse-string (string) 44 (defun rfc2231-parse-string (string)
35 "Parse STRING and return a list. 45 "Parse STRING and return a list.
36 The list will be on the form 46 The list will be on the form
37 `(name (attribute . value) (attribute . value)...)" 47 `(name (attribute . value) (attribute . value)...)"
40 (stoken (ietf-drums-token-to-list ietf-drums-tspecials)) 50 (stoken (ietf-drums-token-to-list ietf-drums-tspecials))
41 (ntoken (ietf-drums-token-to-list "0-9")) 51 (ntoken (ietf-drums-token-to-list "0-9"))
42 (prev-value "") 52 (prev-value "")
43 display-name mailbox c display-string parameters 53 display-name mailbox c display-string parameters
44 attribute value type subtype number encoded 54 attribute value type subtype number encoded
45 prev-attribute) 55 prev-attribute prev-encoded)
46 (ietf-drums-init (mail-header-remove-whitespace 56 (ietf-drums-init (mail-header-remove-whitespace
47 (mail-header-remove-comments string))) 57 (mail-header-remove-comments string)))
48 (let ((table (copy-syntax-table ietf-drums-syntax-table))) 58 (let ((table (copy-syntax-table ietf-drums-syntax-table)))
49 (modify-syntax-entry ?\' "w" table) 59 (modify-syntax-entry ?\' "w" table)
60 (modify-syntax-entry ?* " " table)
61 (modify-syntax-entry ?\; " " table)
62 (modify-syntax-entry ?= " " table)
50 ;; The following isn't valid, but one should be liberal 63 ;; The following isn't valid, but one should be liberal
51 ;; in what one receives. 64 ;; in what one receives.
52 (modify-syntax-entry ?\: "w" table) 65 (modify-syntax-entry ?\: "w" table)
53 (set-syntax-table table)) 66 (set-syntax-table table))
54 (setq c (char-after)) 67 (setq c (char-after))
73 (downcase 86 (downcase
74 (buffer-substring 87 (buffer-substring
75 (point) (progn (forward-sexp 1) (point)))))) 88 (point) (progn (forward-sexp 1) (point))))))
76 (error "Invalid header: %s" string)) 89 (error "Invalid header: %s" string))
77 (setq c (char-after)) 90 (setq c (char-after))
78 (setq encoded nil)
79 (when (eq c ?*) 91 (when (eq c ?*)
80 (forward-char 1) 92 (forward-char 1)
81 (setq c (char-after)) 93 (setq c (char-after))
82 (when (memq c ntoken) 94 (if (not (memq c ntoken))
95 (setq encoded t
96 number nil)
83 (setq number 97 (setq number
84 (string-to-number 98 (string-to-number
85 (buffer-substring 99 (buffer-substring
86 (point) (progn (forward-sexp 1) (point))))) 100 (point) (progn (forward-sexp 1) (point)))))
87 (setq c (char-after)) 101 (setq c (char-after))
90 (forward-char 1) 104 (forward-char 1)
91 (setq c (char-after))))) 105 (setq c (char-after)))))
92 ;; See if we have any previous continuations. 106 ;; See if we have any previous continuations.
93 (when (and prev-attribute 107 (when (and prev-attribute
94 (not (eq prev-attribute attribute))) 108 (not (eq prev-attribute attribute)))
95 (push (cons prev-attribute prev-value) parameters) 109 (push (cons prev-attribute
110 (if prev-encoded
111 (rfc2231-decode-encoded-string prev-value)
112 prev-value))
113 parameters)
96 (setq prev-attribute nil 114 (setq prev-attribute nil
97 prev-value "")) 115 prev-value ""
116 prev-encoded nil))
98 (unless (eq c ?=) 117 (unless (eq c ?=)
99 (error "Invalid header: %s" string)) 118 (error "Invalid header: %s" string))
100 (forward-char 1) 119 (forward-char 1)
101 (setq c (char-after)) 120 (setq c (char-after))
102 (cond 121 (cond
103 ((eq c ?\") 122 ((eq c ?\")
104 (setq value 123 (setq value
105 (buffer-substring (1+ (point)) 124 (buffer-substring (1+ (point))
106 (progn (forward-sexp 1) (1- (point)))))) 125 (progn (forward-sexp 1) (1- (point))))))
107 ((and (memq c ttoken) 126 ((and (or (memq c ttoken)
127 (> c ?\177)) ;; EXTENSION: Support non-ascii chars.
108 (not (memq c stoken))) 128 (not (memq c stoken)))
109 (setq value (buffer-substring 129 (setq value (buffer-substring
110 (point) (progn (forward-sexp 1) (point))))) 130 (point)
131 (progn
132 (forward-sexp)
133 ;; We might not have reached at the end of
134 ;; the value because of non-ascii chars,
135 ;; so we should jump over them if any.
136 (while (and (not (eobp))
137 (> (char-after) ?\177))
138 (forward-char 1)
139 (forward-sexp))
140 (point)))))
111 (t 141 (t
112 (error "Invalid header: %s" string))) 142 (error "Invalid header: %s" string)))
113 (when encoded
114 (setq value (rfc2231-decode-encoded-string value)))
115 (if number 143 (if number
116 (setq prev-attribute attribute 144 (setq prev-attribute attribute
117 prev-value (concat prev-value value)) 145 prev-value (concat prev-value value)
118 (push (cons attribute value) parameters)))) 146 prev-encoded encoded)
147 (push (cons attribute
148 (if encoded
149 (rfc2231-decode-encoded-string value)
150 value))
151 parameters))))
119 152
120 ;; Take care of any final continuations. 153 ;; Take care of any final continuations.
121 (when prev-attribute 154 (when prev-attribute
122 (push (cons prev-attribute prev-value) parameters)) 155 (push (cons prev-attribute
156 (if prev-encoded
157 (rfc2231-decode-encoded-string prev-value)
158 prev-value))
159 parameters))
123 160
124 (when type 161 (when type
125 `(,type ,@(nreverse parameters))))))) 162 `(,type ,@(nreverse parameters)))))))
126 163
127 (defun rfc2231-decode-encoded-string (string) 164 (defun rfc2231-decode-encoded-string (string)
138 (insert 175 (insert
139 (prog1 176 (prog1
140 (string-to-number (buffer-substring (point) (+ (point) 2)) 16) 177 (string-to-number (buffer-substring (point) (+ (point) 2)) 16)
141 (delete-region (1- (point)) (+ (point) 2))))) 178 (delete-region (1- (point)) (+ (point) 2)))))
142 ;; Encode using the charset, if any. 179 ;; Encode using the charset, if any.
143 (when (and (< (length elems) 1) 180 (when (and (mm-multibyte-p)
144 (not (equal (intern (car elems)) 'us-ascii))) 181 (> (length elems) 1)
182 (not (equal (intern (downcase (car elems))) 'us-ascii)))
145 (mm-decode-coding-region (point-min) (point-max) 183 (mm-decode-coding-region (point-min) (point-max)
146 (intern (car elems)))) 184 (intern (downcase (car elems)))))
147 (buffer-string)))) 185 (buffer-string))))
148 186
149 (defun rfc2231-encode-string (param value) 187 (defun rfc2231-encode-string (param value)
150 "Return and PARAM=VALUE string encoded according to RFC2231." 188 "Return and PARAM=VALUE string encoded according to RFC2231."
151 (let ((control (ietf-drums-token-to-list ietf-drums-no-ws-ctl-token)) 189 (let ((control (ietf-drums-token-to-list ietf-drums-no-ws-ctl-token))
173 (cond 211 (cond
174 ((or encodep charsetp) 212 ((or encodep charsetp)
175 (goto-char (point-min)) 213 (goto-char (point-min))
176 (while (not (eobp)) 214 (while (not (eobp))
177 (when (> (current-column) 60) 215 (when (> (current-column) 60)
178 (insert "\n") 216 (insert ";\n")
179 (setq broken t)) 217 (setq broken t))
180 (if (or (not (memq (following-char) ascii)) 218 (if (or (not (memq (following-char) ascii))
181 (memq (following-char) control) 219 (memq (following-char) control)
182 (memq (following-char) tspecial) 220 (memq (following-char) tspecial)
183 (memq (following-char) special) 221 (memq (following-char) special)
185 (progn 223 (progn
186 (insert "%" (format "%02x" (following-char))) 224 (insert "%" (format "%02x" (following-char)))
187 (delete-char 1)) 225 (delete-char 1))
188 (forward-char 1))) 226 (forward-char 1)))
189 (goto-char (point-min)) 227 (goto-char (point-min))
190 (insert (or charset "ascii") "''") 228 (insert (symbol-name (or charset 'us-ascii)) "''")
191 (goto-char (point-min)) 229 (goto-char (point-min))
192 (if (not broken) 230 (if (not broken)
193 (insert param "*=") 231 (insert param "*=")
194 (while (not (eobp)) 232 (while (not (eobp))
195 (insert param "*" (format "%d" (incf num)) "*=") 233 (insert (if (>= num 0) " " "\n ")
234 param "*" (format "%d" (incf num)) "*=")
196 (forward-line 1)))) 235 (forward-line 1))))
197 (spacep 236 (spacep
198 (goto-char (point-min)) 237 (goto-char (point-min))
199 (insert param "=\"") 238 (insert param "=\"")
200 (goto-char (point-max)) 239 (goto-char (point-max))
204 (insert param "="))) 243 (insert param "=")))
205 (buffer-string)))) 244 (buffer-string))))
206 245
207 (provide 'rfc2231) 246 (provide 'rfc2231)
208 247
248 ;;; arch-tag: c3ab751d-d108-406a-b301-68882ad8cd63
209 ;;; rfc2231.el ends here 249 ;;; rfc2231.el ends here