[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 0.126, xemacs, pgnus-0.95, and really large UIDs



Jim Radford <radford@robotics.caltech.edu> writes:

> > One (easy to remedy) is that LIST is hardcoded as the method to use to
> > retrieve a folder list with.  On the server I am trying to use, there are
> > some ten thousand or more folders, and I have to traverse the Internet at
> > large to talk to it.  Listing all 10k+ folders is not something I want to
> > do; neither are the subsets I want to read in any particular parts of the
> > folder hierarchy -- so I cannot use the nnimap-list-pattern method to
> > select those.
> 
> LSUB uses a "subscribed" list on the server.  I'm not sure how you
> created yours, but you can make nnimap-list-pattern be a copy of this
> list.  Not easy or central, but just another solution.

I could, yes.  It does not seem to me that it should be so hard to have an
elisp variable to toggle between LIST and LSUB as the default select method.
Probably easier than me copying over 75 or so folder names the client I have
that supports subscriptions.  Thus (the diff would be half as long, but it
looks like imap-mailbox-list got extra functionality at some point but
imap-mailbox-lsub did not get a corresponding update):

diff -ur nnimap-0.126/imap.el nnimap-lsub/imap.el
--- nnimap-0.126/imap.el	Sat Jul 17 16:17:19 1999
+++ nnimap-lsub/imap.el	Thu Aug  5 09:40:23 1999
@@ -837,15 +837,24 @@
      (imap-send-command-wait (list "RENAME \"" (imap-utf7-encode oldname)
 				   "\" \"" (imap-utf7-encode newname) "\"")))))
 
