This commit was manufactured by cvs2svn to create branch 'elmo-imap4-new-
[elisp/wanderlust.git] / elmo / elmo-pop3.el
index 7aef677..07555c6 100644 (file)
@@ -36,6 +36,7 @@
 (require 'elmo-map)
 
 (eval-when-compile
+  (require 'cl)
   (require 'elmo-util))
 
 (eval-and-compile
@@ -69,7 +70,7 @@ set as non-nil.")
 
 (defvar sasl-mechanism-alist)
 
-(defvar elmo-pop3-total-size nil)
+(defvar elmo-pop3-retrieve-progress-reporter nil)
 
 ;; For debugging.
 (defvar elmo-pop3-debug nil
@@ -227,7 +228,8 @@ CODE is one of the following:
          (goto-char elmo-pop3-read-point))
        (setq match-end (point))
        (setq response-string
-             (buffer-substring elmo-pop3-read-point (- match-end 2)))
+             (buffer-substring elmo-pop3-read-point
+                               (max (- match-end 2) elmo-pop3-read-point)))
        (goto-char elmo-pop3-read-point)
        (if (looking-at "\\+.*$")
            (progn
@@ -267,15 +269,8 @@ CODE is one of the following:
       (goto-char (point-max))
       (insert output)
       (elmo-pop3-debug "RECEIVED: %s\n" output)
-      (if (and elmo-pop3-total-size
-              (> elmo-pop3-total-size
-                 (min elmo-display-retrieval-progress-threshold 100)))
-         (elmo-display-progress
-          'elmo-display-retrieval-progress
-          (format "Retrieving (%d/%d bytes)..."
-                  (buffer-size)
-                  elmo-pop3-total-size)
-          (/ (buffer-size) (/ elmo-pop3-total-size 100)))))))
+      (when elmo-pop3-retrieve-progress-reporter
+       (elmo-progress-notify 'elmo-retrieve-message :set (buffer-size))))))
 
 (defun elmo-pop3-auth-user (session)
   (let ((process (elmo-network-session-process-internal session))
@@ -306,7 +301,7 @@ CODE is one of the following:
     (car response)))
 
 (defun elmo-pop3-auth-apop (session)
-  (unless (string-match "^\+OK .*\\(<[^\>]+>\\)"
+  (unless (string-match "^\+OK .*\\(<[=!-;?-~]+@[=!-;?-~]+>\\)"
                        (elmo-network-session-greeting-internal session))
     (signal 'elmo-open-error '(elmo-pop3-auth-apop)))
   ;; good, APOP ready server
@@ -475,15 +470,15 @@ until the login delay period has expired"))
 (defun elmo-pop3-read-contents (process)
   (with-current-buffer (process-buffer process)
     (let ((case-fold-search nil)
-         match-end)
-      (goto-char elmo-pop3-read-point)
-      (while (not (re-search-forward "^\\.\r\n" nil t))
-       (accept-process-output process 1)
-       (goto-char elmo-pop3-read-point))
-      (setq match-end (point))
+         (point elmo-pop3-read-point))
+      (while (and (goto-char (- point 2))
+                 (not (search-forward "\r\n.\r\n" nil t)))
+       (setq point (max (- (point-max) 2) ; Care of \r\n.\r[EOF] case
+                        elmo-pop3-read-point))
+       (accept-process-output process 1))
       (elmo-delete-cr
        (buffer-substring elmo-pop3-read-point
-                        (- match-end 3))))))
+                        (- (point) 3))))))
 
 (luna-define-method elmo-folder-expand-msgdb-path ((folder elmo-pop3-folder))
   (convert-standard-filename
@@ -589,7 +584,7 @@ until the login delay period has expired"))
       (if elmo-pop3-list-done
          (progn
            (mapatoms (lambda (atom)
-                       (setq list (cons (string-to-int
+                       (setq list (cons (string-to-number
                                          (substring (symbol-name atom) 1))
                                         list)))
                      elmo-pop3-size-hash)
@@ -624,7 +619,7 @@ until the login delay period has expired"))
        (if (not (string-match "^\+OK[ \t]*\\([0-9]*\\)" response))
            (error "POP STAT command failed")
          (setq total
-               (string-to-int
+               (string-to-number
                 (substring response (match-beginning 1)(match-end 1 ))))
          (elmo-folder-close-internal folder)
          (cons total total))))))
@@ -645,44 +640,40 @@ until the login delay period has expired"))
     nil)))
 
 (defun elmo-pop3-retrieve-headers (process tobuffer articles)
-  (save-excursion
-    (set-buffer (process-buffer process))
+  (with-current-buffer (process-buffer process)
     (erase-buffer)
-    (let ((number (length articles))
-         (count 0)
+    (let ((count 0)
          (received 0)
          (last-point (point-min)))
-      ;; Send HEAD commands.
-      (while articles
-       (elmo-pop3-send-command process (format
-                                        "top %s 0" (car articles))
-                               'no-erase)
-;;;    (accept-process-output process 1)
-       (setq articles (cdr articles))
-       (setq count (1+ count))
-       ;; Every 200 requests we have to read the stream in
-       ;; order to avoid deadlocks.
-       (when (or elmo-pop3-send-command-synchronously
-                 (null articles)       ;All requests have been sent.
-                 (zerop (% count elmo-pop3-header-fetch-chop-length)))
-         (unless elmo-pop3-send-command-synchronously
-           (accept-process-output process 1))
-         (discard-input)
-         (while (progn
-                  (goto-char last-point)
-                  ;; Count replies.
-                  (while (elmo-pop3-next-result-arrived-p)
-                    (setq last-point (point))
-                    (setq received (1+ received)))
-                  (< received count))
-           (when (> number elmo-display-progress-threshold)
-             (if (or (zerop (% received 5)) (= received number))
-                 (elmo-display-progress
-                  'elmo-pop3-retrieve-headers "Getting headers..."
-                  (/ (* received 100) number))))
-           (accept-process-output process 1)
-;;;        (accept-process-output process)
-           (discard-input))))
+      (elmo-with-progress-display (elmo-retrieve-header (length articles))
+         "Getting headers"
+       ;; Send HEAD commands.
+       (while articles
+         (elmo-pop3-send-command process
+                                 (format "top %s 0" (car articles))
+                                 'no-erase)
+;;;      (accept-process-output process 1)
+         (setq articles (cdr articles))
+         (setq count (1+ count))
+         ;; Every 200 requests we have to read the stream in
+         ;; order to avoid deadlocks.
+         (when (or elmo-pop3-send-command-synchronously
+                   (null articles)     ;All requests have been sent.
+                   (zerop (% count elmo-pop3-header-fetch-chop-length)))
+           (unless elmo-pop3-send-command-synchronously
+             (accept-process-output process 1))
+           (discard-input)
+           (while (progn
+                    (goto-char last-point)
+                    ;; Count replies.
+                    (while (elmo-pop3-next-result-arrived-p)
+                      (setq last-point (point))
+                      (setq received (1+ received)))
+                    (< received count))
+             (elmo-progress-notify 'elmo-retrieve-header :set received)
+             (accept-process-output process 1)
+;;;          (accept-process-output process)
+             (discard-input)))))
       ;; Replace all CRLF with LF.
       (elmo-delete-cr-buffer)
       (copy-to-buffer tobuffer (point-min) (point-max)))))
@@ -742,47 +733,42 @@ until the login delay period has expired"))
                                       flag-table)
   (save-excursion
     (let ((new-msgdb (elmo-make-msgdb))
-         beg entity i number message-id flags)
+         beg entity number message-id flags)
       (set-buffer buffer)
       (set-buffer-multibyte default-enable-multibyte-characters)
       (goto-char (point-min))
-      (setq i 0)
-      (message "Creating msgdb...")
-      (while (not (eobp))
-       (setq beg (save-excursion (forward-line 1) (point)))
-       (elmo-pop3-next-result-arrived-p)
-       (save-excursion
-         (forward-line -1)
-         (save-restriction
-           (narrow-to-region beg (point))
-           (setq entity
-                 (elmo-msgdb-create-message-entity-from-buffer
-                  (elmo-msgdb-message-entity-handler new-msgdb)
-                  (car numlist)))
-           (setq numlist (cdr numlist))
-           (when entity
-             (with-current-buffer (process-buffer process)
-               (elmo-message-entity-set-field
-                entity
-                'size
-                (elmo-pop3-number-to-size
-                 (elmo-message-entity-number entity)))
-               (when (setq number
-                           (elmo-map-message-number
-                            folder
-                            (elmo-pop3-number-to-uidl
-                             (elmo-message-entity-number entity))))
-                 (elmo-message-entity-set-number entity number)))
-             (setq message-id (elmo-message-entity-field entity 'message-id)
-                   flags (elmo-flag-table-get flag-table message-id))
-             (elmo-global-flags-set flags folder number message-id)
-             (elmo-msgdb-append-entity new-msgdb entity flags))))
-       (when (> num elmo-display-progress-threshold)
-         (setq i (1+ i))
-         (if (or (zerop (% i 5)) (= i num))
-             (elmo-display-progress
-              'elmo-pop3-msgdb-create-message "Creating msgdb..."
-              (/ (* i 100) num)))))
+      (elmo-with-progress-display (elmo-folder-msgdb-create num)
+         "Creating msgdb"
+       (while (not (eobp))
+         (setq beg (save-excursion (forward-line 1) (point)))
+         (elmo-pop3-next-result-arrived-p)
+         (save-excursion
+           (forward-line -1)
+           (save-restriction
+             (narrow-to-region beg (point))
+             (setq entity
+                   (elmo-msgdb-create-message-entity-from-buffer
+                    (elmo-msgdb-message-entity-handler new-msgdb)
+                    (car numlist)))
+             (setq numlist (cdr numlist))
+             (when entity
+               (with-current-buffer (process-buffer process)
+                 (elmo-message-entity-set-field
+                  entity
+                  'size
+                  (elmo-pop3-number-to-size
+                   (elmo-message-entity-number entity)))
+                 (when (setq number
+                             (elmo-map-message-number
+                              folder
+                              (elmo-pop3-number-to-uidl
+                               (elmo-message-entity-number entity))))
+                   (elmo-message-entity-set-number entity number)))
+               (setq message-id (elmo-message-entity-field entity 'message-id)
+                     flags (elmo-flag-table-get flag-table message-id))
+               (elmo-global-flags-set flags folder number message-id)
+               (elmo-msgdb-append-entity new-msgdb entity flags))))
+         (elmo-progress-notify 'elmo-folder-msgdb-create)))
       new-msgdb)))
 
 (defun elmo-pop3-read-body (process outbuf)
@@ -800,8 +786,9 @@ until the login delay period has expired"))
       t)))
 
 (luna-define-method elmo-folder-open-internal ((folder elmo-pop3-folder))
-  (when (elmo-pop3-folder-use-uidl folder)
-    (elmo-location-map-load folder (elmo-folder-msgdb-path folder))))
+  (unless (elmo-location-map-alist folder)
+    (when (elmo-pop3-folder-use-uidl folder)
+      (elmo-location-map-load folder (elmo-folder-msgdb-path folder)))))
 
 (luna-define-method elmo-folder-commit :after ((folder elmo-pop3-folder))
   (when (and (not elmo-inhibit-number-mapping)
@@ -826,26 +813,14 @@ until the login delay period has expired"))
                      (elmo-map-message-location folder number))))
       (setq size (elmo-pop3-number-to-size number))
       (when number
-       (elmo-pop3-send-command process
-                               (format "retr %s" number))
-       (unless elmo-inhibit-display-retrieval-progress
-         (setq elmo-pop3-total-size size)
-         (elmo-display-progress
-          'elmo-display-retrieval-progress
-          (format "Retrieving (0/%d bytes)..." elmo-pop3-total-size)
-          0))
-       (unwind-protect
-           (progn
-             (when (null (setq response (cdr (elmo-pop3-read-response
-                                              process t))))
-               (error "Fetching message failed"))
-             (setq response  (elmo-pop3-read-body process outbuf)))
-         (setq elmo-pop3-total-size nil))
-       (unless elmo-inhibit-display-retrieval-progress
-         (elmo-display-progress
-          'elmo-display-retrieval-progress
-          "Retrieving..." 100)  ; remove progress bar.
-         (message "Retrieving...done"))
+       (elmo-with-progress-display
+           (elmo-retrieve-message size elmo-pop3-retrieve-progress-reporter)
+           "Retrieving"
+         (elmo-pop3-send-command process (format "retr %s" number))
+         (when (null (setq response (cdr (elmo-pop3-read-response
+                                          process t))))
+           (error "Fetching message failed"))
+         (setq response  (elmo-pop3-read-body process outbuf)))
        (set-buffer outbuf)
        (goto-char (point-min))
        (while (re-search-forward "^\\." nil t)