1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-20 10:23:57 +00:00
emacs/lisp/mail/unrmail.el

230 lines
8.0 KiB
EmacsLisp
Raw Normal View History

;;; unrmail.el --- convert Rmail files to mailbox files
1993-03-17 17:17:05 +00:00
2005-08-06 19:51:42 +00:00
;;; Copyright (C) 1992, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1992-08-14 00:14:17 +00:00
2001-08-06 09:59:02 +00:00
;; Maintainer: FSF
1993-03-18 21:29:42 +00:00
;; Keywords: mail
1992-08-14 00:14:17 +00:00
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
1996-01-14 07:34:30 +00:00
;; along with GNU Emacs; see the file COPYING. If not, write to the
2005-07-04 17:55:18 +00:00
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
1992-08-14 00:14:17 +00:00
;;; Commentary:
1993-03-17 17:17:05 +00:00
;;; Code:
1992-08-14 00:14:17 +00:00
(defvar command-line-args-left) ;Avoid 'free variable' warning
;;;###autoload
(defun batch-unrmail ()
1994-03-31 23:40:14 +00:00
"Convert Rmail files to system inbox format.
1992-08-14 00:14:17 +00:00
Specify the input Rmail file names as command line arguments.
For each Rmail file, the corresponding output file name
is made by adding `.mail' at the end.
For example, invoke `emacs -batch -f batch-unrmail RMAIL'."
;; command-line-args-left is what is left of the command line (from startup.el)
(if (not noninteractive)
(error "`batch-unrmail' is to be used only with -batch"))
(let ((error nil))
(while command-line-args-left
(or (unrmail (car command-line-args-left)
(concat (car command-line-args-left) ".mail"))
(setq error t))
(setq command-line-args-left (cdr command-line-args-left)))
(message "Done")
(kill-emacs (if error 1 0))))
;;;###autoload
(defun unrmail (file to-file)
1994-03-31 23:40:14 +00:00
"Convert Rmail file FILE to system inbox format file TO-FILE."
1993-07-25 02:19:59 +00:00
(interactive "fUnrmail (rmail file): \nFUnrmail into (new mailbox file): ")
(with-temp-buffer
;; Read in the old Rmail file with no decoding.
(let ((coding-system-for-read 'raw-text))
(insert-file-contents file))
;; But make it multibyte.
(set-buffer-multibyte t)
(if (not (looking-at "BABYL OPTIONS"))
(error "This file is not in Babyl format"))
;; Decode the file contents just as Rmail did.
(let ((modifiedp (buffer-modified-p))
(coding-system rmail-file-coding-system)
from to)
(goto-char (point-min))
(search-forward "\n\^_" nil t) ; Skip BABYL header.
(setq from (point))
(goto-char (point-max))
(search-backward "\n\^_" from 'mv)
(setq to (point))
(unless (and coding-system
(coding-system-p coding-system))
(setq coding-system
;; Emacs 21.1 and later writes RMAIL files in emacs-mule, but
;; earlier versions did that with the current buffer's encoding.
;; So we want to favor detection of emacs-mule (whose normal
;; priority is quite low), but still allow detection of other
;; encodings if emacs-mule won't fit. The call to
;; detect-coding-with-priority below achieves that.
(car (detect-coding-with-priority
from to
'((coding-category-emacs-mule . emacs-mule))))))
(unless (memq coding-system
'(undecided undecided-unix))
(set-buffer-modified-p t) ; avoid locking when decoding
(let ((buffer-undo-list t))
(decode-coding-region from to coding-system))
(setq coding-system last-coding-system-used))
(setq buffer-file-coding-system nil)
;; We currently don't use this value, but maybe we should.
(setq save-buffer-coding-system
(or coding-system 'undecided)))
;; Default the directory of TO-FILE based on where FILE is.
(setq to-file (expand-file-name to-file default-directory))
(condition-case ()
(delete-file to-file)
(file-error nil))
1993-07-25 02:19:59 +00:00
(message "Writing messages to %s..." to-file)
(goto-char (point-min))
(let ((temp-buffer (get-buffer-create " unrmail"))
(from-buffer (current-buffer)))
;; Process the messages one by one.
(while (search-forward "\^_\^l" nil t)
(let ((beg (point))
(end (save-excursion
(if (search-forward "\^_" nil t)
(1- (point)) (point-max))))
(coding 'raw-text)
label-line attrs keywords
mail-from reformatted)
(with-current-buffer temp-buffer
(setq buffer-undo-list t)
(erase-buffer)
(setq buffer-file-coding-system coding)
(insert-buffer-substring from-buffer beg end)
(goto-char (point-min))
(forward-line 1)
;; Record whether the header is reformatted.
(setq reformatted (= (following-char) ?1))
;; Collect the label line, then get the attributes
;; and the keywords from it.
(setq label-line
(buffer-substring (point)
(save-excursion (forward-line 1)
(point))))
(search-forward ",,")
(unless (eolp)
(setq keywords
(buffer-substring (point)
(progn (end-of-line)
(1- (point)))))
(setq keywords
(replace-regexp-in-string ", " "," keywords)))
(setq attrs
(list
(if (string-match ", answered," label-line) ?A ?-)
(if (string-match ", deleted," label-line) ?D ?-)
(if (string-match ", edited," label-line) ?E ?-)
(if (string-match ", filed," label-line) ?F ?-)
(if (string-match ", resent," label-line) ?R ?-)
(if (string-match ", unseen," label-line) ?\ ?-)
(if (string-match ", stored," label-line) ?S ?-)))
;; Delete the special Babyl lines at the start,
;; and the ***EOOH*** line, and the reformatted header if any.
(goto-char (point-min))
(if reformatted
(progn
(forward-line 2)
;; Delete Summary-Line headers.
(let ((case-fold-search t))
(while (looking-at "Summary-Line:")
(forward-line 1)))
(delete-region (point-min) (point))
;; Delete the old reformatted header.
(re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
(forward-line -1)
(let ((start (point)))
(search-forward "\n\n")
(delete-region start (point))))
;; Not reformatted. Delete the special
;; lines before the real header.
(re-search-forward "^[*][*][*] EOOH [*][*][*]\n")
(delete-region (point-min) (point)))
;; Some operations on the message header itself.
(goto-char (point-min))
(save-restriction
(narrow-to-region
(point-min)
(save-excursion (search-forward "\n\n" nil 'move) (point)))
;; Fetch or construct what we should use in the `From ' line.
(setq mail-from
(or (mail-fetch-field "Mail-From")
(concat "From "
(mail-strip-quoted-names (or (mail-fetch-field "from")
(mail-fetch-field "really-from")
(mail-fetch-field "sender")
"unknown"))
" " (current-time-string))))
;; If the message specifies a coding system, use it.
(let ((maybe-coding (mail-fetch-field "X-Coding-System")))
(if maybe-coding
(setq coding (intern maybe-coding))))
;; Delete the Mail-From: header field if any.
(when (re-search-forward "^Mail-from:" nil t)
(beginning-of-line)
(delete-region (point)
(progn (forward-line 1) (point)))))
(goto-char (point-min))
;; Insert the `From ' line.
(insert mail-from "\n")
;; Record the keywords and attributes in our special way.
(insert "X-BABYL-V6-ATTRIBUTES: " (apply 'string attrs) "\n")
(when keywords
(insert "X-BABYL-V6-KEYWORDS: " keywords "\n"))
(goto-char (point-min))
;; ``Quote'' "\nFrom " as "\n>From "
;; (note that this isn't really quoting, as there is no requirement
;; that "\n[>]+From " be quoted in the same transparent way.)
(let ((case-fold-search nil))
(while (search-forward "\nFrom " nil t)
(forward-char -5)
(insert ?>)))
;; Write it to the output file.
(write-region (point-min) (point-max) to-file t
'nomsg))))
(kill-buffer temp-buffer))
1993-07-25 02:19:59 +00:00
(message "Writing messages to %s...done" to-file)))
1993-03-17 17:17:05 +00:00
1997-06-22 18:57:55 +00:00
(provide 'unrmail)
1993-03-17 17:17:05 +00:00
;;; unrmail.el ends here
2003-09-01 15:45:59 +00:00
;;; arch-tag: 14c6290d-60b2-456f-8909-5c2387de6acb