-(defun imap-mailbox-lsub (&optional buffer reference)
+(defun imap-mailbox-lsub (&optional buffer root have-delimiter reference)
   "Clear the mailbox data and fill it with subscribed mailboxes on
 server in BUFFER. REFERENCE is the implementation-specific string that
 has to be passed to LSUB."
   (with-current-buffer (or buffer (current-buffer))
     (imap-mailbox-map (lambda (mailbox)
 			(imap-mailbox-put 'lsub nil mailbox)))
-    (when (imap-ok-p (imap-send-command-wait 
-		      (concat "LSUB \"" reference "\" \"*\"")))
+    ;; do the little dance from imap-mailbox-list to find hierarchy separator
+    (when root
+      (unless have-delimiter
+	(imap-send-command-wait (concat "LSUB \"" reference "\" \"" 
+					(imap-utf7-encode root) "\""))))
+    (when (imap-ok-p 
+	   (imap-send-command-wait 
+	    (concat "LSUB \"" reference "\" \"" (imap-utf7-encode root)
+		    (when (and root (not have-delimiter))
+		      (imap-mailbox-get 'delimiter root))
+		    "%\"")))
       (let (out)
 	(imap-mailbox-map (lambda (mailbox)
 			    (when (imap-mailbox-get 'lsub mailbox)
diff -ur nnimap-0.126/nnimap.el nnimap-lsub/nnimap.el
--- nnimap-0.126/nnimap.el	Mon Jul 19 05:17:02 1999
+++ nnimap-lsub/nnimap.el	Thu Aug  5 09:34:09 1999
@@ -652,6 +652,11 @@
 	      pattern
 	    (list pattern))))
 
+(defvar nnimap-request-method 'imap-mailbox-list
+  "Method to use to request a list of all folders from the server.
+If this is 'imap-mailbox-lsub, then use a server-side subscription list to
+restrict visible folders.")
+
 (deffoo nnimap-request-list (&optional server)
   (when (nnimap-possibly-change-server server)
     (with-current-buffer nntp-server-buffer
@@ -660,8 +665,8 @@
       (erase-buffer)
       (dolist (pattern (nnimap-pattern-to-list-arguments 
 			nnimap-list-pattern))
-	(dolist (mbx (imap-mailbox-list 
-		      nnimap-server-buffer (cdr pattern) t (car pattern)))
+	(dolist (mbx
+		 (funcall nnimap-request-list-method (cdr pattern) t (car pattern)))
 	  (or (member "\\NoSelect" 
 		      (imap-mailbox-get 'list-flags mbx nnimap-server-buffer))
 	      (let ((info (nnimap-find-minmax-uid mbx 'examine)))

> > (1) (error/warning) Error in process filter:
> >   (invalid-read-syntax Integer constant overflow in reader 2003395529 10)
> >  * 1 FETCH (UID 2003395529)
> 
> We should read UIDs as strings, but we seem to have forgotten to do it
> in a few places.  This patch should fix it.  Let me know if it works.

There are a few other places where UIDs are assumed to be stored as integers.
Even once I do fix the places in nnimap where things fail typechecks, things
don't quite work for some reason.  When I try to open one folder (say,
"INBOX"), I get the following messages:
 Retrieving newsgroup: nnimap+cyrus:INBOX...
 nnimap: Updating info for nnimap+cyrus:INBOX...
 nnimap: Updating info for nnimap+cyrus:INBOX...done
 Group cmu.ece.class.ece794 selected
 Couldn't request group nnimap+cyrus:INBOX: Group cmu.ece.class.ece794 selected
Every group says that "cmu.ece.class.ece794" is selected -- except for ece794,
which says:
 Retrieving newsgroup: nnimap+cyrus:cmu.ece.class.ece794...
 nnimap: Updating info for nnimap+cyrus:cmu.ece.class.ece794...
 nnimap: Updating info for nnimap+cyrus:cmu.ece.class.ece794...done
 Can't select group
 Couldn't enter nnimap+cyrus:cmu.ece.class.ece794

My diff for string UIDs (including your bits) is:

diff -ur nnimap-0.126/imap.el nnimap-work/imap.el
--- nnimap-0.126/imap.el	Thu Aug  5 09:44:41 1999
+++ nnimap-work/imap.el	Thu Aug  5 09:44:17 1999
@@ -985,7 +985,7 @@
 (defun imap-message-put (uid propname value &optional buffer)
   (with-current-buffer (or buffer (current-buffer))
     (if imap-message-data
-	(put (intern (number-to-string uid) imap-message-data)
+	(put (intern uid imap-message-data)
 	     propname value)
       (error "Imap-message-data is nil. Uid %d property %s value %s"
 	     uid propname value))
@@ -993,7 +993,7 @@
 
 (defun imap-message-get (uid propname &optional buffer)
   (with-current-buffer (or buffer (current-buffer))
-    (get (intern-soft (number-to-string uid) imap-message-data)
+    (get (intern-soft uid imap-message-data)
 	 propname)))
 
 (defun imap-message-map (func propname &optional buffer)
@@ -1638,8 +1638,8 @@
     (imap-forward)
     (cond ((search-forward "PERMANENTFLAGS " nil t)
 	   (imap-mailbox-put 'permanentflags (imap-parse-flag-list)))
-	  ((search-forward "UIDNEXT " nil t)
-	   (imap-mailbox-put 'uidnext (read (current-buffer))))
+	  ((search-forward "UIDNEXT \\([0-9]+\\)" nil t)
+	   (imap-mailbox-put 'uidnext (match-string 1)))
 	  ((search-forward "UNSEEN " nil t)
 	   (imap-mailbox-put 'unseen (read (current-buffer))))
 	  ((looking-at "UIDVALIDITY \\([0-9]+\\)")
@@ -1746,7 +1746,8 @@
 	(let ((token (read (current-buffer))))
 	  (imap-forward)
 	  (cond ((eq token 'UID)
-		 (setq uid (read (current-buffer))))
+		 (and (search-forward-regexp "\\([0-9]+\\)")
+		      (setq uid (match-string 1))))
 		((eq token 'FLAGS)
 		 (setq flags (imap-parse-flag-list)))
 		((eq token 'ENVELOPE)
@@ -1808,11 +1809,11 @@
 		((eq token 'RECENT)
 		 (imap-mailbox-put 'recent (read (current-buffer)) mailbox))
 		((eq token 'UIDNEXT)
-		 (imap-mailbox-put 'uidnext (read (current-buffer)) mailbox))
+		 (and (search-forward-regexp "\\= \\([0-9]+\\)")
+		      (imap-mailbox-put 'uidnext (match-string 1) mailbox)))
 		((eq token 'UIDVALIDITY)
-		 (and (looking-at " \\([0-9]+\\)")
-		      (imap-mailbox-put 'uidvalidity (match-string 1) mailbox)
-		      (goto-char (match-end 1))))
+		 (and (search-forward-regexp "\\= \\([0-9]+\\)")
+		      (imap-mailbox-put 'uidvalidity (match-string 1) mailbox)))
 		((eq token 'UNSEEN)
 		 (imap-mailbox-put 'unseen (read (current-buffer)) mailbox))
 		(t
diff -ur nnimap-0.126/nnimap.el nnimap-work/nnimap.el
--- nnimap-0.126/nnimap.el	Mon Jul 19 05:17:02 1999
+++ nnimap-work/nnimap.el	Thu Aug  5 09:49:05 1999
@@ -304,8 +304,8 @@
 	(when (> (imap-mailbox-get 'exists) 0)
 	  (imap-fetch "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)))
+			      (setq minuid (if (and minuid (string-lessp minuid uid)) minuid uid)
+				    maxuid (if (and maxuid (string-lessp uid maxuid)) maxuid uid)))
 			    'UID))
 	(list (imap-mailbox-get 'exists) minuid maxuid)))))
   
@@ -660,17 +660,17 @@
       (erase-buffer)
       (dolist (pattern (nnimap-pattern-to-list-arguments 
 			nnimap-list-pattern))
-	(dolist (mbx (imap-mailbox-list 
-		      nnimap-server-buffer (cdr pattern) t (car pattern)))
+	(dolist (mbx (imap-mailbox-lsub 
+		      nnimap-server-buffer (car pattern))) ; (cdr pattern) t (car pattern)))
 	  (or (member "\\NoSelect" 
 		      (imap-mailbox-get 'list-flags mbx nnimap-server-buffer))
 	      (let ((info (nnimap-find-minmax-uid mbx 'examine)))
 		(when info
 		  ;; Escape SPC in mailboxes xxx relies on gnus internals
-		  (insert (format "%s %d %d y\n" 
+		  (insert (format "%s %s %s y\n" 
 				  (nnimap-replace-in-string mbx " " "\\ ")
-				  (or (nth 2 info) 0)
-				  (max 1 (or (nth 1 info) 1)))))))))
+				  (or (nth 2 info) "0")
+				  (if (and (nth 1 info) (string-lessp "1" (nth 1 info))) (nth 1 info) "1"))))))))
       (gnus-message 5 "nnimap: Generating active list%s...done" 
 		    (if server (concat " for " server) "")))
     t))