Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-digest.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 05472e90ae02 |
children | c0c698873ce1 |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; Message encapsulation | 1 ;;; Message encapsulation |
2 ;;; Copyright (C) 1989, 1990, 1993, 1994, 1997 Kyle E. Jones | 2 ;;; Copyright (C) 1989, 1990, 1993, 1994 Kyle E. Jones |
3 ;;; | 3 ;;; |
4 ;;; This program is free software; you can redistribute it and/or modify | 4 ;;; This program is free software; you can redistribute it and/or modify |
5 ;;; it under the terms of the GNU General Public License as published by | 5 ;;; it under the terms of the GNU General Public License as published by |
6 ;;; the Free Software Foundation; either version 1, or (at your option) | 6 ;;; the Free Software Foundation; either version 1, or (at your option) |
7 ;;; any later version. | 7 ;;; any later version. |
52 (vm-reorder-message-headers nil nil "\\(X-VM-\\|Status:\\)") | 52 (vm-reorder-message-headers nil nil "\\(X-VM-\\|Status:\\)") |
53 (vm-reorder-message-headers nil keep-list discard-regexp))))) | 53 (vm-reorder-message-headers nil keep-list discard-regexp))))) |
54 (goto-char (point-max)) | 54 (goto-char (point-max)) |
55 (insert "------- end of forwarded message -------\n")))) | 55 (insert "------- end of forwarded message -------\n")))) |
56 | 56 |
57 (defun vm-mime-encapsulate-messages (message-list keep-list discard-regexp | |
58 always-use-digest) | |
59 "Encapsulate the messages in MESSAGE-LIST as per the MIME spec. | |
60 The resulting digest is inserted at point in the current buffer. | |
61 Point is not moved. | |
62 | |
63 MESSAGE-LIST should be a list of message structs (real or virtual). | |
64 These are the messages that will be encapsulated. | |
65 KEEP-LIST should be a list of regexps matching headers to keep. | |
66 DISCARD-REGEXP should be a regexp that matches headers to be discarded. | |
67 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | |
68 to be forwarded. See the docs for vm-reorder-message-headers | |
69 to find out how KEEP-LIST and DISCARD-REGEXP are used. | |
70 | |
71 If ALWAYS-USE-DIGEST is non-nil, always encapsulate for a multipart/digest. | |
72 Otherwise if there are fewer than two messages to be encapsulated | |
73 leave off the multipart boundary strings. The caller is assumed to | |
74 be using message/rfc822 or message/news encoding instead. | |
75 | |
76 If multipart/digest encapsulation is done, the function returns | |
77 the multipart boundary parameter (string) that should be used in | |
78 the Content-Type header. Otherwise nil is returned." | |
79 (if message-list | |
80 (let ((target-buffer (current-buffer)) | |
81 (boundary-positions nil) | |
82 (mlist message-list) | |
83 (mime-keep-list (append keep-list vm-mime-header-list)) | |
84 (boundary nil) | |
85 source-buffer m start n beg) | |
86 (save-restriction | |
87 ;; narrow to a zero length region to avoid interacting | |
88 ;; with anything that might have already been inserted | |
89 ;; into the buffer. | |
90 (narrow-to-region (point) (point)) | |
91 (setq start (point)) | |
92 (while mlist | |
93 (setq boundary-positions (cons (point-marker) boundary-positions)) | |
94 (setq m (vm-real-message-of (car mlist)) | |
95 source-buffer (vm-buffer-of m)) | |
96 (setq beg (point)) | |
97 (vm-insert-region-from-buffer source-buffer (vm-headers-of m) | |
98 (vm-text-end-of m)) | |
99 (goto-char beg) | |
100 (vm-reorder-message-headers nil nil "\\(X-VM-\\|Status:\\)") | |
101 (vm-reorder-message-headers | |
102 nil (if (vm-mime-plain-message-p m) | |
103 keep-list | |
104 mime-keep-list) | |
105 discard-regexp) | |
106 (goto-char (point-max)) | |
107 (setq mlist (cdr mlist))) | |
108 (if (and (< (length message-list) 2) (not always-use-digest)) | |
109 nil | |
110 (goto-char start) | |
111 (setq boundary (vm-mime-make-multipart-boundary)) | |
112 (while (re-search-forward (concat "^--" | |
113 (regexp-quote boundary) | |
114 "\\(--\\)?$") | |
115 nil t) | |
116 (setq boundary (vm-mime-make-multipart-boundary)) | |
117 (goto-char start)) | |
118 (goto-char (point-max)) | |
119 (insert "\n--" boundary "--\n") | |
120 (while boundary-positions | |
121 (goto-char (car boundary-positions)) | |
122 (insert "\n--" boundary "\n\n") | |
123 (setq boundary-positions (cdr boundary-positions))) | |
124 (goto-char start) | |
125 (setq n (length message-list)) | |
126 (insert | |
127 (format "This is a digest, %d messages, MIME encapsulation.\n" | |
128 n))) | |
129 (goto-char start)) | |
130 boundary ))) | |
131 | |
132 (defun vm-mime-burst-message (m) | |
133 "Burst messages from the digest message M. | |
134 M should be a message struct for a real message. | |
135 MIME encoding is expected. Somewhere within the MIME layout | |
136 there must be at least one part of type message/news, message/rfc822 or | |
137 multipart/digest. If there are multiple parts matching those types, | |
138 all of them will be burst." | |
139 (let ((ident-header nil) | |
140 (did-burst nil) | |
141 (list (vm-mime-find-digests-in-layout (vm-mm-layout m)))) | |
142 (if vm-digest-identifier-header-format | |
143 (setq ident-header (vm-sprintf 'vm-digest-identifier-header-format m))) | |
144 (while list | |
145 (setq did-burst (or did-burst | |
146 (vm-mime-burst-layout (car list) ident-header))) | |
147 (setq list (cdr list))) | |
148 did-burst)) | |
149 | |
150 (defun vm-mime-burst-layout (layout ident-header) | |
151 (let ((work-buffer nil) | |
152 (folder-buffer (current-buffer)) | |
153 start part-list | |
154 (folder-type vm-folder-type)) | |
155 (unwind-protect | |
156 (vm-save-restriction | |
157 (save-excursion | |
158 (widen) | |
159 (setq work-buffer (generate-new-buffer "*vm-work*")) | |
160 (buffer-disable-undo work-buffer) | |
161 (set-buffer work-buffer) | |
162 (cond ((not (vectorp layout)) | |
163 (error "Not a MIME message")) | |
164 ((vm-mime-types-match "message" | |
165 (car (vm-mm-layout-type layout))) | |
166 (insert (vm-leading-message-separator folder-type)) | |
167 (and ident-header (insert ident-header)) | |
168 (setq start (point)) | |
169 (vm-mime-insert-mime-body layout) | |
170 (vm-munge-message-separators folder-type start (point)) | |
171 (insert (vm-trailing-message-separator folder-type))) | |
172 ((vm-mime-types-match "multipart/digest" | |
173 (car (vm-mm-layout-type layout))) | |
174 (setq part-list (vm-mm-layout-parts layout)) | |
175 (while part-list | |
176 ;; Maybe we should verify that each part is | |
177 ;; of type message/rfc822 or message/news in | |
178 ;; here. But it seems more useful to just | |
179 ;; copy whatever the contents are and let the | |
180 ;; user see the goop, whatever type it really | |
181 ;; is. | |
182 (insert (vm-leading-message-separator folder-type)) | |
183 (and ident-header (insert ident-header)) | |
184 (setq start (point)) | |
185 (vm-mime-insert-mime-body (car part-list)) | |
186 (vm-munge-message-separators folder-type start (point)) | |
187 (insert (vm-trailing-message-separator folder-type)) | |
188 (setq part-list (cdr part-list)))) | |
189 (t (error | |
190 "MIME type is not multipart/digest or message/rfc822 or message/news"))) | |
191 ;; do header conversions. | |
192 (let ((vm-folder-type folder-type)) | |
193 (goto-char (point-min)) | |
194 (while (vm-find-leading-message-separator) | |
195 (vm-skip-past-leading-message-separator) | |
196 (vm-convert-folder-type-headers folder-type folder-type) | |
197 (vm-find-trailing-message-separator) | |
198 (vm-skip-past-trailing-message-separator))) | |
199 ;; now insert the messages into the folder buffer | |
200 (cond ((not (zerop (buffer-size))) | |
201 (set-buffer folder-buffer) | |
202 (let ((old-buffer-modified-p (buffer-modified-p)) | |
203 (buffer-read-only nil) | |
204 (inhibit-quit t)) | |
205 (goto-char (point-max)) | |
206 (insert-buffer-substring work-buffer) | |
207 (set-buffer-modified-p old-buffer-modified-p) | |
208 ;; return non-nil so caller knows we found some messages | |
209 t )) | |
210 ;; return nil so the caller knows we didn't find anything | |
211 (t nil)))) | |
212 (and work-buffer (kill-buffer work-buffer))))) | |
213 | |
214 (defun vm-rfc934-char-stuff-region (start end) | 57 (defun vm-rfc934-char-stuff-region (start end) |
215 "Quote RFC 934 message separators between START and END. | 58 "Quote RFC 934 message separators between START and END. |
216 START and END are buffer positions in the current buffer. | 59 START and END are buffer positions in the current buffer. |
217 Lines beginning with `-' in the region have `- ' prepended to them." | 60 Lines beginning with `-' in the region have `- ' prepended to them." |
218 (setq end (vm-marker end)) | 61 (setq end (vm-marker end)) |
247 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | 90 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers |
248 to be forwarded. See the docs for vm-reorder-message-headers | 91 to be forwarded. See the docs for vm-reorder-message-headers |
249 to find out how KEEP-LIST and DISCARD-REGEXP are used." | 92 to find out how KEEP-LIST and DISCARD-REGEXP are used." |
250 (if message-list | 93 (if message-list |
251 (let ((target-buffer (current-buffer)) | 94 (let ((target-buffer (current-buffer)) |
252 (mime-keep-list (append keep-list vm-mime-header-list)) | |
253 (mlist message-list) | 95 (mlist message-list) |
254 source-buffer m start n) | 96 source-buffer m start n) |
255 (save-restriction | 97 (save-restriction |
256 ;; narrow to a zero length region to avoid interacting | 98 ;; narrow to a zero length region to avoid interacting |
257 ;; with anything that might have already been inserted | 99 ;; with anything that might have already been inserted |
272 (insert-buffer-substring source-buffer (vm-headers-of m) | 114 (insert-buffer-substring source-buffer (vm-headers-of m) |
273 (vm-text-end-of m)) | 115 (vm-text-end-of m)) |
274 (goto-char beg) | 116 (goto-char beg) |
275 (vm-reorder-message-headers nil nil | 117 (vm-reorder-message-headers nil nil |
276 "\\(X-VM-\\|Status:\\)") | 118 "\\(X-VM-\\|Status:\\)") |
277 (vm-reorder-message-headers | 119 (vm-reorder-message-headers nil keep-list discard-regexp) |
278 nil (if (vm-mime-plain-message-p m) | |
279 keep-list | |
280 mime-keep-list) | |
281 discard-regexp) | |
282 (vm-rfc934-char-stuff-region beg (point-max)))))) | 120 (vm-rfc934-char-stuff-region beg (point-max)))))) |
283 (goto-char (point-max)) | 121 (goto-char (point-max)) |
284 (insert "---------------") | 122 (insert "---------------") |
285 (setq mlist (cdr mlist))) | 123 (setq mlist (cdr mlist))) |
286 (delete-region (point) (progn (beginning-of-line) (point))) | 124 (delete-region (point) (progn (beginning-of-line) (point))) |
335 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | 173 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers |
336 to be forwarded. See the docs for vm-reorder-message-headers | 174 to be forwarded. See the docs for vm-reorder-message-headers |
337 to find out how KEEP-LIST and DISCARD-REGEXP are used." | 175 to find out how KEEP-LIST and DISCARD-REGEXP are used." |
338 (if message-list | 176 (if message-list |
339 (let ((target-buffer (current-buffer)) | 177 (let ((target-buffer (current-buffer)) |
340 (mime-keep-list (append keep-list vm-mime-header-list)) | |
341 (mlist message-list) | 178 (mlist message-list) |
342 source-buffer m start) | 179 source-buffer m start) |
343 (save-restriction | 180 (save-restriction |
344 ;; narrow to a zero length region to avoid interacting | 181 ;; narrow to a zero length region to avoid interacting |
345 ;; with anything that might have already been inserted | 182 ;; with anything that might have already been inserted |
360 (insert-buffer-substring source-buffer (vm-headers-of m) | 197 (insert-buffer-substring source-buffer (vm-headers-of m) |
361 (vm-text-end-of m)) | 198 (vm-text-end-of m)) |
362 (goto-char beg) | 199 (goto-char beg) |
363 (vm-reorder-message-headers nil nil | 200 (vm-reorder-message-headers nil nil |
364 "\\(X-VM-\\|Status:\\)") | 201 "\\(X-VM-\\|Status:\\)") |
365 (vm-reorder-message-headers | 202 (vm-reorder-message-headers nil keep-list discard-regexp) |
366 nil (if (vm-mime-plain-message-p m) | |
367 keep-list | |
368 mime-keep-list) | |
369 discard-regexp) | |
370 (vm-rfc1153-char-stuff-region beg (point-max)))))) | 203 (vm-rfc1153-char-stuff-region beg (point-max)))))) |
371 (goto-char (point-max)) | 204 (goto-char (point-max)) |
372 (insert "\n---------------") | 205 (insert "\n---------------") |
373 (setq mlist (cdr mlist))) | 206 (setq mlist (cdr mlist))) |
374 (insert "---------------\n\nEnd of this Digest\n******************\n") | 207 (insert "---------------\n\nEnd of this Digest\n******************\n") |
375 (goto-char start) | 208 (goto-char start) |
376 (delete-region (point) (progn (forward-line 1) (point))) | 209 (delete-region (point) (progn (forward-line 1) (point))) |
377 (insert (format "This is an RFC 1153 digest.\n(%d message%s)\n----------------------------------------------------------------------\n" (length message-list) (if (cdr message-list) "s" ""))) | 210 (insert (format "This is an RFC 1153 digest.\n(%d message%s)\n----------------------------------------------------------------------\n" (length message-list) (if (cdr message-list) "s" ""))) |
378 (goto-char start))))) | 211 (goto-char start))))) |
212 | |
213 (defun vm-rfc1521-encapsulate-messages (message-list keep-list discard-regexp) | |
214 "Encapsulate the messages in MESSAGE-LIST as per RFC 1521 (MIME). | |
215 The resulting digest is inserted at point in the current buffer. | |
216 MIME headers at point-max are added/updated. | |
217 Point is not moved. | |
218 | |
219 MESSAGE-LIST should be a list of message structs (real or virtual). | |
220 These are the messages that will be encapsulated. | |
221 KEEP-LIST should be a list of regexps matching headers to keep. | |
222 DISCARD-REGEXP should be a regexp that matches headers to be discarded. | |
223 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | |
224 to be forwarded. See the docs for vm-reorder-message-headers | |
225 to find out how KEEP-LIST and DISCARD-REGEXP are used." | |
226 (if message-list | |
227 (let ((target-buffer (current-buffer)) | |
228 (mlist message-list) | |
229 (boundary (format "-----%07X%07X" (abs (random)) (abs (random)))) | |
230 ; insertion-point | |
231 source-buffer m start) | |
232 (save-restriction | |
233 ;; narrow to a zero length region to avoid interacting | |
234 ;; with anything that might have already been inserted | |
235 ;; into the buffer. | |
236 (narrow-to-region (point) (point)) | |
237 (setq start (point)) | |
238 (while mlist | |
239 (insert "--" boundary "\nContent-Type: message/rfc822\n\n") | |
240 (setq m (vm-real-message-of (car mlist)) | |
241 source-buffer (vm-buffer-of m)) | |
242 (save-excursion | |
243 (set-buffer source-buffer) | |
244 (save-restriction | |
245 (widen) | |
246 (save-excursion | |
247 (set-buffer target-buffer) | |
248 (let ((beg (point))) | |
249 (insert-buffer-substring source-buffer (vm-headers-of m) | |
250 (vm-text-end-of m)) | |
251 (goto-char beg) | |
252 (vm-reorder-message-headers nil nil | |
253 "\\(X-VM-\\|Status:\\)") | |
254 (vm-reorder-message-headers nil keep-list discard-regexp) | |
255 )))) | |
256 (goto-char (point-max)) | |
257 (insert "\n") | |
258 (setq mlist (cdr mlist))) | |
259 (insert "--" boundary "--\n") | |
260 | |
261 (goto-char start) | |
262 (insert "--" boundary "\nContent-Type: text/plain\n\n") | |
263 (insert (format | |
264 "This is an RFC 1521 (MIME) digest; %d message%s.\n\n\n\n\n" | |
265 (length message-list) | |
266 (if (cdr message-list) "s" ""))) | |
267 ; (setq insertion-point (point-marker)) | |
268 (goto-char start)) | |
269 | |
270 ;; outside of the save-restriction | |
271 (save-excursion | |
272 (let (end) | |
273 (goto-char (point-min)) | |
274 (re-search-forward | |
275 (concat "^" (regexp-quote mail-header-separator) "$") | |
276 nil t) | |
277 (setq end (point)) | |
278 (goto-char (point-min)) | |
279 (cond | |
280 ((re-search-forward "^content-type:" end t) | |
281 (delete-region (point) (progn (forward-line 1) (point))) | |
282 (while (looking-at " \t") | |
283 (delete-region (point) (progn (forward-line 1) (point)))))) | |
284 (goto-char end) | |
285 (insert "MIME-Version: 1.0\n" | |
286 "Content-Type: multipart/digest; boundary=\"" | |
287 boundary "\"\n") | |
288 )) | |
289 | |
290 ; (goto-char insertion-point) | |
291 ; (set-marker insertion-point nil) | |
292 ))) | |
293 | |
379 | 294 |
380 (defun vm-rfc1153-or-rfc934-burst-message (m rfc1153) | 295 (defun vm-rfc1153-or-rfc934-burst-message (m rfc1153) |
381 "Burst messages from the digest message M. | 296 "Burst messages from the digest message M. |
382 M should be a message struct for a real message. | 297 M should be a message struct for a real message. |
383 If RFC1153 is non-nil, assume the digest is of the form specified by | 298 If RFC1153 is non-nil, assume the digest is of the form specified by |
391 (if vm-digest-identifier-header-format | 306 (if vm-digest-identifier-header-format |
392 (setq ident-header (vm-sprintf 'vm-digest-identifier-header-format m))) | 307 (setq ident-header (vm-sprintf 'vm-digest-identifier-header-format m))) |
393 (if rfc1153 | 308 (if rfc1153 |
394 (setq prologue-separator-regexp "^----------------------------------------------------------------------\n" | 309 (setq prologue-separator-regexp "^----------------------------------------------------------------------\n" |
395 separator-regexp "^------------------------------\n") | 310 separator-regexp "^------------------------------\n") |
396 (setq prologue-separator-regexp "\\(^-[^ ].*\n+\\)+" | 311 (setq prologue-separator-regexp "^-[^ ].*\n" |
397 separator-regexp "\\(^-[^ ].*\n+\\)+")) | 312 separator-regexp "^-[^ ].*\n")) |
398 (vm-save-restriction | 313 (save-excursion |
399 (save-excursion | 314 (vm-save-restriction |
400 (widen) | 315 (widen) |
401 (unwind-protect | 316 (unwind-protect |
402 (catch 'done | 317 (catch 'done |
403 (setq work-buffer (generate-new-buffer "*vm-work*")) | 318 (setq work-buffer (generate-new-buffer "*vm-work*")) |
404 (buffer-disable-undo work-buffer) | |
405 (set-buffer work-buffer) | 319 (set-buffer work-buffer) |
406 (insert-buffer-substring (vm-buffer-of m) | 320 (insert-buffer-substring (vm-buffer-of m) |
407 (vm-text-of m) | 321 (vm-text-of m) |
408 (vm-text-end-of m)) | 322 (vm-text-end-of m)) |
409 (goto-char (point-min)) | 323 (goto-char (point-min)) |
422 (unwind-protect | 336 (unwind-protect |
423 (vm-munge-message-separators | 337 (vm-munge-message-separators |
424 folder-type | 338 folder-type |
425 after-prev-sep | 339 after-prev-sep |
426 (match-beginning 0)) | 340 (match-beginning 0)) |
427 (store-match-data md))))) | 341 (store-match-data md))) |
428 ;; there should be at least one valid header at | 342 ;; eat preceding newlines |
429 ;; the beginning of an encapsulated message. If | 343 (while (= (preceding-char) ?\n) |
430 ;; there isn't a valid header, then assume that | 344 (delete-char -1)) |
431 ;; the digest was packed improperly and that this | 345 ;; put one back |
432 ;; isn't a real boundary. | 346 (insert ?\n))) |
433 (if (not | 347 ;; insert a trailing message separator |
434 (save-excursion | 348 ;; delete the digest separator |
435 (save-match-data | 349 ;; insert the leading separator |
436 (skip-chars-forward "\n") | 350 (if prev-sep |
437 (or (and (vm-match-header) | 351 (progn |
438 (vm-digest-get-header-contents "From")) | 352 (delete-region (match-beginning 0) (match-end 0)) |
439 (not (re-search-forward separator-regexp | 353 (insert (vm-trailing-message-separator folder-type)))) |
440 nil t)))))) | 354 (setq prev-sep (point)) |
441 (setq prev-sep (point) | 355 (insert (vm-leading-message-separator folder-type)) |
442 after-prev-sep (point)) | 356 (setq after-prev-sep (point)) |
443 ;; if this isn't the first message, delete the | 357 ;; eat trailing newlines |
444 ;; digest separator goop and insert a trailing message | 358 (while (= (following-char) ?\n) |
445 ;; separator of the proper type. | 359 (delete-char 1)) |
446 (if prev-sep | 360 (insert ident-header) |
447 (progn | |
448 ;; eat preceding newlines | |
449 (while (= (preceding-char) ?\n) | |
450 (delete-char -1)) | |
451 ;; put one back | |
452 (insert ?\n) | |
453 ;; delete the digest separator | |
454 (delete-region (match-beginning 0) (point)) | |
455 ;; insert a trailing message separator | |
456 (insert (vm-trailing-message-separator folder-type)))) | |
457 (setq prev-sep (point)) | |
458 ;; insert the leading separator | |
459 (insert (vm-leading-message-separator folder-type)) | |
460 (setq after-prev-sep (point)) | |
461 ;; eat trailing newlines | |
462 (while (= (following-char) ?\n) | |
463 (delete-char 1)) | |
464 (insert ident-header)) | |
465 ;; try to match message separator and repeat. | 361 ;; try to match message separator and repeat. |
466 (setq match (re-search-forward separator-regexp nil t))) | 362 (setq match (re-search-forward separator-regexp nil t))) |
467 ;; from the last separator to eof is the digest epilogue. | 363 ;; from the last separator to eof is the digest epilogue. |
468 ;; discard it. | 364 ;; discard it. |
469 (delete-region (or prev-sep (point-min)) (point-max)) | 365 (delete-region (or prev-sep (point-min)) (point-max)) |
549 (if (equal digest-type "guess") | 445 (if (equal digest-type "guess") |
550 (progn | 446 (progn |
551 (setq digest-type (vm-guess-digest-type m)) | 447 (setq digest-type (vm-guess-digest-type m)) |
552 (if (null digest-type) | 448 (if (null digest-type) |
553 (error "Couldn't guess digest type.")))) | 449 (error "Couldn't guess digest type.")))) |
554 (message "Bursting %s digest..." digest-type) | 450 (vm-unsaved-message "Bursting %s digest..." digest-type) |
555 (cond | 451 (cond |
556 ((cond ((equal digest-type "mime") | 452 ((cond ((equal digest-type "rfc934") |
557 (vm-mime-burst-message m)) | |
558 ((equal digest-type "rfc934") | |
559 (vm-rfc934-burst-message m)) | 453 (vm-rfc934-burst-message m)) |
560 ((equal digest-type "rfc1153") | 454 ((equal digest-type "rfc1153") |
561 (vm-rfc1153-burst-message m)) | 455 (vm-rfc1153-burst-message m)) |
456 ((equal digest-type "rfc1521") | |
457 (error "Don't yet know how to burst MIME digests.")) | |
562 (t (error "Unknown digest type: %s" digest-type))) | 458 (t (error "Unknown digest type: %s" digest-type))) |
563 (message "Bursting %s digest... done" digest-type) | 459 (message "Bursting %s digest... done" digest-type) |
564 (vm-clear-modification-flag-undos) | 460 (vm-clear-modification-flag-undos) |
565 (vm-set-buffer-modified-p t) | 461 (vm-set-buffer-modified-p t) |
566 (vm-increment vm-modification-counter) | 462 (vm-increment vm-modification-counter) |
567 (and vm-delete-after-bursting | 463 (and vm-delete-after-bursting |
568 ;; if start folder was virtual, we're now in the wrong | 464 ;; if start folder was virtual, we're now in the wrong |
569 ;; buffer. switch back. | 465 ;; buffer. switch back. |
570 (save-excursion | 466 (save-excursion |
571 (set-buffer start-buffer) | 467 (set-buffer start-buffer) |
572 ;; don't move message pointer when deleting the message | 468 (vm-delete-message 1))) |
573 (let ((vm-move-after-deleting nil)) | 469 (vm-assimilate-new-messages t) |
574 (vm-delete-message 1)))) | |
575 (vm-assimilate-new-messages t nil (vm-labels-of (car mlist))) | |
576 ;; do this now so if we error later in another iteration | 470 ;; do this now so if we error later in another iteration |
577 ;; of the loop the summary and mode line will be correct. | 471 ;; of the loop the summary and mode line will be correct. |
578 (vm-update-summary-and-mode-line))) | 472 (vm-update-summary-and-mode-line))) |
579 (setq mlist (cdr mlist))) | 473 (setq mlist (cdr mlist))) |
580 ;; collect this data NOW, before the non-previewers read a | 474 ;; collect this data NOW, before the non-previewers read a |
581 ;; message, alter the new message count and confuse | 475 ;; message, alter the new message count and confuse |
582 ;; themselves. | 476 ;; themselves. |
583 (setq totals-blurb (vm-emit-totals-blurb)) | 477 (setq totals-blurb (vm-emit-totals-blurb)) |
584 (vm-display nil nil '(vm-burst-digest | 478 (vm-display nil nil '(vm-burst-digest |
585 vm-burst-mime-digest | |
586 vm-burst-rfc934-digest | 479 vm-burst-rfc934-digest |
587 vm-burst-rfc1153-digest) | 480 vm-burst-rfc1153-digest |
481 vm-burst-rfc1521-digest) | |
588 (list this-command)) | 482 (list this-command)) |
589 (if (vm-thoughtfully-select-message) | 483 (if (vm-thoughtfully-select-message) |
590 (vm-preview-current-message) | 484 (vm-preview-current-message) |
591 (vm-update-summary-and-mode-line)) | 485 (vm-update-summary-and-mode-line)) |
592 (message totals-blurb))) | 486 (message totals-blurb))) |
599 (defun vm-burst-rfc1153-digest () | 493 (defun vm-burst-rfc1153-digest () |
600 "Burst an RFC 1153 style digest" | 494 "Burst an RFC 1153 style digest" |
601 (interactive) | 495 (interactive) |
602 (vm-burst-digest "rfc1153")) | 496 (vm-burst-digest "rfc1153")) |
603 | 497 |
604 (defun vm-burst-mime-digest () | 498 (defun vm-burst-rfc1521-digest () |
605 "Burst a MIME digest" | 499 "Burst an RFC 1521 (MIME) style digest" |
606 (interactive) | 500 (interactive) |
607 (vm-burst-digest "mime")) | 501 (vm-burst-digest "rfc1521")) |
608 | 502 |
609 (defun vm-guess-digest-type (m) | 503 (defun vm-guess-digest-type (m) |
610 "Guess the digest type of the message M. | 504 "Guess the digest type of the message M. |
611 M should be the message struct of a real message. | 505 M should be the message struct of a real message. |
612 Returns either \"rfc934\", \"rfc1153\" or \"mime\"." | 506 Returns either \"rfc934\", \"rfc1153\", or \"rfc1521\"." |
613 (catch 'return-value | 507 (save-excursion |
614 (save-excursion | 508 (set-buffer (vm-buffer-of m)) |
615 (set-buffer (vm-buffer-of m)) | |
616 (let ((layout (vm-mm-layout m))) | |
617 (if (and (vectorp layout) | |
618 (or (vm-mime-layout-contains-type | |
619 layout | |
620 "multipart/digest") | |
621 (vm-mime-layout-contains-type | |
622 layout | |
623 "message/rfc822") | |
624 (vm-mime-layout-contains-type | |
625 layout | |
626 "message/news"))) | |
627 (throw 'return-value "mime")))) | |
628 (save-excursion | 509 (save-excursion |
629 (save-restriction | 510 (save-restriction |
630 (widen) | 511 (widen) |
631 (goto-char (vm-text-of m)) | 512 (goto-char (vm-headers-of m)) |
632 (cond ((search-forward "\n----------------------------------------------------------------------\n" (vm-text-end-of m) t) | 513 (if (let ((case-fold-search t)) |
633 "rfc1153") | 514 (re-search-forward "^MIME-Version:" nil t)) |
634 (t "rfc934")))))) | 515 "rfc1521" |
635 | 516 (goto-char (vm-text-of m)) |
636 (defun vm-digest-get-header-contents (header-name-regexp) | 517 (if (search-forward "\n----------------------------------------------------------------------\n" nil t) |
637 (let ((contents nil) | 518 "rfc1153" |
638 regexp) | 519 "rfc934")))))) |
639 (setq regexp (concat "^\\(" header-name-regexp "\\)\\|\\(^$\\)")) | |
640 (save-excursion | |
641 (let ((case-fold-search t)) | |
642 (if (and (re-search-forward regexp nil t) | |
643 (match-beginning 1) | |
644 (progn (goto-char (match-beginning 0)) | |
645 (vm-match-header))) | |
646 (vm-matched-header-contents) | |
647 nil ))))) |