Fixed docstring.
[elisp/wanderlust.git] / elmo / elmo-imap4.el
index d7c129e..12d6327 100644 (file)
@@ -53,7 +53,7 @@
 
 (defvar elmo-imap4-disuse-server-flag-mailbox-regexp "^#mh" ; UW imapd
   "Regexp to match IMAP4 mailbox names whose message flags on server should be ignored.
-(Except `\\Deleted' flag).")
+\(Except `\\Deleted' flag\).")
 
 (defvar elmo-imap4-overview-fetch-chop-length 200
   "*Number of overviews to fetch in one request.")
@@ -82,7 +82,7 @@
 
 (defvar elmo-imap4-use-select-to-update-status nil
   "*Some imapd have to send select command to update status.
-(ex. UW imapd 4.5-BETA?).  For these imapd, you must set this variable t.")
+\(ex. UW imapd 4.5-BETA?\).  For these imapd, you must set this variable t.")
 
 (defvar elmo-imap4-use-modified-utf7 nil
   "*Use mofidied UTF-7 (rfc2060) encoding for IMAP4 folder name.")
@@ -92,7 +92,7 @@
 
 (defvar elmo-imap4-extra-namespace-alist
   '(("^\\({.*/nntp}\\).*$" . ".")) ; Default is for UW's remote nntp mailbox...
-  "Extra namespace alist. 
+  "Extra namespace alist.
 A list of cons cell like: (REGEXP . DELIMITER).
 REGEXP should have a grouping for namespace prefix.")
 ;;
@@ -192,13 +192,16 @@ Debug information is inserted in the buffer \"*IMAP4 DEBUG*\"")
   (luna-define-internal-accessors 'mime-elmo-imap-location))
 
 ;;; Debug
-(defsubst elmo-imap4-debug (message &rest args)
-  (if elmo-imap4-debug
-      (with-current-buffer (get-buffer-create "*IMAP4 DEBUG*")
-       (goto-char (point-max))
-       (if elmo-imap4-debug-inhibit-logging
-           (insert "NO LOGGING\n")
-         (insert (apply 'format message args) "\n")))))
+(defmacro elmo-imap4-debug (message &rest args)
+  (` (if elmo-imap4-debug
+        (elmo-imap4-debug-1 (, message) (,@ args)))))
+
+(defun elmo-imap4-debug-1 (message &rest args)
+  (with-current-buffer (get-buffer-create "*IMAP4 DEBUG*")
+    (goto-char (point-max))
+    (if elmo-imap4-debug-inhibit-logging
+       (insert "NO LOGGING\n")
+      (insert (apply 'format message args) "\n"))))
 
 (defsubst elmo-imap4-decode-folder-string (string)
   (if elmo-imap4-use-modified-utf7
@@ -224,6 +227,10 @@ Debug information is inserted in the buffer \"*IMAP4 DEBUG*\"")
   "Returns non-nil if RESPONSE is an 'BYE' response."
   (` (assq 'bye (, response))))
 
+(defmacro elmo-imap4-response-garbage-p (response)
+  "Returns non-nil if RESPONSE is an 'garbage' response."
+  (` (assq 'garbage (, response))))
+
 (defmacro elmo-imap4-response-value (response symbol)
   "Get value of the SYMBOL from RESPONSE."
   (` (nth 1 (assq (, symbol) (, response)))))
@@ -344,7 +351,14 @@ TAG is the tag of the command"
   (with-current-buffer (process-buffer
                        (elmo-network-session-process-internal session))
     (while (not (or (string= tag elmo-imap4-reached-tag)
-                   (elmo-imap4-response-bye-p elmo-imap4-current-response)))
+                   (elmo-imap4-response-bye-p elmo-imap4-current-response)
+                   (when (elmo-imap4-response-garbage-p
+                          elmo-imap4-current-response)
+                     (message "Garbage response: %s" 
+                              (elmo-imap4-response-value
+                               elmo-imap4-current-response
+                               'garbage))
+                     t)))
       (when (memq (process-status
                   (elmo-network-session-process-internal session))
                  '(open run))
@@ -925,7 +939,12 @@ If CHOP-LENGTH is not specified, message set is not chopped."
            (signal 'elmo-open-error
                    '(elmo-imap4-starttls-error)))
        (elmo-imap4-send-command-wait session "starttls")
-       (starttls-negotiate process)))))
+       (starttls-negotiate process)
+       (elmo-imap4-session-set-capability-internal
+        session
+        (elmo-imap4-response-value
+         (elmo-imap4-send-command-wait session "capability")
+         'capability))))))
 
 (luna-define-method elmo-network-authenticate-session ((session
                                                        elmo-imap4-session))
@@ -1537,7 +1556,8 @@ Return nil if no complete line has arrived."
                        (message
                         "Unknown status data %s in mailbox %s ignored"
                         token mailbox))))
-              status))))
+              status))
+       (skip-chars-forward " ")))
     (and elmo-imap4-status-callback
         (funcall elmo-imap4-status-callback
                  status
@@ -1784,9 +1804,7 @@ Return nil if no complete line has arrived."
     (setq parse (elmo-parse-token name ":"))
     (elmo-imap4-folder-set-mailbox-internal folder
                                            (elmo-imap4-encode-folder-string
-                                            (if (eq (length (car parse)) 0)
-                                                elmo-imap4-default-mailbox
-                                              (car parse))))
+                                            (car parse)))
     ;; user
     (setq parse (elmo-parse-prefixed-element ?: (cdr parse) "/"))
     (elmo-net-folder-set-user-internal folder
@@ -1885,15 +1903,16 @@ Return nil if no complete line has arrived."
   (let* ((root (elmo-imap4-folder-mailbox-internal folder))
         (session (elmo-imap4-get-session folder))
         (prefix (elmo-folder-prefix-internal folder))
-        (delim (or
-                (cdr
+        (namespace-assoc
                  (elmo-string-matched-assoc
                   root
                   (with-current-buffer (elmo-network-session-buffer session)
                     elmo-imap4-server-namespace)))
+        (delim (or (cdr namespace-assoc)
                 elmo-imap4-default-hierarchy-delimiter))
         ;; Append delimiter when root with namespace.
-        (root (if (and (match-end 1)
+        (root (if (and namespace-assoc
+                       (match-end 1)
                        (string= (substring root (match-end 1))
                                 ""))
                   (concat root delim)
@@ -1903,8 +1922,10 @@ Return nil if no complete line has arrived."
                  (elmo-imap4-send-command-wait
                   session
                   (list "list " (elmo-imap4-mailbox root) " *"))))
-    (unless (string= (elmo-net-folder-user-internal folder)
-                    elmo-imap4-default-user)
+    (when (or (not (string= (elmo-net-folder-user-internal folder)
+                           elmo-imap4-default-user))
+             (not (eq (elmo-net-folder-auth-internal folder)
+                      (or elmo-imap4-default-authenticate-type 'clear))))
       (setq append-serv (concat ":" (elmo-net-folder-user-internal folder))))
     (unless (eq (elmo-net-folder-auth-internal folder)
                (or elmo-imap4-default-authenticate-type 'clear))
@@ -1979,6 +2000,9 @@ Return nil if no complete line has arrived."
        (elmo-imap4-folder-mailbox-internal folder)
        'force 'notify-bye))))
 
+(luna-define-method elmo-folder-creatable-p ((folder elmo-imap4-folder))
+  t)
+
 (luna-define-method elmo-folder-writable-p ((folder elmo-imap4-folder))
   t)
 
@@ -2083,7 +2107,8 @@ If optional argument REMOVE is non-nil, remove FLAG."
 
 (defun elmo-imap4-search-internal-primitive (folder session filter from-msgs)
   (let ((search-key (elmo-filter-key filter))
-       (imap-search-keys '("bcc" "body" "cc" "from" "subject" "to"))
+       (imap-search-keys '("bcc" "body" "cc" "from" "subject" "to"
+                           "larger" "smaller"))
        (total 0)
        (length (length from-msgs))
        charset set-list end results)
@@ -2357,7 +2382,7 @@ If optional argument REMOVE is non-nil, remove FLAG."
 (luna-define-method elmo-folder-open :around ((folder elmo-imap4-folder)
                                              &optional load-msgdb)
   (if (elmo-folder-plugged-p folder)
-      (let (session mailbox msgdb response tag)
+      (let (session mailbox msgdb result response tag)
        (condition-case err
            (progn
              (setq session (elmo-imap4-get-session folder)
@@ -2366,30 +2391,46 @@ If optional argument REMOVE is non-nil, remove FLAG."
                                                 (list "select "
                                                       (elmo-imap4-mailbox
                                                        mailbox))))
+             (message "Selecting %s..."
+                      (elmo-folder-name-internal folder))
              (if load-msgdb
-                 (setq msgdb (elmo-msgdb-load folder)))
+                 (setq msgdb (elmo-msgdb-load folder 'silent)))
              (elmo-folder-set-killed-list-internal
               folder
               (elmo-msgdb-killed-list-load (elmo-folder-msgdb-path folder)))
-             (setq response (elmo-imap4-read-response session tag)))
+             (if (setq result (elmo-imap4-response-ok-p
+                               (setq response
+                                     (elmo-imap4-read-response session tag))))
+                 (progn
+                   (elmo-imap4-session-set-current-mailbox-internal
+                    session mailbox)
+                   (elmo-imap4-session-set-read-only-internal
+                    session
+                    (nth 1 (assq 'read-only (assq 'ok response)))))
+               (elmo-imap4-session-set-current-mailbox-internal session nil)
+               (if (elmo-imap4-response-bye-p response)
+                   (elmo-imap4-process-bye session)
+                 (error (or
+                         (elmo-imap4-response-error-text response)
+                         (format "Select %s failed" mailbox)))))
+             (message "Selecting %s...done"
+                      (elmo-folder-name-internal folder))
+             (elmo-folder-set-msgdb-internal
+              folder msgdb))
          (quit
-          (if response
+          (if (elmo-imap4-response-ok-p response)
               (elmo-imap4-session-set-current-mailbox-internal
                session mailbox)
             (and session
                  (elmo-imap4-session-set-current-mailbox-internal
                   session nil))))
          (error
-          (if response
+          (if (elmo-imap4-response-ok-p response)
               (elmo-imap4-session-set-current-mailbox-internal
                session mailbox)
             (and session
                  (elmo-imap4-session-set-current-mailbox-internal
-                  session nil)))))
-       (if load-msgdb
-           (elmo-folder-set-msgdb-internal
-            folder
-            (or msgdb (elmo-msgdb-load folder)))))
+                  session nil))))))
     (luna-call-next-method)))
 
 ;; elmo-folder-open-internal: do nothing.
@@ -2441,7 +2482,7 @@ If optional argument REMOVE is non-nil, remove FLAG."
                                      (elmo-file-cache-path
                                       cache-file)))))))
 
-(luna-define-method elmo-folder-create ((folder elmo-imap4-folder))
+(luna-define-method elmo-folder-create-plugged ((folder elmo-imap4-folder))
   (elmo-imap4-send-command-wait
    (elmo-imap4-get-session folder)
    (list "create "
@@ -2465,7 +2506,7 @@ If optional argument REMOVE is non-nil, remove FLAG."
                    "append "
                    (elmo-imap4-mailbox (elmo-imap4-folder-mailbox-internal
                                         folder))
-                   (if unread " " " (\\Seen) ")
+                   (if unread " () " " (\\Seen) ")
                    (elmo-imap4-buffer-literal send-buffer))))
          (kill-buffer send-buffer))
        result)
@@ -2537,7 +2578,7 @@ If optional argument REMOVE is non-nil, remove FLAG."
     (unless elmo-inhibit-display-retrieval-progress
       (elmo-display-progress 'elmo-imap4-display-literal-progress
                             "Retrieving..." 100)  ; remove progress bar.
-      (message "Retrieving...done."))
+      (message "Retrieving...done"))
     (if (setq response (elmo-imap4-response-bodydetail-text
                        (elmo-imap4-response-value-all
                         response 'fetch)))