Check error.
[elisp/wanderlust.git] / elmo / elmo.el
index 65b517d..b2a437c 100644 (file)
@@ -1,4 +1,4 @@
-;;; elmo.el -- Elisp Library for Message Orchestration
+;;; elmo.el --- Elisp Library for Message Orchestration.
 
 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
 
 
 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
 
@@ -27,7 +27,7 @@
 ;;
 
 ;;; Code:
 ;;
 
 ;;; Code:
-;; 
+;;
 
 (require 'luna)
 
 
 (require 'luna)
 
@@ -66,6 +66,9 @@ Otherwise, entire fetching of the message is aborted without confirmation."
   :type 'boolean
   :group 'elmo)
 
   :type 'boolean
   :group 'elmo)
 
+(defvar elmo-message-displaying nil
+  "A global switch to indicate message is displaying or not.")
+
 ;;; internal
 (defvar elmo-folder-type-alist nil)
 
 ;;; internal
 (defvar elmo-folder-type-alist nil)
 
@@ -74,7 +77,7 @@ Otherwise, entire fetching of the message is aborted without confirmation."
 (elmo-define-error 'elmo-error "Error" 'error)
 (elmo-define-error 'elmo-open-error "Cannot open" 'elmo-error)
 (elmo-define-error 'elmo-authenticate-error "Login failed" 'elmo-open-error)
 (elmo-define-error 'elmo-error "Error" 'error)
 (elmo-define-error 'elmo-open-error "Cannot open" 'elmo-error)
 (elmo-define-error 'elmo-authenticate-error "Login failed" 'elmo-open-error)
-(elmo-define-error 'elmo-imap4-bye-error "IMAP4 BYE response" 'elmo-open-error)
+(elmo-define-error 'elmo-imap4-bye-error "IMAP4 session was terminated" 'elmo-open-error)
 
 (defun elmo-define-folder (prefix backend)
   "Define a folder.
 
 (defun elmo-define-folder (prefix backend)
   "Define a folder.
@@ -106,6 +109,7 @@ If a folder name begins with PREFIX, use BACKEND."
                                     message-modified ; message is modified.
                                     mark-modified    ; mark is modified.
                                     process-duplicates  ; read or hide
                                     message-modified ; message is modified.
                                     mark-modified    ; mark is modified.
                                     process-duplicates  ; read or hide
+                                    biff   ; folder for biff
                                     ))
   (luna-define-internal-accessors 'elmo-folder))
 
                                     ))
   (luna-define-internal-accessors 'elmo-folder))
 
@@ -130,7 +134,9 @@ If optional argument NON-PERSISTENT is non-nil, folder is treated as
          (setq prefix (substring name 0 1))
          (setq name (substring name 1)))
       (setq type (intern (car (setq split (split-string name ":")))))
          (setq prefix (substring name 0 1))
          (setq name (substring name 1)))
       (setq type (intern (car (setq split (split-string name ":")))))
-      (setq name (substring name (+ 1 (length (car split)))))
+      (if (> (length split) 2)
+         (setq name (substring name (+ 1 (length (car split)))))
+       (error "Error in folder name `%s'" original))
       (setq prefix (concat (car split) ":")))
     (setq class (format "elmo-%s" (symbol-name type)))
     (require (intern class))
       (setq prefix (concat (car split) ":")))
     (setq class (format "elmo-%s" (symbol-name type)))
     (require (intern class))
@@ -188,7 +194,9 @@ If optional KEEP-KILLED is non-nil, killed-list is not cleared.")
   "Get diff of FOLDER.
 If optional NUMBERS is set, it is used as current NUMBERS.
 Otherwise, saved status for folder is used for comparison.
   "Get diff of FOLDER.
 If optional NUMBERS is set, it is used as current NUMBERS.
 Otherwise, saved status for folder is used for comparison.
-Return value is a cons cell of NEWS and MESSAGES.")
+Return value is cons cell or list:
+ - a cons cell (NEWS . MESSAGES)
+ - a list (RECENT UNSEEN MESSAGES) ; RECENT means NEWS, UNSEEN means UNREAD.")
 
 (luna-define-generic elmo-folder-status (folder)
   "Returns a cons cell of (MAX-NUMBER . MESSAGES) in the FOLDER.")
 
 (luna-define-generic elmo-folder-status (folder)
   "Returns a cons cell of (MAX-NUMBER . MESSAGES) in the FOLDER.")
