aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2004-05-10 16:24:26 +0000
committerRichard M. Stallman2004-05-10 16:24:26 +0000
commit6740652e6d63701107312f7dd1efcc623c4b38fc (patch)
treeee5891a431fa662f5833521d222fd7bda1caddc1
parentb82a6ae78c2112209f81b9b64470ae92c0350a2c (diff)
downloademacs-6740652e6d63701107312f7dd1efcc623c4b38fc.tar.gz
emacs-6740652e6d63701107312f7dd1efcc623c4b38fc.zip
(unrmail): Mostly rewritten. Parses the file
directly, without calling any functions in Rmail. (unrmail-unprune): Function deleted.
-rw-r--r--lisp/mail/unrmail.el189
1 files changed, 121 insertions, 68 deletions
diff --git a/lisp/mail/unrmail.el b/lisp/mail/unrmail.el
index 55f611b53ad..db6990d625b 100644
--- a/lisp/mail/unrmail.el
+++ b/lisp/mail/unrmail.el
@@ -51,43 +51,71 @@ For example, invoke `emacs -batch -f batch-unrmail RMAIL'."
51(defun unrmail (file to-file) 51(defun unrmail (file to-file)
52 "Convert Rmail file FILE to system inbox format file TO-FILE." 52 "Convert Rmail file FILE to system inbox format file TO-FILE."
53 (interactive "fUnrmail (rmail file): \nFUnrmail into (new mailbox file): ") 53 (interactive "fUnrmail (rmail file): \nFUnrmail into (new mailbox file): ")
54 (let ((message-count 1) 54 (with-temp-buffer
55 ;; Prevent rmail from making, or switching to, a summary buffer. 55 ;; Read in the old Rmail file with no decoding.
56 (rmail-display-summary nil) 56 (let ((coding-system-for-read 'raw-text))
57 (rmail-delete-after-output nil) 57 (insert-file-contents file))
58 (temp-buffer (get-buffer-create " unrmail"))) 58 ;; But make it multibyte.
59 (rmail file) 59 (set-buffer-multibyte t)
60
61 (if (not (looking-at "BABYL OPTIONS"))
62 (error "This file is not in Babyl format"))
63
64 ;; Decode the file contents just as Rmail did.
65 (let ((modifiedp (buffer-modified-p))
66 (coding-system rmail-file-coding-system)
67 from to)
68 (goto-char (point-min))
69 (search-forward "\n\^_" nil t) ; Skip BABYL header.
70 (setq from (point))
71 (goto-char (point-max))
72 (search-backward "\n\^_" from 'mv)
73 (setq to (point))
74 (unless (and coding-system
75 (coding-system-p coding-system))
76 (setq coding-system
77 ;; Emacs 21.1 and later writes RMAIL files in emacs-mule, but
78 ;; earlier versions did that with the current buffer's encoding.
79 ;; So we want to favor detection of emacs-mule (whose normal
80 ;; priority is quite low), but still allow detection of other
81 ;; encodings if emacs-mule won't fit. The call to
82 ;; detect-coding-with-priority below achieves that.
83 (car (detect-coding-with-priority
84 from to
85 '((coding-category-emacs-mule . emacs-mule))))))
86 (unless (memq coding-system
87 '(undecided undecided-unix))
88 (set-buffer-modified-p t) ; avoid locking when decoding
89 (let ((buffer-undo-list t))
90 (decode-coding-region from to coding-system))
91 (setq coding-system last-coding-system-used))
92
93 (setq buffer-file-coding-system nil)
94
95 ;; We currently don't use this value, but maybe we should.
96 (setq save-buffer-coding-system
97 (or coding-system 'undecided)))
98
60 ;; Default the directory of TO-FILE based on where FILE is. 99 ;; Default the directory of TO-FILE based on where FILE is.
61 (setq to-file (expand-file-name to-file default-directory)) 100 (setq to-file (expand-file-name to-file default-directory))
62 (condition-case () 101 (condition-case ()
63 (delete-file to-file) 102 (delete-file to-file)
64 (file-error nil)) 103 (file-error nil))
65 (message "Writing messages to %s..." to-file) 104 (message "Writing messages to %s..." to-file)
66 (save-restriction 105 (goto-char (point-min))
67 (widen) 106
68 (while (<= message-count rmail-total-messages) 107 (let ((temp-buffer (get-buffer-create " unrmail"))
69 (let ((beg (rmail-msgbeg message-count)) 108 (from-buffer (current-buffer)))
70 (end (rmail-msgbeg (1+ message-count))) 109
71 (from-buffer (current-buffer)) 110 ;; Process the messages one by one.
72 (coding (or rmail-file-coding-system 'raw-text)) 111 (while (search-forward "\^_\^l" nil t)
112 (let ((beg (point))
113 (end (save-excursion
114 (if (search-forward "\^_" nil t)
115 (1- (point)) (point-max))))
116 (coding 'raw-text)
73 label-line attrs keywords 117 label-line attrs keywords
74 header-beginning mail-from) 118 mail-from reformatted)
75 (save-excursion
76 (goto-char (rmail-msgbeg message-count))
77 (setq header-beginning (point))
78 (search-forward "\n*** EOOH ***\n")
79 (forward-line -1)
80 (search-forward "\n\n")
81 (save-restriction
82 (narrow-to-region header-beginning (point))
83 (setq mail-from
84 (or (mail-fetch-field "Mail-From")
85 (concat "From "
86 (mail-strip-quoted-names (or (mail-fetch-field "from")
87 (mail-fetch-field "really-from")
88 (mail-fetch-field "sender")
89 "unknown"))
90 " " (current-time-string))))))
91 (with-current-buffer temp-buffer 119 (with-current-buffer temp-buffer
92 (setq buffer-undo-list t) 120 (setq buffer-undo-list t)
93 (erase-buffer) 121 (erase-buffer)
@@ -95,11 +123,15 @@ For example, invoke `emacs -batch -f batch-unrmail RMAIL'."
95 (insert-buffer-substring from-buffer beg end) 123 (insert-buffer-substring from-buffer beg end)
96 (goto-char (point-min)) 124 (goto-char (point-min))
97 (forward-line 1) 125 (forward-line 1)
126 ;; Record whether the header is reformatted.
127 (setq reformatted (= (following-char) ?1))
128
129 ;; Collect the label line, then get the attributes
130 ;; and the keywords from it.
98 (setq label-line 131 (setq label-line
99 (buffer-substring (point) 132 (buffer-substring (point)
100 (progn (forward-line 1) 133 (save-excursion (forward-line 1)
101 (point)))) 134 (point))))
102 (forward-line -1)
103 (search-forward ",,") 135 (search-forward ",,")
104 (unless (eolp) 136 (unless (eolp)
105 (setq keywords 137 (setq keywords
@@ -118,9 +150,61 @@ For example, invoke `emacs -batch -f batch-unrmail RMAIL'."
118 (if (string-match ", resent," label-line) ?R ?-) 150 (if (string-match ", resent," label-line) ?R ?-)
119 (if (string-match ", unseen," label-line) ?\ ?-) 151 (if (string-match ", unseen," label-line) ?\ ?-)
120 (if (string-match ", stored," label-line) ?S ?-))) 152 (if (string-match ", stored," label-line) ?S ?-)))
121 (unrmail-unprune) 153
154 ;; Delete the special Babyl lines at the start,
155 ;; and the ***EOOH*** line, and the reformatted header if any.
156 (goto-char (point-min))
157 (if reformatted
158 (progn
159 (forward-line 2)
160 ;; Delete Summary-Line headers.
161 (let ((case-fold-search t))
162 (while (looking-at "Summary-Line:")
163 (forward-line 1)))
164 (delete-region (point-min) (point))
165 ;; Delete the old reformatted header.
166 (re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
167 (forward-line -1)
168 (let ((start (point)))
169 (search-forward "\n\n")
170 (delete-region start (point))))
171 ;; Not reformatted. Delete the special
172 ;; lines before the real header.
173 (re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
174 (delete-region (point-min) (point)))
175
176 ;; Some operations on the message header itself.
122 (goto-char (point-min)) 177 (goto-char (point-min))
178 (save-restriction
179 (narrow-to-region
180 (point-min)
181 (save-excursion (search-forward "\n\n" nil 'move) (point)))
182
183 ;; Fetch or construct what we should use in the `From ' line.
184 (setq mail-from
185 (or (mail-fetch-field "Mail-From")
186 (concat "From "
187 (mail-strip-quoted-names (or (mail-fetch-field "from")
188 (mail-fetch-field "really-from")
189 (mail-fetch-field "sender")
190 "unknown"))
191 " " (current-time-string))))
192
193 ;; If the message specifies a coding system, use it.
194 (let ((maybe-coding (mail-fetch-field "X-Coding-System")))
195 (if maybe-coding
196 (setq coding (intern maybe-coding))))
197
198 ;; Delete the Mail-From: header field if any.
199 (when (re-search-forward "^Mail-from:" nil t)
200 (beginning-of-line)
201 (delete-region (point)
202 (progn (forward-line 1) (point)))))
203
204 (goto-char (point-min))
205 ;; Insert the `From ' line.
123 (insert mail-from "\n") 206 (insert mail-from "\n")
207 ;; Record the keywords and attributes in our special way.
124 (insert "X-BABYL-V6-ATTRIBUTES: " (apply 'string attrs) "\n") 208 (insert "X-BABYL-V6-ATTRIBUTES: " (apply 'string attrs) "\n")
125 (when keywords 209 (when keywords
126 (insert "X-BABYL-V6-KEYWORDS: " keywords "\n")) 210 (insert "X-BABYL-V6-KEYWORDS: " keywords "\n"))
@@ -132,43 +216,12 @@ For example, invoke `emacs -batch -f batch-unrmail RMAIL'."
132 (while (search-forward "\nFrom " nil t) 216 (while (search-forward "\nFrom " nil t)
133 (forward-char -5) 217 (forward-char -5)
134 (insert ?>))) 218 (insert ?>)))
219 ;; Write it to the output file.
135 (write-region (point-min) (point-max) to-file t 220 (write-region (point-min) (point-max) to-file t
136 'nomsg))) 221 'nomsg))))
137 (setq message-count (1+ message-count)))) 222 (kill-buffer temp-buffer))
138 (message "Writing messages to %s...done" to-file))) 223 (message "Writing messages to %s...done" to-file)))
139 224
140(defun unrmail-unprune ()
141 (let* ((pruned
142 (save-excursion
143 (goto-char (point-min))
144 (forward-line 1)
145 (= (following-char) ?1))))
146 (if pruned
147 (progn
148 (goto-char (point-min))
149 (forward-line 2)
150 ;; Delete Summary-Line headers.
151 (let ((case-fold-search t))
152 (while (looking-at "Summary-Line:")
153 (forward-line 1)))
154 (delete-region (point-min) (point))
155 ;; Delete the old reformatted header.
156 (re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
157 (forward-line -1)
158 (let ((start (point)))
159 (search-forward "\n\n")
160 (delete-region start (point))))
161 ;; Delete everything up to the real header.
162 (goto-char (point-min))
163 (re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
164 (delete-region (point-min) (point)))
165 (goto-char (point-min))
166 (when (re-search-forward "^Mail-from:")
167 (beginning-of-line)
168 (delete-region (point)
169 (progn (forward-line 1) (point))))))
170
171
172(provide 'unrmail) 225(provide 'unrmail)
173 226
174;;; unrmail.el ends here 227;;; unrmail.el ends here