aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2004-03-04 23:33:44 +0000
committerKenichi Handa2004-03-04 23:33:44 +0000
commit608aa380cffd0645d9ea99abae420ea82a601e5e (patch)
treec6d3acab838f112388176890e7697255ffb064d9
parent9fb9a1b555501db302a77a4860b223922d1dded4 (diff)
downloademacs-608aa380cffd0645d9ea99abae420ea82a601e5e.tar.gz
emacs-608aa380cffd0645d9ea99abae420ea82a601e5e.zip
Sync to HEAD.
-rw-r--r--lisp/mail/rmail.el239
1 files changed, 176 insertions, 63 deletions
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index deb043ffba9..4090749d83e 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -1,6 +1,6 @@
1;;; rmail.el --- main code of "RMAIL" mail reader for Emacs 1;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
2 2
3;; Copyright (C) 1985,86,87,88,93,94,95,96,97,98,2000, 2001 3;; Copyright (C) 1985,86,87,88,93,94,95,96,97,98,2000, 01, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Maintainer: FSF 6;; Maintainer: FSF
@@ -139,9 +139,9 @@ plus whatever is specified by `rmail-default-dont-reply-to-names'."
139 :group 'rmail-reply) 139 :group 'rmail-reply)
140 140
141;;;###autoload 141;;;###autoload
142(defvar rmail-default-dont-reply-to-names "info-" "\ 142(defvar rmail-default-dont-reply-to-names "\\`info-" "\
143A regular expression specifying part of the value of the default value of 143A regular expression specifying part of the default value of the
144the variable `rmail-dont-reply-to-names', for when the user does not set 144variable `rmail-dont-reply-to-names', for when the user does not set
145`rmail-dont-reply-to-names' explicitly. (The other part of the default 145`rmail-dont-reply-to-names' explicitly. (The other part of the default
146value is the user's email address and name.) 146value is the user's email address and name.)
147It is useful to set this variable in the site customization file.") 147It is useful to set this variable in the site customization file.")
@@ -1364,6 +1364,7 @@ It returns t if it got any new messages."
1364 (while all-files 1364 (while all-files
1365 (let ((opoint (point)) 1365 (let ((opoint (point))
1366 (new-messages 0) 1366 (new-messages 0)
1367 (rsf-number-of-spam 0)
1367 (delete-files ()) 1368 (delete-files ())
1368 ;; If buffer has not changed yet, and has not been saved yet, 1369 ;; If buffer has not changed yet, and has not been saved yet,
1369 ;; don't replace the old backup file now. 1370 ;; don't replace the old backup file now.
@@ -1446,11 +1447,62 @@ It returns t if it got any new messages."
1446 (progn (goto-char opoint) 1447 (progn (goto-char opoint)
1447 (if (or file-name rmail-inbox-list) 1448 (if (or file-name rmail-inbox-list)
1448 (message "(No new mail has arrived)"))) 1449 (message "(No new mail has arrived)")))
1449 (if (rmail-summary-exists) 1450 ;; check new messages to see if any of them is spam:
1451 (if (and (featurep 'rmail-spam-filter)
1452 rmail-use-spam-filter)
1453 (let*
1454 ((old-messages (- rmail-total-messages new-messages))
1455 (rsf-scanned-message-number (1+ old-messages))
1456 ;; save deletion flags of old messages: vector starts
1457 ;; at zero (is one longer that no of messages),
1458 ;; therefore take 1+ old-messages
1459 (save-deleted
1460 (substring rmail-deleted-vector 0 (1+
1461 old-messages))))
1462 ;; set all messages to undeleted
1463 (setq rmail-deleted-vector
1464 (make-string (1+ rmail-total-messages) ?\ ))
1465 (while (<= rsf-scanned-message-number
1466 rmail-total-messages)
1467 (progn
1468 (if (not (rmail-spam-filter rsf-scanned-message-number))
1469 (progn (setq rsf-number-of-spam (1+ rsf-number-of-spam)))
1470 )
1471 (setq rsf-scanned-message-number (1+ rsf-scanned-message-number))
1472 ))
1473 (if (> rsf-number-of-spam 0)
1474 (progn
1475 (when (rmail-expunge-confirmed)
1476 (rmail-only-expunge t))
1477 ))
1478 (setq rmail-deleted-vector
1479 (concat
1480 save-deleted
1481 (make-string (- rmail-total-messages old-messages)
1482 ?\ )))
1483 ))
1484 (if (rmail-summary-exists)
1450 (rmail-select-summary 1485 (rmail-select-summary
1451 (rmail-update-summary))) 1486 (rmail-update-summary)))
1452 (message "%d new message%s read" 1487 (message "%d new message%s read%s"
1453 new-messages (if (= 1 new-messages) "" "s")) 1488 new-messages (if (= 1 new-messages) "" "s")
1489 ;; print out a message on number of spam messages found:
1490 (if (and (featurep 'rmail-spam-filter)
1491 rmail-use-spam-filter
1492 (> rsf-number-of-spam 0))
1493 (if (= 1 new-messages)
1494 ", and found to be a spam message"
1495 (if (> rsf-number-of-spam 1)
1496 (format ", %d of which found to be spam messages"
1497 rsf-number-of-spam)
1498 ", one of which found to be a spam message"))
1499 ""))
1500 (if (and (featurep 'rmail-spam-filter)
1501 rmail-use-spam-filter
1502 (> rsf-number-of-spam 0))
1503 (progn (if rmail-spam-filter-beep (beep t))
1504 (sleep-for rmail-spam-sleep-after-message)))
1505
1454 ;; Move to the first new message 1506 ;; Move to the first new message
1455 ;; unless we have other unseen messages before it. 1507 ;; unless we have other unseen messages before it.
1456 (rmail-show-message (rmail-first-unseen-message)) 1508 (rmail-show-message (rmail-first-unseen-message))
@@ -1652,12 +1704,73 @@ It returns t if it got any new messages."
1652 (save-excursion 1704 (save-excursion
1653 (skip-chars-forward " \t\n") 1705 (skip-chars-forward " \t\n")
1654 (point))) 1706 (point)))
1655 (setq last-coding-system-used nil) 1707 (save-excursion
1656 (or rmail-enable-mime 1708 (let* ((header-end
1657 (not rmail-enable-multibyte) 1709 (progn
1658 (decode-coding-region start (point) 1710 (save-excursion
1659 (or rmail-file-coding-system 1711 (goto-char start)
1660 'undecided))) 1712 (forward-line 1)
1713 (if (looking-at "0")
1714 (forward-line 1)
1715 (forward-line 2))
1716 (save-restriction
1717 (narrow-to-region (point) (point-max))
1718 (rfc822-goto-eoh)
1719 (point)))))
1720 (case-fold-search t)
1721 (quoted-printable-header-field-end
1722 (save-excursion
1723 (goto-char start)
1724 (re-search-forward
1725 "^content-transfer-encoding:\\(\n?[\t ]\\)*quoted-printable\\(\n?[\t ]\\)*"
1726 header-end t)))
1727 (base64-header-field-end
1728 (save-excursion
1729 (goto-char start)
1730 (re-search-forward
1731 "^content-transfer-encoding:\\(\n?[\t ]\\)*base64\\(\n?[\t ]\\)*"
1732 header-end t))))
1733 (if quoted-printable-header-field-end
1734 (save-excursion
1735 (unless
1736 (mail-unquote-printable-region header-end (point) nil t)
1737 (message "Malformed MIME quoted-printable message"))
1738 ;; Change "quoted-printable" to "8bit",
1739 ;; to reflect the decoding we just did.
1740 (goto-char quoted-printable-header-field-end)
1741 (delete-region (point) (search-backward ":"))
1742 (insert ": 8bit")))
1743 (if base64-header-field-end
1744 (save-excursion
1745 (when
1746 (condition-case nil
1747 (progn
1748 (base64-decode-region (1+ header-end)
1749 (- (point) 2))
1750 t)
1751 (error nil))
1752 ;; Change "base64" to "8bit", to reflect the
1753 ;; decoding we just did.
1754 (goto-char (1+ header-end))
1755 (while (search-forward "\r\n" (point-max) t)
1756 (replace-match "\n"))
1757 (goto-char base64-header-field-end)
1758 (delete-region (point) (search-backward ":"))
1759 (insert ": 8bit"))))
1760 (setq last-coding-system-used nil)
1761 (or rmail-enable-mime
1762 (not rmail-enable-multibyte)
1763 (let ((mime-charset
1764 (if (and rmail-decode-mime-charset
1765 (save-excursion
1766 (goto-char start)
1767 (search-forward "\n\n" nil t)
1768 (let ((case-fold-search t))
1769 (re-search-backward
1770 rmail-mime-charset-pattern
1771 start t))))
1772 (intern (downcase (match-string 1))))))
1773 (rmail-decode-region start (point) mime-charset)))))
1661 ;; Add an X-Coding-System: header if we don't have one. 1774 ;; Add an X-Coding-System: header if we don't have one.
1662 (save-excursion 1775 (save-excursion
1663 (goto-char start) 1776 (goto-char start)
@@ -1673,7 +1786,9 @@ It returns t if it got any new messages."
1673 (insert "X-Coding-System: " 1786 (insert "X-Coding-System: "
1674 (symbol-name last-coding-system-used) 1787 (symbol-name last-coding-system-used)
1675 "\n"))) 1788 "\n")))
1676 (narrow-to-region (point) (point-max))) 1789 (narrow-to-region (point) (point-max))
1790 (and (= 0 (% count 10))
1791 (message "Converting to Babyl format...%d" count)))
1677 ;;*** MMDF format 1792 ;;*** MMDF format
1678 ((let ((case-fold-search t)) 1793 ((let ((case-fold-search t))
1679 (looking-at rmail-mmdf-delim1)) 1794 (looking-at rmail-mmdf-delim1))
@@ -1698,7 +1813,9 @@ It returns t if it got any new messages."
1698 (symbol-name last-coding-system-used) 1813 (symbol-name last-coding-system-used)
1699 "\n")) 1814 "\n"))
1700 (narrow-to-region (point) (point-max)) 1815 (narrow-to-region (point) (point-max))
1701 (setq count (1+ count))) 1816 (setq count (1+ count))
1817 (and (= 0 (% count 10))
1818 (message "Converting to Babyl format...%d" count)))
1702 ;;*** Mail format 1819 ;;*** Mail format
1703 ((looking-at "^From ") 1820 ((looking-at "^From ")
1704 (insert "\^L\n0, unseen,,\n*** EOOH ***\n") 1821 (insert "\^L\n0, unseen,,\n*** EOOH ***\n")
@@ -1714,6 +1831,11 @@ It returns t if it got any new messages."
1714 (re-search-forward 1831 (re-search-forward
1715 "^content-transfer-encoding:\\(\n?[\t ]\\)*quoted-printable\\(\n?[\t ]\\)*" 1832 "^content-transfer-encoding:\\(\n?[\t ]\\)*quoted-printable\\(\n?[\t ]\\)*"
1716 header-end t))) 1833 header-end t)))
1834 (base64-header-field-end
1835 (save-excursion
1836 (re-search-forward
1837 "^content-transfer-encoding:\\(\n?[\t ]\\)*base64\\(\n?[\t ]\\)*"
1838 header-end t)))
1717 (size 1839 (size
1718 ;; Get the numeric value from the Content-Length field. 1840 ;; Get the numeric value from the Content-Length field.
1719 (save-excursion 1841 (save-excursion
@@ -1757,12 +1879,37 @@ It returns t if it got any new messages."
1757 (setq count (1+ count)) 1879 (setq count (1+ count))
1758 (if quoted-printable-header-field-end 1880 (if quoted-printable-header-field-end
1759 (save-excursion 1881 (save-excursion
1760 (rmail-decode-quoted-printable header-end (point)) 1882 (unless
1883 (mail-unquote-printable-region header-end (point) nil t)
1884
1885 (message "Malformed MIME quoted-printable message"))
1761 ;; Change "quoted-printable" to "8bit", 1886 ;; Change "quoted-printable" to "8bit",
1762 ;; to reflect the decoding we just did. 1887 ;; to reflect the decoding we just did.
1763 (goto-char quoted-printable-header-field-end) 1888 (goto-char quoted-printable-header-field-end)
1764 (delete-region (point) (search-backward ":")) 1889 (delete-region (point) (search-backward ":"))
1765 (insert ": 8bit")))) 1890 (insert ": 8bit")))
1891 (if base64-header-field-end
1892 (save-excursion
1893 (when
1894 (condition-case nil
1895 (progn
1896 (base64-decode-region
1897 (1+ header-end)
1898 (save-excursion
1899 ;; Prevent base64-decode-region
1900 ;; from removing newline characters.
1901 (skip-chars-backward "\n\t ")
1902 (point)))
1903 t)
1904 (error nil))
1905 (goto-char header-end)
1906 (while (search-forward "\r\n" (point-max) t)
1907 (replace-match "\n"))
1908 ;; Change "base64" to "8bit", to reflect the
1909 ;; decoding we just did.
1910 (goto-char base64-header-field-end)
1911 (delete-region (point) (search-backward ":"))
1912 (insert ": 8bit")))))
1766 1913
1767 (save-excursion 1914 (save-excursion
1768 (save-restriction 1915 (save-restriction
@@ -1770,6 +1917,7 @@ It returns t if it got any new messages."
1770 (goto-char (point-min)) 1917 (goto-char (point-min))
1771 (while (search-forward "\n\^_" nil t); single char 1918 (while (search-forward "\n\^_" nil t); single char
1772 (replace-match "\n^_")))); 2 chars: "^" and "_" 1919 (replace-match "\n^_")))); 2 chars: "^" and "_"
1920 (or (bolp) (newline)) ; in case we lost the final newline.
1773 (insert ?\^_) 1921 (insert ?\^_)
1774 (setq last-coding-system-used nil) 1922 (setq last-coding-system-used nil)
1775 (or rmail-enable-mime 1923 (or rmail-enable-mime
@@ -1791,7 +1939,9 @@ It returns t if it got any new messages."
1791 (insert "X-Coding-System: " 1939 (insert "X-Coding-System: "
1792 (symbol-name last-coding-system-used) 1940 (symbol-name last-coding-system-used)
1793 "\n")) 1941 "\n"))
1794 (narrow-to-region (point) (point-max))) 1942 (narrow-to-region (point) (point-max))
1943 (and (= 0 (% count 10))
1944 (message "Converting to Babyl format...%d" count)))
1795 ;; 1945 ;;
1796 ;; This kludge is because some versions of sendmail.el 1946 ;; This kludge is because some versions of sendmail.el
1797 ;; insert an extra newline at the beginning that shouldn't 1947 ;; insert an extra newline at the beginning that shouldn't
@@ -1801,45 +1951,6 @@ It returns t if it got any new messages."
1801 (t (error "Cannot convert to babyl format"))))) 1951 (t (error "Cannot convert to babyl format")))))
1802 count)) 1952 count))
1803 1953
1804(defun rmail-hex-char-to-integer (character)
1805 "Return CHARACTER's value interpreted as a hex digit."
1806 (if (and (>= character ?0) (<= character ?9))
1807 (- character ?0)
1808 (let ((ch (logior character 32)))
1809 (if (and (>= ch ?a) (<= ch ?f))
1810 (- ch (- ?a 10))
1811 (error "Invalid hex digit `%c'" ch)))))
1812
1813(defun rmail-hex-string-to-integer (hex-string)
1814 "Return decimal integer for HEX-STRING."
1815 (let ((hex-num 0)
1816 (index 0))
1817 (while (< index (length hex-string))
1818 (setq hex-num (+ (* hex-num 16)
1819 (rmail-hex-char-to-integer (aref hex-string index))))
1820 (setq index (1+ index)))
1821 hex-num))
1822
1823(defun rmail-decode-quoted-printable (from to)
1824 "Decode Quoted-Printable in the region between FROM and TO."
1825 (interactive "r")
1826 (goto-char from)
1827 (or (markerp to)
1828 (setq to (copy-marker to)))
1829 (while (search-forward "=" to t)
1830 (cond ((eq (following-char) ?\n)
1831 (delete-char -1)
1832 (delete-char 1))
1833 ((looking-at "[0-9A-F][0-9A-F]")
1834 (let ((byte (rmail-hex-string-to-integer
1835 (buffer-substring (point) (+ 2 (point))))))
1836 (delete-region (1- (point)) (+ 2 (point)))
1837 (insert byte)))
1838 ((looking-at "=")
1839 (delete-char 1))
1840 (t
1841 (message "Malformed MIME quoted-printable message")))))
1842
1843;; Delete the "From ..." line, creating various other headers with 1954;; Delete the "From ..." line, creating various other headers with
1844;; information from it if they don't already exist. Now puts the 1955;; information from it if they don't already exist. Now puts the
1845;; original line into a mail-from: header line for debugging and for 1956;; original line into a mail-from: header line for debugging and for
@@ -2947,7 +3058,7 @@ See also user-option `rmail-confirm-expunge'."
2947 (funcall rmail-confirm-expunge 3058 (funcall rmail-confirm-expunge
2948 "Erase deleted messages from Rmail file? "))) 3059 "Erase deleted messages from Rmail file? ")))
2949 3060
2950(defun rmail-only-expunge () 3061(defun rmail-only-expunge (&optional dont-show)
2951 "Actually erase all deleted messages in the file." 3062 "Actually erase all deleted messages in the file."
2952 (interactive) 3063 (interactive)
2953 (set-buffer rmail-buffer) 3064 (set-buffer rmail-buffer)
@@ -3026,11 +3137,12 @@ See also user-option `rmail-confirm-expunge'."
3026 (message "Expunging deleted messages...done") 3137 (message "Expunging deleted messages...done")
3027 (if (not win) 3138 (if (not win)
3028 (narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax))) 3139 (narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax)))
3029 (rmail-show-message 3140 (if (not dont-show)
3030 (if (zerop rmail-current-message) 1 nil)) 3141 (rmail-show-message
3031 (if rmail-enable-mime 3142 (if (zerop rmail-current-message) 1 nil)
3032 (goto-char (+ (point-min) opoint)) 3143 (if rmail-enable-mime
3033 (goto-char (+ (point) opoint)))))) 3144 (goto-char (+ (point-min) opoint))
3145 (goto-char (+ (point) opoint))))))))
3034 3146
3035(defun rmail-expunge () 3147(defun rmail-expunge ()
3036 "Erase deleted messages from Rmail file and summary buffer." 3148 "Erase deleted messages from Rmail file and summary buffer."
@@ -3755,4 +3867,5 @@ encoded string (and the same mask) will decode the string."
3755 3867
3756(provide 'rmail) 3868(provide 'rmail)
3757 3869
3870;;; arch-tag: cff0a950-57fe-4f73-a86e-91ff75afd06c
3758;;; rmail.el ends here 3871;;; rmail.el ends here