From d1c411b1e8723cee3707d49a995e118a6682199b Mon Sep 17 00:00:00 2001 From: yamaoka Date: Thu, 20 Mar 2003 01:16:57 +0000 Subject: [PATCH] Synch to Oort Gnus 200303200032. --- GNUS-NEWS | 8 +++ contrib/ChangeLog | 4 ++ contrib/gnus-idna.el | 174 ++++++++++++++++++++++++++++++-------------------- lisp/ChangeLog | 49 ++++++++++++++ lisp/gnus-art.el | 34 +++++++++- lisp/gnus-cache.el | 1 + lisp/gnus-sum.el | 13 +--- lisp/gnus-util.el | 7 +- lisp/gnus.el | 45 ++++++++++++- lisp/message.el | 72 ++++++++++++++++++++- lisp/nnmaildir.el | 11 +++- lisp/spam.el | 72 ++++++++++----------- texi/ChangeLog | 7 ++ texi/gnus-ja.texi | 24 +++++-- texi/gnus.texi | 24 +++++-- texi/message.texi | 32 ++++++++++ 16 files changed, 439 insertions(+), 138 deletions(-) diff --git a/GNUS-NEWS b/GNUS-NEWS index b399c7b..8f39bfd 100644 --- a/GNUS-NEWS +++ b/GNUS-NEWS @@ -8,6 +8,14 @@ For older news, see Gnus info node "New Features". * Changes in Oort Gnus +** Support for non-ASCII domain names + +Message supports non-ASCII domain names in From:, To: and Cc: and will +query you whether to perform encoding when you try to send a message. +The variable `message-use-idna' controls this. Gnus will also decode +non-ASCII domain names in From:, To: and Cc: when you view a message. +The variable `gnus-use-idna' controls this. + ** Better handling of Microsoft citation styles Gnus now tries to recognize the mangled header block that some Microsoft diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 4f6586b..dea7109 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2003-03-19 Simon Josefsson + + * gnus-idna.el: Update. + 2003-03-11 Teodor Zlatanov * hashcash.el (hashcash-version, hashcash-insert-payment): patch diff --git a/contrib/gnus-idna.el b/contrib/gnus-idna.el index 32eb2f8..15c47b6 100644 --- a/contrib/gnus-idna.el +++ b/contrib/gnus-idna.el @@ -24,9 +24,8 @@ ;;; Commentary: -;; This package implement crude support for internationalized -;; (non-ASCII) domain names in Gnus. It is meant as a proof of -;; concept. +;; This package implement crude support for internationalized domain +;; names in Gnus. ;; Theory of Operation: @@ -34,82 +33,121 @@ ;; using IDNA ToASCII() when you send mail using Message. The hook ;; used is message-send-hook. ;; -;; For incoming articles, when QP in headers are decoded, it searches -;; for "xn--" prefixes and decode them using IDNA ToUnicode(). The -;; hook used is gnus-article-decode-hook. +;; For incoming articles, when QP in headers are decoded (i.e., when +;; gnus-article-decode-hook is invoked), it searches for "xn--" +;; prefixes and decode them if they are found inside (heuristically +;; determined) RHS in From:, To: and Cc:, using IDNA ToUnicode(). ;; Usage: -;; Simply put (require 'gnus-idna) in your ~/.gnus or ~/.emacs and it -;; should work. You need to install GNU Libidn (0.1.11 or later) and -;; make sure the idna.el installed by it is found by emacs. +;; You need to install GNU Libidn (0.1.11 or later) and make sure the +;; idna.el installed by it is found by emacs. + +;; If you use an older Gnus, you may need to put the following in your +;; init scripts too, but keep in mind that most older Gnuses either +;; doesn't have these hooks or are buggy in other regards so it +;; doesn't work anyway. (The window of Gnus versions that this works +;; on is a few weeks during the Oort CVS in winter 2003.) Update to a +;; recent Gnus instead, then you don't have to do anything. + +;; (add-hook 'message-send-hook 'message-idna-to-ascii-rhs) +;; (add-hook 'gnus-article-decode-hook 'gnus-idna-to-unicode-rhs 'append) + +;; Revision history: + +;; 2003-02-26 Initial release +;; +;; 2003-03-19 Cleanup. Fixes a bug that may corrupt outgoing mail if +;; it contains From:, To: or Cc: headers in the body. ;;; Code: (require 'gnus) +(require 'gnus-util) (require 'rfc822) -(require 'idna) - -(eval-and-compile - (cond - ((fboundp 'replace-in-string) - (defalias 'gnus-replace-in-string 'replace-in-string)) - ((fboundp 'replace-regexp-in-string) - (defun gnus-replace-in-string (string regexp newtext &optional literal) - (replace-regexp-in-string regexp newtext string nil literal))) - (t - (defun gnus-replace-in-string (string regexp newtext &optional literal) - (let ((start 0) tail) - (while (string-match regexp string start) - (setq tail (- (length string) (match-end 0))) - (setq string (replace-match newtext nil literal string)) - (setq start (- (length string) tail)))) - string)))) - -(defun gnus-idna-to-ascii-rhs-1 (header) - (save-excursion - (save-restriction - (let (address header-data new-header-data rhs ace) +(autoload 'idna-to-ascii "idna") +(autoload 'idna-to-unicode "idna") + +(defcustom message-use-idna 'ask + "Whether to encode non-ASCII in domain names into ASCII according to IDNA." + :type '(choice (const :tag "Ask" ask) + (const :tag "Never" nil) + (const :tag "Always" t))) + +(defun message-idna-inside-rhs-p () + "Return t iff point is inside a RHS (heuristically). +Only works properly if header contains mailbox-list or address-list. +I.e., calling it on a Subject: header is useless." + (if (re-search-backward + "[\\\n\r\t ]" (save-excursion (search-backward "@" nil t)) t) + ;; whitespace between @ and point + nil + (let ((dquote 1) (paren 1)) + (while (save-excursion (re-search-backward "[^\\]\"" nil t dquote)) + (incf dquote)) + (while (save-excursion (re-search-backward "[^\\]\(" nil t paren)) + (incf paren)) + (and (= (% dquote 2) 1) (= (% paren 2) 1))))) + +(defun message-idna-to-ascii-rhs-1 (header) + "Interactively potentially IDNA encode domain names in HEADER." + (let (rhs ace start end startpos endpos) + (goto-char (point-min)) + (setq start (re-search-forward (concat "^" header) nil t) + end (or (save-excursion (re-search-forward "^[ \t]" nil t)) + (point-max))) + (when (and start end) + (while (re-search-forward "@\\([^ \t\r\n>]+\\)" end t) + (setq rhs (match-string-no-properties 1) + startpos (match-beginning 1) + endpos (match-end 1)) + (when (save-match-data + (and (message-idna-inside-rhs-p) + (setq ace (idna-to-ascii rhs)) + (not (string= rhs ace)) + (if (eq message-use-idna 'ask) + (unwind-protect + (progn + (replace-highlight startpos endpos) + (y-or-n-p + (format "Replace with `%s'? " ace))) + (message "") + (replace-dehighlight)) + message-use-idna))) + (replace-match (concat "@" ace))))))) + +;;;###autoload +(defun message-idna-to-ascii-rhs () + "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers. +See `message-idna-encode'." + (interactive) + (when (condition-case nil (require 'idna) (file-error)) + (save-excursion + (save-restriction (message-narrow-to-head) - (setq header-data (message-fetch-field header)) - (when header-data - (dolist (element (message-tokenize-header header-data)) - (setq address (car (rfc822-addresses element))) - (when (string-match "\\(.*\\)@\\([^@]+\\)" address) - (setq ace (if (setq rhs (match-string 2 address)) - (idna-to-ascii rhs))) - (push (if (string= rhs ace) - element - (gnus-replace-in-string - element (regexp-quote rhs) ace t)) - new-header-data))) - (message-remove-header header) - (message-position-on-field header) - (dolist (addr (reverse new-header-data)) - (insert addr ", ")) - (when new-header-data - (delete-backward-char 2))))))) - -(defun gnus-idna-to-ascii-rhs () - (gnus-idna-to-ascii-rhs-1 "From") - (gnus-idna-to-ascii-rhs-1 "To") - (gnus-idna-to-ascii-rhs-1 "Cc")) - -(add-hook 'message-send-hook 'gnus-idna-to-ascii-rhs) + (message-idna-to-ascii-rhs-1 "From") + (message-idna-to-ascii-rhs-1 "To") + (message-idna-to-ascii-rhs-1 "Cc"))))) +;;;###autoload (defun gnus-idna-to-unicode-rhs () - (let ((inhibit-point-motion-hooks t) - buffer-read-only) - (goto-char (point-min)) - (while (re-search-forward "xn--.*[ \t\n\r.,<>()@!]" nil t) - ;(or (eobp) (forward-char)) - (let (ace unicode) - (when (setq ace (match-string 0)) - (setq unicode (idna-to-unicode ace)) - (unless (string= ace unicode) - (replace-match unicode))))))) - -(add-hook 'gnus-article-decode-hook 'gnus-idna-to-unicode-rhs 'append) + "Decode IDNA strings in RHS in From:, To: and Cc: headers in current buffer." + (when (condition-case nil (require 'idna) (file-error)) + (let ((inhibit-point-motion-hooks t) + buffer-read-only) + (article-narrow-to-head) + (goto-char (point-min)) + (while (re-search-forward "\\(xn--.*\\)[ \t\n\r,>]" nil t) + (let (ace unicode) + (when (save-match-data + (and (setq ace (match-string 1)) + (save-excursion (and (re-search-backward "^[^ \t]" nil t) + (looking-at "From\\|To\\|Cc"))) + (save-excursion (backward-char) + (message-idna-inside-rhs-p)) + (setq unicode (idna-to-unicode ace)))) + (unless (string= ace unicode) + (replace-match unicode nil nil nil 1)))))))) (provide 'gnus-idna) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7e1be81..0a9528d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,52 @@ +2003-03-20 Katsumi Yamaoka + + * gnus-cache.el (gnus-cache-braid-nov): Test if a line looks like + a NOV. + +2003-03-20 Simon Josefsson + + * message.el (message-use-idna): Disable if UTF-8 unavailable. + (message-idna-to-ascii-rhs): Use it. + + * gnus-art.el (gnus-use-idna): Disable if UTF-8 unavailable. + +2003-03-19 Teodor Zlatanov + + * spam.el (spam-group-ham-mark-p, spam-group-spam-mark-p) + (spam-group-ham-marks, spam-group-spam-marks): new functions + (spam-spam-marks, spam-ham-marks): removed in favor of the + spam-marks and ham-marks parameters + (spam-generic-register-routine, spam-ham-move-routine): use the + new spam-group-{spam,ham}-mark-p functions + + * gnus.el (spam-marks, ham-marks): new group parameters with + default values same as the old spam-spam-marks and spam-ham-marks + +2003-03-19 Simon Josefsson + + * gnus-art.el (gnus-article-decode-hook): Add IDNA. + (gnus-use-idna): New variable. + (article-decode-idna-rhs): New function. + + * message.el (message-use-idna): New variable. + (message-mode-field-menu): Add entry for IDNA. + (message-idna-inside-rhs-p, message-idna-to-ascii-rhs-1) + (message-idna-to-ascii-rhs): New function. + (message-generate-headers): Invoke IDNA code. + +2003-03-19 Paul Jarc + + * nnmaildir.el (nnmaildir--system-name): New function. + (nnmaildir-request-accept-article): Use it. + +2003-03-19 Katsumi Yamaoka + + * gnus-util.el (gnus-byte-compile): Make it work silently as the + gnus-compile function does. + + * gnus-sum.el (gnus-summary-highlight-line-0): Revoke the last + bogus change. + 2003-03-19 Jesper Harder * mm-util.el (mm-mule-charset-to-mime-charset): Test if diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index d84e51c..1f76669 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -731,7 +731,8 @@ displayed by the first non-nil matching CONTENT face." (item :tag "skip" nil) (face :value default))))) -(defcustom gnus-article-decode-hook nil +(defcustom gnus-article-decode-hook + '(article-decode-group-name article-decode-idna-rhs) "*Hook run to decode charsets in articles." :group 'gnus-article-headers :type 'hook) @@ -1418,6 +1419,14 @@ It is a string, such as \"PGP\". If nil, ask user." (defvar gnus-article-wash-function nil "Function used for converting HTML into text.") +(defcustom gnus-use-idna (and (condition-case nil (require 'idna) (file-error)) + (fboundp 'coding-system-p) + (coding-system-p 'utf-8)) + "Whether IDNA decoding of headers is used when viewing messages. +This requires GNU Libidn, and by default only enabled if it is found." + :group 'gnus-article-headers + :type 'boolean) + ;;; Internal variables (defvar gnus-english-month-names @@ -2255,6 +2264,29 @@ If PROMPT (the prefix), prompt for a coding system to use." (nnmail-fetch-field "Followup-To")) gnus-newsgroup-name method)))))) +(autoload 'idna-to-unicode "idna") + +(defun article-decode-idna-rhs () + "Decode IDNA strings in RHS in From:, To: and Cc: headers in current buffer." + (when gnus-use-idna + (save-restriction + (let ((inhibit-point-motion-hooks t) + buffer-read-only) + (article-narrow-to-head) + (goto-char (point-min)) + (while (re-search-forward "\\(xn--.*\\)[ \t\n\r,>]" nil t) + (let (ace unicode) + (when (save-match-data + (and (setq ace (match-string 1)) + (save-excursion + (and (re-search-backward "^[^ \t]" nil t) + (looking-at "From\\|To\\|Cc"))) + (save-excursion (backward-char) + (message-idna-inside-rhs-p)) + (setq unicode (idna-to-unicode ace)))) + (unless (string= ace unicode) + (replace-match unicode nil nil nil 1))))))))) + (defun article-de-quoted-unreadable (&optional force read-charset) "Translate a quoted-printable-encoded article. If FORCE, decode the article whether it is marked as quoted-printable diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el index e9733a2..0194803 100644 --- a/lisp/gnus-cache.el +++ b/lisp/gnus-cache.el @@ -511,6 +511,7 @@ Returns the list of articles removed." (goto-char (point-min)) (while cached (while (and (not (eobp)) + (looking-at "[0-9]+\t") (< (read (current-buffer)) (car cached))) (forward-line 1)) (beginning-of-line) diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index ad9f6e5..5cc2b95 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -11218,18 +11218,7 @@ If REVERSE, save parts that do not match TYPE." (setcdr c (cons (list (caar list) (list 'quote (cdar list))) nil)) (setq c (cdr c) list (cdr list))) - (let ((byte-compile-warnings - ;; Since XEmacs version of bytecomp complains about - ;; the unbound variables because of `globally-boundp' - ;; even if they are bound by `let', we silence it. - (if (and (boundp 'byte-compile-default-warnings) ;; XEmacs - (listp (symbol-value - 'byte-compile-default-warnings))) - (delq 'free-vars - (copy-sequence (symbol-value - 'byte-compile-default-warnings))) - byte-compile-warnings))) - (gnus-byte-compile (list 'lambda nil cond))))))) + (gnus-byte-compile (list 'lambda nil cond)))))) (defun gnus-summary-highlight-line () "Highlight current line according to `gnus-summary-highlight'." diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index df890d1..6f924dc 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -1168,8 +1168,11 @@ Setting it to nil has no effect after first time running (require 'byte-optimize) (error)) (require 'bytecomp) - (defalias 'gnus-byte-compile 'byte-compile) - (byte-compile form)) + (defalias 'gnus-byte-compile + (lambda (form) + (let ((byte-compile-warnings '(unresolved callargs redefine))) + (byte-compile form)))) + (gnus-byte-compile form)) form)) (defun gnus-remassoc (key alist) diff --git a/lisp/gnus.el b/lisp/gnus.el index 2030ffb..fc93a9b 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -1983,7 +1983,50 @@ mail groups, and only works in spam groups." (string :tag "Move to a group") (const :tag "Expire" nil)))) :parameter-document - "Where ham articles will go at summary exit from a spam group.")) + "Where ham articles will go at summary exit from a spam group.") + + (gnus-define-group-parameter + ham-marks + :type 'list + :parameter-type '(list :tag "Ham mark choices" + (set + (variable-item gnus-del-mark) + (variable-item gnus-read-mark) + (variable-item gnus-killed-mark) + (variable-item gnus-kill-file-mark) + (variable-item gnus-low-score-mark))) + + :parameter-document + "Marks considered ham (positively not spam). Such articles will be +processed as ham (non-spam) on group exit. When nil, the global +spam-ham-marks variable takes precedence." + :variable-default '((".*" ((gnus-del-mark + gnus-read-mark + gnus-killed-mark + gnus-kill-file-mark + gnus-low-score-mark)))) + :variable-group spam + :variable-document + "*Groups in which to explicitly set the ham marks to some value.") + + (gnus-define-group-parameter + spam-marks + :type 'list + :parameter-type '(list :tag "Spam mark choices" + (set + (variable-item gnus-spam-mark) + (variable-item gnus-killed-mark) + (variable-item gnus-kill-file-mark) + (variable-item gnus-low-score-mark))) + + :parameter-document + "Marks considered spam. +Such articles will be processed as spam on group exit. When nil, the global +spam-spam-marks variable takes precedence." + :variable-default '((".*" ((gnus-spam-mark)))) + :variable-group spam + :variable-document + "*Groups in which to explicitly set the spam marks to some value.")) (defcustom gnus-group-uncollapsed-levels 1 "Number of group name elements to leave alone when making a short group name." diff --git a/lisp/message.el b/lisp/message.el index 7abec7f..2009338 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -1504,6 +1504,17 @@ no, only reply back to the author." :link '(custom-manual "(message)News Headers") :type 'string) +(defcustom message-use-idna (and (condition-case nil (require 'idna) + (file-error)) + (fboundp 'coding-system-p) + (coding-system-p 'utf-8) + 'ask) + "Whether to encode non-ASCII in domain names into ASCII according to IDNA." + :group 'message-headers + :type '(choice (const :tag "Ask" ask) + (const :tag "Never" nil) + (const :tag "Always" t))) + ;;; Internal variables. (defvar message-sending-message "Sending...") @@ -2413,6 +2424,7 @@ Point is left at the beginning of the narrowed-to region." ["Reduce To: to Cc:" message-reduce-to-to-cc t] "----" ["Sort Headers" message-sort-headers t] + ["Encode non-ASCII domain names" message-idna-to-ascii-rhs t] ["Goto Body" message-goto-body t] ["Goto Signature" message-goto-signature t])) @@ -5260,6 +5272,62 @@ string." (concat message-user-agent " " user-agent)) message-user-agent))))) +(defun message-idna-inside-rhs-p () + "Return t iff point is inside a RHS (heuristically). +Only works properly if header contains mailbox-list or address-list. +I.e., calling it on a Subject: header is useless." + (if (re-search-backward + "[\\\n\r\t ]" (save-excursion (search-backward "@" nil t)) t) + ;; whitespace between @ and point + nil + (let ((dquote 1) (paren 1)) + (while (save-excursion (re-search-backward "[^\\]\"" nil t dquote)) + (incf dquote)) + (while (save-excursion (re-search-backward "[^\\]\(" nil t paren)) + (incf paren)) + (and (= (% dquote 2) 1) (= (% paren 2) 1))))) + +(autoload 'idna-to-ascii "idna") + +(defun message-idna-to-ascii-rhs-1 (header) + "Interactively potentially IDNA encode domain names in HEADER." + (let (rhs ace start end startpos endpos) + (goto-char (point-min)) + (setq start (re-search-forward (concat "^" header) nil t) + end (or (save-excursion (re-search-forward "^[ \t]" nil t)) + (point-max))) + (when (and start end) + (while (re-search-forward "@\\([^ \t\r\n>]+\\)" end t) + (setq rhs (match-string-no-properties 1) + startpos (match-beginning 1) + endpos (match-end 1)) + (when (save-match-data + (and (message-idna-inside-rhs-p) + (setq ace (idna-to-ascii rhs)) + (not (string= rhs ace)) + (if (eq message-use-idna 'ask) + (unwind-protect + (progn + (replace-highlight startpos endpos) + (y-or-n-p + (format "Replace with `%s'? " ace))) + (message "") + (replace-dehighlight)) + message-use-idna))) + (replace-match (concat "@" ace))))))) + +(defun message-idna-to-ascii-rhs () + "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers. +See `message-idna-encode'." + (interactive) + (when message-use-idna + (save-excursion + (save-restriction + (message-narrow-to-head) + (message-idna-to-ascii-rhs-1 "From") + (message-idna-to-ascii-rhs-1 "To") + (message-idna-to-ascii-rhs-1 "Cc"))))) + (defun message-generate-headers (headers) "Prepare article HEADERS. Headers already prepared in the buffer are not modified." @@ -5413,7 +5481,9 @@ Headers already prepared in the buffer are not modified." (beginning-of-line)) (when (or (message-news-p) (string-match "@.+\\.." secure-sender)) - (insert "Sender: " secure-sender "\n"))))))) + (insert "Sender: " secure-sender "\n")))) + ;; Check for IDNA + (message-idna-to-ascii-rhs)))) (defun message-insert-courtesy-copy () "Insert a courtesy message in mail copies of combined messages." diff --git a/lisp/nnmaildir.el b/lisp/nnmaildir.el index e49b77a..a625bf2 100644 --- a/lisp/nnmaildir.el +++ b/lisp/nnmaildir.el @@ -547,6 +547,15 @@ by nnmaildir-request-article.") (defun nnmaildir--up2-1 (n) (if (zerop n) 1 (1- (lsh 1 (1+ (logb n)))))) +(defun nnmaildir--system-name () + (gnus-replace-in-string + (gnus-replace-in-string + (gnus-replace-in-string + (system-name) + "\\\\" "\\134" 'literal) + "/" "\\057" 'literal) + ":" "\\072" 'literal)) + (defun nnmaildir-request-type (group &optional article) 'mail) @@ -1318,7 +1327,7 @@ by nnmaildir-request-article.") (setq file (concat file "M" (number-to-string (caddr time))))) (setq file (concat file nnmaildir--delivery-pid) file (concat file "Q" (number-to-string nnmaildir--delivery-count)) - file (concat file "." (system-name)) ;;;; FIXME: encode / and : + file (concat file "." (nnmaildir--system-name)) tmpfile (concat (nnmaildir--tmp dir) file) curfile (concat (nnmaildir--cur dir) file ":2,")) (when (file-exists-p tmpfile) diff --git a/lisp/spam.el b/lisp/spam.el index dc44be1..fc5b8c6 100644 --- a/lisp/spam.el +++ b/lisp/spam.el @@ -187,29 +187,6 @@ All unmarked article in such group receive the spam mark on group entry." :type 'regexp :group 'spam) -(defcustom spam-ham-marks (list 'gnus-del-mark 'gnus-read-mark - 'gnus-killed-mark 'gnus-kill-file-mark - 'gnus-low-score-mark) - "Marks considered as being ham (positively not spam). -Such articles will be processed as ham (non-spam) on group exit." - :type '(set - (variable-item gnus-del-mark) - (variable-item gnus-read-mark) - (variable-item gnus-killed-mark) - (variable-item gnus-kill-file-mark) - (variable-item gnus-low-score-mark)) - :group 'spam) - -(defcustom spam-spam-marks (list 'gnus-spam-mark) - "Marks considered as being spam (positively spam). -Such articles will be transmitted to `bogofilter -s' on group exit." - :type '(set - (variable-item gnus-spam-mark) - (variable-item gnus-killed-mark) - (variable-item gnus-kill-file-mark) - (variable-item gnus-low-score-mark)) - :group 'spam) - (defcustom spam-face 'gnus-splash-face "Face for spam-marked articles" :type 'face @@ -313,6 +290,29 @@ your main source of newsgroup names." gnus-summary-highlight) ;; convenience functions +(defun spam-group-ham-mark-p (group mark &optional spam) + (when (stringp group) + (let* ((marks (spam-group-ham-marks group spam)) + (marks (if (symbolp mark) + marks + (mapcar 'symbol-value marks)))) + (memq mark marks)))) + +(defun spam-group-spam-mark-p (group mark) + (spam-group-ham-mark-p group mark t)) + +(defun spam-group-ham-marks (group &optional spam) + (when (stringp group) + (let* ((marks (if spam + (gnus-parameter-spam-marks group) + (gnus-parameter-ham-marks group))) + (marks (car marks)) + (marks (if (listp (car marks)) (car marks) marks))) + marks))) + +(defun spam-group-spam-marks (group) + (spam-group-ham-marks group t)) + (defun spam-group-spam-contents-p (group) (if (stringp group) (or (member group spam-junk-mailgroups) @@ -466,13 +466,12 @@ your main source of newsgroup names." (defun spam-ham-move-routine (&optional group copy) (gnus-summary-kill-process-mark) (let ((articles gnus-newsgroup-articles) - article ham-mark-values mark tomove) + article mark tomove) (when (stringp group) ; this routine will do nothing ; without a valid group - (dolist (mark spam-ham-marks) - (push (symbol-value mark) ham-mark-values)) (dolist (article articles) - (when (memq (gnus-summary-article-mark article) ham-mark-values) + (when (spam-group-spam-mark-p gnus-newsgroup-name + (gnus-summary-article-mark article)) (push article tomove))) ;; now do the actual move @@ -488,24 +487,17 @@ your main source of newsgroup names." (defun spam-generic-register-routine (spam-func ham-func) (let ((articles gnus-newsgroup-articles) - article mark ham-articles spam-articles spam-mark-values - ham-mark-values) - - ;; marks are stored as symbolic values, so we have to dereference - ;; them for memq to work. we wouldn't have to do this if - ;; gnus-summary-article-mark returned a symbol. - (dolist (mark spam-ham-marks) - (push (symbol-value mark) ham-mark-values)) - - (dolist (mark spam-spam-marks) - (push (symbol-value mark) spam-mark-values)) + article mark ham-articles spam-articles) (while articles (setq article (pop articles) mark (gnus-summary-article-mark article)) - (cond ((memq mark spam-mark-values) (push article spam-articles)) + (cond ((spam-group-spam-mark-p gnus-newsgroup-name mark) + (push article spam-articles)) ((memq article gnus-newsgroup-saved)) - ((memq mark ham-mark-values) (push article ham-articles)))) + ((spam-group-ham-mark-p gnus-newsgroup-name mark) + (push article ham-articles)))) + (when (and ham-articles ham-func) (mapc ham-func ham-articles)) ; we use mapc because unlike ; mapcar it discards the diff --git a/texi/ChangeLog b/texi/ChangeLog index bfe6ec9..8020268 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,10 @@ +2003-03-19 Simon Josefsson + + * gnus.texi (Misc Article): Add. + (Agent Basics): Fix makeinfo warnings. + + * message.texi (IDNA): New. + 2003-03-18 Kevin Greiner * gnus.texi (Gnus Unplugged): Refer to new agent Group/Topic diff --git a/texi/gnus-ja.texi b/texi/gnus-ja.texi index 91d1f1f..0b23be9 100644 --- a/texi/gnus-ja.texi +++ b/texi/gnus-ja.texi @@ -10388,6 +10388,17 @@ GNUS $B$d(B Gnus $B$G$O!"$3$N$?$A$N0-$$LdBj$G6C$+$5$l$J$$$h$&$K$9$k$K$O!"35N, @vindex gnus-page-delimiter $B$3$l$,>e$G?($l$?6h@Z$jJ8;z$G$9!#%G%#%U%)%k%H$G$O(B @samp{^L} ($B%U%)!<%`(B $B%U%#!<%I!"2~JG(B) $B$G$9!#(B + +@c TRANSLATEME +@cindex IDNA +@cindex internationalized domain names +@vindex gnus-use-idna +@item gnus-use-idna +This variable controls whether Gnus performs IDNA decoding of +internationalized domain names inside @sc{From:}, @sc{To:} and +@sc{Cc:} headers. This requires GNU Libidn +(@url{http://www.gnu.org/software/libidn/}, and this variable is only +enabled if you have installed it. @end table @node Composing Messages @@ -16618,12 +16629,13 @@ you are going to use agent categories, topic parameters, and/or group parameters to implement your policy. If you're new to gnus, it is probably best to start with a category @xref{Agent Categories}. -Both topic parameters (@xref{Topic Parameters}) and agent -categories (@xref{Agent Categories}) provide for setting a policy that -applies to multiple groups. Which you use is entirely up to you. Topic -parameters do override categories so, if you mix the two, you'll have to -take that into account. If you have a few groups that deviate from your -policy, you can use @xref{Group Parameters} to configure them. +Both topic parameters (@pxref{Topic Parameters}) and agent categories +(@pxref{Agent Categories}) provide for setting a policy that applies +to multiple groups. Which you use is entirely up to you. Topic +parameters do override categories so, if you mix the two, you'll have +to take that into account. If you have a few groups that deviate from +your policy, you can use grou parameters (@pxref{Group Parameters}) to +configure them. @item $B$($($H(B@dots{}$B!"0J>e$G$9!#(B diff --git a/texi/gnus.texi b/texi/gnus.texi index fdd35cc..2f1ea2c 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -10941,6 +10941,17 @@ paging will not be done. @vindex gnus-page-delimiter This is the delimiter mentioned above. By default, it is @samp{^L} (formfeed). + +@cindex IDNA +@cindex internationalized domain names +@vindex gnus-use-idna +@item gnus-use-idna +This variable controls whether Gnus performs IDNA decoding of +internationalized domain names inside @sc{From:}, @sc{To:} and +@sc{Cc:} headers. This requires GNU Libidn +(@url{http://www.gnu.org/software/libidn/}, and this variable is only +enabled if you have installed it. + @end table @@ -17020,12 +17031,13 @@ you are going to use agent categories, topic parameters, and/or group parameters to implement your policy. If you're new to gnus, it is probably best to start with a category @xref{Agent Categories}. -Both topic parameters (@xref{Topic Parameters}) and agent -categories (@xref{Agent Categories}) provide for setting a policy that -applies to multiple groups. Which you use is entirely up to you. Topic -parameters do override categories so, if you mix the two, you'll have to -take that into account. If you have a few groups that deviate from your -policy, you can use @xref{Group Parameters} to configure them. +Both topic parameters (@pxref{Topic Parameters}) and agent categories +(@pxref{Agent Categories}) provide for setting a policy that applies +to multiple groups. Which you use is entirely up to you. Topic +parameters do override categories so, if you mix the two, you'll have +to take that into account. If you have a few groups that deviate from +your policy, you can use grou parameters (@pxref{Group Parameters}) to +configure them. @item Uhm@dots{} that's it. diff --git a/texi/message.texi b/texi/message.texi index c387174..bbeaaf0 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -503,6 +503,7 @@ better than you do. * Movement:: Moving around in message buffers. * Insertion:: Inserting things into message buffers. * MIME:: @sc{mime} considerations. +* IDNA:: Non-ASCII domain name considerations. * Security:: Signing and encrypting messages. * Various Commands:: Various things. * Sending:: Actually sending the message. @@ -833,6 +834,37 @@ You can also create arbitrarily complex multiparts using the MML language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME Manual}). +@node IDNA +@section IDNA +@cindex IDNA +@cindex internationalized domain names +@cindex non-ascii domain names + +Message is a @sc{idna}-compliant posting agent. The user generally +doesn't have to do anything to make the @sc{idna} happen---Message +will encode non-ASCII domain names in @code{From}, @code{To}, and +@code{Cc} headers automatically. + +Until IDNA becomes more well known, Message queries you whether IDNA +encoding of the domain name really should occur. Some users might not +be aware that domain names can contain non-ASCII now, so this gives +them a safety net if they accidently typed a non-ASCII domain name. + +@vindex message-use-idna +The @code{message-use-idna} variable control whether @sc{idna} is +used. If the variable is @sc{nil} no IDNA encoding will ever happen, +if it is set to the symbol @sc{ask} the user will be queried (the +default), and if set to @sc{t} IDNA encoding happens automatically. + +@findex message-idna-to-ascii-rhs +If you want to experiment with the IDNA encoding, you can invoke +@kbd{M-x message-idna-to-ascii-rhs RET} in the message buffer to have +the non-ASCII domain names encoded while you edit the message. + +Note that you must have GNU Libidn +(@url{http://www.gnu.org/software/libidn/} installed in order to use +this functionality. + @node Security @section Security @cindex Security -- 1.7.10.4