@@ -236,10 +244,10 @@ IMPORTANT-MARK is the important mark."
        num-pair result)
     (dolist (mark-pair (or elmo-msgdb-global-mark-alist
                           (setq elmo-msgdb-global-mark-alist
        num-pair result)
     (dolist (mark-pair (or elmo-msgdb-global-mark-alist
                           (setq elmo-msgdb-global-mark-alist
-                                (elmo-object-load 
+                                (elmo-object-load
                                  (expand-file-name
                                   elmo-msgdb-global-mark-filename
                                  (expand-file-name
                                   elmo-msgdb-global-mark-filename
-                                  elmo-msgdb-dir)))))
+                                  elmo-msgdb-directory)))))
       (if (and (string= important-mark (cdr mark-pair))
               (setq num-pair (rassoc (car mark-pair) number-alist)))
          (setq result (cons (car num-pair) result))))
       (if (and (string= important-mark (cdr mark-pair))
               (setq num-pair (rassoc (car mark-pair) number-alist)))
          (setq result (cons (car num-pair) result))))
@@ -308,10 +316,18 @@ NUMBERS is a list of message numbers to be deleted.")
 (luna-define-generic elmo-folder-search (folder condition &optional numbers)
   "Search and return list of message numbers.
 FOLDER is the ELMO folder structure.
 (luna-define-generic elmo-folder-search (folder condition &optional numbers)
   "Search and return list of message numbers.
 FOLDER is the ELMO folder structure.
-CONDITION is a condition string for searching.
+CONDITION is a condition structure for searching.
 If optional argument NUMBERS is specified and is a list of message numbers,
 messages are searched from the list.")
 
 If optional argument NUMBERS is specified and is a list of message numbers,
 messages are searched from the list.")
 
+(luna-define-generic elmo-message-match-condition (folder number
+                                                         condition
+                                                         numbers)
+  "Return non-nil when the message in the FOLDER with NUMBER is matched.
+CONDITION is a condition structure for testing.
+NUMBERS is a list of message numbers,
+use to be test for \"last\" and \"first\" predicates.")
+
 (luna-define-generic elmo-folder-msgdb-create
   (folder numbers new-mark already-mark seen-mark important-mark seen-list)
   "Create a message database (implemented in each backends).
 (luna-define-generic elmo-folder-msgdb-create
   (folder numbers new-mark already-mark seen-mark important-mark seen-list)
   "Create a message database (implemented in each backends).
@@ -492,7 +508,7 @@ Return newly created temporary directory name which contains temporary files.")
       (if (not ignore-cache)
          (elmo-make-fetch-strategy
           'entire
       (if (not ignore-cache)
          (elmo-make-fetch-strategy
           'entire
-          ;; ...But ignore current section cache and re-fetch 
+          ;; ...But ignore current section cache and re-fetch
           ;; if section cache.
           (not (eq (elmo-file-cache-status cache-file) 'section))
           ;; Save cache.
           ;; if section cache.
           (not (eq (elmo-file-cache-status cache-file) 'section))
           ;; Save cache.
@@ -511,15 +527,18 @@ Return newly created temporary directory name which contains temporary files.")
   ((folder elmo-folder) important-mark)
   t)
 
   ((folder elmo-folder) important-mark)
   t)
 
-(defun elmo-folder-encache (folder numbers)
-  "Encache messages in the FOLDER with NUMBERS."
+(defun elmo-folder-encache (folder numbers &optional unread)
+  "Encache messages in the FOLDER with NUMBERS.
+If UNREAD is non-nil, messages are not marked as read."
   (dolist (number numbers)
   (dolist (number numbers)
-    (elmo-message-encache folder number)))
+    (elmo-message-encache folder number unread)))
 
 
-(luna-define-generic elmo-message-encache (folder number)
-  "Encache message in the FOLDER with NUMBER.")
+(luna-define-generic elmo-message-encache (folder number &optional read)
+  "Encache message in the FOLDER with NUMBER.
+If READ is non-nil, message is marked as read.")
 
 
-(luna-define-method elmo-message-encache ((folder elmo-folder) number)
+(luna-define-method elmo-message-encache ((folder elmo-folder) number
+                                         &optional read)
   (elmo-message-fetch
    folder number
    (elmo-make-fetch-strategy 'entire
   (elmo-message-fetch
    folder number
    (elmo-make-fetch-strategy 'entire
@@ -528,7 +547,7 @@ Return newly created temporary directory name which contains temporary files.")
                             (elmo-file-cache-get-path
                              (elmo-message-field
                               folder number 'message-id)))
                             (elmo-file-cache-get-path
                              (elmo-message-field
                               folder number 'message-id)))
-   nil nil 'unread))
+   nil nil (not read)))
 
 (luna-define-generic elmo-message-fetch (folder number strategy
                                                &optional
 
 (luna-define-generic elmo-message-fetch (folder number strategy
                                                &optional
@@ -592,6 +611,12 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
 (luna-define-generic elmo-folder-append-msgdb (folder append-msgdb)
   "Append  APPEND-MSGDB to the current msgdb of the folder.")
 
 (luna-define-generic elmo-folder-append-msgdb (folder append-msgdb)
   "Append  APPEND-MSGDB to the current msgdb of the folder.")
 
+(luna-define-generic elmo-folder-newsgroups (folder)
+  "Return list of newsgroup name of FOLDER.")
+
+(luna-define-method elmo-folder-newsgroups ((folder elmo-folder))
+  nil)
+
 (luna-define-method elmo-folder-open ((folder elmo-folder)
                                      &optional load-msgdb)
   (elmo-generic-folder-open folder load-msgdb))
 (luna-define-method elmo-folder-open ((folder elmo-folder)
                                      &optional load-msgdb)
   (elmo-generic-folder-open folder load-msgdb))
@@ -668,7 +693,10 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
   t) ; default is creatable.
 
 (luna-define-method elmo-folder-writable-p ((folder elmo-folder))
   t) ; default is creatable.
 
 (luna-define-method elmo-folder-writable-p ((folder elmo-folder))
-  t) ; default is writable.
+  nil) ; default is not writable.
+
+(luna-define-method elmo-folder-delete ((folder elmo-folder))
+  (elmo-msgdb-delete-path folder))
 
 (luna-define-method elmo-folder-rename ((folder elmo-folder) new-name)
   (let* ((new-folder (elmo-make-folder new-name)))
 
 (luna-define-method elmo-folder-rename ((folder elmo-folder) new-name)
   (let* ((new-folder (elmo-make-folder new-name)))
@@ -681,6 +709,77 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
     (elmo-folder-send folder 'elmo-folder-rename-internal new-folder)
     (elmo-msgdb-rename-path folder new-folder)))
 
     (elmo-folder-send folder 'elmo-folder-rename-internal new-folder)
     (elmo-msgdb-rename-path folder new-folder)))
 
+(defsubst elmo-folder-search-fast (folder condition numbers)
+  (when (and numbers
+            (vectorp condition)
+            (member (elmo-filter-key condition) '("first" "last")))
+    (let ((len (length numbers))
+         (lastp (string= (elmo-filter-key condition) "last"))
+         (value (string-to-number (elmo-filter-value condition))))
+      (when (eq (elmo-filter-type condition) 'unmatch)
+       (setq lastp (not lastp)
+             value  (- len value)))
+      (if lastp
+         (nthcdr (max (- len value) 0) numbers)
+       (when (> value 0)
+         (let ((last (nthcdr (1- value) numbers)))
+           (when last
+             (setcdr last nil))
+           numbers))))))
+
+(luna-define-method elmo-folder-search ((folder elmo-folder)
+                                       condition
+                                       &optional numbers)
+  (let ((numbers (or numbers (elmo-folder-list-messages folder))))
+    (or (elmo-folder-search-fast folder condition numbers)
+       (let ((msgdb (elmo-folder-msgdb folder))
+             (len (length numbers))
+             matched)
+         (when (> len elmo-display-progress-threshold)
+           (elmo-progress-set 'elmo-folder-search len "Searching..."))
+         (unwind-protect
+             (dolist (number numbers)
+               (let ((entity (elmo-msgdb-overview-get-entity number msgdb))
+                     result)
+                 (if entity
+                     (setq result (elmo-msgdb-match-condition
+                                   condition
+                                   entity
+                                   numbers))
+                   (setq result condition))
+                 (when (elmo-filter-condition-p result)
+                   (setq result (elmo-message-match-condition
+                                 folder
+                                 number
+                                 condition
+                                 numbers)))
+                 (when result
+                   (setq matched (cons number matched))))
+               (elmo-progress-notify 'elmo-folder-search))
+           (elmo-progress-clear 'elmo-folder-search))
+         (nreverse matched)))))
+
+(luna-define-method elmo-message-match-condition ((folder elmo-folder)
+                                                 number condition
+                                                 numbers)
+  (let ((filename (cond
+                  ((elmo-message-file-name folder number))
+                  ((let* ((cache (elmo-file-cache-get
+                                  (elmo-message-field folder number
+                                                      'message-id)))
+                          (cache-path (elmo-file-cache-path cache)))
+                     (when (and cache-path
+                                (not (elmo-cache-path-section-p cache-path)))
+                       cache-path))))))
+    (when (and filename
+              (file-readable-p filename))
+      (with-temp-buffer
+       (insert-file-contents-as-binary filename)
+       (elmo-set-buffer-multibyte default-enable-multibyte-characters)
+       ;; Should consider charset?
+       (decode-mime-charset-region (point-min) (point-max) elmo-mime-charset)
+       (elmo-buffer-field-condition-match condition number numbers)))))
+
 (luna-define-method elmo-folder-pack-numbers ((folder elmo-folder))
   nil) ; default is noop.
 
 (luna-define-method elmo-folder-pack-numbers ((folder elmo-folder))
   nil) ; default is noop.
 
@@ -763,6 +862,18 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
      info-alist)
     (setq elmo-folder-info-hashtb hashtb)))
 
      info-alist)
     (setq elmo-folder-info-hashtb hashtb)))
 
+(defsubst elmo-diff-new (diff)
+  (car diff))
+
+(defsubst elmo-diff-unread (diff)
+  (when (consp (cdr diff))
+    (nth 1 diff)))
+
+(defsubst elmo-diff-all (diff)
+  (if (consp (cdr diff))
+      (nth 2 diff)
+    (cdr diff)))
+
 (defsubst elmo-strict-folder-diff (folder)
   "Return folder diff information strictly from FOLDER."
   (let* ((dir (elmo-folder-msgdb-path folder))
 (defsubst elmo-strict-folder-diff (folder)
   "Return folder diff information strictly from FOLDER."
   (let* ((dir (elmo-folder-msgdb-path folder))
@@ -852,31 +963,39 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
                                                   unread-marks same-number)
   (let (unseen seen-list succeed-numbers failure cache)
     (with-temp-buffer
                                                   unread-marks same-number)
   (let (unseen seen-list succeed-numbers failure cache)
     (with-temp-buffer
+      (set-buffer-multibyte nil)
       (while numbers
        (setq failure nil)
        (condition-case nil
       (while numbers
        (setq failure nil)
        (condition-case nil
-           (progn
-             (elmo-message-fetch
-              src-folder (car numbers)
-              (if (and (not (elmo-folder-plugged-p src-folder))
-                       elmo-enable-disconnected-operation
-                       (setq cache (elmo-file-cache-get
-                                    (elmo-message-field
-                                     src-folder (car numbers)
-                                     'message-id)))
-                       (eq (elmo-file-cache-status cache) 'entire))
-                  (elmo-make-fetch-strategy
-                   'entire t nil (elmo-file-cache-path cache))
-                (elmo-make-fetch-strategy 'entire t))
-              nil (current-buffer)
-              'unread)
-             (unless (eq (buffer-size) 0)
-               (elmo-folder-append-buffer
-                folder
-                (setq unseen (member (elmo-message-mark
-                                      src-folder (car numbers))
-                                     unread-marks))
-                (if same-number (car numbers)))))
+           (setq cache (elmo-file-cache-get
+                        (elmo-message-field src-folder
+                                            (car numbers)
+                                            'message-id))
+                 failure
+                 (not
+                  (and
+                   (elmo-message-fetch
+                    src-folder (car numbers)
+                    (if (elmo-folder-plugged-p src-folder)
+                        (elmo-make-fetch-strategy
+                         'entire 'maybe nil
+                         (and cache (elmo-file-cache-path cache)))
+                      (or (and elmo-enable-disconnected-operation
+                               cache
+                               (eq (elmo-file-cache-status cache) 'entire)
+                               (elmo-make-fetch-strategy
+                                'entire t nil
+                                (elmo-file-cache-path cache)))
+                          (error "Unplugged")))
+                    nil (current-buffer)
+                    'unread)
+                   (> (buffer-size) 0)
+                   (elmo-folder-append-buffer
+                    folder
+                    (setq unseen (member (elmo-message-mark
+                                          src-folder (car numbers))
+                                         unread-marks))
+                    (if same-number (car numbers))))))
          (error (setq failure t)))
        ;; FETCH & APPEND finished
        (unless failure
          (error (setq failure t)))
        ;; FETCH & APPEND finished
        (unless failure
@@ -886,6 +1005,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
                                   'message-id)
                                  seen-list)))
          (setq succeed-numbers (cons (car numbers) succeed-numbers)))
                                   'message-id)
                                  seen-list)))
          (setq succeed-numbers (cons (car numbers) succeed-numbers)))
+       (elmo-progress-notify 'elmo-folder-move-messages)
        (setq numbers (cdr numbers)))
       (if (and seen-list (elmo-folder-persistent-p folder))
          (elmo-msgdb-seen-save (elmo-folder-msgdb-path folder)
        (setq numbers (cdr numbers)))
       (if (and seen-list (elmo-folder-persistent-p folder))
          (elmo-msgdb-seen-save (elmo-folder-msgdb-path folder)
@@ -896,7 +1016,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
 
 ;; Arguments should be reduced.
 (defun elmo-folder-move-messages (src-folder msgs dst-folder
 
 ;; Arguments should be reduced.
 (defun elmo-folder-move-messages (src-folder msgs dst-folder
-                                            &optional msgdb all done
+                                            &optional msgdb
                                             no-delete-info
                                             no-delete
                                             same-number
                                             no-delete-info
                                             no-delete
                                             same-number
@@ -906,16 +1026,14 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
     (let* ((messages msgs)
           (elmo-inhibit-display-retrieval-progress t)
           (len (length msgs))
     (let* ((messages msgs)
           (elmo-inhibit-display-retrieval-progress t)
           (len (length msgs))
-          (all-msg-num (or all len))
-          (done-msg-num (or done 0))
-          (progress-message (if no-delete
-                                "Copying messages..."
-                              "Moving messages..."))
           succeeds i result)
       (if (eq dst-folder 'null)
          (setq succeeds messages)
           succeeds i result)
       (if (eq dst-folder 'null)
          (setq succeeds messages)
-       ;; src is already opened.
+       (unless (elmo-folder-writable-p dst-folder)
+         (error "move: %d is not writable"
+                (elmo-folder-name-internal dst-folder)))
        (when messages
        (when messages
+         ;; src is already opened.
          (elmo-folder-open-internal dst-folder)
          (unless (setq succeeds (elmo-folder-append-messages dst-folder
                                                              src-folder
          (elmo-folder-open-internal dst-folder)
          (unless (setq succeeds (elmo-folder-append-messages dst-folder
                                                              src-folder
@@ -935,17 +1053,12 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
                   msgs (elmo-folder-msgdb src-folder)
                   unread-marks seen-list))
            (elmo-msgdb-seen-save dir seen-list))))
                   msgs (elmo-folder-msgdb src-folder)
                   unread-marks seen-list))
            (elmo-msgdb-seen-save dir seen-list))))
-      (when (and done
-                (> all-msg-num elmo-display-progress-threshold))
-       (elmo-display-progress
-        'elmo-folder-move-messages progress-message
-        (/ (* done-msg-num 100) all-msg-num)))
       (if (and (not no-delete) succeeds)
          (progn
            (if (not no-delete-info)
                (message "Cleaning up src folder..."))
            (if (and (elmo-folder-delete-messages src-folder succeeds)
       (if (and (not no-delete) succeeds)
          (progn
            (if (not no-delete-info)
                (message "Cleaning up src folder..."))
            (if (and (elmo-folder-delete-messages src-folder succeeds)
-                    (elmo-msgdb-delete-msgs 
+                    (elmo-msgdb-delete-msgs
                      (elmo-folder-msgdb src-folder) succeeds))
                (setq result t)
              (message "move: delete messages from %s failed."
                      (elmo-folder-msgdb src-folder) succeeds))
                (setq result t)
              (message "move: delete messages from %s failed."
@@ -1079,7 +1192,7 @@ FIELD is a symbol of the field."
                   'read)
               ;; Mark as read duplicates.
               (elmo-folder-mark-as-read folder to-be-deleted))
                   'read)
               ;; Mark as read duplicates.
               (elmo-folder-mark-as-read folder to-be-deleted))
-             (t 
+             (t
               ;; Do nothing.
               (setq to-be-deleted nil)))
        (elmo-folder-set-msgdb-internal folder
               ;; Do nothing.
               (setq to-be-deleted nil)))
        (elmo-folder-set-msgdb-internal folder
@@ -1096,9 +1209,10 @@ FIELD is a symbol of the field."
 (defun elmo-folder-confirm-appends (appends)
   (let ((len (length appends))
        in)
 (defun elmo-folder-confirm-appends (appends)
   (let ((len (length appends))
        in)
-    (if (and (> len elmo-folder-update-threshold)
+    (if (and elmo-folder-update-threshold
+            (> len elmo-folder-update-threshold)
             elmo-folder-update-confirm)
             elmo-folder-update-confirm)
-       (if (y-or-n-p (format "Too many messages(%d).  Continue? " len))
+       (if (y-or-n-p (format "Too many messages(%d).  Update all? " len))
            appends
          (setq in elmo-folder-update-threshold)
          (catch 'end
            appends
          (setq in elmo-folder-update-threshold)
          (catch 'end
@@ -1108,11 +1222,12 @@ FIELD is a symbol of the field."
                    in (string-to-int in))
              (if (< len in)
                  (throw 'end len))
                    in (string-to-int in))
              (if (< len in)
                  (throw 'end len))
-             (if (y-or-n-p (format "%d messages are disappeared.  OK? "
+             (if (y-or-n-p (format "%d messages are not appeared.  OK? "
                                    (max (- len in) 0)))
                  (throw 'end in))))
          (nthcdr (max (- len in) 0) appends))
                                    (max (- len in) 0)))
                  (throw 'end in))))
          (nthcdr (max (- len in) 0) appends))
-      (if (and (> len elmo-folder-update-threshold)
+      (if (and elmo-folder-update-threshold
+              (> len elmo-folder-update-threshold)
               (not elmo-folder-update-confirm))
          (nthcdr (max (- len elmo-folder-update-threshold) 0) appends)
        appends))))
               (not elmo-folder-update-confirm))
          (nthcdr (max (- len elmo-folder-update-threshold) 0) appends)
        appends))))
@@ -1127,8 +1242,7 @@ FIELD is a symbol of the field."
       (with-current-buffer outbuf
        (erase-buffer)
        (elmo-message-fetch-with-cache-process folder number
       (with-current-buffer outbuf
        (erase-buffer)
        (elmo-message-fetch-with-cache-process folder number
-                                              strategy section unread)
-       t)
+                                              strategy section unread))
     (with-temp-buffer
       (elmo-message-fetch-with-cache-process folder number
                                             strategy section unread)
     (with-temp-buffer
       (elmo-message-fetch-with-cache-process folder number
                                             strategy section unread)
@@ -1138,24 +1252,37 @@ FIELD is a symbol of the field."
                                                           number strategy
                                                           &optional
                                                           section unread)
                                                           number strategy
                                                           &optional
                                                           section unread)
-  (let (cache-path cache-file)
-    (if (and (elmo-fetch-strategy-use-cache strategy)
-            (setq cache-path (elmo-fetch-strategy-cache-path strategy))
-            (setq cache-file (elmo-file-cache-expand-path
-                              cache-path
-                              section))
-            (file-exists-p cache-file)
-            (or (not (elmo-cache-path-section-p cache-file))
-                (not (eq (elmo-fetch-strategy-entireness strategy) 'entire))))
-       (insert-file-contents-as-binary cache-file)
-      (elmo-message-fetch-internal folder number strategy section unread)
-      (elmo-delete-cr-buffer)
-      (when (and (> (buffer-size) 0)
-                (elmo-fetch-strategy-save-cache strategy)
-                (elmo-fetch-strategy-cache-path strategy))
-       (elmo-file-cache-save
-        (elmo-fetch-strategy-cache-path strategy)
-        section)))))
+  (let ((cache-path (elmo-fetch-strategy-cache-path strategy))
+       (method-priorities
+        (cond ((eq (elmo-fetch-strategy-use-cache strategy) 'maybe)
+               '(entity cache))
+              ((elmo-fetch-strategy-use-cache strategy)
+               '(cache entity))
+              (t
+               '(entity))))
+       result err)
+    (while (and method-priorities
+               (null result))
+      (setq result
+           (case (car method-priorities)
+             (cache
+              (elmo-file-cache-load cache-path section))
+             (entity
+              (when (and (condition-case error
+                             (elmo-message-fetch-internal folder number
+                                                          strategy
+                                                          section
+                                                          unread)
+                           (error (setq err error) nil))
+                         (> (buffer-size) 0))
+                (elmo-delete-cr-buffer)
+                (when (and (elmo-fetch-strategy-save-cache strategy)
+                           cache-path)
+                  (elmo-file-cache-save cache-path section))
+                t)))
+           method-priorities (cdr method-priorities)))
+    (or result
+       (and err (signal (car err) (cdr err))))))
 
 (luna-define-method elmo-folder-clear ((folder elmo-folder)
                                       &optional keep-killed)
 
 (luna-define-method elmo-folder-clear ((folder elmo-folder)
                                       &optional keep-killed)
@@ -1164,7 +1291,7 @@ FIELD is a symbol of the field."
   (elmo-folder-set-msgdb-internal folder (elmo-msgdb-clear)))
 
 (defun elmo-folder-synchronize (folder
   (elmo-folder-set-msgdb-internal folder (elmo-msgdb-clear)))
 
 (defun elmo-folder-synchronize (folder
-                               new-mark             ;"N"
+                               new-mark             ;"N"
                                unread-uncached-mark ;"U"
                                unread-cached-mark   ;"!"
                                read-uncached-mark   ;"u"
                                unread-uncached-mark ;"U"
                                unread-cached-mark   ;"!"
                                read-uncached-mark   ;"u"
@@ -1178,7 +1305,7 @@ are mark strings for new messages, unread but cached messages,
 read but not cached messages, and important messages.
 If optional IGNORE-MSGDB is non-nil, current msgdb is thrown away except
 read mark status. If IGNORE-MSGDB is 'visible-only, only visible messages
 read but not cached messages, and important messages.
 If optional IGNORE-MSGDB is non-nil, current msgdb is thrown away except
 read mark status. If IGNORE-MSGDB is 'visible-only, only visible messages
-\(the messages which are not in the killed-list\) are thrown away and 
+\(the messages which are not in the killed-list\) are thrown away and
 synchronized.
 If NO-CHECK is non-nil, rechecking folder is skipped.
 
 synchronized.
 If NO-CHECK is non-nil, rechecking folder is skipped.
 
@@ -1190,7 +1317,7 @@ CROSSED is cross-posted message number.
 If update process is interrupted, return nil."
   (let ((killed-list (elmo-folder-killed-list-internal folder))
        (before-append t)
 If update process is interrupted, return nil."
   (let ((killed-list (elmo-folder-killed-list-internal folder))
        (before-append t)
-       number-alist mark-alist 
+       number-alist mark-alist
        old-msgdb diff diff-2 delete-list new-list new-msgdb mark
        seen-list crossed after-append)
     (setq old-msgdb (elmo-folder-msgdb folder))
        old-msgdb diff diff-2 delete-list new-list new-msgdb mark
        seen-list crossed after-append)
     (setq old-msgdb (elmo-folder-msgdb folder))
@@ -1218,8 +1345,8 @@ If update process is interrupted, return nil."
                                      folder
                                      (eq 'visible-only ignore-msgdb))
                                     (unless ignore-msgdb
                                      folder
                                      (eq 'visible-only ignore-msgdb))
                                     (unless ignore-msgdb
-                                      (sort (mapcar 
-                                             'car 
+                                      (sort (mapcar
+                                             'car
                                              number-alist)
                                             '<))))
          (message "Checking folder diff...done")
                                              number-alist)
                                             '<))))
          (message "Checking folder diff...done")
@@ -1229,16 +1356,7 @@ If update process is interrupted, return nil."
                              (length new-list)))
                     (setq diff-2 (elmo-list-diff (car diff) new-list)))
            (elmo-msgdb-append-to-killed-list folder (car diff-2)))
                              (length new-list)))
                     (setq diff-2 (elmo-list-diff (car diff) new-list)))
            (elmo-msgdb-append-to-killed-list folder (car diff-2)))
-         ;; Don't delete important marked messages.
-         (setq delete-list
-               (if (eq (elmo-folder-type-internal folder) 'mark)
-                   (cadr diff)
-                 (elmo-delete-if
-                  (lambda (x)
-                    (and (setq mark (cadr (assq x mark-alist)))
-                         (string= mark important-mark)))
-                  ;; delete message list
-                  (cadr diff))))
+         (setq delete-list (cadr diff))
          (if (or (equal diff '(nil nil))
                  (equal diff '(nil))
                  (and (eq (length (car diff)) 0)
          (if (or (equal diff '(nil nil))
                  (equal diff '(nil))
                  (and (eq (length (car diff)) 0)
@@ -1286,30 +1404,6 @@ If update process is interrupted, return nil."
     (elmo-folder-msgdb folder))))
 
 ;;;
     (elmo-folder-msgdb folder))))
 
 ;;;
-(defun elmo-msgdb-search (folder condition msgdb)
-  "Search messages which satisfy CONDITION from FOLDER with MSGDB."
-  (let* ((condition (car (elmo-parse-search-condition condition)))
-        (overview (elmo-msgdb-get-overview msgdb))
-        (number-alist (elmo-msgdb-get-number-alist msgdb))
-        (number-list (mapcar 'car number-alist))
-        (length (length overview))
-        (i 0)
-        result)
-    (if (not (elmo-condition-in-msgdb-p condition))
-       (elmo-folder-search folder condition number-list)
-      (while overview
-       (if (elmo-msgdb-search-internal condition (car overview)
-                                       number-list)
-           (setq result
-                 (cons
-                  (elmo-msgdb-overview-entity-get-number (car overview))
-                  result)))
-       (setq i (1+ i))
-       (elmo-display-progress
-        'elmo-msgdb-search "Searching..." (/ (* i 100) length))
-       (setq overview (cdr overview)))
-      (nreverse result))))
-
 (defun elmo-msgdb-load (folder)
   (message "Loading msgdb for %s..." (elmo-folder-name-internal folder))
   (let* ((path (elmo-folder-msgdb-path folder))
 (defun elmo-msgdb-load (folder)
   (message "Loading msgdb for %s..." (elmo-folder-name-internal folder))
   (let* ((path (elmo-folder-msgdb-path folder))
@@ -1377,7 +1471,7 @@ Return a hashtable for newsgroups."
       (elmo-crosspost-alist-save elmo-crosspost-message-alist)
       (setq elmo-crosspost-message-alist-modified nil))))
 
       (elmo-crosspost-alist-save elmo-crosspost-message-alist)
       (setq elmo-crosspost-message-alist-modified nil))))
 
-(defun elmo-folder-make-temp-dir (folder)
+(defun elmo-folder-make-temporary-directory (folder)
   ;; Make a temporary directory for FOLDER.
   (let ((temp-dir (make-temp-name
                   (concat
   ;; Make a temporary directory for FOLDER.
   (let ((temp-dir (make-temp-name
                   (concat
@@ -1394,8 +1488,8 @@ Return a hashtable for newsgroups."
 
 (defun elmo-quit ()
   "Quit and cleanup ELMO."
 
 (defun elmo-quit ()
   "Quit and cleanup ELMO."
-;  (setq elmo-newsgroups-hashtb nil)
   (elmo-crosspost-message-alist-save)
   (elmo-crosspost-message-alist-save)
+  (elmo-dop-queue-save)
   ;; Not implemented yet.
   (let ((types elmo-folder-type-alist)
        class)
   ;; Not implemented yet.
   (let ((types elmo-folder-type-alist)
        class)
@@ -1436,12 +1530,16 @@ Return a hashtable for newsgroups."
                               'elmo-imap4-default-user)
 (elmo-define-obsolete-variable 'elmo-default-imap4-port
                               'elmo-imap4-default-port)
                               'elmo-imap4-default-user)
 (elmo-define-obsolete-variable 'elmo-default-imap4-port
                               'elmo-imap4-default-port)
+(elmo-define-obsolete-variable 'elmo-default-imap4-stream-type
+                              'elmo-imap4-default-stream-type)
 (elmo-define-obsolete-variable 'elmo-default-nntp-server
                               'elmo-nntp-default-server)
 (elmo-define-obsolete-variable 'elmo-default-nntp-user
                               'elmo-nntp-default-user)
 (elmo-define-obsolete-variable 'elmo-default-nntp-port
                               'elmo-nntp-default-port)
 (elmo-define-obsolete-variable 'elmo-default-nntp-server
                               'elmo-nntp-default-server)
 (elmo-define-obsolete-variable 'elmo-default-nntp-user
                               'elmo-nntp-default-user)
 (elmo-define-obsolete-variable 'elmo-default-nntp-port
                               'elmo-nntp-default-port)
+(elmo-define-obsolete-variable 'elmo-default-nntp-stream-type
+                              'elmo-nntp-default-stream-type)
 (elmo-define-obsolete-variable 'elmo-default-pop3-server
                               'elmo-pop3-default-server)
 (elmo-define-obsolete-variable 'elmo-default-pop3-user
 (elmo-define-obsolete-variable 'elmo-default-pop3-server
                               'elmo-pop3-default-server)
 (elmo-define-obsolete-variable 'elmo-default-pop3-user
@@ -1450,6 +1548,19 @@ Return a hashtable for newsgroups."
                               'elmo-pop3-default-authenticate-type)
 (elmo-define-obsolete-variable 'elmo-default-pop3-port
                               'elmo-pop3-default-port)
                               'elmo-pop3-default-authenticate-type)
 (elmo-define-obsolete-variable 'elmo-default-pop3-port
                               'elmo-pop3-default-port)
+(elmo-define-obsolete-variable 'elmo-default-pop3-stream-type
+                              'elmo-pop3-default-stream-type)
+(elmo-define-obsolete-variable 'elmo-cache-dirname
+                              'elmo-cache-directory)
+(elmo-define-obsolete-variable 'elmo-msgdb-dir
+                              'elmo-msgdb-directory)
+
+;; Obsolete functions.
+;; 2001-12-11: *-dir -> *-directory
+(defalias 'elmo-folder-make-temp-dir 'elmo-folder-make-temporary-directory)
+(make-obsolete 'elmo-folder-make-temp-dir
+              'elmo-folder-make-temporary-directory)
+
 
 ;; autoloads
 (autoload 'elmo-dop-queue-flush "elmo-dop")
 
 ;; autoloads
 (autoload 'elmo-dop-queue-flush "elmo-dop")