Gnus development mailing list
 help / color / mirror / Atom feed
From: Dave Love <fx@gnu.org>
To: simon@josefsson.org
Cc: ding@gnus.org
Subject: Re: imap.el workaround for Exchange 2007
Date: Tue, 23 Dec 2008 15:41:01 +0000	[thread overview]
Message-ID: <87iqpa99wy.fsf@liv.ac.uk> (raw)
In-Reply-To: <87ocz3n8d4.fsf@marauder.physik.uni-ulm.de> (Reiner Steib's message of "Mon, 22 Dec 2008 22:38:31 +0000")

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

Reiner Steib <reinersteib+gmane@imap.cc> writes:

> You meant "*:*" (i.e. the variant used if
> `imap-enable-exchange-bug-workaround' is t)?

Oops, yes.

> If I recall the
> discussion correctly, this is much slower.
> Cf. <http://thread.gmane.org/gmane.emacs.gnus.general/66635>.

That refers to a different sequence set but anyhow see below.  I haven't
checked the traffic with anything except exchange.

>> Alternatively, perhaps it should check for Exchange and set it
>> (per-server?) automatically, 
>
> This has been discussed, but nobody implemented it yet.  I also think
> this would be the right thing.

I think the change below DTRT, as it checks for the exact problem.  I've
tested it with our exchange server.  Sorry it's conflated with some
random doc/commentary changes -- I should use darcs in parallel...  You
might want to note or zap the `fixme' comments in particular.

>> or otherwise at least provide a user variable to customize.
>
> Making `imap-enable-exchange-bug-workaround' customizable?

Yes, but that's moot if this change is OK.

> Installed.  (IIRC you still have write access to the repository, don't
> you?)

I don't know, but as my access to the Emacs repository was chopped, I
don't suppose I should be using it anyway.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 11422 bytes --]

2008-12-23  Dave Love  <fx@gnu.org>

	* imap.el: Doc fixes.
	(imap-fetch-safe): New.
	(imap-message-copyuid-1, imap-message-appenduid-1): Use it.
	(imap-parse-flag-list): Disambiguate assertion.

	* nnimap.el: Fix author address.
	(nnimap-debug): Doc fix.
	(nnimap-find-minmax-uid): Use imap-fetch-safe.

Index: nnimap.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/nnimap.el,v
retrieving revision 7.55
diff -u -F^( -r7.55 nnimap.el
--- nnimap.el	3 Dec 2008 20:33:34 -0000	7.55
+++ nnimap.el	23 Dec 2008 11:41:37 -0000
@@ -3,7 +3,7 @@
 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
 ;;   2007, 2008  Free Software Foundation, Inc.
 
-;; Author: Simon Josefsson <jas@pdc.kth.se>
+;; Author: Simon Josefsson <simon@josefsson.org>
 ;;         Jim Radford <radford@robby.caltech.edu>
 ;; Keywords: mail
 
@@ -163,6 +163,8 @@ (defcustom nnimap-split-rule nil
 before, either a function, or a list with group/regexp or
 group/function elements."
   :group 'nnimap
+  ;; fixme: doesn't allow `("my2server" ("INBOX" nnimap-split-fancy))'
+  ;; per example above.
   :type '(choice :tag "Rule type"
 		 (repeat :menu-tag "Single-server"
 			 :tag "Single-server list"
@@ -460,11 +462,17 @@ (defcustom nnimap-id nil
 		 (plist :key-type string :value-type string)))
 
 (defcustom nnimap-debug nil
-  "If non-nil, random debug spews are placed in *nnimap-debug* buffer.
+  "If non-nil, trace nnimap- functions into `nnimap-debug-buffer'.
+Uses `trace-function-background', so you can turn it off with,
+say, `untrace-all'.
+
 Note that username, passwords and other privacy sensitive
-information (such as e-mail) may be stored in the *nnimap-debug*
-buffer.  It is not written to disk, however.  Do not enable this
-variable unless you are comfortable with that."
+information (such as e-mail) may be stored in the buffer.
+It is not written to disk, however.  Do not enable this
+variable unless you are comfortable with that.
+
+This variable only takes effect when loading the `nnimap' library.
+See also `nnimap-log'."
   :group 'nnimap
   :type 'boolean)
 
@@ -555,8 +562,7 @@ (defun nnimap-find-minmax-uid (group &op
 	      (imap-mailbox-select group examine))
       (let (minuid maxuid)
 	(when (> (imap-mailbox-get 'exists) 0)
-	  (imap-fetch (if imap-enable-exchange-bug-workaround "1,*:*" "1,*")
-		      "UID" nil 'nouidfetch)
+	  (imap-fetch-safe '("1,*" . "1,*:*") "UID" nil 'nouidfetch)
 	  (imap-message-map (lambda (uid Uid)
 			      (setq minuid (if minuid (min minuid uid) uid)
 				    maxuid (if maxuid (max maxuid uid) uid)))
Index: imap.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/imap.el,v
retrieving revision 7.48
diff -u -F^( -r7.48 imap.el
--- imap.el	22 Dec 2008 22:38:50 -0000	7.48
+++ imap.el	23 Dec 2008 15:36:08 -0000
@@ -212,12 +212,12 @@ (defcustom imap-shell-program '("ssh %s 
 
 (defcustom imap-process-connection-type nil
   "*Value for `process-connection-type' to use for Kerberos4, GSSAPI and SSL.
-The `process-connection-type' variable control type of device
+The `process-connection-type' variable controls the type of device
 used to communicate with subprocesses.  Values are nil to use a
 pipe, or t or `pty' to use a pty.  The value has no effect if the
 system has no ptys or if all ptys are busy: then a pipe is used
-in any case.  The value takes effect when a IMAP server is
-opened, changing it after that has no effect."
+in any case.  The value takes effect when an IMAP server is
+opened; changing it after that has no effect."
   :version "22.1"
   :group 'imap
   :type 'boolean)
@@ -242,10 +242,13 @@ (defcustom imap-log nil
   :type 'boolean)
 
 (defcustom imap-debug nil
-  "If non-nil, random debug spews are placed in *imap-debug* buffer.
+  "If non-nil, trace imap- functions into `imap-debug-buffer'.
+Uses `trace-function-background', so you can turn it off with,
+say, `untrace-all'.
+
 Note that username, passwords and other privacy sensitive
-information (such as e-mail) may be stored in the *imap-debug*
-buffer.  It is not written to disk, however.  Do not enable this
+information (such as e-mail) may be stored in the buffer.
+It is not written to disk, however.  Do not enable this
 variable unless you are comfortable with that.
 
 This variable only takes effect when loading the `imap' library.
@@ -717,6 +720,15 @@ (defun imap-tls-open (name buffer server
 	 (process (open-tls-stream name buffer server port)))
     (when process
       (while (and (memq (process-status process) '(open run))
+		  ;; Fixme:  Per the "blue moon" comment, the
+		  ;; process/buffer handling here, and elsewhere in
+		  ;; functions which open streams, looks confused.
+		  ;; Obviously we can change buffers if a different
+		  ;; process handler kicks in from
+		  ;; `accept-process-output' or `sit-for' below, and
+		  ;; TRT seems to be to `save-buffer' around those
+		  ;; calls.  (I wonder why `sit-for' is used with a
+		  ;; non-zero wait.)  -- fx
 		  (set-buffer buffer) ;; XXX "blue moon" nntp.el bug
 		  (goto-char (point-max))
 		  (forward-line -1)
@@ -1087,7 +1099,7 @@ (defun imap-open-1 (buffer)
 	   imap-process))))
 
 (defun imap-open (server &optional port stream auth buffer)
-  "Open a IMAP connection to host SERVER at PORT returning a buffer.
+  "Open an IMAP connection to host SERVER at PORT returning a buffer.
 If PORT is unspecified, a default value is used (143 except
 for SSL which use 993).
 STREAM indicates the stream to use, see `imap-streams' for available
@@ -1726,6 +1738,7 @@ (defmacro imap-message-body (uid &option
   `(with-current-buffer (or ,buffer (current-buffer))
      (imap-message-get ,uid 'BODY)))
 
+;; Fixme:  Should this try to use CHARSET?
 (defun imap-search (predicate &optional buffer)
   (with-current-buffer (or buffer (current-buffer))
     (imap-mailbox-put 'search 'dummy)
@@ -1772,9 +1785,38 @@ (defun imap-string-to-integer (string &o
   (let ((number (string-to-number string base)))
     (if (> number most-positive-fixnum)
 	(error
-	 (format "String %s cannot be converted to a lisp integer" number))
+	 (format "String %s cannot be converted to a Lisp integer" number))
       number)))
 
+(defun imap-fetch-safe (uids props &optional receive nouidfetch buffer)
+  "Like `imap-fetch', but DTRT with Exchange 2007 bug.
+However, UIDS here is a cons, where the car is the canonical form
+of the UIDS specification, and the cdr is the one which works with
+Exchange 2007 or, potentially, other buggy servers.
+See `imap-enable-exchange-bug-workaround'."
+  ;; We don't unconditionally use the alternative (valid) form, since
+  ;; this is said to be significantly inefficient.  The first time we
+  ;; get here for a given, we'll try the canonical form.  If we get
+  ;; the known error from the buggy server, set the flag
+  ;; buffer-locally (to account for connexions to multiple servers),
+  ;; then re-try with the alternative UIDS spec.
+  (condition-case data
+      (imap-fetch (if imap-enable-exchange-bug-workaround
+		      (cdr uids)
+		    (car uids))
+		  props receive nouidfetch buffer)
+    (error
+     (if (and (not imap-enable-exchange-bug-workaround)
+	      (string-match
+	       "The specified message set is invalid"
+	       (cadr data)))
+	 (with-current-buffer (or buffer (current-buffer))
+	   (set (make-local-variable
+		 'imap-enable-exchange-bug-workaround)
+		t)
+	   (imap-fetch (cdr uids) props receive nouidfetch))
+       (signal (car data) (cdr data))))))
+
 (defun imap-message-copyuid-1 (mailbox)
   (if (imap-capability 'UIDPLUS)
       (list (nth 0 (imap-mailbox-get-1 'copyuid mailbox))
@@ -1784,11 +1826,7 @@ (defun imap-message-copyuid-1 (mailbox)
 	  (imap-message-data (make-vector 2 0)))
       (when (imap-mailbox-examine-1 mailbox)
 	(prog1
-	    (and (imap-fetch
-		  ;; why the switch here, since they seem to be
-		  ;; equivalent, and ~ no-one is going to find this
-		  ;; switch?  -- fx
-		  (if imap-enable-exchange-bug-workaround "*:*" "*") "UID")
+	    (and (imap-fetch-safe '("*" . "*:*") "UID")
 		 (list (imap-mailbox-get-1 'uidvalidity mailbox)
 		       (apply 'max (imap-message-map
 				    (lambda (uid prop) uid) 'UID))))
@@ -1824,6 +1862,8 @@ (defun imap-message-copy (articles mailb
 	    (or no-copyuid
 		(imap-message-copyuid-1 mailbox)))))))
 
+;; Fixme: Amalgamate with imap-message-copyuid-1, using an extra arg,
+;; since it shares most of the code?
 (defun imap-message-appenduid-1 (mailbox)
   (if (imap-capability 'UIDPLUS)
       (imap-mailbox-get-1 'appenduid mailbox)
@@ -1832,8 +1872,7 @@ (defun imap-message-appenduid-1 (mailbox
 	  (imap-message-data (make-vector 2 0)))
       (when (imap-mailbox-examine-1 mailbox)
 	(prog1
-	    (and (imap-fetch
-		  (if imap-enable-exchange-bug-workaround "*:*" "*") "UID")
+	    (and (imap-fetch-safe '("*" "*:*") "UID")
 		 (list (imap-mailbox-get-1 'uidvalidity mailbox)
 		       (apply 'max (imap-message-map
 				    (lambda (uid prop) uid) 'UID))))
@@ -2210,7 +2249,7 @@ (defsubst imap-parse-mailbox ()
 ;;   resp-cond-bye   = "BYE" SP resp-text
 
 (defun imap-parse-greeting ()
-  "Parse a IMAP greeting."
+  "Parse an IMAP greeting."
   (cond ((looking-at "\\* OK ")
 	 (setq imap-state 'nonauth))
 	((looking-at "\\* PREAUTH ")
@@ -2255,7 +2294,7 @@ (defun imap-parse-greeting ()
 ;;                       ; capability.
 
 (defun imap-parse-response ()
-  "Parse a IMAP command response."
+  "Parse an IMAP command response."
   (let (token)
     (case (setq token (read (current-buffer)))
       (+ (setq imap-continuation
@@ -2637,7 +2676,7 @@ (defun imap-parse-flag-list ()
 			      (point)))
 		(> (skip-chars-forward "^ )" (point-at-eol)) 0))
       (push (buffer-substring start (point)) flag-list))
-    (assert (eq (char-after) ?\)) nil "In imap-parse-flag-list")
+    (assert (eq (char-after) ?\)) nil "In imap-parse-flag-list 2")
     (imap-forward)
     (nreverse flag-list)))
 
@@ -2866,9 +2905,10 @@ (defun imap-parse-body ()
 	(imap-forward)
 	(push (imap-parse-nstring) body) ;; body-fld-desc
 	(imap-forward)
-	;; next `or' for Sun SIMS bug, it regard body-fld-enc as a
-	;; nstring and return nil instead of defaulting back to 7BIT
+	;; Next `or' for Sun SIMS bug.  It regards body-fld-enc as a
+	;; nstring and returns nil instead of defaulting back to 7BIT
 	;; as the standard says.
+	;; Exchange (2007, at least) does this as well.
 	(push (or (imap-parse-nstring) "7BIT") body) ;; body-fld-enc
 	(imap-forward)
 	;; Exchange 2007 can return -1, contrary to the spec...
@@ -2878,15 +2918,15 @@ (defun imap-parse-body ()
 	      (push nil body))
 	  (push (imap-parse-number) body)) ;; body-fld-octets
 
-   ;; ok, we're done parsing the required parts, what comes now is one
+	;; ok, we're done parsing the required parts, what comes now is one
 	;; of three things:
 	;;
 	;; envelope       (then we're parsing body-type-msg)
 	;; body-fld-lines (then we're parsing body-type-text)
 	;; body-ext-1part (then we're parsing body-type-basic)
 	;;
-  ;; the problem is that the two first are in turn optionally followed
-;; by the third.  So we parse the first two here (if there are any)...
+	;; the problem is that the two first are in turn optionally followed
+	;; by the third.  So we parse the first two here (if there are any)...
 
 	(when (eq (char-after) ?\ )
 	  (imap-forward)

  reply	other threads:[~2008-12-23 15:41 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87iqphil5p.fsf@liv.ac.uk>
2008-12-22 22:38 ` Reiner Steib
2008-12-23 15:41   ` Dave Love [this message]
2009-01-01 18:34     ` Reiner Steib
2009-01-02 22:20       ` Ted Zlatanov
2009-01-02 22:38         ` Reiner Steib
2009-01-09 12:00       ` Simon Josefsson
2009-01-01 18:55     ` FIXMEs in imap.el and nnimap.el (was: imap.el workaround for Exchange 2007) Reiner Steib
2009-01-02 22:19       ` FIXMEs in imap.el and nnimap.el Ted Zlatanov
2009-01-02 22:57         ` Reiner Steib
2009-01-04 23:10           ` Dave Love
2009-01-07 21:07             ` Dave Love
2009-01-08 20:42               ` Reiner Steib
2009-01-07 19:25           ` Ted Zlatanov
2009-01-08 21:04             ` Reiner Steib
2009-01-13 10:40               ` Dave Love
2009-01-13 17:00                 ` IMAP and Exchange 2007 - imap-fetch-safe (was: FIXMEs in imap.el and nnimap.el) Reiner Steib
2009-01-13 17:20                   ` IMAP and Exchange 2007 - imap-fetch-safe Simon Josefsson
2009-01-17 20:58                     ` Dave Love
2009-01-28  1:18                       ` Dave Love
2009-01-31 15:27                       ` Reiner Steib
2009-02-01 15:43                         ` Bjorn Solberg
2009-02-02 14:54                           ` Dave Goldberg
2009-02-02 19:19                             ` Reiner Steib
2009-02-03 16:21                               ` Stephen J. Turnbull
2009-02-08 18:00                               ` Dave Love
2009-02-08 18:38                                 ` Dave Goldberg
2009-02-02 19:15                           ` Reiner Steib
2009-01-13 18:28                   ` Bjorn Solberg
2009-01-13 20:18                     ` Bjorn Solberg
2009-01-17 20:59                     ` Dave Love
2009-01-04 20:08       ` FIXMEs in imap.el and nnimap.el Dave Love
2009-01-05 16:13       ` Dave Love
2009-01-05 20:35         ` Conventions (was: FIXMEs in imap.el and nnimap.el) Reiner Steib
2009-01-06 11:33           ` Conventions Tassilo Horn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87iqpa99wy.fsf@liv.ac.uk \
    --to=fx@gnu.org \
    --cc=ding@gnus.org \
    --cc=simon@josefsson.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).