Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-digest.el @ 20:859a2309aef8 r19-15b93
Import from CVS: tag r19-15b93
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:05 +0200 |
parents | 49a24b4fd526 |
children | 4103f0995bd7 |
comparison
equal
deleted
inserted
replaced
19:ac1f612d5250 | 20:859a2309aef8 |
---|---|
1 ;;; Message encapsulation | 1 ;;; Message encapsulation |
2 ;;; Copyright (C) 1989, 1990, 1993, 1994 Kyle E. Jones | 2 ;;; Copyright (C) 1989, 1990, 1993, 1994, 1997 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 "Encapsulate the messages in MESSAGE-LIST as per the MIME spec. | |
59 The resulting digest is inserted at point in the current buffer. | |
60 Point is not moved. | |
61 | |
62 MESSAGE-LIST should be a list of message structs (real or virtual). | |
63 These are the messages that will be encapsulated. | |
64 KEEP-LIST should be a list of regexps matching headers to keep. | |
65 DISCARD-REGEXP should be a regexp that matches headers to be discarded. | |
66 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | |
67 to be forwarded. See the docs for vm-reorder-message-headers | |
68 to find out how KEEP-LIST and DISCARD-REGEXP are used. | |
69 | |
70 Returns the multipart boundary parameter (string) that should be used | |
71 in the Content-Type header." | |
72 (if message-list | |
73 (let ((target-buffer (current-buffer)) | |
74 (boundary-positions nil) | |
75 (mlist message-list) | |
76 (mime-keep-list (append keep-list vm-mime-header-list)) | |
77 boundary source-buffer m start n beg) | |
78 (save-restriction | |
79 ;; narrow to a zero length region to avoid interacting | |
80 ;; with anything that might have already been inserted | |
81 ;; into the buffer. | |
82 (narrow-to-region (point) (point)) | |
83 (setq start (point)) | |
84 (while mlist | |
85 (setq boundary-positions (cons (point-marker) boundary-positions)) | |
86 (setq m (vm-real-message-of (car mlist)) | |
87 source-buffer (vm-buffer-of m)) | |
88 (setq beg (point)) | |
89 (vm-insert-region-from-buffer source-buffer (vm-headers-of m) | |
90 (vm-text-end-of m)) | |
91 (goto-char beg) | |
92 (vm-reorder-message-headers nil nil "\\(X-VM-\\|Status:\\)") | |
93 (vm-reorder-message-headers | |
94 nil (if (vm-mime-plain-message-p m) | |
95 keep-list | |
96 mime-keep-list) | |
97 discard-regexp) | |
98 (goto-char (point-max)) | |
99 (setq mlist (cdr mlist))) | |
100 (goto-char start) | |
101 (setq boundary (vm-mime-make-multipart-boundary)) | |
102 (while (re-search-forward (concat "^--" | |
103 (regexp-quote boundary) | |
104 "\\(--\\)?$") | |
105 nil t) | |
106 (setq boundary (vm-mime-make-multipart-boundary)) | |
107 (goto-char start)) | |
108 (goto-char (point-max)) | |
109 (insert "\n--" boundary "--\n") | |
110 (while boundary-positions | |
111 (goto-char (car boundary-positions)) | |
112 (insert "\n--" boundary "\n\n") | |
113 (setq boundary-positions (cdr boundary-positions))) | |
114 (goto-char start) | |
115 (setq n (length message-list)) | |
116 (insert (format "This is a %s%sMIME encapsulation.\n" | |
117 (if (cdr message-list) | |
118 "digest, " | |
119 "forwarded message, ") | |
120 (if (cdr message-list) | |
121 (format "%d messages, " n) | |
122 ""))) | |
123 (goto-char start)) | |
124 boundary ))) | |
125 | |
126 (defun vm-mime-burst-message (m) | |
127 "Burst messages from the digest message M. | |
128 M should be a message struct for a real message. | |
129 MIME encoding is expected. The message content type | |
130 must be either message/* or multipart/digest." | |
131 (let ((ident-header nil) | |
132 (layout (vm-mm-layout m))) | |
133 (if vm-digest-identifier-header-format | |
134 (setq ident-header (vm-sprintf 'vm-digest-identifier-header-format m))) | |
135 (vm-mime-burst-layout layout ident-header))) | |
136 | |
137 (defun vm-mime-burst-layout (layout ident-header) | |
138 (let ((work-buffer nil) | |
139 (folder-buffer (current-buffer)) | |
140 start part-list | |
141 (folder-type vm-folder-type)) | |
142 (unwind-protect | |
143 (vm-save-restriction | |
144 (save-excursion | |
145 (widen) | |
146 (setq work-buffer (generate-new-buffer "*vm-work*")) | |
147 (buffer-disable-undo work-buffer) | |
148 (set-buffer work-buffer) | |
149 (cond ((not (vectorp layout)) | |
150 (error "Not a MIME message")) | |
151 ((vm-mime-types-match "message" | |
152 (car (vm-mm-layout-type layout))) | |
153 (insert (vm-leading-message-separator folder-type)) | |
154 (and ident-header (insert ident-header)) | |
155 (setq start (point)) | |
156 (vm-mime-insert-mime-body layout) | |
157 (vm-munge-message-separators folder-type start (point)) | |
158 (insert (vm-trailing-message-separator folder-type))) | |
159 ((vm-mime-types-match "multipart/digest" | |
160 (car (vm-mm-layout-type layout))) | |
161 (setq part-list (vm-mm-layout-parts layout)) | |
162 (while part-list | |
163 ;; Maybe we should verify that each part is | |
164 ;; of type message/rfc822 in here. But it | |
165 ;; seems more useful to just copy whatever | |
166 ;; the contents are and let teh user see the | |
167 ;; goop, whatever type it really is. | |
168 (insert (vm-leading-message-separator folder-type)) | |
169 (and ident-header (insert ident-header)) | |
170 (setq start (point)) | |
171 (vm-mime-insert-mime-body (car part-list)) | |
172 (vm-munge-message-separators folder-type start (point)) | |
173 (insert (vm-trailing-message-separator folder-type)) | |
174 (setq part-list (cdr part-list)))) | |
175 (t (error | |
176 "MIME type is not multipart/digest or message/rfc822"))) | |
177 ;; do header conversions. | |
178 (let ((vm-folder-type folder-type)) | |
179 (goto-char (point-min)) | |
180 (while (vm-find-leading-message-separator) | |
181 (vm-skip-past-leading-message-separator) | |
182 (vm-convert-folder-type-headers folder-type folder-type) | |
183 (vm-find-trailing-message-separator) | |
184 (vm-skip-past-trailing-message-separator))) | |
185 ;; now insert the messages into the folder buffer | |
186 (cond ((not (zerop (buffer-size))) | |
187 (set-buffer folder-buffer) | |
188 (let ((old-buffer-modified-p (buffer-modified-p)) | |
189 (buffer-read-only nil) | |
190 (inhibit-quit t)) | |
191 (goto-char (point-max)) | |
192 (insert-buffer-substring work-buffer) | |
193 (set-buffer-modified-p old-buffer-modified-p) | |
194 ;; return non-nil so caller knows we found some messages | |
195 t )) | |
196 ;; return nil so the caller knows we didn't find anything | |
197 (t nil)))) | |
198 (and work-buffer (kill-buffer work-buffer))))) | |
199 | |
57 (defun vm-rfc934-char-stuff-region (start end) | 200 (defun vm-rfc934-char-stuff-region (start end) |
58 "Quote RFC 934 message separators between START and END. | 201 "Quote RFC 934 message separators between START and END. |
59 START and END are buffer positions in the current buffer. | 202 START and END are buffer positions in the current buffer. |
60 Lines beginning with `-' in the region have `- ' prepended to them." | 203 Lines beginning with `-' in the region have `- ' prepended to them." |
61 (setq end (vm-marker end)) | 204 (setq end (vm-marker end)) |
90 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | 233 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers |
91 to be forwarded. See the docs for vm-reorder-message-headers | 234 to be forwarded. See the docs for vm-reorder-message-headers |
92 to find out how KEEP-LIST and DISCARD-REGEXP are used." | 235 to find out how KEEP-LIST and DISCARD-REGEXP are used." |
93 (if message-list | 236 (if message-list |
94 (let ((target-buffer (current-buffer)) | 237 (let ((target-buffer (current-buffer)) |
238 (mime-keep-list (append keep-list vm-mime-header-list)) | |
95 (mlist message-list) | 239 (mlist message-list) |
96 source-buffer m start n) | 240 source-buffer m start n) |
97 (save-restriction | 241 (save-restriction |
98 ;; narrow to a zero length region to avoid interacting | 242 ;; narrow to a zero length region to avoid interacting |
99 ;; with anything that might have already been inserted | 243 ;; with anything that might have already been inserted |
114 (insert-buffer-substring source-buffer (vm-headers-of m) | 258 (insert-buffer-substring source-buffer (vm-headers-of m) |
115 (vm-text-end-of m)) | 259 (vm-text-end-of m)) |
116 (goto-char beg) | 260 (goto-char beg) |
117 (vm-reorder-message-headers nil nil | 261 (vm-reorder-message-headers nil nil |
118 "\\(X-VM-\\|Status:\\)") | 262 "\\(X-VM-\\|Status:\\)") |
119 (vm-reorder-message-headers nil keep-list discard-regexp) | 263 (vm-reorder-message-headers |
264 nil (if (vm-mime-plain-message-p m) | |
265 keep-list | |
266 mime-keep-list) | |
267 discard-regexp) | |
120 (vm-rfc934-char-stuff-region beg (point-max)))))) | 268 (vm-rfc934-char-stuff-region beg (point-max)))))) |
121 (goto-char (point-max)) | 269 (goto-char (point-max)) |
122 (insert "---------------") | 270 (insert "---------------") |
123 (setq mlist (cdr mlist))) | 271 (setq mlist (cdr mlist))) |
124 (delete-region (point) (progn (beginning-of-line) (point))) | 272 (delete-region (point) (progn (beginning-of-line) (point))) |
173 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers | 321 KEEP-LIST and DISCARD-REGEXP are used to order and trim the headers |
174 to be forwarded. See the docs for vm-reorder-message-headers | 322 to be forwarded. See the docs for vm-reorder-message-headers |
175 to find out how KEEP-LIST and DISCARD-REGEXP are used." | 323 to find out how KEEP-LIST and DISCARD-REGEXP are used." |
176 (if message-list | 324 (if message-list |
177 (let ((target-buffer (current-buffer)) | 325 (let ((target-buffer (current-buffer)) |
326 (mime-keep-list (append keep-list vm-mime-header-list)) | |
178 (mlist message-list) | 327 (mlist message-list) |
179 source-buffer m start) | 328 source-buffer m start) |
180 (save-restriction | 329 (save-restriction |
181 ;; narrow to a zero length region to avoid interacting | 330 ;; narrow to a zero length region to avoid interacting |
182 ;; with anything that might have already been inserted | 331 ;; with anything that might have already been inserted |
197 (insert-buffer-substring source-buffer (vm-headers-of m) | 346 (insert-buffer-substring source-buffer (vm-headers-of m) |
198 (vm-text-end-of m)) | 347 (vm-text-end-of m)) |
199 (goto-char beg) | 348 (goto-char beg) |
200 (vm-reorder-message-headers nil nil | 349 (vm-reorder-message-headers nil nil |
201 "\\(X-VM-\\|Status:\\)") | 350 "\\(X-VM-\\|Status:\\)") |
202 (vm-reorder-message-headers nil keep-list discard-regexp) | 351 (vm-reorder-message-headers |
352 nil (if (vm-mime-plain-message-p m) | |
353 keep-list | |
354 mime-keep-list) | |
355 discard-regexp) | |
203 (vm-rfc1153-char-stuff-region beg (point-max)))))) | 356 (vm-rfc1153-char-stuff-region beg (point-max)))))) |
204 (goto-char (point-max)) | 357 (goto-char (point-max)) |
205 (insert "\n---------------") | 358 (insert "\n---------------") |
206 (setq mlist (cdr mlist))) | 359 (setq mlist (cdr mlist))) |
207 (insert "---------------\n\nEnd of this Digest\n******************\n") | 360 (insert "---------------\n\nEnd of this Digest\n******************\n") |
226 (if rfc1153 | 379 (if rfc1153 |
227 (setq prologue-separator-regexp "^----------------------------------------------------------------------\n" | 380 (setq prologue-separator-regexp "^----------------------------------------------------------------------\n" |
228 separator-regexp "^------------------------------\n") | 381 separator-regexp "^------------------------------\n") |
229 (setq prologue-separator-regexp "^-[^ ].*\n" | 382 (setq prologue-separator-regexp "^-[^ ].*\n" |
230 separator-regexp "^-[^ ].*\n")) | 383 separator-regexp "^-[^ ].*\n")) |
231 (save-excursion | 384 (vm-save-restriction |
232 (vm-save-restriction | 385 (save-excursion |
233 (widen) | 386 (widen) |
234 (unwind-protect | 387 (unwind-protect |
235 (catch 'done | 388 (catch 'done |
236 (setq work-buffer (generate-new-buffer "*vm-work*")) | 389 (setq work-buffer (generate-new-buffer "*vm-work*")) |
390 (buffer-disable-undo work-buffer) | |
237 (set-buffer work-buffer) | 391 (set-buffer work-buffer) |
238 (insert-buffer-substring (vm-buffer-of m) | 392 (insert-buffer-substring (vm-buffer-of m) |
239 (vm-text-of m) | 393 (vm-text-of m) |
240 (vm-text-end-of m)) | 394 (vm-text-end-of m)) |
241 (goto-char (point-min)) | 395 (goto-char (point-min)) |
365 (setq digest-type (vm-guess-digest-type m)) | 519 (setq digest-type (vm-guess-digest-type m)) |
366 (if (null digest-type) | 520 (if (null digest-type) |
367 (error "Couldn't guess digest type.")))) | 521 (error "Couldn't guess digest type.")))) |
368 (vm-unsaved-message "Bursting %s digest..." digest-type) | 522 (vm-unsaved-message "Bursting %s digest..." digest-type) |
369 (cond | 523 (cond |
370 ((cond ((equal digest-type "rfc934") | 524 ((cond ((equal digest-type "mime") |
525 (vm-mime-burst-message m)) | |
526 ((equal digest-type "rfc934") | |
371 (vm-rfc934-burst-message m)) | 527 (vm-rfc934-burst-message m)) |
372 ((equal digest-type "rfc1153") | 528 ((equal digest-type "rfc1153") |
373 (vm-rfc1153-burst-message m)) | 529 (vm-rfc1153-burst-message m)) |
374 (t (error "Unknown digest type: %s" digest-type))) | 530 (t (error "Unknown digest type: %s" digest-type))) |
375 (message "Bursting %s digest... done" digest-type) | 531 (message "Bursting %s digest... done" digest-type) |
379 (and vm-delete-after-bursting | 535 (and vm-delete-after-bursting |
380 ;; if start folder was virtual, we're now in the wrong | 536 ;; if start folder was virtual, we're now in the wrong |
381 ;; buffer. switch back. | 537 ;; buffer. switch back. |
382 (save-excursion | 538 (save-excursion |
383 (set-buffer start-buffer) | 539 (set-buffer start-buffer) |
384 (vm-delete-message 1))) | 540 ;; don't move message pointer when deleting the message |
385 (vm-assimilate-new-messages t) | 541 (let ((vm-move-after-deleting nil)) |
542 (vm-delete-message 1)))) | |
543 (vm-assimilate-new-messages t nil (vm-labels-of (car mlist))) | |
386 ;; do this now so if we error later in another iteration | 544 ;; do this now so if we error later in another iteration |
387 ;; of the loop the summary and mode line will be correct. | 545 ;; of the loop the summary and mode line will be correct. |
388 (vm-update-summary-and-mode-line))) | 546 (vm-update-summary-and-mode-line))) |
389 (setq mlist (cdr mlist))) | 547 (setq mlist (cdr mlist))) |
390 ;; collect this data NOW, before the non-previewers read a | 548 ;; collect this data NOW, before the non-previewers read a |
391 ;; message, alter the new message count and confuse | 549 ;; message, alter the new message count and confuse |
392 ;; themselves. | 550 ;; themselves. |
393 (setq totals-blurb (vm-emit-totals-blurb)) | 551 (setq totals-blurb (vm-emit-totals-blurb)) |
394 (vm-display nil nil '(vm-burst-digest | 552 (vm-display nil nil '(vm-burst-digest |
553 vm-burst-mime-digest | |
395 vm-burst-rfc934-digest | 554 vm-burst-rfc934-digest |
396 vm-burst-rfc1153-digest) | 555 vm-burst-rfc1153-digest) |
397 (list this-command)) | 556 (list this-command)) |
398 (if (vm-thoughtfully-select-message) | 557 (if (vm-thoughtfully-select-message) |
399 (vm-preview-current-message) | 558 (vm-preview-current-message) |
408 (defun vm-burst-rfc1153-digest () | 567 (defun vm-burst-rfc1153-digest () |
409 "Burst an RFC 1153 style digest" | 568 "Burst an RFC 1153 style digest" |
410 (interactive) | 569 (interactive) |
411 (vm-burst-digest "rfc1153")) | 570 (vm-burst-digest "rfc1153")) |
412 | 571 |
572 (defun vm-burst-mime-digest () | |
573 "Burst a MIME digest" | |
574 (interactive) | |
575 (vm-burst-digest "mime")) | |
576 | |
413 (defun vm-guess-digest-type (m) | 577 (defun vm-guess-digest-type (m) |
414 "Guess the digest type of the message M. | 578 "Guess the digest type of the message M. |
415 M should be the message struct of a real message. | 579 M should be the message struct of a real message. |
416 Returns either \"rfc934\" or \"rfc1153\"." | 580 Returns either \"rfc934\", \"rfc1153\" or \"mime\"." |
417 (save-excursion | 581 (catch 'return-value |
418 (set-buffer (vm-buffer-of m)) | 582 (save-excursion |
583 (set-buffer (vm-buffer-of m)) | |
584 (let ((layout (vm-mm-layout m))) | |
585 (if (and (vectorp layout) | |
586 (or (vm-mime-types-match "multipart/digest" | |
587 (car (vm-mm-layout-type layout))) | |
588 (vm-mime-types-match "message/rfc822" | |
589 (car (vm-mm-layout-type layout))))) | |
590 (throw 'return-value "mime")))) | |
419 (save-excursion | 591 (save-excursion |
420 (save-restriction | 592 (save-restriction |
421 (widen) | 593 (widen) |
422 (goto-char (vm-text-of m)) | 594 (goto-char (vm-text-of m)) |
423 (if (search-forward "\n----------------------------------------------------------------------\n" nil t) | 595 (cond ((search-forward "\n----------------------------------------------------------------------\n" (vm-text-end-of m) t) |
424 "rfc1153" | 596 "rfc1153") |
425 "rfc934"))))) | 597 (t "rfc934")))))) |