From: yamaoka Date: Thu, 20 Apr 2000 22:00:58 +0000 (+0000) Subject: Importing Gnus v5.8.4. X-Git-Tag: gnus-5_8_4~1 X-Git-Url: http://git.chise.org/gitweb/?p=elisp%2Fgnus.git-;a=commitdiff_plain;h=3ad5943c4ad67b4f8d556436b31c3ca8bc4b5064 Importing Gnus v5.8.4. --- diff --git a/GNUS-NEWS b/GNUS-NEWS index ae36555..c9f6a07 100644 --- a/GNUS-NEWS +++ b/GNUS-NEWS @@ -7,6 +7,22 @@ internationalization and mail-fetching. *** The mail-fetching functions have changed. See the manual for the many details. In particular, all procmail fetching variables are gone. +If you used procmail like in + +(setq nnmail-use-procmail t) +(setq nnmail-spool-file 'procmail) +(setq nnmail-procmail-directory "~/mail/incoming/") +(setq nnmail-procmail-suffix "\\.in") + +this now has changed to + +(setq mail-sources + '((directory :path "~/mail/incoming/" + :suffix ".in"))) + +More information is available in the info doc at Select Methods -> +Getting Mail -> Mail Sources + *** Gnus is now a MIME-capable reader. This affects many parts of Gnus, and adds a slew of new commands. See the manual for details. diff --git a/README b/README index e487c43..d99625f 100644 --- a/README +++ b/README @@ -24,6 +24,13 @@ To enable reading the Gnus manual, you could say something like: (setq Info-default-directory-list (cons "~/gnus-5.6.53/texi" Info-default-directory-list)) +or + + (setq Info-directory-list + (cons "~/gnus-5.6.53/texi" Info-directory-list)) + +depending on which version of Emacs or XEmacs you're using. + Note that Gnus and GNUS can't coexist in a single Emacs. They both use the same function and variable names. If you have been running GNUS in your Emacs, you should probably exit that Emacs and start a new one diff --git a/aclocal.m4 b/aclocal.m4 index 1e00601..1b62c54 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -4,7 +4,7 @@ AC_DEFUN(AM_PATH_LISPDIR, [# If set to t, that means we are running in a shell under Emacs. # If you have an Emacs named "t", then use the full path. test "$EMACS" = t && EMACS= - AC_PATH_PROGS(EMACS, emacs xemacs, no) + test "$EMACS" || AC_PATH_PROGS(EMACS, emacs xemacs, no) if test $EMACS != "no"; then AC_MSG_CHECKING([where .elc files should go]) dnl Set default value diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 7eeca12..74238c9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,301 @@ +Thu Apr 20 01:39:25 2000 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v5.8.4 is released. + +2000-04-19 Dave Love + + * mailcap.el (mailcap-parse-mimetypes): Add ...mime.types. + +2000-04-18 12:28:24 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-type-definition): New egroups html. + (nnwarchive-egroups-*): Ditto. + (nnwarchive-url): Unibyte buffer and single line cookie. + +2000-04-14 18:50:04 Shenghuo ZHU + + * mm-util.el (mm-char-or-char-int-p): New alias. + * nnweb.el (nnweb-decode-entities): Check the validity of numeric + entities. + +2000-04-10 Daiki Ueno + + * lisp/imap.el (imap-body-lines): Check Content-Type: of the + article case insensitively. + +2000-04-10 20:35:46 Shenghuo ZHU + + * mail-source.el (mail-source-fetch-webmail): Use the default + password provided in mail-sources; use webmail:subtype:user as + the key. + +2000-04-10 20:35:46 John Wiegley + + * mail-source.el (mail-source-fetch-webmail): Use + mail-source-password-cache. + +2000-04-09 18:13:47 Shenghuo ZHU + + * webmail.el: Add netscape mail and fix HotMail mail. + +2000-04-08 Simon Josefsson + + * imap.el (imap-kerberos4-open): Work with recent `imtest's. + +2000-04-02 Simon Josefsson + + * nnimap.el (nnimap-request-article): Use BODY.PEEK[] instead of + RFC822.PEEK if server support IMAP4rev1. + (nnimap-request-body): Use BODY.PEEK[TEXT] instead of + RFC822.TEXT.PEEK if server support IMAP4rev1. + (nnimap-request-head): Use BODY.PEEK[HEADER] instead of + RFC822.HEADER if server support IMAP4rev1. + (nnimap-request-article-part): Support bodydetail in response + data. + +2000-03-11 Simon Josefsson + + * fill-flowed.el: New file. + + * mm-decode.el (mm-dissect-singlepart): Create a MIME handle for + text/plain parts with `format' parameters. + + * mm-view.el (autoload): Autoload fill-flowed. + (mm-inline-text): For "plain" parts with a format=flowed + parameter, call `fill-flowed'. + +2000-03-21 10:32:44 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-list): Fudge new-style + slashdot ids. + +2000-03-20 00:12:42 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-list): Use the new slashdot + format. + +2000-03-16 Simon Josefsson + + * imap.el: GSSAPI support, support kerberos 4 with Cyrus v1.6.x + `imtest' too. + (imap-kerberos4-program): Renamed from `imap-imtest-program'. + (imap-gssapi-program): New variable. + (imap-streams): Add gssapi. + (imap-stream-alist): Ditto. + (imap-authenticators): Ditto. + (imap-authenticator-alist): Ditto. + (imap-kerberos4-stream-p): Rename from `imap-kerberos4s-p'. + (imap-kerberos4-open): Loop over imtest programs, support Cyrus + 1.6.x `imtest' syntax. + (imap-gssapi-stream-p): New function. + (imap-gssapi-open): Ditto. + (imap-gssapi-auth-p): Ditto. + (imap-gssapi-auth): Ditto. + (imap-kerberos4-auth-p): Renamed from `imap-kerberos4a-p'. + (imap-send-command): Use buffer-local `imap-client-eol' value. + + * nnimap.el (nnimap-retrieve-headers-progress): Fold continuation + lines and turn TAB into SPC before parsing. + +2000-03-15 Simon Josefsson + + * nnheader.el (nnheader-group-pathname): Make sure to return a + directory. + * nnmail.el (nnmail-group-pathname): Ditto. + +2000-02-08 Per Abrahamsen + + * nnmail.el (nnmail-fix-eudora-headers): Fix `In-Reply-To' too, it + might split in the middle of a message-id. + +2000-03-13 13:51:38 Lars Magne Ingebrigtsen + + * gnus-srvr.el (gnus-server-kill-server): Offer to kill all the + groups from the server. + + * gnus-sum.el (gnus-summary-save-parts): Fix interactive spec. + (gnus-summary-toggle-header): Update the wash status. + + * gnus-uu.el ((gnus-uu-extract-map "X" gnus-summary-mode-map)): + Moved here. + + * gnus-agent.el (gnus-agent-save-group-info): Respect old + setting. + + * nnmail.el (nnmail-get-active): Use it. + (nnmail-parse-active): New function. + + * mm-view.el (mm-inline-text): Support the new version of + vcard.el. + + * gnus-sum.el (gnus-summary-move-article): Only delete article + when moving junk. + (gnus-deaden-summary): Bury the buffer. + + * nnmail.el (nnmail-group-pathname): Ditto. + + * nnheader.el (nnheader-group-pathname): Use expand-file-name. + +2000-03-13 20:23:06 Christoph Rohland + + * rfc2047.el (rfc2047-encode-message-header): Encode no matter + whether Mule. + +2000-03-10 14:57:58 Lars Magne Ingebrigtsen + + * message.el (message-send-mail): Protect against unloaded Gnus. + + * gnus-topic.el (gnus-topic-update-topic-line): Don't update the + parent. + (gnus-topic-update-topic-line): Yes, do. + (gnus-topic-goto-missing-group): Tally the correct number of + unread articles before inserting the topic line. + +2000-03-01 09:55:26 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Ignore errors. + +2000-02-13 13:53:08 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-dissect-buffer): Ditto. + + * gnus-art.el (article-decode-charset): Strip CTE. + + * ietf-drums.el (ietf-drums-strip): New function. + + * gnus-sum.el (gnus-summary-move-article): Don't use the prefix + when prompting in read-only groups. + +2000-02-23 Simon Josefsson + + * imap.el (imap-send-command): Change EOL-chars when + `imap-client-eol' differs from default, not only for kerberos4. + (imap-mailbox-status): Get encoded mailbox's status. + +2000-02-19 Simon Josefsson + + * mail-source.el (mail-source-fetch-imap): Copy `imap-password' + into `mail-source-password-cache'. + +2000-02-17 Florian Weimer + + * mm-util.el (mm-mime-charset): Check for presence of + `coding-system-get' and `get-charset-property' (recent XEmacs has + the former, but not the latter). + +2000-01-28 Dave Love + + * message.el (message-check-news-header-syntax): Fix typo + `newsgroyps'. + (message-talkative-question): Put temp buffer in fundamental-mode. + (message-recover): Use fundamental-mode in the right buffer. + + * nnmail.el (nnmail-split-history): Use fundamental-mode in the + right buffer. + +2000-01-26 12:01:18 Shenghuo ZHU + + * qp.el (quoted-printable-decode-region): Add charset parameter. + (quoted-printable-decode-string): Ditto. + + * gnus-art.el (article-de-quoted-unreadable): Use it. + +2000-01-21 Simon Josefsson + + * nnimap.el (nnimap-split-predicate): New variable. + (nnimap-split-articles): Use it. + +2000-01-20 Simon Josefsson + + * utf7.el: Change email address. + +2000-01-18 22:03:51 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-catchup): Purge split history. + +2000-01-14 02:43:55 Shenghuo ZHU + + * nnmail.el (nnmail-generate-active): Support extended group name. + (nnmail-get-active): Ditto. + +2000-01-13 15:16:10 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-write-active): Since no prefix in + group names, don't remove anything. + +2000-01-13 15:10:53 Shenghuo ZHU + + * webmail.el (webmail-my-deja-open): My-deja changes. + +2000-01-13 Simon Josefsson + + * nnimap.el (nnimap-retrieve-headers-progress): Create xref field. + +2000-01-10 23:35:33 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-fetch-headers): Translate full path. + +2000-01-09 22:52:35 Shenghuo ZHU + + * gnus.el (gnus-other-frame): Fix typo. + +1999-06-25 Andreas Jaeger + + * gnus-cus.el (gnus-group-customize): Fix typo. + +2000-01-08 08:36:13 Lars Magne Ingebrigtsen + + * nnweb.el (nnweb-insert): Simplified. + +2000-01-06 18:32:53 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-mode-map): "e" is + gnus-summary-edit-article. + +2000-01-06 18:25:37 Jari Aalto + + * mailcap.el (mailcap-mime-extensions): Add .diff. + +2000-01-06 00:06:40 Kim-Minh Kaplan + + * mm-decode.el (mm-mailcap-command): handle "%%" and the case where + there is no "%s" in the method. + +2000-01-08 21:01:04 Kim-Minh Kaplan + + * gnus-sum.el (gnus-summary-select-article): Return 'old. + +2000-01-06 13:41:11 Lars Magne Ingebrigtsen + + * nnfolder.el (nnfolder-read-folder): Use nnfolder-save-buffer. + + * gnus.el: Really always pop up a new frame. + + * parse-time.el (parse-time-rules): Allow 100-110 to be + 2000-2010. + + * time-date.el (date-to-time): Don't use timezone. + +2000-01-06 Dave Love + + * time-date.el: Add keywords. + (date-to-time): Add autoload cookie. Canonicalize with + timezone-make-date-arpa-standard. + (time-to-seconds): Avoid caddr. + (safe-date-to-time): Add autoload cookie. + + * base64.el: Require cl when compiling. + +2000-01-05 17:31:52 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-select-article): Return whether we + selected something new. + (gnus-summary-search-article): Start searching at the window + point. + + * gnus-group.el (gnus-fetch-group): Complete over + gnus-active-hashtb. + Wed Jan 5 17:06:41 2000 Lars Magne Ingebrigtsen * gnus.el: Pterodactyl Gnus v5.8.3 is released. diff --git a/lisp/base64.el b/lisp/base64.el index 2635349..36e1374 100644 --- a/lisp/base64.el +++ b/lisp/base64.el @@ -25,6 +25,8 @@ ;;; Boston, MA 02111-1307, USA. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(eval-when-compile (require 'cl)) + ;; For non-MULE (if (not (fboundp 'char-int)) (fset 'char-int 'identity)) diff --git a/lisp/fill-flowed.el b/lisp/fill-flowed.el new file mode 100644 index 0000000..b0883de --- /dev/null +++ b/lisp/fill-flowed.el @@ -0,0 +1,94 @@ +;;; fill-flowed.el --- interprete RFC2646 "flowed" text +;; Copyright (C) 2000 Free Software Foundation, Inc. + +;; Author: Simon Josefsson +;; Keywords: mail + +;; This program 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 of the License, or +;; (at your option) any later version. +;; +;; This program 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 +;; along with this program; if not, write to the Free Software +;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +;;; Commentary: + +;; This implement decoding of RFC2646 formatted text, including the +;; quoted-depth wins rules. + +;; Theory of operation: search for lines ending with SPC, save quote +;; length of line, remove SPC and concatenate line with the following +;; line if quote length of following line matches current line. + +;; When no further concatenations are possible, we've found a +;; paragraph and we let `fill-region' fill the long line into several +;; lines with the quote prefix as `fill-prefix'. + +;; Todo: encoding + +;; History: + +;; 2000-02-17 posted on ding mailing list +;; 2000-02-19 use `point-at-{b,e}ol' in XEmacs +;; 2000-03-11 no compile warnings for point-at-bol stuff +;; 2000-03-26 commited to gnus cvs + +;;; Code: + +(eval-and-compile + (fset 'fill-flowed-point-at-bol + (if (fboundp 'point-at-bol) + 'point-at-bol + 'line-beginning-position)) + + (fset 'fill-flowed-point-at-eol + (if (fboundp 'point-at-eol) + 'point-at-eol + 'line-end-position))) + +(defun fill-flowed (&optional buffer) + (save-excursion + (set-buffer (or (current-buffer) buffer)) + (goto-char (point-min)) + (while (re-search-forward " $" nil t) + (when (save-excursion + (beginning-of-line) + (looking-at "^\\(>*\\)\\( ?\\)")) + (let ((quote (match-string 1))) + (if (string= quote "") + (setq quote nil)) + (when (and quote (string= (match-string 2) "")) + (save-excursion + ;; insert SP after quote for pleasant reading of quoted lines + (beginning-of-line) + (when (> (skip-chars-forward ">") 0) + (insert " ")))) + (while (and (save-excursion + (backward-char 3) + (looking-at "[^-][^-] ")) + (save-excursion + (unless (eobp) + (forward-char 1) + (if quote + (looking-at (format "^\\(%s\\)\\([^>]\\)" quote)) + (looking-at "^ ?"))))) + (save-excursion + (replace-match (if (string= (match-string 2) " ") + "" "\\2"))) + (backward-delete-char -1) + (end-of-line)) + (let ((fill-prefix (when quote (concat quote " ")))) + (fill-region (fill-flowed-point-at-bol) + (fill-flowed-point-at-eol) + 'left 'nosqueeze))))))) + +(provide 'fill-flowed) + +;;; fill-flowed.el ends here diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index 7b867e5..4e9ddd8 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -611,7 +611,9 @@ the actual number of articles toggled is returned." new)) (gnus-make-directory (file-name-directory file)) (let ((coding-system-for-write gnus-agent-file-coding-system)) - (gnus-write-active-file file orig)))) + ;; The hashtable contains real names of groups, no more prefix + ;; removing, so set `full' to `t'. + (gnus-write-active-file file orig t)))) (defun gnus-agent-save-groups (method) (gnus-agent-save-active-1 method 'gnus-groups-to-gnus-format)) @@ -619,7 +621,8 @@ the actual number of articles toggled is returned." (defun gnus-agent-save-group-info (method group active) (when (gnus-agent-method-p method) (let* ((gnus-command-method method) - (file (gnus-agent-lib-file "active"))) + (file (gnus-agent-lib-file "active")) + oactive) (gnus-make-directory (file-name-directory file)) (with-temp-file file (when (file-exists-p file) @@ -627,9 +630,17 @@ the actual number of articles toggled is returned." (goto-char (point-min)) (when (re-search-forward (concat "^" (regexp-quote group) " ") nil t) + (save-excursion + (save-restriction + (narrow-to-region (match-beginning 0) + (progn + (forward-line 1) + (point))) + (setq oactive (car (nnmail-parse-active))))) (gnus-delete-line)) - (insert (format "%S %d %d y\n" (intern group) (cdr active) - (car active))) + (insert (format "%S %d %d y\n" (intern group) + (cdr active) + (or (car oactive) (car active)))) (goto-char (point-max)) (while (search-backward "\\." nil t) (delete-char 1)))))) @@ -865,7 +876,7 @@ the actual number of articles toggled is returned." (cdr (gnus-active group))))))) ;; Fetch them. (gnus-make-directory (nnheader-translate-file-chars - (file-name-directory file))) + (file-name-directory file) t)) (when articles (gnus-message 7 "Fetching headers for %s..." group) (save-excursion diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 99b3001..d4e73a8 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -1439,6 +1439,8 @@ If PROMPT (the prefix), prompt for a coding system to use." (mm-read-coding-system "Charset to decode: ")) (ctl (mail-content-type-get ctl 'charset)))) + (when cte + (setq cte (mail-header-strip cte))) (if (and ctl (not (string-match "/" (car ctl)))) (setq ctl nil)) (goto-char (point-max))) @@ -1478,11 +1480,7 @@ or not." (when (or force (and type (string-match "quoted-printable" (downcase type)))) (article-goto-body) - (save-restriction - (narrow-to-region (point) (point-max)) - (quoted-printable-decode-region (point-min) (point-max)) - (when charset - (mm-decode-body charset))))))) + (quoted-printable-decode-region (point) (point-max) charset))))) (eval-when-compile (require 'rfc1843)) @@ -2474,7 +2472,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is "s" gnus-article-show-summary "\C-c\C-m" gnus-article-mail "?" gnus-article-describe-briefly - "e" gnus-summary-article-edit + "e" gnus-summary-edit-article "<" beginning-of-buffer ">" end-of-buffer "\C-c\C-i" gnus-info-find-node diff --git a/lisp/gnus-cus.el b/lisp/gnus-cus.el index 92baaca..1bc3c6c 100644 --- a/lisp/gnus-cus.el +++ b/lisp/gnus-cus.el @@ -323,7 +323,7 @@ DOC is a documentation string for the parameter.") :tag "Parameters" :format "%t:\n%h%v" :doc "\ -These special paramerters are recognized by Gnus. +These special parameters are recognized by Gnus. Check the [ ] for the parameters you want to apply to this group or to the groups in this topic, then edit the value to suit your taste." ,@types) diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index f465afc..dc09b56 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -1570,7 +1570,7 @@ be permanent." (defun gnus-fetch-group (group) "Start Gnus if necessary and enter GROUP. Returns whether the fetching was successful or not." - (interactive "sGroup name: ") + (interactive (list (completing-read "Group name: " gnus-active-hashtb))) (unless (get-buffer gnus-group-buffer) (gnus-no-server)) (gnus-group-read-group nil nil group)) @@ -2599,6 +2599,8 @@ The return value is the number of articles that were marked as read, or nil if no action could be taken." (let* ((entry (gnus-gethash group gnus-newsrc-hashtb)) (num (car entry))) + ;; Remove entries for this group. + (nnmail-purge-split-history (gnus-group-real-name group)) ;; Do the updating only if the newsgroup isn't killed. (if (not (numberp (car entry))) (gnus-message 1 "Can't catch up %s; non-active group" group) diff --git a/lisp/gnus-srvr.el b/lisp/gnus-srvr.el index bba79f0..9057e21 100644 --- a/lisp/gnus-srvr.el +++ b/lisp/gnus-srvr.el @@ -296,6 +296,18 @@ The following commands are available: (push (assoc server gnus-server-alist) gnus-server-killed-servers) (setq gnus-server-alist (delq (car gnus-server-killed-servers) gnus-server-alist)) + (let ((groups (gnus-groups-from-server server))) + (when (and groups + (gnus-yes-or-no-p + (format "Kill all %s groups from this server? " + (length groups)))) + (dolist (group groups) + (setq gnus-newsrc-alist + (delq (assoc group gnus-newsrc-alist) + gnus-newsrc-alist)) + (when gnus-group-change-level-function + (funcall gnus-group-change-level-function + group gnus-level-killed 3))))) (gnus-server-position-point)) (defun gnus-server-yank-server () diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index 405bd8d..25bc11f 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -1899,7 +1899,10 @@ newsgroup." (gnus-group-prefixed-name "" method)))) ;; Let the Gnus agent save the active file. - (if (and gnus-agent real-active gnus-plugged (gnus-agent-method-p method)) + (if (and gnus-agent + real-active + gnus-plugged + (gnus-agent-method-p method)) (progn (gnus-agent-save-groups method) (gnus-active-to-gnus-format method hashtb nil real-active)) diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 31d99d9..fb0663f 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -696,7 +696,8 @@ is not run if `gnus-visual' is nil." :type 'hook) (defcustom gnus-exit-group-hook nil - "*A hook called when exiting (not quitting) summary mode." + "*A hook called when exiting summary mode. +This hook is not called from the non-updating exit commands like `Q'." :group 'gnus-various :type 'hook) @@ -5537,7 +5538,8 @@ The state which existed when entering the ephemeral is reset." (rename-buffer (concat (substring name 0 (match-beginning 0)) "Dead " (substring name (match-beginning 0))) - t)))) + t) + (bury-buffer)))) (defun gnus-kill-or-deaden-summary (buffer) "Kill or deaden the summary BUFFER." @@ -5796,37 +5798,34 @@ be displayed." (set-buffer gnus-summary-buffer)) (let ((article (or article (gnus-summary-article-number))) (all-headers (not (not all-headers))) ;Must be T or NIL. - gnus-summary-display-article-function - did) + gnus-summary-display-article-function) (and (not pseudo) (gnus-summary-article-pseudo-p article) (error "This is a pseudo-article")) - (prog1 - (save-excursion - (set-buffer gnus-summary-buffer) - (if (or (and gnus-single-article-buffer - (or (null gnus-current-article) - (null gnus-article-current) - (null (get-buffer gnus-article-buffer)) - (not (eq article (cdr gnus-article-current))) - (not (equal (car gnus-article-current) - gnus-newsgroup-name)))) - (and (not gnus-single-article-buffer) - (or (null gnus-current-article) - (not (eq gnus-current-article article)))) - force) - ;; The requested article is different from the current article. - (prog1 - (gnus-summary-display-article article all-headers) - (setq did article) - (when (or all-headers gnus-show-all-headers) - (gnus-article-show-all-headers))) + (save-excursion + (set-buffer gnus-summary-buffer) + (if (or (and gnus-single-article-buffer + (or (null gnus-current-article) + (null gnus-article-current) + (null (get-buffer gnus-article-buffer)) + (not (eq article (cdr gnus-article-current))) + (not (equal (car gnus-article-current) + gnus-newsgroup-name)))) + (and (not gnus-single-article-buffer) + (or (null gnus-current-article) + (not (eq gnus-current-article article)))) + force) + ;; The requested article is different from the current article. + (progn + (gnus-summary-display-article article all-headers) (when (or all-headers gnus-show-all-headers) (gnus-article-show-all-headers)) - 'old)) - (when did - (gnus-article-set-window-start - (cdr (assq article gnus-newsgroup-bookmarks))))))) + (gnus-article-set-window-start + (cdr (assq article gnus-newsgroup-bookmarks))) + article) + (when (or all-headers gnus-show-all-headers) + (gnus-article-show-all-headers)) + 'old)))) (defun gnus-summary-set-current-mark (&optional current-mark) "Obsolete function." @@ -6986,6 +6985,7 @@ Optional argument BACKWARD means do search for backward. (gnus-save-hidden-threads (gnus-summary-select-article) (set-buffer gnus-article-buffer) + (goto-char (window-point (get-buffer-window (current-buffer)))) (when backward (forward-line -1)) (while (not found) @@ -7236,8 +7236,11 @@ If ARG is a negative number, hide the unwanted header lines." (if hidden (let ((gnus-treat-hide-headers nil) (gnus-treat-hide-boring-headers nil)) + (setq gnus-article-wash-types + (delq 'headers gnus-article-wash-types)) (gnus-treat-article 'head)) - (gnus-treat-article 'head))))))) + (gnus-treat-article 'head))) + (gnus-set-mode-line 'article))))) (defun gnus-summary-show-all-headers () "Make all header lines visible." @@ -7304,7 +7307,10 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." 'request-replace-article gnus-newsgroup-name))) (error "The current group does not support article editing"))) (let ((articles (gnus-summary-work-articles n)) - (prefix (gnus-group-real-prefix gnus-newsgroup-name)) + (prefix (if (gnus-check-backend-function + 'request-move-article gnus-newsgroup-name) + (gnus-group-real-prefix gnus-newsgroup-name) + "")) (names '((move "Move" "Moving") (copy "Copy" "Copying") (crosspost "Crosspost" "Crossposting"))) @@ -7393,10 +7399,10 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (gnus-message 1 "Couldn't %s article %s: %s" (cadr (assq action names)) article (nnheader-get-report (car to-method)))) - ((and (eq art-group 'junk) - (eq action 'move)) - (gnus-summary-mark-article article gnus-canceled-mark) - (gnus-message 4 "Deleted article %s" article)) + ((eq art-group 'junk) + (when (eq action 'move) + (gnus-summary-mark-article article gnus-canceled-mark) + (gnus-message 4 "Deleted article %s" article))) (t (let* ((pto-group (gnus-group-prefixed-name (car art-group) to-method)) @@ -9041,12 +9047,12 @@ save those articles instead." (error "No such group: %s" to-newsgroup))) to-newsgroup)) -(defun gnus-summary-save-parts (type dir n reverse) +(defun gnus-summary-save-parts (type dir n &optional reverse) "Save parts matching TYPE to DIR. If REVERSE, save parts that do not match TYPE." (interactive (list (read-string "Save parts of type: " "image/.*") - (read-file-name "Save to directory: " t nil t) + (read-file-name "Save to directory: " nil nil t) current-prefix-arg)) (gnus-summary-iterate n (let ((gnus-display-mime-function nil) diff --git a/lisp/gnus-topic.el b/lisp/gnus-topic.el index 34f5a7b..b5b18cf 100644 --- a/lisp/gnus-topic.el +++ b/lisp/gnus-topic.el @@ -594,7 +594,8 @@ articles in the topic and its subtopics." (let* ((topic (gnus-group-topic group)) (groups (cdr (assoc topic gnus-topic-alist))) (g (cdr (member group groups))) - (unfound t)) + (unfound t) + entry) ;; Try to jump to a visible group. (while (and g (not (gnus-group-goto-group (car g) t))) (pop g)) @@ -608,8 +609,20 @@ articles in the topic and its subtopics." (when (and unfound topic (not (gnus-topic-goto-missing-topic topic))) - (gnus-topic-insert-topic-line - topic t t (car (gnus-topic-find-topology topic)) nil 0))))) + (let* ((top (gnus-topic-find-topology topic)) + (children (cddr top)) + (type (cadr top)) + (unread 0) + (entries (gnus-topic-find-groups + (car type) (car gnus-group-list-mode) + (cdr gnus-group-list-mode)))) + (while children + (incf unread (gnus-topic-unread (caar (pop children))))) + (while (setq entry (pop entries)) + (when (numberp (car entry)) + (incf unread (car entry)))) + (gnus-topic-insert-topic-line + topic t t (car (gnus-topic-find-topology topic)) nil unread)))))) (defun gnus-topic-goto-missing-topic (topic) (if (gnus-topic-goto-topic topic) diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el index 8418f26..1f4ed39 100644 --- a/lisp/gnus-uu.el +++ b/lisp/gnus-uu.el @@ -369,12 +369,11 @@ didn't work, and overwrite existing files. Otherwise, ask each time." "k" gnus-summary-kill-process-mark "y" gnus-summary-yank-process-mark "w" gnus-summary-save-process-mark - "i" gnus-uu-invert-processable - "m" gnus-summary-save-parts) + "i" gnus-uu-invert-processable) (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map) ;;"x" gnus-uu-extract-any - ;;"m" gnus-uu-extract-mime + "m" gnus-summary-save-parts "u" gnus-uu-decode-uu "U" gnus-uu-decode-uu-and-save "s" gnus-uu-decode-unshar diff --git a/lisp/gnus-win.el b/lisp/gnus-win.el index 6a335e8..1da662d 100644 --- a/lisp/gnus-win.el +++ b/lisp/gnus-win.el @@ -446,12 +446,12 @@ See the Gnus manual for an explanation of the syntax used.") (gnus-delete-windows-in-gnusey-frames)) ;; Just remove some windows. (gnus-remove-some-windows) - (set-buffer nntp-server-buffer)) + (set-buffer nntp-server-buffer)) (select-frame frame))) (let (gnus-window-frame-focus) - (set-buffer nntp-server-buffer) - (gnus-configure-frame split) + (set-buffer nntp-server-buffer) + (gnus-configure-frame split) (when gnus-window-frame-focus (select-frame (window-frame gnus-window-frame-focus)))))))) diff --git a/lisp/gnus.el b/lisp/gnus.el index debcd1f..10c4eea 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -1,5 +1,6 @@ ;;; gnus.el --- a newsreader for GNU Emacs -;; Copyright (C) 1987-1990,1993-1999 Free Software Foundation, Inc. +;; Copyright (C) 1987, 88, 89, 90, 93, 94, 95, 96, 97, 98, 99 +;; Free Software Foundation, Inc. ;; Author: Masanobu UMEDA ;; Lars Magne Ingebrigtsen @@ -31,10 +32,6 @@ (eval-when-compile (require 'cl)) (require 'mm-util) -(require 'custom) -(eval-and-compile - (if (< emacs-major-version 20) - (require 'gnus-load))) (require 'message) (defgroup gnus nil @@ -260,7 +257,7 @@ is restarted, and sometimes reloaded." :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) -(defconst gnus-version-number "5.8.3" +(defconst gnus-version-number "5.8.4" "Version number for this version of Gnus.") (defconst gnus-version (format "Gnus v%s" gnus-version-number) @@ -1616,17 +1613,16 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.") (when (consp function) (setq keymap (car (memq 'keymap function))) (setq function (car function))) - (autoload function (car package) nil interactive keymap))) + (unless (fboundp function) + (autoload function (car package) nil interactive keymap)))) (if (eq (nth 1 package) ':interactive) - (cdddr package) + (nthcdr 3 package) (cdr package))))) - '(("metamail" metamail-buffer) - ("info" Info-goto-node) + '(("info" :interactive t Info-goto-node) ("pp" pp pp-to-string pp-eval-expression) ("qp" quoted-printable-decode-region quoted-printable-decode-string) ("ps-print" ps-print-preprint) - ("mail-extr" mail-extract-address-components) - ("browse-url" browse-url) + ("browse-url" :interactive t browse-url) ("message" :interactive t message-send-and-exit message-yank-original) ("babel" babel-as-string) @@ -2861,10 +2857,13 @@ As opposed to `gnus', this command will not connect to the local server." (let ((window (get-buffer-window gnus-group-buffer))) (cond (window (select-frame (window-frame window))) - (t - (other-frame 1)))) + (t + (select-frame (make-frame))))) (gnus arg)) +;;(setq thing ? ; this is a comment +;; more 'yes) + ;;;###autoload (defun gnus (&optional arg dont-connect slave) "Read network news. diff --git a/lisp/ietf-drums.el b/lisp/ietf-drums.el index 6ef4fc1..6df0b0f 100644 --- a/lisp/ietf-drums.el +++ b/lisp/ietf-drums.el @@ -115,7 +115,7 @@ (buffer-string)))) (defun ietf-drums-remove-whitespace (string) - "Remove comments from STRING." + "Remove whitespace from STRING." (with-temp-buffer (ietf-drums-init string) (let (c) @@ -151,6 +151,10 @@ (forward-char 1)))) result))) +(defun ietf-drums-strip (string) + "Remove comments and whitespace from STRING." + (ietf-drums-remove-whitespace (ietf-drums-remove-comments string))) + (defun ietf-drums-parse-address (string) "Parse STRING and return a MAILBOX / DISPLAY-NAME pair." (with-temp-buffer diff --git a/lisp/imap.el b/lisp/imap.el index 7460431..caab6c9 100644 --- a/lisp/imap.el +++ b/lisp/imap.el @@ -74,9 +74,11 @@ ;; ;; imap.el support RFC1730/2060 (IMAP4/IMAP4rev1), implemented IMAP ;; extensions are RFC2195 (CRAM-MD5), RFC2086 (ACL), RFC2342 -;; (NAMESPACE), RFC2359 (UIDPLUS), and the kerberos V4 part of RFC1731 -;; (with use of external program `imtest'). It also take advantage -;; the UNSELECT extension in Cyrus IMAPD. +;; (NAMESPACE), RFC2359 (UIDPLUS), the IMAP-part of RFC2595 (STARTTLS) +;; (with use of external library starttls.el and program starttls) and +;; the GSSAPI / kerberos V4 sections of RFC1731 (with use of external +;; program `imtest'). It also take advantage the UNSELECT extension +;; in Cyrus IMAPD. ;; ;; Without the work of John McClary Prevost and Jim Radford this library ;; would not have seen the light of day. Many thanks. @@ -122,7 +124,6 @@ ;; o Don't use `read' at all (important places already fixed) ;; o Accept list of articles instead of message set string in most ;; imap-message-* functions. -;; o Cyrus IMAPd 1.6.x `imtest' support in the imtest wrapper ;; ;; Revision history: ;; @@ -154,11 +155,18 @@ ;; User variables. -(defvar imap-imtest-program "imtest -kp %s %p" - "How to call program for Kerberos 4 authentication. -%s is replaced with server and %p with port to connect to. The -program should accept IMAP commands on stdin and return responses to -stdout.") +(defvar imap-kerberos4-program '("imtest -m kerberos_v4 -u %l -p %p %s" + "imtest -kp %s %p") + "List of strings containing commands for Kerberos 4 authentication. +%s is replaced with server hostname, %p with port to connect to, and +%l with the value of `imap-default-user'. The program should accept +IMAP commands on stdin and return responses to stdout.") + +(defvar imap-gssapi-program '("imtest -m gssapi -u %l -p %p %s") + "List of strings containing commands for GSSAPI (krb5) authentication. +%s is replaced with server hostname, %p with port to connect to, and +%l with the value of `imap-default-user'. The program should accept +IMAP commands on stdin and return responses to stdout.") (defvar imap-ssl-program '("openssl s_client -ssl3 -connect %s:%p" "openssl s_client -ssl2 -connect %s:%p" @@ -180,14 +188,15 @@ stdin and return responses to stdout.") (defvar imap-fetch-data-hook nil "Hooks called after receiving each FETCH response.") -(defvar imap-streams '(kerberos4 starttls ssl network) +(defvar imap-streams '(gssapi kerberos4 starttls ssl network) "Priority of streams to consider when opening connection to server.") (defvar imap-stream-alist - '((kerberos4 imap-kerberos4s-p imap-kerberos4-open) - (ssl imap-ssl-p imap-ssl-open) - (network imap-network-p imap-network-open) - (starttls imap-starttls-p imap-starttls-open)) + '((gssapi imap-gssapi-stream-p imap-gssapi-open) + (kerberos4 imap-kerberos4-stream-p imap-kerberos4-open) + (ssl imap-ssl-p imap-ssl-open) + (network imap-network-p imap-network-open) + (starttls imap-starttls-p imap-starttls-open)) "Definition of network streams. (NAME CHECK OPEN) @@ -196,15 +205,21 @@ NAME names the stream, CHECK is a function returning non-nil if the server support the stream and OPEN is a function for opening the stream.") -(defvar imap-authenticators '(kerberos4 digest-md5 cram-md5 login anonymous) +(defvar imap-authenticators '(gssapi + kerberos4 + digest-md5 + cram-md5 + login + anonymous) "Priority of authenticators to consider when authenticating to server.") (defvar imap-authenticator-alist - '((kerberos4 imap-kerberos4a-p imap-kerberos4-auth) - (cram-md5 imap-cram-md5-p imap-cram-md5-auth) - (login imap-login-p imap-login-auth) - (anonymous imap-anonymous-p imap-anonymous-auth) - (digest-md5 imap-digest-md5-p imap-digest-md5-auth)) + '((gssapi imap-gssapi-auth-p imap-gssapia-auth) + (kerberos4 imap-kerberos4-auth-p imap-kerberos4-auth) + (cram-md5 imap-cram-md5-p imap-cram-md5-auth) + (login imap-login-p imap-login-auth) + (anonymous imap-anonymous-p imap-anonymous-auth) + (digest-md5 imap-digest-md5-p imap-digest-md5-auth)) "Definition of authenticators. (NAME CHECK AUTHENTICATE) @@ -376,46 +391,119 @@ If ARGS, PROMPT is used as an argument to `format'." ;; Server functions; stream stuff: -(defun imap-kerberos4s-p (buffer) +(defun imap-kerberos4-stream-p (buffer) (imap-capability 'AUTH=KERBEROS_V4 buffer)) (defun imap-kerberos4-open (name buffer server port) - (message "Opening Kerberized IMAP connection...") - (let* ((port (or port imap-default-port)) - (coding-system-for-read imap-coding-system-for-read) - (coding-system-for-write imap-coding-system-for-write) - (process (start-process - name buffer shell-file-name shell-command-switch - (format-spec - imap-imtest-program - (format-spec-make ?s server ?p (number-to-string port)))))) - (when process - (with-current-buffer buffer - (setq imap-client-eol "\n") - ;; Result of authentication is a string: __Full privacy protection__ - (while (and (memq (process-status process) '(open run)) - (goto-char (point-min)) - (not (and (imap-parse-greeting) - (re-search-forward "__\\(.*\\)__\n" nil t)))) - (accept-process-output process 1) - (sit-for 1)) - (and imap-log - (with-current-buffer (get-buffer-create imap-log) - (imap-disable-multibyte) - (buffer-disable-undo) - (goto-char (point-max)) - (insert-buffer-substring buffer))) - (let ((response (match-string 1))) - (erase-buffer) - (message "Kerberized IMAP connection: %s" response) - (if (and response (let ((case-fold-search nil)) - (not (string-match "failed" response)))) - process - (if (memq (process-status process) '(open run)) - (imap-send-command-wait "LOGOUT")) - (delete-process process) - nil)))))) + (let ((cmds imap-kerberos4-program) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "Opening Kerberos 4 IMAP connection with `%s'..." cmd) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (start-process + name buffer shell-file-name shell-command-switch + (format-spec + cmd + (format-spec-make + ?s server + ?p (number-to-string port) + ?l imap-default-user)))) + response) + (when process + (with-current-buffer buffer + (setq imap-client-eol "\n") + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + ;; cyrus 1.6.x (13? < x <= 22) queries capabilities + (or (while (looking-at "^C:") + (forward-line)) + t) + ;; cyrus 1.6 imtest print "S: " before server greeting + (or (not (looking-at "S: ")) + (forward-char 3) + t) + (not (and (imap-parse-greeting) + ;; success in imtest < 1.6: + (or (re-search-forward + "^__\\(.*\\)__\n" nil t) + ;; success in imtest 1.6: + (re-search-forward + "^\\(Authenticat.*\\)" nil t)) + (setq response (match-string 1))))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (erase-buffer) + (message "Kerberos 4 IMAP connection: %s" (or response "failed")) + (if (and response (let ((case-fold-search nil)) + (not (string-match "failed" response)))) + (setq done process) + (if (memq (process-status process) '(open run)) + (imap-send-command-wait "LOGOUT")) + (delete-process process) + nil))))) + done)) +(defun imap-gssapi-stream-p (buffer) + (imap-capability 'AUTH=GSSAPI buffer)) + +(defun imap-gssapi-open (name buffer server port) + (let ((cmds imap-gssapi-program) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "Opening GSSAPI IMAP connection with `%s'..." cmd) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (start-process + name buffer shell-file-name shell-command-switch + (format-spec + cmd + (format-spec-make + ?s server + ?p (number-to-string port) + ?l imap-default-user)))) + response) + (when process + (with-current-buffer buffer + (setq imap-client-eol "\n") + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + ;; cyrus 1.6 imtest print "S: " before server greeting + (or (not (looking-at "S: ")) + (forward-char 3) + t) + (not (and (imap-parse-greeting) + ;; success in imtest 1.6: + (re-search-forward + "^\\(Authenticat.*\\)" nil t) + (setq response (match-string 1))))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (erase-buffer) + (message "GSSAPI IMAP connection: %s" (or response "failed")) + (if (and response (let ((case-fold-search nil)) + (not (string-match "failed" response)))) + (setq done process) + (if (memq (process-status process) '(open run)) + (imap-send-command-wait "LOGOUT")) + (delete-process process) + nil))))) + done)) + (defun imap-ssl-p (buffer) nil) @@ -558,7 +646,13 @@ Returns t if login was successful, nil otherwise." ;; passwd nil)))) ret))) -(defun imap-kerberos4a-p (buffer) +(defun imap-gssapi-auth-p (buffer) + (imap-capability 'AUTH=GSSAPI buffer)) + +(defun imap-gssapi-auth (buffer) + (eq imap-stream 'gssapi)) + +(defun imap-kerberos4-auth-p (buffer) (imap-capability 'AUTH=KERBEROS_V4 buffer)) (defun imap-kerberos4-auth (buffer) @@ -1001,9 +1095,9 @@ returned, if ITEMS is a symbol only it's value is returned." (list items)))))) (if (listp items) (mapcar (lambda (item) - (imap-mailbox-get-1 item mailbox)) + (imap-mailbox-get item mailbox)) items) - (imap-mailbox-get-1 items mailbox))))) + (imap-mailbox-get items mailbox))))) (defun imap-mailbox-acl-get (&optional mailbox buffer) "Get ACL on mailbox from server in BUFFER." @@ -1265,10 +1359,11 @@ on failure." "Return number of lines in article by looking at the mime bodystructure BODY." (if (listp body) (if (stringp (car body)) - (cond ((and (string= (car body) "TEXT") + ;; upcase for bug in courier imap server + (cond ((and (string= (upcase (car body)) "TEXT") (numberp (nth 7 body))) (nth 7 body)) - ((and (string= (car body) "MESSAGE") + ((and (string= (upcase (car body)) "MESSAGE") (numberp (nth 9 body))) (nth 9 body)) (t 0)) @@ -1318,13 +1413,14 @@ on failure." (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) (setq command nil);; abort command if no cont-req (let ((process imap-process) - (stream imap-stream)) + (stream imap-stream) + (eol imap-client-eol)) (with-current-buffer cmd - (when (eq stream 'kerberos4) + (when (not (equal eol "\r\n")) ;; XXX modifies buffer! (goto-char (point-min)) (while (search-forward "\r\n" nil t) - (replace-match "\n"))) + (replace-match eol))) (and imap-log (with-current-buffer (get-buffer-create imap-log) diff --git a/lisp/lpath.el b/lisp/lpath.el index 8fe4c16..7302cda 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -41,7 +41,8 @@ rmail-summary-exists rmail-select-summary rmail-update-summary url-retrieve temp-directory babel-fetch babel-wash - find-coding-systems-for-charsets sc-cite-regexp)) + find-coding-systems-for-charsets sc-cite-regexp + vcard-pretty-print)) (maybe-bind '(global-face-data mark-active transient-mark-mode mouse-selection-click-count mouse-selection-click-count-buffer buffer-display-table @@ -57,7 +58,8 @@ url-current-callback-func url-current-callback-data url-be-asynchronous temporary-file-directory babel-translations babel-history - display-time-mail-function))) + display-time-mail-function imap-password + ))) (maybe-bind '(mail-mode-hook enable-multibyte-characters browse-url-browser-function adaptive-fill-first-line-regexp adaptive-fill-regexp @@ -65,7 +67,7 @@ w3-meta-content-type-charset-regexp w3-meta-charset-content-type-regexp babel-translations babel-history - display-time-mail-function)) + display-time-mail-function imap-password)) (maybe-fbind '(color-instance-rgb-components temp-directory glyph-width annotation-glyph window-pixel-width glyph-height @@ -91,7 +93,8 @@ w3-coding-system-for-mime-charset rmail-summary-exists rmail-select-summary rmail-update-summary url-generic-parse-url valid-image-instantiator-format-p - babel-fetch babel-wash babel-as-string sc-cite-regexp))) + babel-fetch babel-wash babel-as-string sc-cite-regexp + vcard-pretty-print))) (setq load-path (cons "." load-path)) (require 'custom) diff --git a/lisp/mail-parse.el b/lisp/mail-parse.el index d9caac1..078907e 100644 --- a/lisp/mail-parse.el +++ b/lisp/mail-parse.el @@ -49,6 +49,7 @@ (defalias 'mail-header-remove-comments 'ietf-drums-remove-comments) (defalias 'mail-header-remove-whitespace 'ietf-drums-remove-whitespace) +(defalias 'mail-header-strip 'ietf-drums-strip) (defalias 'mail-header-get-comment 'ietf-drums-get-comment) (defalias 'mail-header-parse-address 'ietf-drums-parse-address) (defalias 'mail-header-parse-addresses 'ietf-drums-parse-addresses) diff --git a/lisp/mail-source.el b/lisp/mail-source.el index 13be412..2fb2b28 100644 --- a/lisp/mail-source.el +++ b/lisp/mail-source.el @@ -632,15 +632,23 @@ This only works when `display-time' is enabled." (defun mail-source-fetch-imap (source callback) "Fetcher for imap sources." (mail-source-bind (imap source) - (let ((found 0) + (let ((from (format "%s:%s:%s" server user port)) + (found 0) (buf (get-buffer-create (generate-new-buffer-name " *imap source*"))) (mail-source-string (format "imap:%s:%s" server mailbox)) remove) (if (and (imap-open server port stream authentication buf) - (imap-authenticate user password buf) + (imap-authenticate + user (or (cdr (assoc from mail-source-password-cache)) + password) buf) (imap-mailbox-select mailbox nil buf)) (let (str (coding-system-for-write 'binary)) (with-temp-file mail-source-crash-box + ;; remember password + (with-current-buffer buf + (when (or imap-password + (assoc from mail-source-password-cache)) + (push (cons from imap-password) mail-source-password-cache))) ;; if predicate is nil, use all uids (dolist (uid (imap-search (or predicate "1:*") buf)) (when (setq str (imap-fetch uid "RFC822.PEEK" 'RFC822 nil buf)) @@ -661,6 +669,11 @@ This only works when `display-time' is enabled." (imap-mailbox-close buf)) (imap-close buf)) (imap-close buf) + ;; We nix out the password in case the error + ;; was because of a wrong password being given. + (setq mail-source-password-cache + (delq (assoc from mail-source-password-cache) + mail-source-password-cache)) (error (imap-error-text buf))) (kill-buffer buf) found))) @@ -677,8 +690,15 @@ This only works when `display-time' is enabled." (when (eq authentication 'password) (setq password (or password + (cdr (assoc (format "webmail:%s:%s" subtype user) + mail-source-password-cache)) (mail-source-read-passwd - (format "Password for %s at %s: " user subtype))))) + (format "Password for %s at %s: " user subtype)))) + (when (and password + (not (assoc (format "webmail:%s:%s" subtype user) + mail-source-password-cache))) + (push (cons (format "webmail:%s:%s" subtype user) password) + mail-source-password-cache))) (webmail-fetch mail-source-crash-box subtype user password) (mail-source-callback callback (symbol-name subtype))))) diff --git a/lisp/mailcap.el b/lisp/mailcap.el index 8a15334..ba2bfb7 100644 --- a/lisp/mailcap.el +++ b/lisp/mailcap.el @@ -714,6 +714,7 @@ this type is returned." (".cpio" . "application/x-cpio") (".csh" . "application/x-csh") (".dvi" . "application/x-dvi") + (".diff" . "text/x-patch") (".el" . "application/emacs-lisp") (".eps" . "application/postscript") (".etx" . "text/x-setext") @@ -800,11 +801,21 @@ this type is returned." ((memq system-type '(ms-dos ms-windows windows-nt)) (setq path (mapconcat 'expand-file-name '("~/mime.typ" "~/etc/mime.typ") ";"))) - (t (setq path (mapconcat 'expand-file-name - '("~/.mime-types" - "/etc/mime-types:/usr/etc/mime-types" - "/usr/local/etc/mime-types" - "/usr/local/www/conf/mime-types") ":")))) + (t (setq path (mapconcat + 'expand-file-name + ;; mime.types seems to be the normal name, + ;; definitely so on current GNUish systems. The + ;; ordering follows that for mailcap. + '("~/.mime.types" + "/etc/mime.types" + "/usr/etc/mime.types" + "/usr/local/etc/mime.types" + "/usr/local/www/conf/mime.types" + "~/.mime-types" + "/etc/mime-types" + "/usr/etc/mime-types" + "/usr/local/etc/mime-types" + "/usr/local/www/conf/mime-types") ":")))) (let ((fnames (reverse (split-string path (if (memq system-type diff --git a/lisp/message.el b/lisp/message.el index 9f08945..7056b1b 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -33,7 +33,6 @@ (require 'mailheader) (require 'nnheader) (require 'easymenu) -(require 'custom) (if (string-match "XEmacs\\|Lucid" emacs-version) (require 'mail-abbrevs) (require 'mailabbrev)) @@ -2135,7 +2134,10 @@ It should typically alter the sending method in some way or other." (news (message-news-p)) (mailbuf (current-buffer)) (message-this-is-mail t) - (message-posting-charset (gnus-setup-posting-charset nil))) + (message-posting-charset + (if (fboundp 'gnus-setup-posting-charset) + (gnus-setup-posting-charset nil) + message-posting-charset))) (save-restriction (message-narrow-to-headers) ;; Insert some headers. @@ -2179,7 +2181,8 @@ It should typically alter the sending method in some way or other." (defun message-send-mail-with-sendmail () "Send off the prepared buffer with sendmail." (let ((errbuf (if message-interactive - (message-generate-new-buffer-clone-locals " sendmail errors") + (message-generate-new-buffer-clone-locals + " sendmail errors") 0)) resend-to-addresses delimline) (let ((case-fold-search t)) @@ -2397,7 +2400,7 @@ to find out how to use this." (defun message-check-news-header-syntax () (and ;; Check Newsgroups header. - (message-check 'newsgroyps + (message-check 'newsgroups (let ((group (message-fetch-field "newsgroups"))) (or (and group @@ -3793,6 +3796,8 @@ header line with the old Message-ID." (cond ((save-window-excursion (if (not (eq system-type 'vax-vms)) (with-output-to-temp-buffer "*Directory*" + (with-current-buffer standard-output + (fundamental-mode)) ; for Emacs 20.4+ (buffer-disable-undo standard-output) (let ((default-directory "/")) (call-process @@ -4161,6 +4166,7 @@ The following arguments may contain lists of values." (save-excursion (with-output-to-temp-buffer " *MESSAGE information message*" (set-buffer " *MESSAGE information message*") + (fundamental-mode) ; for Emacs 20.4+ (mapcar 'princ text) (goto-char (point-min)))) (funcall ask question)) diff --git a/lisp/mm-bodies.el b/lisp/mm-bodies.el index 0901615..2ee6bf2 100644 --- a/lisp/mm-bodies.el +++ b/lisp/mm-bodies.el @@ -150,15 +150,16 @@ If no encoding was done, nil is returned." ((eq encoding 'quoted-printable) (quoted-printable-decode-region (point-min) (point-max))) ((eq encoding 'base64) - (base64-decode-region (point-min) - ;; Some mailers insert whitespace - ;; junk at the end which - ;; base64-decode-region dislikes. - (save-excursion - (goto-char (point-max)) - (skip-chars-backward "\n\t ") - (delete-region (point) (point-max)) - (point)))) + (base64-decode-region + (point-min) + ;; Some mailers insert whitespace + ;; junk at the end which + ;; base64-decode-region dislikes. + (save-excursion + (goto-char (point-max)) + (skip-chars-backward "\n\t ") + (delete-region (point) (point-max)) + (point)))) ((memq encoding '(7bit 8bit binary)) ;; Do nothing. ) diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index cc8a4cc..3a2b0df 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -220,6 +220,8 @@ to: cd (mail-fetch-field "content-disposition") description (mail-fetch-field "content-description") id (mail-fetch-field "content-id")))) + (when cte + (setq cte (mail-header-strip cte))) (if (or (not ctl) (not (string-match "/" (car ctl)))) (mm-dissect-singlepart @@ -255,7 +257,9 @@ to: (defun mm-dissect-singlepart (ctl cte &optional force cdl description id) (when (or force - (not (equal "text/plain" (car ctl)))) + (if (equal "text/plain" (car ctl)) + (assoc 'format ctl) + t)) (let ((res (mm-make-handle (mm-copy-to-buffer) ctl cte nil cdl description nil id))) (push (car res) mm-dissection-list) @@ -433,20 +437,28 @@ external if displayed external." (defun mm-mailcap-command (method file type-list) (let ((ctl (cdr type-list)) (beg 0) + (uses-stdin t) out sub total) - (while (string-match "%{\\([^}]+\\)}\\|%s\\|%t" method beg) + (while (string-match "%{\\([^}]+\\)}\\|%s\\|%t\\|%%" method beg) (push (substring method beg (match-beginning 0)) out) (setq beg (match-end 0) total (match-string 0 method) sub (match-string 1 method)) (cond + ((string= total "%%") + (push "%" out)) ((string= total "%s") + (setq uses-stdin nil) (push (mm-quote-arg file) out)) ((string= total "%t") (push (mm-quote-arg (car type-list)) out)) (t (push (mm-quote-arg (or (cdr (assq (intern sub) ctl)) "")) out)))) (push (substring method beg (length method)) out) + (if uses-stdin + (progn + (push "<" out) + (push (mm-quote-arg file) out))) (mapconcat 'identity (nreverse out) ""))) (defun mm-remove-parts (handles) diff --git a/lisp/mm-util.el b/lisp/mm-util.el index bf94df4..f23c873 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -94,6 +94,13 @@ prompt (mapcar (lambda (s) (list (symbol-name (car s)))) mm-mime-mule-charset-alist))))))) +(eval-and-compile + (defalias 'mm-char-or-char-int-p + (cond + ((fboundp 'char-or-char-int-p) 'char-or-char-int-p) + ((fboundp 'char-valid-p) 'char-valid-p) + (t 'identity)))) + (defvar mm-coding-system-list nil) (defun mm-get-coding-system-list () "Get the coding system list." @@ -241,7 +248,7 @@ If the charset is `composition', return the actual one." (defun mm-mime-charset (charset) "Return the MIME charset corresponding to the MULE CHARSET." - (if (fboundp 'coding-system-get) + (if (and (fboundp 'coding-system-get) (fboundp 'get-charset-property)) ;; This exists in Emacs 20. (or (and (mm-preferred-coding-system charset) diff --git a/lisp/mm-view.el b/lisp/mm-view.el index 6dcc35f..a5e5030 100644 --- a/lisp/mm-view.el +++ b/lisp/mm-view.el @@ -33,6 +33,7 @@ (autoload 'gnus-article-prepare-display "gnus-art") (autoload 'vcard-parse-string "vcard") (autoload 'vcard-format-string "vcard") + (autoload 'fill-flowed "fill-flowed") (autoload 'diff-mode "diff-mode")) ;;; @@ -127,15 +128,25 @@ (mm-insert-inline handle (concat "\n-- \n" - (vcard-format-string - (vcard-parse-string (mm-get-part handle) - 'vcard-standard-filter))))) + (if (fboundp 'vcard-pretty-print) + (vcard-pretty-print (mm-get-part handle)) + (vcard-format-string + (vcard-parse-string (mm-get-part handle) + 'vcard-standard-filter)))))) (t (setq text (mm-get-part handle)) (let ((b (point)) (charset (mail-content-type-get (mm-handle-type handle) 'charset))) (insert (mm-decode-string text charset)) + (when (and (equal type "plain") + (equal (cdr (assoc 'format (mm-handle-type handle))) + "flowed")) + (save-restriction + (narrow-to-region b (point)) + (goto-char b) + (fill-flowed) + (goto-char (point-max)))) (save-restriction (narrow-to-region b (point)) (set-text-properties (point-min) (point-max) nil) diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index 1d1f2a8..f6b5854 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -746,7 +746,7 @@ deleted. Point is left where the deleted region was." buffer (push (list group buffer) nnfolder-buffer-alist) (set-buffer-modified-p t) - (save-buffer)) + (nnfolder-save-buffer)) ;; Parse the damn thing. (save-excursion (goto-char (point-min)) diff --git a/lisp/nnheader.el b/lisp/nnheader.el index 4bee834..5010f4c 100644 --- a/lisp/nnheader.el +++ b/lisp/nnheader.el @@ -1,6 +1,7 @@ - ;;; nnheader.el --- header access macros for Gnus and its backends -;; Copyright (C) 1987-1990,1993-1999 Free Software Foundation, Inc. + +;; Copyright (C) 1987, 88, 89, 90, 93, 94, 95, 96, 97, 98, 99 +;; Free Software Foundation, Inc. ;; Author: Masanobu UMEDA ;; Lars Magne Ingebrigtsen @@ -728,14 +729,14 @@ without formatting." (concat (let ((dir (file-name-as-directory (expand-file-name dir)))) ;; If this directory exists, we use it directly. - (if (file-directory-p (concat dir group)) - (concat dir group "/") - ;; If not, we translate dots into slashes. - (concat dir - (mm-encode-coding-string - (nnheader-replace-chars-in-string group ?. ?/) - nnheader-pathname-coding-system) - "/"))) + (file-name-as-directory + (if (file-directory-p (concat dir group)) + (expand-file-name group dir) + ;; If not, we translate dots into slashes. + (expand-file-name (mm-encode-coding-string + (nnheader-replace-chars-in-string group ?. ?/) + nnheader-pathname-coding-system) + dir)))) (cond ((null file) "") ((numberp file) (int-to-string file)) (t file)))) diff --git a/lisp/nnimap.el b/lisp/nnimap.el index 7581479..9a8bc3f 100644 --- a/lisp/nnimap.el +++ b/lisp/nnimap.el @@ -126,6 +126,13 @@ This variable can also have a function as its value, the function will be called with the headers narrowed and should return a group where it thinks the article should be splitted to.") +(defvar nnimap-split-predicate "UNSEEN UNDELETED" + "The predicate used to find articles to split. +If you use another IMAP client to peek on articles but always would +like nnimap to split them once it's started, you could change this to +\"UNDELETED\". Other available predicates are available in +RFC2060 section 6.4.4.") + (defvar nnimap-split-fancy nil "Like `nnmail-split-fancy', which see.") @@ -361,9 +368,10 @@ If EXAMINE is non-nil the group is selected read-only." nnimap-progress-how-often) nnimap-progress-chars))) (with-current-buffer nntp-server-buffer - (let (headers lines chars uid) + (let (headers lines chars uid mbx) (with-current-buffer nnimap-server-buffer (setq uid imap-current-message + mbx imap-current-mailbox headers (if (imap-capability 'IMAP4rev1) ;; xxx don't just use car? alist doesn't contain ;; anything else now, but it might... @@ -376,10 +384,14 @@ If EXAMINE is non-nil the group is selected read-only." (buffer-disable-undo) (insert headers) (nnheader-ms-strip-cr) + (nnheader-fold-continuation-lines) + (subst-char-in-region (point-min) (point-max) ?\t ? ) (let ((head (nnheader-parse-head 'naked))) (mail-header-set-number head uid) (mail-header-set-chars head chars) (mail-header-set-lines head lines) + (mail-header-set-xref + head (format "%s %s:%d" (system-name) mbx uid)) head)))))) (defun nnimap-retrieve-which-headers (articles fetch-old) @@ -492,8 +504,8 @@ If EXAMINE is non-nil the group is selected read-only." ;; remove nov's for articles which has expired on server (goto-char (point-min)) (dolist (uid (gnus-set-difference articles uids)) - (when (re-search-forward (format "^%d\t" uid) nil t) - (gnus-delete-line))))) + (when (re-search-forward (format "^%d\t" uid) nil t) + (gnus-delete-line))))) ;; nothing cached, fetch whole range from server (nnimap-retrieve-headers-from-server (cons low high) group server)) @@ -602,8 +614,8 @@ function is generally only called when Gnus is shutting down." (nnheader-ms-strip-cr) (funcall nnimap-callback-callback-function t))) -(defun nnimap-request-article-part (article part prop - &optional group server to-buffer) +(defun nnimap-request-article-part (article part prop &optional + group server to-buffer detail) (when (nnimap-possibly-change-group group server) (let ((article (if (stringp article) (car-safe (imap-search @@ -615,9 +627,12 @@ function is generally only called when Gnus is shutting down." (if (not nnheader-callback-function) (with-current-buffer (or to-buffer nntp-server-buffer) (erase-buffer) - (insert (nnimap-demule (imap-fetch article part prop nil - nnimap-server-buffer))) - (nnheader-ms-strip-cr) + (let ((data (imap-fetch article part prop nil + nnimap-server-buffer))) + (insert (nnimap-demule (if detail + (nth 2 (car data)) + data)))) + (nnheader-ms-strip-cr) (gnus-message 9 "nnimap: Fetching (part of) article %d...done" article) (if (bobp) @@ -634,16 +649,25 @@ function is generally only called when Gnus is shutting down." t) (deffoo nnimap-request-article (article &optional group server to-buffer) - (nnimap-request-article-part - article "RFC822.PEEK" 'RFC822 group server to-buffer)) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.PEEK" 'RFC822 group server to-buffer))) (deffoo nnimap-request-head (article &optional group server to-buffer) - (nnimap-request-article-part - article "RFC822.HEADER" 'RFC822.HEADER group server to-buffer)) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[HEADER]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.HEADER" 'RFC822.HEADER group server to-buffer))) (deffoo nnimap-request-body (article &optional group server to-buffer) - (nnimap-request-article-part - article "RFC822.TEXT.PEEK" 'RFC822.TEXT group server to-buffer)) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[TEXT]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.TEXT.PEEK" 'RFC822.TEXT group server to-buffer))) (deffoo nnimap-request-group (group &optional server fast) (nnimap-request-update-info-internal @@ -889,7 +913,7 @@ function is generally only called when Gnus is shutting down." ;; find split rule for this server / inbox (when (setq rule (nnimap-split-find-rule server inbox)) ;; iterate over articles - (dolist (article (imap-search "UNSEEN UNDELETED")) + (dolist (article (imap-search nnimap-split-predicate)) (when (nnimap-request-head article) ;; copy article to right group(s) (setq removeorig nil) diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 9329646..1b90143 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -1,5 +1,5 @@ ;;; nnmail.el --- mail support functions for the Gnus mail backends -;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc. +;; Copyright (C) 1995,96,97,98,99, 00 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news, mail @@ -468,32 +468,50 @@ parameter. It should return nil, `warn' or `delete'." ?. ?_)) (setq group (nnheader-translate-file-chars group)) ;; If this directory exists, we use it directly. - (if (or nnmail-use-long-file-names - (file-directory-p (concat dir group))) - (concat dir group "/") - ;; If not, we translate dots into slashes. - (concat dir - (mm-encode-coding-string - (nnheader-replace-chars-in-string group ?. ?/) - nnmail-pathname-coding-system) - "/"))) + (file-name-as-directory + (if (or nnmail-use-long-file-names + (file-directory-p (concat dir group))) + (expand-file-name group dir) + ;; If not, we translate dots into slashes. + (expand-file-name + (mm-encode-coding-string + (nnheader-replace-chars-in-string group ?. ?/) + nnmail-pathname-coding-system) + dir)))) (or file ""))) (defun nnmail-get-active () "Returns an assoc of group names and active ranges. nn*-request-list should have been called before calling this function." - (let (group-assoc) - ;; Go through all groups from the active list. - (save-excursion - (set-buffer nntp-server-buffer) - (goto-char (point-min)) - (while (re-search-forward - "^\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\([0-9]+\\)" nil t) - ;; We create an alist with `(GROUP (LOW . HIGH))' elements. - (push (list (match-string 1) - (cons (string-to-int (match-string 3)) - (string-to-int (match-string 2)))) - group-assoc))) + ;; Go through all groups from the active list. + (save-excursion + (set-buffer nntp-server-buffer) + (nnmail-parse-active))) + +(defun nnmail-parse-active () + "Parse the active file in the current buffer and return an alist." + (goto-char (point-min)) + (unless (re-search-forward "[\\\"]" nil t) + (goto-char (point-max)) + (while (re-search-backward "[][';?()#]" nil t) + (insert ?\\))) + (goto-char (point-min)) + (let ((buffer (current-buffer)) + group-assoc group max min) + (while (not (eobp)) + (condition-case err + (progn + (narrow-to-region (point) (gnus-point-at-eol)) + (setq group (read buffer)) + (unless (stringp group) + (setq group (symbol-name group))) + (if (and (numberp (setq max (read nntp-server-buffer))) + (numberp (setq min (read nntp-server-buffer)))) + (push (list group (cons min max)) + group-assoc))) + (error nil)) + (widen) + (forward-line 1)) group-assoc)) (defvar nnmail-active-file-coding-system 'raw-text @@ -511,8 +529,11 @@ nn*-request-list should have been called before calling this function." (erase-buffer) (let (group) (while (setq group (pop alist)) - (insert (format "%s %d %d y\n" (car group) (cdadr group) - (caadr group)))))) + (insert (format "%S %d %d y\n" (intern (car group)) (cdadr group) + (caadr group)))) + (goto-char (point-max)) + (while (search-backward "\\." nil t) + (delete-char 1)))) (defun nnmail-get-split-group (file source) "Find out whether this FILE is to be split into GROUP only. @@ -1066,7 +1087,10 @@ Return the number of characters in the body." (goto-char (point-min)) (when (re-search-forward "^References:" nil t) (beginning-of-line) - (insert "X-Gnus-Broken-Eudora-")))) + (insert "X-Gnus-Broken-Eudora-")) + (goto-char (point-min)) + (when (re-search-forward "^In-Reply-To:[^\n]+\\(\n[ \t]+\\)" nil t) + (replace-match "" t t nil 1)))) (custom-add-option 'nnmail-prepare-incoming-header-hook 'nnmail-fix-eudora-headers) @@ -1577,6 +1601,8 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (unless nnmail-split-history (error "No current split history")) (with-output-to-temp-buffer "*nnmail split history*" + (with-current-buffer standard-output + (fundamental-mode)) ; for Emacs 20.4+ (let ((history nnmail-split-history) elem) (while (setq elem (pop history)) diff --git a/lisp/nnml.el b/lisp/nnml.el index fd7d216..212251d 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -41,11 +41,11 @@ "Spool directory for the nnml mail backend.") (defvoo nnml-active-file - (concat (file-name-as-directory nnml-directory) "active") + (expand-file-name "active" nnml-directory) "Mail active file.") (defvoo nnml-newsgroups-file - (concat (file-name-as-directory nnml-directory) "newsgroups") + (expand-file-name "newsgroups" nnml-directory) "Mail newsgroups description file.") (defvoo nnml-get-new-mail t @@ -372,8 +372,8 @@ all. This may very well take some time.") (nnmail-write-region (point-min) (point-max) (or (nnml-article-to-file article) - (concat nnml-current-directory - (int-to-string article))) + (expand-file-name (int-to-string article) + nnml-current-directory)) nil (if (nnheader-be-verbose 5) nil 'nomesg)) t) (setq headers (nnml-parse-head chars article)) @@ -477,7 +477,7 @@ all. This may very well take some time.") (nnml-update-file-alist) (let (file) (if (setq file (cdr (assq article nnml-article-file-alist))) - (concat nnml-current-directory file) + (expand-file-name file nnml-current-directory) ;; Just to make sure nothing went wrong when reading over NFS -- ;; check once more. (when (file-exists-p @@ -518,8 +518,8 @@ all. This may very well take some time.") (defun nnml-find-id (group id) (erase-buffer) - (let ((nov (concat (nnmail-group-pathname group nnml-directory) - nnml-nov-file-name)) + (let ((nov (expand-file-name nnml-nov-file-name + (nnmail-group-pathname group nnml-directory))) number found) (when (file-exists-p nov) (nnheader-insert-file-contents nov) @@ -539,7 +539,7 @@ all. This may very well take some time.") (defun nnml-retrieve-headers-with-nov (articles &optional fetch-old) (if (or gnus-nov-is-evil nnml-nov-is-evil) nil - (let ((nov (concat nnml-current-directory nnml-nov-file-name))) + (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory))) (when (file-exists-p nov) (save-excursion (set-buffer nntp-server-buffer) @@ -635,8 +635,8 @@ all. This may very well take some time.") (push (list group active) nnml-group-alist)) (setcdr active (1+ (cdr active))) (while (file-exists-p - (concat (nnmail-group-pathname group nnml-directory) - (int-to-string (cdr active)))) + (expand-file-name (int-to-string (cdr active)) + (nnmail-group-pathname group nnml-directory))) (setcdr active (1+ (cdr active)))) (cdr active))) @@ -676,8 +676,9 @@ all. This may very well take some time.") (save-excursion (set-buffer buffer) (set (make-local-variable 'nnml-nov-buffer-file-name) - (concat (nnmail-group-pathname group nnml-directory) - nnml-nov-file-name)) + (expand-file-name + nnml-nov-file-name + (nnmail-group-pathname group nnml-directory))) (erase-buffer) (when (file-exists-p nnml-nov-buffer-file-name) (nnheader-insert-file-contents nnml-nov-buffer-file-name))) diff --git a/lisp/nnslashdot.el b/lisp/nnslashdot.el index 23dae0d..c6decd2 100644 --- a/lisp/nnslashdot.el +++ b/lisp/nnslashdot.el @@ -377,11 +377,12 @@ (narrow-to-region (point) (search-forward "")) (goto-char (point-min)) (re-search-forward "\\([^<]+\\)") - (setq description (nnweb-decode-entities-string (match-string 1))) + (setq description + (nnweb-decode-entities-string (match-string 1))) (re-search-forward "\\([^<]+\\)") (setq sid (match-string 1)) - (string-match "/\\([0-9/]+\\).shtml" sid) - (setq sid (match-string 1 sid)) + (string-match "/\\([0-9/]+\\)\\(.shtml\\|$\\)" sid) + (setq sid (concat "00/" (match-string 1 sid))) (re-search-forward "\\([^<]+\\)") (setq articles (string-to-number (match-string 1))) (setq gname (concat description " (" sid ")")) @@ -397,9 +398,11 @@ (nnweb-insert (format nnslashdot-active-url number) t) (goto-char (point-min)) (while (re-search-forward - "article.pl\\?sid=\\([^&]+\\).*\\([^<]+\\)" nil t) + "article.pl\\?sid=\\([^&]+\\).*\\([^<]+\\)" + nil t) (setq sid (match-string 1) - description (nnweb-decode-entities-string (match-string 2))) + description + (nnweb-decode-entities-string (match-string 2))) (forward-line 1) (when (re-search-forward "\\([0-9]+\\)" nil t) (setq articles (string-to-number (match-string 1)))) diff --git a/lisp/nntp.el b/lisp/nntp.el index 98ad46a..cddd8ac 100644 --- a/lisp/nntp.el +++ b/lisp/nntp.el @@ -1,5 +1,6 @@ ;;; nntp.el --- nntp access for Gnus -;;; Copyright (C) 1987-90,92-99 Free Software Foundation, Inc. +;;; Copyright (C) 1987, 88, 89, 90, 92, 93, 94, 95, 96, 97, 98, 99 +;;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news diff --git a/lisp/nnultimate.el b/lisp/nnultimate.el index d30c1a8..693bb0b 100644 --- a/lisp/nnultimate.el +++ b/lisp/nnultimate.el @@ -82,7 +82,8 @@ (while (and (setq article (car articles)) map) (while (and map - (> article (caar map))) + (or (> article (caar map)) + (< (cadar map) (caar map)))) (pop map)) (when (setq mmap (car map)) (setq farticle -1) @@ -124,7 +125,8 @@ "-" (number-to-string current-page) (match-string 0 href)))) (goto-char (point-min)) - (setq contents (w3-parse-buffer (current-buffer))) + (setq contents + (ignore-errors (w3-parse-buffer (current-buffer)))) (setq table (nnultimate-find-forum-table contents)) (setq string (mapconcat 'identity (nnweb-text table) "")) (when (string-match "topic is \\([0-9]\\) pages" string) @@ -337,25 +339,26 @@ (setq art (1+ (string-to-number (car artlist))))) (pop artlist)) (setq garticles art)) - (string-match "/\\([0-9]+\\).html" href) - (setq topic (string-to-number (match-string 1 href))) - (if (setq tinfo (assq topic topics)) - (progn - (setq old-max (cadr tinfo)) - (setcar (cdr tinfo) garticles)) - (setq old-max 0) - (push (list topic garticles subject href) topics) - (setcar (nthcdr 4 entry) topics)) - (when (not (= old-max garticles)) - (setq inc (- garticles old-max)) - (setq mapping (nconc mapping - (list - (list - old-total (1- (incf old-total inc)) - topic (1+ old-max))))) - (incf old-max inc) - (setcar (nthcdr 5 entry) mapping) - (setcar (nthcdr 6 entry) old-total))))) + (when garticles + (string-match "/\\([0-9]+\\).html" href) + (setq topic (string-to-number (match-string 1 href))) + (if (setq tinfo (assq topic topics)) + (progn + (setq old-max (cadr tinfo)) + (setcar (cdr tinfo) garticles)) + (setq old-max 0) + (push (list topic garticles subject href) topics) + (setcar (nthcdr 4 entry) topics)) + (when (not (= old-max garticles)) + (setq inc (- garticles old-max)) + (setq mapping (nconc mapping + (list + (list + old-total (1- (incf old-total inc)) + topic (1+ old-max))))) + (incf old-max inc) + (setcar (nthcdr 5 entry) mapping) + (setcar (nthcdr 6 entry) old-total)))))) (setcar (nthcdr 7 entry) current-time) (setcar (nthcdr 1 entry) (1- old-total)) (nnultimate-write-groups) diff --git a/lisp/nnwarchive.el b/lisp/nnwarchive.el index 4057db5..e48f9df 100644 --- a/lisp/nnwarchive.el +++ b/lisp/nnwarchive.el @@ -61,20 +61,20 @@ '((egroups (address . "www.egroups.com") (open-url - "http://www.egroups.com/register?method=loginAction&email=%s&password=%s" + "http://www.egroups.com/login.cgi?&login_email=%s&login_password=%s" nnwarchive-login nnwarchive-passwd) (list-url - "http://www.egroups.com/UserGroupsPage?") + "http://www.egroups.com/mygroups") (list-dissect . nnwarchive-egroups-list) (list-groups . nnwarchive-egroups-list-groups) (xover-url - "http://www.egroups.com/group/%s/?fetchForward=1&start=%d" group aux) + "http://www.egroups.com/message/%s/%d" group aux) (xover-last-url - "http://www.egroups.com/group/%s/?fetchForward=1" group) + "http://www.egroups.com/message/%s/" group) (xover-page-size . 13) (xover-dissect . nnwarchive-egroups-xover) (article-url - "http://www.egroups.com/group/%s/%d.html?raw=1" group article) + "http://www.egroups.com/message/%s/%d?source=1" group article) (article-dissect . nnwarchive-egroups-article) (authentication . t) (article-offset . 0) @@ -287,31 +287,29 @@ t) (deffoo nnwarchive-open-server (server &optional defs connectionless) + (nnoo-change-server 'nnwarchive server defs) (nnwarchive-init server) - (if (nnwarchive-server-opened server) - t - (nnoo-change-server 'nnwarchive server defs) - (when nnwarchive-authentication - (setq nnwarchive-login - (or nnwarchive-login - (read-string + (when nnwarchive-authentication + (setq nnwarchive-login + (or nnwarchive-login + (read-string (format "Login at %s: " server) user-mail-address))) - (setq nnwarchive-passwd - (or nnwarchive-passwd - (mail-source-read-passwd - (format "Password for %s at %s: " - nnwarchive-login server))))) - (unless nnwarchive-groups - (nnwarchive-read-groups)) - (save-excursion - (set-buffer nnwarchive-buffer) - (erase-buffer) - (if nnwarchive-open-url - (nnwarchive-url nnwarchive-open-url)) - (if nnwarchive-open-dissect - (funcall nnwarchive-open-dissect))) - t)) + (setq nnwarchive-passwd + (or nnwarchive-passwd + (mail-source-read-passwd + (format "Password for %s at %s: " + nnwarchive-login server))))) + (unless nnwarchive-groups + (nnwarchive-read-groups)) + (save-excursion + (set-buffer nnwarchive-buffer) + (erase-buffer) + (if nnwarchive-open-url + (nnwarchive-url nnwarchive-open-url)) + (if nnwarchive-open-dissect + (funcall nnwarchive-open-dissect))) + t) (nnoo-define-skeleton nnwarchive) @@ -389,14 +387,16 @@ expr))) (defun nnwarchive-url (xurl) - (let ((url-confirmation-func 'identity)) - (cond - ((eq (car xurl) 'post) - (pop xurl) - (nnwarchive-fetch-form (car xurl) (nnwarchive-eval (cdr xurl)))) - (t - (nnweb-insert (apply 'format (nnwarchive-eval xurl))))))) - + (mm-with-unibyte-current-buffer + (let ((url-confirmation-func 'identity) + (url-cookie-multiple-line nil)) + (cond + ((eq (car xurl) 'post) + (pop xurl) + (nnwarchive-fetch-form (car xurl) (nnwarchive-eval (cdr xurl)))) + (t + (nnweb-insert (apply 'format (nnwarchive-eval xurl)))))))) + (defun nnwarchive-generate-active () (save-excursion (set-buffer nntp-server-buffer) @@ -424,7 +424,7 @@ (erase-buffer) (nnwarchive-url nnwarchive-xover-last-url) (goto-char (point-min)) - (when (re-search-forward "of \\([0-9]+\\)" nil t) + (when (re-search-forward "of \\([0-9]+\\)[ \t\n\r]*" nil t) (setq articles (string-to-number (match-string 1)))) (let ((elem (assoc group nnwarchive-groups))) (if elem @@ -442,16 +442,11 @@ group description elem articles) (goto-char (point-min)) (while - (re-search-forward - "/group/\\([^/]+\\)/info\\.html[^>]+>[^>]+>[\040\t]*-[\040\t]*\\([^<]+\\)<" - nil t) + (re-search-forward "href=\"/group/\\([^/\"\> ]+\\)" nil t) (setq group (match-string 1) description (match-string 2)) - (forward-line 1) - (when (re-search-forward ">\\([0-9]+\\)<" nil t) - (setq articles (string-to-number (match-string 1)))) (if (setq elem (assoc group nnwarchive-groups)) - (setcar (cdr elem) articles) + (setcar (cdr elem) 0) (push (list group articles description) nnwarchive-groups)))) t) @@ -459,7 +454,7 @@ (let (article subject from date) (goto-char (point-min)) (while (re-search-forward - "]+>\\([^<]+\\)<" + "]+>\\([^<]+\\)<" nil t) (setq group (match-string 1) article (string-to-number (match-string 2)) diff --git a/lisp/nnweb.el b/lisp/nnweb.el index 5a56941..2ad8cb2 100644 --- a/lisp/nnweb.el +++ b/lisp/nnweb.el @@ -722,7 +722,10 @@ and `altavista'.") (while (re-search-forward "&\\(#[0-9]+\\|[a-z]+\\);" nil t) (replace-match (char-to-string (if (eq (aref (match-string 1) 0) ?\#) - (string-to-number (substring (match-string 1) 1)) + (let ((c + (string-to-number (substring + (match-string 1) 1)))) + (if (mm-char-or-char-int-p c) c 32)) (or (cdr (assq (intern (match-string 1)) w3-html-entities)) ?#))) @@ -754,14 +757,11 @@ If FOLLOW-REFRESH is non-nil, redirect refresh url in META." (narrow-to-region (point) (point)) (url-insert-file-contents url) (goto-char (point-min)) - (while (re-search-forward - "HTTP-EQUIV=\"Refresh\"[^>]*URL=\\([^\"]+\\)\"" - nil t) + (when (re-search-forward + "HTTP-EQUIV=\"Refresh\"[^>]*URL=\\([^\"]+\\)\"" nil t) (let ((url (match-string 1))) (delete-region (point-min) (point-max)) - (nnweb-insert url)) - (goto-char (point-min))) - (goto-char (point-max))) + (nnweb-insert url t)))) (url-insert-file-contents url)) (setq buffer-file-name name))) diff --git a/lisp/parse-time.el b/lisp/parse-time.el index 11e4682..9cc4ce2 100644 --- a/lisp/parse-time.el +++ b/lisp/parse-time.el @@ -167,7 +167,7 @@ (= (length elt) 7) (= (aref elt 1) ?:))) [0 1] [2 4] [5 7]) - ((5) (50 99) ,#'(lambda () (+ 1900 elt))) + ((5) (50 110) ,#'(lambda () (+ 1900 elt))) ((5) (0 49) ,#'(lambda () (+ 2000 elt)))) "(slots predicate extractor...)") diff --git a/lisp/pop3.el b/lisp/pop3.el index 4aafc48..dd88de3 100644 --- a/lisp/pop3.el +++ b/lisp/pop3.el @@ -1,9 +1,10 @@ ;;; pop3.el --- Post Office Protocol (RFC 1460) interface -;; Copyright (C) 1996-1999 Free Software Foundation, Inc. +;; Copyright (C) 1996, 97, 98, 1999 Free Software Foundation, Inc. ;; Author: Richard L. Pieri -;; Keywords: mail, pop3 +;; Maintainer: FSF +;; Keywords: mail ;; Version: 1.3s ;; This file is part of GNU Emacs. @@ -35,7 +36,6 @@ ;;; Code: (require 'mail-utils) -(provide 'pop3) (defconst pop3-version "1.3s") @@ -60,6 +60,9 @@ values are 'apop.") "Timestamp returned when initially connected to the POP server. Used for APOP authentication.") +(defvar pop3-movemail-file-coding-system nil + "Coding system for the crashbox made by `pop3-movemail'.") + (defvar pop3-read-point nil) (defvar pop3-debug nil) @@ -71,8 +74,6 @@ Used for APOP authentication.") (n 1) message-count (pop3-password pop3-password) - ;; use Unix line endings for crashbox - (coding-system-for-write 'binary) ) ;; for debugging only (if pop3-debug (switch-to-buffer (process-buffer process))) @@ -85,7 +86,7 @@ Used for APOP authentication.") ((equal 'pass pop3-authentication-scheme) (pop3-user process pop3-maildrop) (pop3-pass process)) - (t (error "Invalid POP3 authentication scheme."))) + (t (error "Invalid POP3 authentication scheme"))) (setq message-count (car (pop3-stat process))) (unwind-protect (while (<= n message-count) @@ -94,7 +95,8 @@ Used for APOP authentication.") (pop3-retr process n crashbuf) (save-excursion (set-buffer crashbuf) - (write-region (point-min) (point-max) crashbox t 'nomesg) + (let ((coding-system-for-write pop3-movemail-file-coding-system)) + (write-region (point-min) (point-max) crashbox t 'nomesg)) (set-buffer (process-buffer process)) (while (> (buffer-size) 5000) (goto-char (point-min)) @@ -109,50 +111,23 @@ Used for APOP authentication.") ) t) -(defun pop3-get-message-count () - "Return the number of messages in the maildrop." - (let* ((process (pop3-open-server pop3-mailhost pop3-port)) - message-count - (pop3-password pop3-password) - ) - ;; for debugging only - (if pop3-debug (switch-to-buffer (process-buffer process))) - ;; query for password - (if (and pop3-password-required (not pop3-password)) - (setq pop3-password - (pop3-read-passwd (format "Password for %s: " pop3-maildrop)))) - (cond ((equal 'apop pop3-authentication-scheme) - (pop3-apop process pop3-maildrop)) - ((equal 'pass pop3-authentication-scheme) - (pop3-user process pop3-maildrop) - (pop3-pass process)) - (t (error "Invalid POP3 authentication scheme."))) - (setq message-count (car (pop3-stat process))) - (pop3-quit process) - message-count)) - (defun pop3-open-server (mailhost port) - "Open TCP connection to MAILHOST. + "Open TCP connection to MAILHOST on PORT. Returns the process associated with the connection." - (let ((process-buffer - (get-buffer-create (format "trace of POP session to %s" mailhost))) - (process) - (coding-system-for-read 'binary);; because FSF Emacs 20 and - (coding-system-for-write 'binary);; XEmacs 20 & 21 are st00pid - ) + (let ((coding-system-for-read 'binary) + (coding-system-for-write 'binary) + process) (save-excursion - (set-buffer process-buffer) + (set-buffer (get-buffer-create (concat " trace of POP session to %s" + mailhost))) (erase-buffer) (setq pop3-read-point (point-min)) - ) - (setq process - (open-network-stream "POP" process-buffer mailhost port)) - (let ((response (pop3-read-response process t))) - (setq pop3-timestamp - (substring response (or (string-match "<" response) 0) - (+ 1 (or (string-match ">" response) -1))))) - process - )) + (setq process (open-network-stream "POP"(current-buffer) mailhost port)) + (let ((response (pop3-read-response process t))) + (setq pop3-timestamp + (substring response (or (string-match "<" response) 0) + (+ 1 (or (string-match ">" response) -1))))) + process))) ;; Support functions @@ -163,15 +138,15 @@ Returns the process associated with the connection." (insert output))) (defun pop3-send-command (process command) - (set-buffer (process-buffer process)) - (goto-char (point-max)) - ;; (if (= (aref command 0) ?P) - ;; (insert "PASS \r\n") - ;; (insert command "\r\n")) - (setq pop3-read-point (point)) - (goto-char (point-max)) - (process-send-string process (concat command "\r\n")) - ) + (set-buffer (process-buffer process)) + (goto-char (point-max)) +;; (if (= (aref command 0) ?P) +;; (insert "PASS \r\n") +;; (insert command "\r\n")) + (setq pop3-read-point (point)) + (goto-char (point-max)) + (process-send-string process (concat command "\r\n")) + ) (defun pop3-read-response (process &optional return) "Read the response from the server. @@ -187,7 +162,7 @@ Return the response string if optional second argument is non-nil." (setq match-end (point)) (goto-char pop3-read-point) (if (looking-at "-ERR") - (signal 'error (list (buffer-substring (point) (- match-end 2)))) + (error (buffer-substring (point) (- match-end 2))) (if (not (looking-at "+OK")) (progn (setq pop3-read-point match-end) nil) (setq pop3-read-point match-end) @@ -196,29 +171,15 @@ Return the response string if optional second argument is non-nil." t) ))))) -(defun pop3-string-to-list (string &optional regexp) - "Chop up a string into a list." - (let ((list) - (regexp (or regexp " ")) - (string (if (string-match "\r" string) - (substring string 0 (match-beginning 0)) - string))) - (store-match-data nil) - (while string - (if (string-match regexp string) - (setq list (cons (substring string 0 (- (match-end 0) 1)) list) - string (substring string (match-end 0))) - (setq list (cons string list) - string nil))) - (nreverse list))) - (defvar pop3-read-passwd nil) (defun pop3-read-passwd (prompt) (if (not pop3-read-passwd) - (if (load "passwd" t) + (if (fboundp 'read-passwd) (setq pop3-read-passwd 'read-passwd) - (autoload 'ange-ftp-read-passwd "ange-ftp") - (setq pop3-read-passwd 'ange-ftp-read-passwd))) + (if (load "passwd" t) + (setq pop3-read-passwd 'read-passwd) + (autoload 'ange-ftp-read-passwd "ange-ftp") + (setq pop3-read-passwd 'ange-ftp-read-passwd)))) (funcall pop3-read-passwd prompt)) (defun pop3-clean-region (start end) @@ -245,8 +206,9 @@ Return the response string if optional second argument is non-nil." (looking-at "BABYL OPTIONS:") ; Babyl )) (let ((from (mail-strip-quoted-names (mail-fetch-field "From"))) - (date (pop3-string-to-list (or (mail-fetch-field "Date") - (message-make-date)))) + (date (split-string (or (mail-fetch-field "Date") + (message-make-date)) + " ")) (From_)) ;; sample date formats I have seen ;; Date: Tue, 9 Jul 1996 09:04:21 -0400 (EDT) @@ -300,21 +262,40 @@ Return the response string if optional second argument is non-nil." (defun pop3-apop (process user) "Send alternate authentication information to the server." - (if (not (fboundp 'md5)) (autoload 'md5 "md5")) - (let ((hash (md5 (concat pop3-timestamp pop3-password)))) - (pop3-send-command process (format "APOP %s %s" user hash)) - (let ((response (pop3-read-response process t))) - (if (not (and response (string-match "+OK" response))) - (pop3-quit process))))) + (let ((pass pop3-password)) + (if (and pop3-password-required (not pass)) + (setq pass + (pop3-read-passwd (format "Password for %s: " pop3-maildrop)))) + (if pass + (let ((hash (pop3-md5 (concat pop3-timestamp pass)))) + (pop3-send-command process (format "APOP %s %s" user hash)) + (let ((response (pop3-read-response process t))) + (if (not (and response (string-match "+OK" response))) + (pop3-quit process))))) + )) ;; TRANSACTION STATE +(defvar pop3-md5-program "md5" + "*Program to encode its input in MD5.") + +(defun pop3-md5 (string) + (with-temp-buffer + (insert string) + (call-process-region (point-min) (point-max) + (or shell-file-name "/bin/sh") + t (current-buffer) nil + "-c" pop3-md5-program) + ;; The meaningful output is the first 32 characters. + ;; Don't return the newline that follows them! + (buffer-substring (point-min) (+ (point-min) 32)))) + (defun pop3-stat (process) "Return the number of messages in the maildrop and the maildrop's size." (pop3-send-command process "STAT") (let ((response (pop3-read-response process t))) - (list (string-to-int (nth 1 (pop3-string-to-list response))) - (string-to-int (nth 2 (pop3-string-to-list response)))) + (list (string-to-int (nth 1 (split-string response " "))) + (string-to-int (nth 2 (split-string response " ")))) )) (defun pop3-list (process &optional msg) @@ -341,16 +322,16 @@ This function currently does nothing.") ;; bill@att.com ;; condensed into: ;; (sometimes causes problems for really large messages.) - ;; (if (> (buffer-size) 20000) (sleep-for (/ (buffer-size) 20000))) +; (if (> (buffer-size) 20000) (sleep-for (/ (buffer-size) 20000))) (goto-char start)) (setq pop3-read-point (point-marker)) - ;; this code does not seem to work for some POP servers... - ;; and I cannot figure out why not. - ;; (goto-char (match-beginning 0)) - ;; (backward-char 2) - ;; (if (not (looking-at "\r\n")) - ;; (insert "\r\n")) - ;; (re-search-forward "\\.\r\n") +;; this code does not seem to work for some POP servers... +;; and I cannot figure out why not. +; (goto-char (match-beginning 0)) +; (backward-char 2) +; (if (not (looking-at "\r\n")) +; (insert "\r\n")) +; (re-search-forward "\\.\r\n") (goto-char (match-beginning 0)) (setq end (point-marker)) (pop3-clean-region start end) @@ -376,7 +357,7 @@ This function currently does nothing.") "Return highest accessed message-id number for the session." (pop3-send-command process "LAST") (let ((response (pop3-read-response process t))) - (string-to-int (nth 1 (pop3-string-to-list response))) + (string-to-int (nth 1 (split-string response " "))) )) (defun pop3-rset (process) @@ -477,3 +458,7 @@ and close the connection." ;; Restrictions: none ;; Possible responses: ;; +OK [TCP connection closed] + +(provide 'pop3) + +;;; pop3.el ends here diff --git a/lisp/qp.el b/lisp/qp.el index 8643104..fc909e4 100644 --- a/lisp/qp.el +++ b/lisp/qp.el @@ -23,46 +23,63 @@ ;;; Code: +(require 'mm-util) + (defvar quoted-printable-encoding-characters (mapcar 'identity "0123456789ABCDEFabcdef")) -(defun quoted-printable-decode-region (from to) - "Decode quoted-printable in the region between FROM and TO." +(defun quoted-printable-decode-region (from to &optional charset) + "Decode quoted-printable in the region between FROM and TO. +If CHARSET is non-nil, decode the region with charset." (interactive "r") (save-excursion - (goto-char from) - (while (search-forward "=" to t) - (cond - ;; End of the line. - ((eq (char-after) ?\n) - (delete-char -1) - (delete-char 1)) - ;; Encoded character. - ((and - (memq (char-after) quoted-printable-encoding-characters) - (memq (char-after (1+ (point))) - quoted-printable-encoding-characters)) - (subst-char-in-region - (1- (point)) (point) ?= - (string-to-number - (buffer-substring (point) (+ 2 (point))) - 16)) - (delete-char 2)) - ;; Quoted equal sign. - ((eq (char-after) ?=) - (delete-char 1)) - ;; End of buffer. - ((eobp) - (delete-char -1)) - ;; Invalid. - (t - (message "Malformed MIME quoted-printable message")))))) - -(defun quoted-printable-decode-string (string) - "Decode the quoted-printable-encoded STRING and return the results." + (save-restriction + (let (start) + (narrow-to-region from to) + (goto-char from) + (while (not (eobp)) + (cond + ((eq (char-after) ?=) + (delete-char 1) + (unless start + (setq start (point))) + (cond + ;; End of the line. + ((eq (char-after) ?\n) + (delete-char 1)) + ;; Encoded character. + ((and + (memq (char-after) quoted-printable-encoding-characters) + (memq (char-after (1+ (point))) + quoted-printable-encoding-characters)) + (insert + (string-to-number + (buffer-substring (point) (+ 2 (point))) + 16)) + (delete-char 2)) + ;; Quoted equal sign. + ((eq (char-after) ?=) + (forward-char 1)) + ;; End of buffer. + ((eobp)) + ;; Invalid. + (t + (message "Malformed MIME quoted-printable message")))) + ((and charset start (not (eq (mm-charset-after) 'ascii))) + (mm-decode-coding-region start (point) charset) + (setq start nil) + (forward-char 1)) + (t + (forward-char 1)))) + (if (and charset start) + (mm-decode-coding-region start (point) charset)))))) + +(defun quoted-printable-decode-string (string &optional charset) + "Decode the quoted-printable-encoded STRING and return the results. +If CHARSET is non-nil, decode the region with charset." (with-temp-buffer (insert string) - (quoted-printable-decode-region (point-min) (point-max)) + (quoted-printable-decode-region (point-min) (point-max) charset) (buffer-string))) (defun quoted-printable-encode-region (from to &optional fold class) diff --git a/lisp/rfc2047.el b/lisp/rfc2047.el index 74705da..e01d7b8 100644 --- a/lisp/rfc2047.el +++ b/lisp/rfc2047.el @@ -105,33 +105,31 @@ Valid encodings are nil, `Q' and `B'.") "Encode the message header according to `rfc2047-header-encoding-alist'. Should be called narrowed to the head of the message." (interactive "*") - (when (featurep 'mule) - (save-excursion - (goto-char (point-min)) - (let ((alist rfc2047-header-encoding-alist) - elem method) - (while (not (eobp)) - (save-restriction - (rfc2047-narrow-to-field) - (when (rfc2047-encodable-p) - ;; We found something that may perhaps be encoded. - (while (setq elem (pop alist)) - (when (or (and (stringp (car elem)) - (looking-at (car elem))) - (eq (car elem) t)) - (setq alist nil - method (cdr elem)))) - (when method - (cond - ((eq method 'mime) - (rfc2047-encode-region (point-min) (point-max)) - (rfc2047-fold-region (point-min) (point-max))) - ;; Hm. - (t)))) - (goto-char (point-max))))) - (when mail-parse-charset - (encode-coding-region (point-min) (point-max) - mail-parse-charset))))) + (save-excursion + (goto-char (point-min)) + (let ((alist rfc2047-header-encoding-alist) + elem method) + (while (not (eobp)) + (save-restriction + (rfc2047-narrow-to-field) + (when (rfc2047-encodable-p) + ;; We found something that may perhaps be encoded. + (while (setq elem (pop alist)) + (when (or (and (stringp (car elem)) + (looking-at (car elem))) + (eq (car elem) t)) + (setq alist nil + method (cdr elem)))) + (cond + ((eq method 'mime) + (rfc2047-encode-region (point-min) (point-max)) + (rfc2047-fold-region (point-min) (point-max))) + ;; Hm. + (t))) + (goto-char (point-max))))) + (when mail-parse-charset + (encode-coding-region + (point-min) (point-max) mail-parse-charset)))) (defun rfc2047-encodable-p (&optional header) "Say whether the current (narrowed) buffer contains characters that need encoding in headers." diff --git a/lisp/time-date.el b/lisp/time-date.el index c40ddbe..06f5ad1 100644 --- a/lisp/time-date.el +++ b/lisp/time-date.el @@ -3,6 +3,8 @@ ;; Author: Lars Magne Ingebrigtsen ;; Masanobu Umeda +;; Keywords: mail news util + ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify @@ -26,6 +28,7 @@ (require 'parse-time) +;;;###autoload (defun date-to-time (date) "Convert DATE into time." (condition-case () @@ -36,7 +39,7 @@ "Convert TIME to a floating point number." (+ (* (car time) 65536.0) (cadr time) - (/ (or (caddr time) 0) 1000000.0))) + (/ (or (nth 2 time) 0) 1000000.0))) (defun seconds-to-time (seconds) "Convert SECONDS (a floating point number) to an Emacs time structure." @@ -116,6 +119,7 @@ The Gregorian date Sunday, December 31, 1bce is imaginary." (- (/ (1- year) 100)) ; - century years (/ (1- year) 400)))) ; + Gregorian leap years +;;;###autoload (defun safe-date-to-time (date) "Parse DATE and return a time structure. If DATE is malformed, a zero time will be returned." diff --git a/lisp/utf7.el b/lisp/utf7.el index 27be1c9..1f3652c 100644 --- a/lisp/utf7.el +++ b/lisp/utf7.el @@ -1,7 +1,7 @@ ;;; utf7.el --- UTF-7 encoding/decoding for Emacs ;; Copyright (C) 1999 Free Software Foundation, Inc. -;; Author: Jon K Hellan +;; Author: Jon K Hellan ;; Keywords: mail ;; This file is part of GNU Emacs, but the same permissions apply diff --git a/lisp/webmail.el b/lisp/webmail.el index 1b9b9c4..f81869e 100644 --- a/lisp/webmail.el +++ b/lisp/webmail.el @@ -2,7 +2,7 @@ ;; Copyright (C) 1999 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu -;; Keywords: hotmail yahoo netaddress my-deja +;; Keywords: hotmail netaddress my-deja netscape ;; This file is part of GNU Emacs. @@ -77,7 +77,7 @@ (list-snarf . webmail-hotmail-list) (article-snarf . webmail-hotmail-article) (trash-url - "%s&login=%s&f=33792&curmbox=ACTIVE&_lang=&js=&foo=inbox&page=&%s=on&Move+To.x=Move+To&tobox=trAsH" + "%s&login=%s&f=33792&curmbox=ACTIVE&_lang=&foo=inbox&js=&page=&%s=on&_HMaction=MoveTo&tobox=trAsH&nullbox=" webmail-aux user id)) (yahoo (paranoid cookie post) @@ -111,10 +111,31 @@ "http://www.netaddress.com/tpl/Mail/%s/List?FolderID=-4&SortUseCase=True" webmail-session) (list-snarf . webmail-netaddress-list) + (article-url "http://www.netaddress.com/") (article-snarf . webmail-netaddress-article) (trash-url "http://www.netaddress.com/tpl/Message/%s/Move?FolderID=-4&Q=%s&N=&Sort=Date&F=-1" webmail-session id)) + (netscape + (paranoid cookie post agent) + (address . "webmail.netscape.com") + (open-url "http://ureg.netscape.com/iiop/UReg2/login/login?U2_LA=en&U2_BACK_FROM_CJ=true&U2_CS=iso-8859-1&U2_ENDURL=http://webmail.netscape.com/tpl/Subscribe/Step1&U2_NEW_ENDURL=http://webmail.netscape.com/tpl/Subscribe/Step1&U2_EXITURL=http://home.netscape.com/&U2_SOURCE=Webmail") + (open-snarf . webmail-netscape-open) + (login-url + content + ("http://ureg.netscape.com/iiop/UReg2/login/loginform") + "%s&U2_USERNAME=%s&U2_PASSWORD=%s" + webmail-aux user password) + (login-snarf . webmail-netaddress-login) + (list-url + "http://webmail.netscape.com/tpl/Mail/%s/List?FolderID=-4&SortUseCase=True" + webmail-session) + (list-snarf . webmail-netaddress-list) + (article-url "http://webmail.netscape.com/") + (article-snarf . webmail-netscape-article) + (trash-url + "http://webmail.netscape.com/tpl/Message/%s/Move?FolderID=-4&Q=%s&N=&Sort=Date&F=-1" + webmail-session id)) (my-deja (paranoid cookie post) (address . "www.my-deja.com") @@ -123,7 +144,7 @@ (login-url content ("%s" webmail-aux) - "user=%s&pw=%s&autologout=60&go=" + "member_name=%s&pw=%s&go=&priv_opt_MyDeja99=" user password) (list-url "http://www.deja.com/rg_gotomail.xp") (list-snarf . webmail-my-deja-list) @@ -356,7 +377,7 @@ (defun webmail-hotmail-list () (let (site url newp) (goto-char (point-min)) - (if (re-search-forward "[0-9]+ messages, [0-9]+ new" nil t) + (if (re-search-forward "[0-9]+ new" nil t) (message "Found %s" (match-string 0)) (webmail-error "maybe your w3 version is too old")) (goto-char (point-min)) @@ -644,6 +665,12 @@ ;;; netaddress +(defun webmail-netscape-open () + (goto-char (point-min)) + (if (re-search-forward "login/hint\\?\\([^\"]+\\)\"" nil t) + (setq webmail-aux (match-string 1)) + (webmail-error "open@1"))) + (defun webmail-netaddress-open () (goto-char (point-min)) (if (re-search-forward "action=\"\\([^\"]+\\)\"" nil t) @@ -671,7 +698,7 @@ (setq item (cons id (format "%s/tpl/Message/%s/Read?Q=%s&FolderID=-4&SortUseCase=True&Sort=Date&Headers=True" - (car webmail-open-url) + (car webmail-article-url) webmail-session id))) (if (or (not webmail-newmail-only) (equal (match-string 1) "True")) @@ -788,7 +815,132 @@ ;; Some blank line to seperate mails. (insert "\n\nFrom nobody " (current-time-string) "\n") (if id - (insert (format "Message-ID: <%s@usa.net>\n" id))) + (insert (format "Message-ID: <%s@%s>\n" id webmail-address))) + (unless (looking-at "$") + (if (search-forward "\n\n" nil t) + (forward-line -1) + (webmail-error "article@2"))) + (when mime + (narrow-to-region (point-min) (point)) + (goto-char (point-min)) + (while (not (eobp)) + (if (looking-at "MIME-Version\\|Content-Type") + (delete-region (point) + (progn + (forward-line 1) + (if (re-search-forward "^[^ \t]" nil t) + (goto-char (match-beginning 0)) + (point-max)))) + (forward-line 1))) + (goto-char (point-max)) + (widen) + (narrow-to-region (point) (point-max)) + (insert "MIME-Version: 1.0\n" + (prog1 + (mml-generate-mime) + (delete-region (point-min) (point-max)))) + (goto-char (point-min)) + (widen)) + (let (case-fold-search) + (while (re-search-forward "^From " nil t) + (beginning-of-line) + (insert ">")))) + (mm-append-to-file (point-min) (point-max) file))) + +(defun webmail-netscape-article (file id) + (let (p p1 attachment count mime type) + (save-restriction + (webmail-encode-8bit) + (goto-char (point-min)) + (if (not (search-forward "Trash" nil t)) + (webmail-error "article@1")) + (if (not (search-forward "
" nil t)) + (webmail-error "article@2")) + (delete-region (point-min) (match-beginning 0)) + (if (not (search-forward "
" nil t)) + (webmail-error "article@3")) + (narrow-to-region (point-min) (match-end 0)) + (goto-char (point-min)) + (while (re-search-forward "[\040\t\r\n]+" nil t) + (replace-match " ")) + (goto-char (point-min)) + (while (re-search-forward "
]*>[^<]*" nil t) + (replace-match "")) + (goto-char (point-min)) + (while (search-forward "" nil t) + (replace-match "\n")) + (nnweb-remove-markup) + (nnweb-decode-entities) + (goto-char (point-min)) + (delete-blank-lines) + (goto-char (point-min)) + (while (re-search-forward "^\040+\\|\040+$" nil t) + (replace-match "")) + (goto-char (point-min)) + (while (re-search-forward "\040+" nil t) + (replace-match " ")) + (goto-char (point-max)) + (widen) + (insert "\n\n") + (setq p (point)) + (unless (search-forward "" nil t) + (webmail-error "article@4")) + (forward-line 14) + (delete-region p (point)) + (goto-char (point-max)) + (unless (re-search-backward + "
" + nil t 2) + (setq mime t) + (unless (search-forward "" nil t) + (webmail-error "article@6")) + (setq p1 (point)) + (if (search-backward "" nil t) + (webmail-error "article@8")) + (delete-region p (point)) + (let (bufname);; Attachment + (save-excursion + (set-buffer (generate-new-buffer " *webmail-att*")) + (nnweb-insert (concat (car webmail-open-url) attachment)) + (push (current-buffer) webmail-buffer-list) + (setq bufname (buffer-name))) + (insert "<#part type=" type) + (insert " buffer=\"" bufname "\"") + (insert " disposition=\"inline\"") + (insert "><#/part>\n") + (setq p (point)))) + (delete-region p p1) + (narrow-to-region + p + (if (search-forward + "" + nil t) + (match-beginning 0) + (point-max))) + (webmail-netaddress-single-part) + (goto-char (point-max)) + (setq p (point)) + (widen))) + (unless mime + (narrow-to-region p (point-max)) + (setq mime (webmail-netaddress-single-part)) + (widen)) + (goto-char (point-min)) + ;; Some blank line to seperate mails. + (insert "\n\nFrom nobody " (current-time-string) "\n") + (if id + (insert (format "Message-ID: <%s@%s>\n" id webmail-address))) (unless (looking-at "$") (if (search-forward "\n\n" nil t) (forward-line -1) @@ -825,7 +977,7 @@ (defun webmail-my-deja-open () (webmail-refresh-redirect) (goto-char (point-min)) - (if (re-search-forward "action=\"\\([^\"]+login_confirm\\.xp[^\"]+\\)\"" + (if (re-search-forward "action=\"\\([^\"]+login_confirm\\.xp[^\"]*\\)\"" nil t) (setq webmail-aux (match-string 1)) (webmail-error "open@1"))) diff --git a/make.bat b/make.bat index b203277..9e9936c 100755 --- a/make.bat +++ b/make.bat @@ -1,14 +1,14 @@ @echo off -rem Written by David Charlap - -rem There are two catches, however. The emacs.bat batch file may not exist -rem in all distributions. It is part of the Voelker build of Emacs 19.34 -rem (http://www.cs.washington.edu/homes/voelker/ntemacs.html). If the user -rem installs Gnus with some other build, he may have to replace calls to +rem Written by David Charlap (shamino@writeme.com) +rem +rem There are two possible problems with this batch file. The emacs.bat batch +rem file may not exist in all distributions. It is part of the GNU build of +rem Emacs 20.4 (http://www.gnu.org/softare/emacs/windows.ntemacs.html) If you +rem install Gnus with some other build, you may have to replace calls to rem %1\emacs.bat with something else. rem -rem Also, the emacs.bat file that Voelker ships does not accept more than 9 +rem Also, the emacs.bat file that comes with Emacs does not accept more than 9 rem parameters, so the attempts to compile the .texi files will fail. To rem fix that (at least on NT. I don't know about Win95), the following rem change should be made to emacs.bat: @@ -31,16 +31,19 @@ if "%1" == "" goto usage cd lisp call %1\bin\emacs.bat -batch -q -no-site-file -l ./dgnushack.el -f dgnushack-compile if not "%2" == "copy" goto info -copy *.el* %1\lisp +attrib -r %1\lisp\gnus\* +copy *.el* %1\lisp\gnus :info cd ..\texi -call %1\bin\emacs.bat -batch -q -no-site-file gnus.texi -l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer -call %1\bin\emacs.bat -batch -q -no-site-file message.texi -l texinfmt -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer +call %1\bin\emacs.bat -batch -q -no-site-file message.texi -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer +call %1\bin\emacs.bat -batch -q -no-site-file emacs-mime.texi -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer +call %1\bin\emacs.bat -batch -q -no-site-file gnus.texi -f texinfo-every-node-update -f texinfo-format-buffer -f save-buffer if not "%2" == "copy" goto done copy gnus %1\info copy gnus-?? %1\info copy message %1\info +copy emacs-mime %1\info :etc cd ..\etc @@ -54,7 +57,7 @@ goto end echo Usage: make ^ [copy] echo. echo where: ^ is the directory you installed emacs in -echo eg. d:\emacs\19.34 +echo eg. d:\emacs\20.4 echo copy indicates that the compiled files should be copied to your echo emacs lisp, info, and etc directories diff --git a/texi/ChangeLog b/texi/ChangeLog index 73d708c..ad588ba 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,6 +1,44 @@ +2000-03-19 Simon Josefsson + + * gnus.texi (IMAP): Addition. + +2000-03-13 17:44:59 Lars Magne Ingebrigtsen + + * gnus.texi (Process/Prefix): Addition. + +2000-02-04 Simon Josefsson + + * gnus.texi (IMAP): Fix. + +2000-01-27 18:06:35 Lars Magne Ingebrigtsen + + * gnus.texi (Remember): Addition. + +2000-01-21 Simon Josefsson + + * gnus.texi (Splitting in IMAP): Addition. + (Mail Source Specifiers): Add fetchflag setting in example. + +2000-01-08 08:10:04 Martin Bialasinski + + * gnus.texi (Mail and Post): Example. + +2000-01-08 07:46:13 Lars Magne Ingebrigtsen + + * gnus.texi (Customizing w3): New. + +2000-01-08 07:46:06 Hamish Macdonald + + * gnus.texi (Customizing w3): Example. + +2000-01-06 17:55:28 Lars Magne Ingebrigtsen + + * gnus.texi (Charsets): Addition. + 2000-01-05 15:58:48 Lars Magne Ingebrigtsen * gnus.texi (Mail Group Commands): Addition. + (Top): Added detailmenu. 2000-01-03 01:31:02 Lars Magne Ingebrigtsen diff --git a/texi/gnus.texi b/texi/gnus.texi index 5c0ac9f..c6808b2 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -355,7 +355,7 @@ can be gotten by any nefarious means you can think of---@sc{nntp}, local spool or your mbox file. All at the same time, if you want to push your luck. -This manual corresponds to Gnus 5.8.3. +This manual corresponds to Gnus 5.8.4. @end ifinfo @@ -386,7 +386,6 @@ the program. @end iftex - @menu * Starting Up:: Finding news can be a pain. * The Group Buffer:: Selecting, subscribing and killing groups. @@ -400,6 +399,465 @@ the program. * Appendices:: Terminology, Emacs intro, FAQ, History, Internals. * Index:: Variable, function and concept index. * Key Index:: Key Index. + +@detailmenu + --- The Detailed Node Listing --- + +Starting Gnus + +* Finding the News:: Choosing a method for getting news. +* The First Time:: What does Gnus do the first time you start it? +* The Server is Down:: How can I read my mail then? +* Slave Gnusae:: You can have more than one Gnus active at a time. +* Fetching a Group:: Starting Gnus just to read a group. +* New Groups:: What is Gnus supposed to do with new groups? +* Startup Files:: Those pesky startup files---@file{.newsrc}. +* Auto Save:: Recovering from a crash. +* The Active File:: Reading the active file over a slow line Takes Time. +* Changing Servers:: You may want to move from one server to another. +* Startup Variables:: Other variables you might change. + +New Groups + +* Checking New Groups:: Determining what groups are new. +* Subscription Methods:: What Gnus should do with new groups. +* Filtering New Groups:: Making Gnus ignore certain new groups. + +The Group Buffer + +* Group Buffer Format:: Information listed and how you can change it. +* Group Maneuvering:: Commands for moving in the group buffer. +* Selecting a Group:: Actually reading news. +* Group Data:: Changing the info for a group. +* Subscription Commands:: Unsubscribing, killing, subscribing. +* Group Levels:: Levels? What are those, then? +* Group Score:: A mechanism for finding out what groups you like. +* Marking Groups:: You can mark groups for later processing. +* Foreign Groups:: Creating and editing groups. +* Group Parameters:: Each group may have different parameters set. +* Listing Groups:: Gnus can list various subsets of the groups. +* Sorting Groups:: Re-arrange the group order. +* Group Maintenance:: Maintaining a tidy @file{.newsrc} file. +* Browse Foreign Server:: You can browse a server. See what it has to offer. +* Exiting Gnus:: Stop reading news and get some work done. +* Group Topics:: A folding group mode divided into topics. +* Misc Group Stuff:: Other stuff that you can to do. + +Group Buffer Format + +* Group Line Specification:: Deciding how the group buffer is to look. +* Group Modeline Specification:: The group buffer modeline. +* Group Highlighting:: Having nice colors in the group buffer. + +Group Topics + +* Topic Variables:: How to customize the topics the Lisp Way. +* Topic Commands:: Interactive E-Z commands. +* Topic Sorting:: Sorting each topic individually. +* Topic Topology:: A map of the world. +* Topic Parameters:: Parameters that apply to all groups in a topic. + +Misc Group Stuff + +* Scanning New Messages:: Asking Gnus to see whether new messages have arrived. +* Group Information:: Information and help on groups and Gnus. +* Group Timestamp:: Making Gnus keep track of when you last read a group. +* File Commands:: Reading and writing the Gnus files. + +The Summary Buffer + +* Summary Buffer Format:: Deciding how the summary buffer is to look. +* Summary Maneuvering:: Moving around the summary buffer. +* Choosing Articles:: Reading articles. +* Paging the Article:: Scrolling the current article. +* Reply Followup and Post:: Posting articles. +* Marking Articles:: Marking articles as read, expirable, etc. +* Limiting:: You can limit the summary buffer. +* Threading:: How threads are made. +* Sorting:: How articles and threads are sorted. +* Asynchronous Fetching:: Gnus might be able to pre-fetch articles. +* Article Caching:: You may store articles in a cache. +* Persistent Articles:: Making articles expiry-resistant. +* Article Backlog:: Having already read articles hang around. +* Saving Articles:: Ways of customizing article saving. +* Decoding Articles:: Gnus can treat series of (uu)encoded articles. +* Article Treatment:: The article buffer can be mangled at will. +* MIME Commands:: Doing MIMEy things with the articles. +* Charsets:: Character set issues. +* Article Commands:: Doing various things with the article buffer. +* Summary Sorting:: Sorting the summary buffer in various ways. +* Finding the Parent:: No child support? Get the parent. +* Alternative Approaches:: Reading using non-default summaries. +* Tree Display:: A more visual display of threads. +* Mail Group Commands:: Some commands can only be used in mail groups. +* Various Summary Stuff:: What didn't fit anywhere else. +* Exiting the Summary Buffer:: Returning to the Group buffer. +* Crosspost Handling:: How crossposted articles are dealt with. +* Duplicate Suppression:: An alternative when crosspost handling fails. + +Summary Buffer Format + +* Summary Buffer Lines:: You can specify how summary lines should look. +* To From Newsgroups:: How to not display your own name. +* Summary Buffer Mode Line:: You can say how the mode line should look. +* Summary Highlighting:: Making the summary buffer all pretty and nice. + +Choosing Articles + +* Choosing Commands:: Commands for choosing articles. +* Choosing Variables:: Variables that influence these commands. + +Reply, Followup and Post + +* Summary Mail Commands:: Sending mail. +* Summary Post Commands:: Sending news. +* Summary Message Commands:: Other Message-related commands. +* Canceling and Superseding:: ``Whoops, I shouldn't have called him that.'' + +Marking Articles + +* Unread Articles:: Marks for unread articles. +* Read Articles:: Marks for read articles. +* Other Marks:: Marks that do not affect readedness. + +Marking Articles + +* Setting Marks:: How to set and remove marks. +* Generic Marking Commands:: How to customize the marking. +* Setting Process Marks:: How to mark articles for later processing. + +Threading + +* Customizing Threading:: Variables you can change to affect the threading. +* Thread Commands:: Thread based commands in the summary buffer. + +Customizing Threading + +* Loose Threads:: How Gnus gathers loose threads into bigger threads. +* Filling In Threads:: Making the threads displayed look fuller. +* More Threading:: Even more variables for fiddling with threads. +* Low-Level Threading:: You thought it was over... but you were wrong! + +Decoding Articles + +* Uuencoded Articles:: Uudecode articles. +* Shell Archives:: Unshar articles. +* PostScript Files:: Split PostScript. +* Other Files:: Plain save and binhex. +* Decoding Variables:: Variables for a happy decoding. +* Viewing Files:: You want to look at the result of the decoding? + +Decoding Variables + +* Rule Variables:: Variables that say how a file is to be viewed. +* Other Decode Variables:: Other decode variables. +* Uuencoding and Posting:: Variables for customizing uuencoding. + +Article Treatment + +* Article Highlighting:: You want to make the article look like fruit salad. +* Article Fontisizing:: Making emphasized text look nice. +* Article Hiding:: You also want to make certain info go away. +* Article Washing:: Lots of way-neat functions to make life better. +* Article Buttons:: Click on URLs, Message-IDs, addresses and the like. +* Article Date:: Grumble, UT! +* Article Signature:: What is a signature? +* Article Miscellania:: Various other stuff. + +Alternative Approaches + +* Pick and Read:: First mark articles and then read them. +* Binary Groups:: Auto-decode all articles. + +Various Summary Stuff + +* Summary Group Information:: Information oriented commands. +* Searching for Articles:: Multiple article commands. +* Summary Generation Commands:: (Re)generating the summary buffer. +* Really Various Summary Commands:: Those pesky non-conformant commands. + +The Article Buffer + +* Hiding Headers:: Deciding what headers should be displayed. +* Using MIME:: Pushing articles through @sc{mime} before reading them. +* Customizing Articles:: Tailoring the look of the articles. +* Article Keymap:: Keystrokes available in the article buffer. +* Misc Article:: Other stuff. + +Composing Messages + +* Mail:: Mailing and replying. +* Post:: Posting and following up. +* Posting Server:: What server should you post via? +* Mail and Post:: Mailing and posting at the same time. +* Archived Messages:: Where Gnus stores the messages you've sent. +* Posting Styles:: An easier way to specify who you are. +* Drafts:: Postponing messages and rejected messages. +* Rejected Articles:: What happens if the server doesn't like your article? + +Select Methods + +* The Server Buffer:: Making and editing virtual servers. +* Getting News:: Reading USENET news with Gnus. +* Getting Mail:: Reading your personal mail with Gnus. +* Browsing the Web:: Getting messages from a plethora of Web sources. +* Other Sources:: Reading directories, files, SOUP packets. +* Combined Groups:: Combining groups into one group. +* Gnus Unplugged:: Reading news and mail offline. + +The Server Buffer + +* Server Buffer Format:: You can customize the look of this buffer. +* Server Commands:: Commands to manipulate servers. +* Example Methods:: Examples server specifications. +* Creating a Virtual Server:: An example session. +* Server Variables:: Which variables to set. +* Servers and Methods:: You can use server names as select methods. +* Unavailable Servers:: Some servers you try to contact may be down. + +Getting News + +* NNTP:: Reading news from an @sc{nntp} server. +* News Spool:: Reading news from the local spool. + +Getting Mail + +* Mail in a Newsreader:: Important introductory notes. +* Getting Started Reading Mail:: A simple cookbook example. +* Splitting Mail:: How to create mail groups. +* Mail Sources:: How to tell Gnus where to get mail from. +* Mail Backend Variables:: Variables for customizing mail handling. +* Fancy Mail Splitting:: Gnus can do hairy splitting of incoming mail. +* Group Mail Splitting:: Use group customize to drive mail splitting. +* Incorporating Old Mail:: What about the old mail you have? +* Expiring Mail:: Getting rid of unwanted mail. +* Washing Mail:: Removing gruft from the mail you get. +* Duplicates:: Dealing with duplicated mail. +* Not Reading Mail:: Using mail backends for reading other files. +* Choosing a Mail Backend:: Gnus can read a variety of mail formats. + +Mail Sources + +* Mail Source Specifiers:: How to specify what a mail source is. +* Mail Source Customization:: Some variables that influence things. +* Fetching Mail:: Using the mail source specifiers. + +Choosing a Mail Backend + +* Unix Mail Box:: Using the (quite) standard Un*x mbox. +* Rmail Babyl:: Emacs programs use the rmail babyl format. +* Mail Spool:: Store your mail in a private spool? +* MH Spool:: An mhspool-like backend. +* Mail Folders:: Having one file for each group. +* Comparing Mail Backends:: An in-depth looks at pros and cons. + +Browsing the Web + +* Web Searches:: Creating groups from articles that match a string. +* Slashdot:: Reading the Slashdot comments. +* Ultimate:: The Ultimate Bulletin Board systems. +* Web Archive:: Reading mailing list archived on web. + +Other Sources + +* Directory Groups:: You can read a directory as if it was a newsgroup. +* Anything Groups:: Dired? Who needs dired? +* Document Groups:: Single files can be the basis of a group. +* SOUP:: Reading @sc{soup} packets ``offline''. +* Mail-To-News Gateways:: Posting articles via mail-to-news gateways. +* IMAP:: Using Gnus as a @sc{imap} client. + +Document Groups + +* Document Server Internals:: How to add your own document types. + +SOUP + +* SOUP Commands:: Commands for creating and sending @sc{soup} packets +* SOUP Groups:: A backend for reading @sc{soup} packets. +* SOUP Replies:: How to enable @code{nnsoup} to take over mail and news. + +@sc{imap} + +* Splitting in IMAP:: Splitting mail with nnimap. +* Editing IMAP ACLs:: Limiting/enabling other users access to a mailbox. +* Expunging mailboxes:: Equivalent of a "compress mailbox" button. + +Combined Groups + +* Virtual Groups:: Combining articles from many groups. +* Kibozed Groups:: Looking through parts of the newsfeed for articles. + +Gnus Unplugged + +* Agent Basics:: How it all is supposed to work. +* Agent Categories:: How to tell the Gnus Agent what to download. +* Agent Commands:: New commands for all the buffers. +* Agent Expiry:: How to make old articles go away. +* Outgoing Messages:: What happens when you post/mail something? +* Agent Variables:: Customizing is fun. +* Example Setup:: An example @file{.gnus.el} file for offline people. +* Batching Agents:: How to fetch news from a @code{cron} job. +* Agent Caveats:: What you think it'll do and what it does. + +Agent Categories + +* Category Syntax:: What a category looks like. +* The Category Buffer:: A buffer for maintaining categories. +* Category Variables:: Customize'r'Us. + +Agent Commands + +* Group Agent Commands:: +* Summary Agent Commands:: +* Server Agent Commands:: + +Scoring + +* Summary Score Commands:: Adding score entries for the current group. +* Group Score Commands:: General score commands. +* Score Variables:: Customize your scoring. (My, what terminology). +* Score File Format:: What a score file may contain. +* Score File Editing:: You can edit score files by hand as well. +* Adaptive Scoring:: Big Sister Gnus knows what you read. +* Home Score File:: How to say where new score entries are to go. +* Followups To Yourself:: Having Gnus notice when people answer you. +* Scoring Tips:: How to score effectively. +* Reverse Scoring:: That problem child of old is not problem. +* Global Score Files:: Earth-spanning, ear-splitting score files. +* Kill Files:: They are still here, but they can be ignored. +* Converting Kill Files:: Translating kill files to score files. +* GroupLens:: Getting predictions on what you like to read. +* Advanced Scoring:: Using logical expressions to build score rules. +* Score Decays:: It can be useful to let scores wither away. + +GroupLens + +* Using GroupLens:: How to make Gnus use GroupLens. +* Rating Articles:: Letting GroupLens know how you rate articles. +* Displaying Predictions:: Displaying predictions given by GroupLens. +* GroupLens Variables:: Customizing GroupLens. + +Advanced Scoring + +* Advanced Scoring Syntax:: A definition. +* Advanced Scoring Examples:: What they look like. +* Advanced Scoring Tips:: Getting the most out of it. + +Various + +* Process/Prefix:: A convention used by many treatment commands. +* Interactive:: Making Gnus ask you many questions. +* Symbolic Prefixes:: How to supply some Gnus functions with options. +* Formatting Variables:: You can specify what buffers should look like. +* Windows Configuration:: Configuring the Gnus buffer windows. +* Faces and Fonts:: How to change how faces look. +* Compilation:: How to speed Gnus up. +* Mode Lines:: Displaying information in the mode lines. +* Highlighting and Menus:: Making buffers look all nice and cozy. +* Buttons:: Get tendonitis in ten easy steps! +* Daemons:: Gnus can do things behind your back. +* NoCeM:: How to avoid spam and other fatty foods. +* Undo:: Some actions can be undone. +* Moderation:: What to do if you're a moderator. +* XEmacs Enhancements:: There are more pictures and stuff under XEmacs. +* Fuzzy Matching:: What's the big fuzz? +* Thwarting Email Spam:: A how-to on avoiding unsolicited commercial email. +* Various Various:: Things that are really various. + +Formatting Variables + +* Formatting Basics:: A formatting variable is basically a format string. +* Mode Line Formatting:: Some rules about mode line formatting variables. +* Advanced Formatting:: Modifying output in various ways. +* User-Defined Specs:: Having Gnus call your own functions. +* Formatting Fonts:: Making the formatting look colorful and nice. + +XEmacs Enhancements + +* Picons:: How to display pictures of what your reading. +* Smileys:: Show all those happy faces the way they were meant to be shown. +* Toolbar:: Click'n'drool. +* XVarious:: Other XEmacsy Gnusey variables. + +Picons + +* Picon Basics:: What are picons and How do I get them. +* Picon Requirements:: Don't go further if you aren't using XEmacs. +* Easy Picons:: Displaying Picons---the easy way. +* Hard Picons:: The way you should do it. You'll learn something. +* Picon Useless Configuration:: Other variables you can trash/tweak/munge/play with. + +Appendices + +* History:: How Gnus got where it is today. +* On Writing Manuals:: Why this is not a beginner's guide. +* Terminology:: We use really difficult, like, words here. +* Customization:: Tailoring Gnus to your needs. +* Troubleshooting:: What you might try if things do not work. +* Gnus Reference Guide:: Rilly, rilly technical stuff. +* Emacs for Heathens:: A short introduction to Emacsian terms. +* Frequently Asked Questions:: A question-and-answer session. + +History + +* Gnus Versions:: What Gnus versions have been released. +* Other Gnus Versions:: Other Gnus versions that also have been released. +* Why?:: What's the point of Gnus? +* Compatibility:: Just how compatible is Gnus with @sc{gnus}? +* Conformity:: Gnus tries to conform to all standards. +* Emacsen:: Gnus can be run on a few modern Emacsen. +* Gnus Development:: How Gnus is developed. +* Contributors:: Oodles of people. +* New Features:: Pointers to some of the new stuff in Gnus. +* Newest Features:: Features so new that they haven't been written yet. + +New Features + +* ding Gnus:: New things in Gnus 5.0/5.1, the first new Gnus. +* September Gnus:: The Thing Formally Known As Gnus 5.3/5.3. +* Red Gnus:: Third time best---Gnus 5.4/5.5. +* Quassia Gnus:: Two times two is four, or Gnus 5.6/5.7. + +Customization + +* Slow/Expensive Connection:: You run a local Emacs and get the news elsewhere. +* Slow Terminal Connection:: You run a remote Emacs. +* Little Disk Space:: You feel that having large setup files is icky. +* Slow Machine:: You feel like buying a faster machine. + +Gnus Reference Guide + +* Gnus Utility Functions:: Common functions and variable to use. +* Backend Interface:: How Gnus communicates with the servers. +* Score File Syntax:: A BNF definition of the score file standard. +* Headers:: How Gnus stores headers internally. +* Ranges:: A handy format for storing mucho numbers. +* Group Info:: The group info format. +* Extended Interactive:: Symbolic prefixes and stuff. +* Emacs/XEmacs Code:: Gnus can be run under all modern Emacsen. +* Various File Formats:: Formats of files that Gnus use. + +Backend Interface + +* Required Backend Functions:: Functions that must be implemented. +* Optional Backend Functions:: Functions that need not be implemented. +* Error Messaging:: How to get messages and report errors. +* Writing New Backends:: Extending old backends. +* Hooking New Backends Into Gnus:: What has to be done on the Gnus end. +* Mail-like Backends:: Some tips on mail backends. + +Various File Formats + +* Active File Format:: Information on articles and groups available. +* Newsgroups File Format:: Group descriptions. + +Emacs for Heathens + +* Keystrokes:: Entering text and executing commands. +* Emacs Lisp:: The built-in Emacs programming language. + +@end detailmenu @end menu @node Starting Up @@ -1733,6 +2191,9 @@ will go to the next group of the same level (or lower). This might be handy if you want to read the most important groups before you read the rest. +If this variable is @code{best}, Gnus will make the next newsgroup the +one with the best level. + @vindex gnus-group-default-list-level All groups with a level less than or equal to @code{gnus-group-default-list-level} will be listed in the group buffer @@ -6599,9 +7060,10 @@ Signature}. @kindex W W l (Summary) @findex gnus-article-hide-list-identifiers @vindex gnus-list-identifiers -Hide list identifiers specified in @code{gnus-list-identifiers}. These -are strings some list servers add to the beginning of all @code{Subject} -headers---for example, @samp{[zebra 4711]}. +Strip list identifiers specified in @code{gnus-list-identifiers}. +These are strings some mailing list servers add to the beginning of +all @code{Subject} headers---for example, @samp{[zebra 4711]}. Any +leading @samp{Re: } is skipped before stripping. @table @code @@ -7338,7 +7800,31 @@ on a group-by-group basis using the group parameters (@pxref{Group Parameters}). The default value is @code{(unknown-8bit)}, which is something some agents insist on having in there. -@cindex Russina +@vindex gnus-group-posting-charset-alist +When posting, @code{gnus-group-posting-charset-alist} is used to +determine which charsets should not be encoded using the @sc{mime} +encodings. For instance, some hierarchies discourage using +quoted-printable header encoding. + +This variable is an alist of regexps and permitted unencoded charsets +for posting. Each element of the alist has the form @code{(}@var{test +header body-list}@code{)}, where: + +@table @var +@item +test +is either a regular expression matching the newsgroup header or a +variable to query, +@item header +is the charset which may be left unencoded in the header (@code{nil} +means encode all charsets), +@item body-list +is a list of charsets which may be encoded using 8bit content-transfer +encoding in the body, or one of the special values @code{nil} (always +encode using quoted-printable) or @code{t} (always use 8bit). +@end table + +@cindex Russian @cindex koi8-r @cindex koi8-u @cindex iso-8859-5 @@ -8222,8 +8708,9 @@ command will make exit without updating (the @kbd{Q} command) worthless. @end table @vindex gnus-exit-group-hook -@code{gnus-exit-group-hook} is called when you exit the current -group. +@code{gnus-exit-group-hook} is called when you exit the current group +with an ``updating'' exit. For instance @kbd{Q} +(@code{gnus-summary-exit-no-update}) does not call this hook. @findex gnus-summary-wake-up-the-dead @findex gnus-dead-summary-mode @@ -8982,6 +9469,21 @@ spell-checking via the @code{ispell} package: (add-hook 'message-send-hook 'ispell-message) @end lisp +If you want to change the @code{ispell} dictionary based on what group +you're in, you could say something like the following: + +@lisp +(add-hook 'gnus-select-group-hook + (lambda () + (cond + ((string-match "^de\\." gnus-newsgroup-name) + (ispell-change-dictionary "deutsch")) + (t + (ispell-change-dictionary "english"))))) +@end lisp + +Modify to suit your needs. + @node Archived Messages @section Archived Messages @@ -9199,7 +9701,7 @@ So here's a new example: (signature my-quote-randomizer)) ((message-news-p) (signature my-news-signature)) - ((header "From.*To" "larsi.*org") + (header "From.*To" "larsi.*org" (Organization "Somewhere, Inc.")) ((posting-from-work-p) (signature-file "~/.work-signature") @@ -10656,7 +11158,7 @@ after finishing the fetch. An example @sc{imap} mail source: @lisp -(imap :server "mail.mycorp.com" :stream kerberos4) +(imap :server "mail.mycorp.com" :stream kerberos4 :fetchflag "\\Seen") @end lisp @item webmail @@ -11863,8 +12365,11 @@ interfaces to these sources. * Slashdot:: Reading the Slashdot comments. * Ultimate:: The Ultimate Bulletin Board systems. * Web Archive:: Reading mailing list archived on web. +* Customizing w3:: Doing stuff to Emacs/w3 from Gnus. @end menu +All the web sources require Emacs/w3 and the url library to work. + The main caveat with all these web sources is that they probably won't work for a very long time. Gleaning information from the @sc{html} data is guesswork at best, and when the layout is altered, the Gnus backend @@ -12084,6 +12589,7 @@ The directory where @code{nnultimate} stores its files. The default is @samp{~/News/ultimate/}. @end table + @node Web Archive @subsection Web Archive @cindex nnwarchive @@ -12120,6 +12626,38 @@ The account name on the web server. The password for your account on the web server. @end table + +@node Customizing w3 +@subsection Customizing w3 +@cindex w3 +@cindex html +@cindex url +@cindex Netscape + +Gnus uses the url library to fetch web pages and Emacs/w3 to display web +pages. Emacs/w3 is documented in its own manual, but there are some +things that may be more relevant for Gnus users. + +For instance, a common question is how to make Emacs/w3 follow links +using the @code{browse-url} functions (which will call some external web +browser like Netscape). Here's one way: + +@lisp +(eval-after-load "w3" + '(progn + (fset 'w3-fetch-orig (symbol-function 'w3-fetch)) + (defun w3-fetch (&optional url target) + (interactive (list (w3-read-url-with-default))) + (if (eq major-mode 'gnus-article-mode) + (browse-url url) + (w3-fetch-orig url target))))) +@end lisp + +Put that in your @file{.emacs} file, and hitting links in w3-rendered +@sc{html} in the Gnus article buffers will use @code{browse-url} to +follow the link. + + @node Other Sources @section Other Sources @@ -12851,17 +13389,36 @@ Example: @item nnimap-stream @vindex nnimap-stream The type of stream used to connect to your server. By default, nnimap -will use the most secure stream your server is capable of. +will detect and automatically use all of the below, with the exception +of SSL. (SSL is being replaced by STARTTLS, which can be automatically +detected, but it's not widely deployed yet). @itemize @bullet @item -@dfn{kerberos4:} Uses the `imtest' program. +@dfn{gssapi:} Connect with GSSAPI (usually kerberos 5). Require the +@samp{imtest} program. +@item +@dfn{kerberos4:} Connect with kerberos 4. Require the @samp{imtest} program. @item -@dfn{ssl:} Uses OpenSSL or SSLeay. +@dfn{starttls:} Connect via the STARTTLS extension (similar to +SSL). Require the external library @samp{starttls.el} and program +@samp{starttls}. +@item +@dfn{ssl:} Connect through SSL. Require OpenSSL (the +program @samp{openssl}) or SSLeay (@samp{s_client}). @item @dfn{network:} Plain, TCP/IP network connection. @end itemize +The @samp{imtest} program is shipped with Cyrus IMAPD, nnimap support +both @samp{imtest} version 1.5.x and version 1.6.x. + +For SSL connections, the OpenSSL program is available from +@file{http://www.openssl.org/}. OpenSSL was formerly known as SSLeay, +and nnimap support it too - altough the most recent versions of SSLeay, +0.9.x, are known to have serious bugs making it useless. Earlier +versions, especially 0.8.x, of SSLeay are known to work. + @item nnimap-authenticator @vindex nnimap-authenticator @@ -12870,7 +13427,14 @@ will use the most secure authenticator your server is capable of. @itemize @bullet @item -@dfn{kerberos4:} Kerberos authentication. +@dfn{gssapi:} GSSAPI (usually kerberos 5) authentication. Require +external program @code{imtest}. +@item +@dfn{kerberos4:} Kerberos authentication. Require external program +@code{imtest}. +@item +@dfn{digest-md5:} Encrypted username/password via DIGEST-MD5. Require +external library @code{digest-md5.el}. @item @dfn{cram-md5:} Encrypted username/password via CRAM-MD5. @item @@ -13020,6 +13584,18 @@ The splitting code tries to create mailboxes if it need too. Nnmail equivalent: @code{nnmail-split-methods}. +@item nnimap-split-predicate +@cindex splitting +@vindex nnimap-split-predicate + +Mail matching this predicate in @code{nnimap-split-inbox} will be +splitted, it is a string and the default is @samp{UNSEEN UNDELETED}. + +This might be useful if you use another @sc{imap} client to read mail in +your inbox but would like Gnus to split all articles in the inbox +regardless of readedness. Then you might change this to +@samp{UNDELETED}. + @item nnimap-split-fancy @cindex splitting, fancy @findex nnimap-split-fancy @@ -15856,6 +16432,12 @@ will mark the next three unread articles as read, no matter what the summary buffer looks like. Set @code{gnus-summary-goto-unread} to @code{nil} for a more straightforward action. +Many commands do not use the process/prefix convention. All commands +that do explicitly say so in this manual. To apply the process/prefix +convention to commands that do not use it, you can use the @kbd{M-&} +command. For instance, to mark all the articles in the group as +expirable, you could say `M P b M-& E'. + @node Interactive @section Interactive diff --git a/texi/message.texi b/texi/message.texi index ac6e009..5b16cf8 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @setfilename message -@settitle Pterodactyl Message 5.8.3 Manual +@settitle Pterodactyl Pterodactyl Message 5.8.4 Manual @synindex fn cp @synindex vr cp @synindex pg cp @@ -42,7 +42,7 @@ into another language, under the above conditions for modified versions. @tex @titlepage -@title Pterodactyl Message 5.8.3 Manual +@title Pterodactyl Pterodactyl Message 5.8.4 Manual @author by Lars Magne Ingebrigtsen @page @@ -83,7 +83,7 @@ Message mode buffers. * Key Index:: List of Message mode keys. @end menu -This manual corresponds to Pterodactyl Message 5.8.3. Message is +This manual corresponds to Pterodactyl Pterodactyl Message 5.8.4. Message is distributed with the Gnus distribution bearing the same version number as this manual.