diff options
| -rw-r--r-- | lisp/gnus/ChangeLog | 20 | ||||
| -rw-r--r-- | lisp/gnus/gnus-start.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/mail-source.el | 17 | ||||
| -rw-r--r-- | lisp/gnus/pop3.el | 118 |
4 files changed, 131 insertions, 26 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 9ed24b72a55..5bd02f73bbf 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,5 +1,25 @@ | |||
| 1 | 2010-09-04 Lars Magne Ingebrigtsen <larsi@gnus.org> | 1 | 2010-09-04 Lars Magne Ingebrigtsen <larsi@gnus.org> |
| 2 | 2 | ||
| 3 | * mail-source.el (mail-source-delete-crash-box): Only check the | ||
| 4 | incoming files for deletion once per day to save a lot of file | ||
| 5 | accesses. | ||
| 6 | |||
| 7 | * pop3.el (pop3-logon): Fix up unbound variable typo. | ||
| 8 | |||
| 9 | * mail-source.el (pop3-streaming-movemail): Autoload. | ||
| 10 | |||
| 11 | * pop3.el (pop3-streaming-movemail): Respect | ||
| 12 | pop3-leave-mail-on-server. | ||
| 13 | |||
| 14 | * mail-source.el (mail-source-fetch-pop): Use streaming pop3 | ||
| 15 | retrieval. | ||
| 16 | |||
| 17 | * pop3.el (pop3-process-filter): Removed unused function. | ||
| 18 | (pop3-streaming-movemail, pop3-send-streaming-command) | ||
| 19 | (pop3-wait-for-messages, pop3-write-to-file) | ||
| 20 | (pop3-number-of-responses): New functions for streaming pop3 | ||
| 21 | retrieval. | ||
| 22 | |||
| 3 | * gnus-start.el (gnus-get-unread-articles): Protect against groups that | 23 | * gnus-start.el (gnus-get-unread-articles): Protect against groups that |
| 4 | come from no known methods. | 24 | come from no known methods. |
| 5 | (gnus-make-hashtable-from-newsrc-alist): Remove duplicates from .newsrc | 25 | (gnus-make-hashtable-from-newsrc-alist): Remove duplicates from .newsrc |
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 0e35a12cf7d..9458e0ed52d 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el | |||
| @@ -3184,5 +3184,3 @@ If this variable is nil, don't do anything." | |||
| 3184 | (provide 'gnus-start) | 3184 | (provide 'gnus-start) |
| 3185 | 3185 | ||
| 3186 | ;;; gnus-start.el ends here | 3186 | ;;; gnus-start.el ends here |
| 3187 | |||
| 3188 | |||
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 08b7a5ebbd2..080433c0d26 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | (require 'cl) | 34 | (require 'cl) |
| 35 | (require 'imap)) | 35 | (require 'imap)) |
| 36 | (autoload 'auth-source-user-or-password "auth-source") | 36 | (autoload 'auth-source-user-or-password "auth-source") |
| 37 | (autoload 'pop3-movemail "pop3") | 37 | (autoload 'pop3-streaming-movemail "pop3") |
| 38 | (autoload 'pop3-get-message-count "pop3") | 38 | (autoload 'pop3-get-message-count "pop3") |
| 39 | (autoload 'nnheader-cancel-timer "nnheader") | 39 | (autoload 'nnheader-cancel-timer "nnheader") |
| 40 | (require 'mm-util) | 40 | (require 'mm-util) |
| @@ -624,11 +624,20 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) | |||
| 624 | 0) | 624 | 0) |
| 625 | (funcall callback mail-source-crash-box info))) | 625 | (funcall callback mail-source-crash-box info))) |
| 626 | 626 | ||
| 627 | (defvar mail-source-incoming-last-checked-time nil) | ||
| 628 | |||
| 627 | (defun mail-source-delete-crash-box () | 629 | (defun mail-source-delete-crash-box () |
| 628 | (when (file-exists-p mail-source-crash-box) | 630 | (when (file-exists-p mail-source-crash-box) |
| 629 | ;; Delete or move the incoming mail out of the way. | 631 | ;; Delete or move the incoming mail out of the way. |
| 630 | (if (eq mail-source-delete-incoming t) | 632 | (if (eq mail-source-delete-incoming t) |
| 631 | (delete-file mail-source-crash-box) | 633 | (delete-file mail-source-crash-box) |
| 634 | ;; Don't check for old incoming files more than once per day to | ||
| 635 | ;; save a lot of file accesses. | ||
| 636 | (when (or (null mail-source-incoming-last-checked-time) | ||
| 637 | (> (time-to-seconds | ||
| 638 | (time-since mail-source-incoming-last-checked-time)) | ||
| 639 | (* 24 60 60))) | ||
| 640 | (setq mail-source-incoming-last-checked-time (current-time))) | ||
| 632 | (let ((incoming | 641 | (let ((incoming |
| 633 | (mm-make-temp-file | 642 | (mm-make-temp-file |
| 634 | (expand-file-name | 643 | (expand-file-name |
| @@ -825,9 +834,11 @@ Deleting old (> %s day(s)) incoming mail file `%s'." diff bfile) | |||
| 825 | (if (eq authentication 'apop) 'apop 'pass)) | 834 | (if (eq authentication 'apop) 'apop 'pass)) |
| 826 | (pop3-stream-type stream)) | 835 | (pop3-stream-type stream)) |
| 827 | (if (or debug-on-quit debug-on-error) | 836 | (if (or debug-on-quit debug-on-error) |
| 828 | (save-excursion (pop3-movemail mail-source-crash-box)) | 837 | (save-excursion (pop3-streaming-movemail |
| 838 | mail-source-crash-box)) | ||
| 829 | (condition-case err | 839 | (condition-case err |
| 830 | (save-excursion (pop3-movemail mail-source-crash-box)) | 840 | (save-excursion (pop3-streaming-movemail |
| 841 | mail-source-crash-box)) | ||
| 831 | (error | 842 | (error |
| 832 | ;; We nix out the password in case the error | 843 | ;; We nix out the password in case the error |
| 833 | ;; was because of a wrong password being given. | 844 | ;; was because of a wrong password being given. |
diff --git a/lisp/gnus/pop3.el b/lisp/gnus/pop3.el index 8b9ff662781..ca92046f1a8 100644 --- a/lisp/gnus/pop3.el +++ b/lisp/gnus/pop3.el | |||
| @@ -128,15 +128,90 @@ Shorter values mean quicker response, but are more CPU intensive.") | |||
| 128 | (truncate pop3-read-timeout)) | 128 | (truncate pop3-read-timeout)) |
| 129 | 1000)))))) | 129 | 1000)))))) |
| 130 | 130 | ||
| 131 | (defun pop3-movemail (&optional crashbox) | 131 | (defun pop3-streaming-movemail (file) |
| 132 | "Transfer contents of a maildrop to the specified CRASHBOX." | 132 | "Transfer contents of a maildrop to the specified FILE. |
| 133 | (or crashbox (setq crashbox (expand-file-name "~/.crashbox"))) | 133 | Use streaming commands." |
| 134 | (let* ((process (pop3-open-server pop3-mailhost pop3-port)) | 134 | (let* ((process (pop3-open-server pop3-mailhost pop3-port)) |
| 135 | (crashbuf (get-buffer-create " *pop3-retr*")) | 135 | message-count message-total-size) |
| 136 | (n 1) | 136 | (pop3-logon process) |
| 137 | message-count | 137 | (with-current-buffer (process-buffer process) |
| 138 | message-sizes | 138 | (let ((size (pop3-stat process))) |
| 139 | (pop3-password pop3-password)) | 139 | (setq message-count (car size) |
| 140 | message-total-size (cadr size))) | ||
| 141 | (when (plusp message-count) | ||
| 142 | (pop3-send-streaming-command | ||
| 143 | process "RETR" message-count message-total-size) | ||
| 144 | (pop3-write-to-file file) | ||
| 145 | (unless pop3-leave-mail-on-server | ||
| 146 | (pop3-send-streaming-command | ||
| 147 | process "DELE" message-count nil)) | ||
| 148 | (pop3-quit process))))) | ||
| 149 | |||
| 150 | (defun pop3-send-streaming-command (process command count total-size) | ||
| 151 | (erase-buffer) | ||
| 152 | (let ((i 1)) | ||
| 153 | (while (>= (1+ count) i) | ||
| 154 | (process-send-string process (format "%s %d\r\n" command i)) | ||
| 155 | ;; Only do 100 messages at a time to avoid pipe stalls. | ||
| 156 | (when (zerop (% i 100)) | ||
| 157 | (pop3-wait-for-messages process i total-size)) | ||
| 158 | (incf i))) | ||
| 159 | (pop3-wait-for-messages process count total-size)) | ||
| 160 | |||
| 161 | (defun pop3-wait-for-messages (process count total-size) | ||
| 162 | (while (< (pop3-number-of-responses total-size) count) | ||
| 163 | (when total-size | ||
| 164 | (message "pop3 retrieved %dKB (%d%%)" | ||
| 165 | (truncate (/ (buffer-size) 1000)) | ||
| 166 | (truncate (* (/ (* (buffer-size) 1.0) | ||
| 167 | total-size) 100)))) | ||
| 168 | (nnheader-accept-process-output process))) | ||
| 169 | |||
| 170 | (defun pop3-write-to-file (file) | ||
| 171 | (let ((pop-buffer (current-buffer)) | ||
| 172 | (start (point-min)) | ||
| 173 | beg end | ||
| 174 | temp-buffer) | ||
| 175 | (with-temp-buffer | ||
| 176 | (setq temp-buffer (current-buffer)) | ||
| 177 | (with-current-buffer pop-buffer | ||
| 178 | (goto-char (point-min)) | ||
| 179 | (while (re-search-forward "^\\+OK" nil t) | ||
| 180 | (forward-line 1) | ||
| 181 | (setq beg (point)) | ||
| 182 | (when (re-search-forward "^\\.\r?\n" nil t) | ||
| 183 | (setq start (point)) | ||
| 184 | (forward-line -1) | ||
| 185 | (setq end (point))) | ||
| 186 | (with-current-buffer temp-buffer | ||
| 187 | (goto-char (point-max)) | ||
| 188 | (let ((hstart (point))) | ||
| 189 | (insert-buffer-substring pop-buffer beg end) | ||
| 190 | (pop3-clean-region hstart (point)) | ||
| 191 | (goto-char (point-max)) | ||
| 192 | (pop3-munge-message-separator hstart (point)) | ||
| 193 | (goto-char (point-max)))))) | ||
| 194 | (let ((coding-system-for-write 'binary)) | ||
| 195 | (goto-char (point-min)) | ||
| 196 | ;; Check whether something inserted a newline at the start and | ||
| 197 | ;; delete it. | ||
| 198 | (when (eolp) | ||
| 199 | (delete-char 1)) | ||
| 200 | (write-region (point-min) (point-max) file))))) | ||
| 201 | |||
| 202 | (defun pop3-number-of-responses (endp) | ||
| 203 | (let ((responses 0)) | ||
| 204 | (save-excursion | ||
| 205 | (goto-char (point-min)) | ||
| 206 | (while (or (and (re-search-forward "^\\+OK " nil t) | ||
| 207 | (or (not endp) | ||
| 208 | (re-search-forward "^\\.\r?\n" nil t))) | ||
| 209 | (re-search-forward "^-ERR " nil t)) | ||
| 210 | (incf responses))) | ||
| 211 | responses)) | ||
| 212 | |||
| 213 | (defun pop3-logon (process) | ||
| 214 | (let ((pop3-password pop3-password)) | ||
| 140 | ;; for debugging only | 215 | ;; for debugging only |
| 141 | (if pop3-debug (switch-to-buffer (process-buffer process))) | 216 | (if pop3-debug (switch-to-buffer (process-buffer process))) |
| 142 | ;; query for password | 217 | ;; query for password |
| @@ -148,10 +223,19 @@ Shorter values mean quicker response, but are more CPU intensive.") | |||
| 148 | ((equal 'pass pop3-authentication-scheme) | 223 | ((equal 'pass pop3-authentication-scheme) |
| 149 | (pop3-user process pop3-maildrop) | 224 | (pop3-user process pop3-maildrop) |
| 150 | (pop3-pass process)) | 225 | (pop3-pass process)) |
| 151 | (t (error "Invalid POP3 authentication scheme"))) | 226 | (t (error "Invalid POP3 authentication scheme"))))) |
| 227 | |||
| 228 | (defun pop3-movemail (&optional crashbox) | ||
| 229 | "Transfer contents of a maildrop to the specified CRASHBOX." | ||
| 230 | (or crashbox (setq crashbox (expand-file-name "~/.crashbox"))) | ||
| 231 | (let* ((process (pop3-open-server pop3-mailhost pop3-port)) | ||
| 232 | (crashbuf (get-buffer-create " *pop3-retr*")) | ||
| 233 | (n 1) | ||
| 234 | message-count | ||
| 235 | message-sizes) | ||
| 236 | (pop3-logon process) | ||
| 152 | (setq message-count (car (pop3-stat process))) | 237 | (setq message-count (car (pop3-stat process))) |
| 153 | (when (and pop3-display-message-size-flag | 238 | (when (> message-count 0) |
| 154 | (> message-count 0)) | ||
| 155 | (setq message-sizes (pop3-list process))) | 239 | (setq message-sizes (pop3-list process))) |
| 156 | (unwind-protect | 240 | (unwind-protect |
| 157 | (while (<= n message-count) | 241 | (while (<= n message-count) |
| @@ -277,16 +361,11 @@ Returns the process associated with the connection." | |||
| 277 | (setq pop3-timestamp | 361 | (setq pop3-timestamp |
| 278 | (substring response (or (string-match "<" response) 0) | 362 | (substring response (or (string-match "<" response) 0) |
| 279 | (+ 1 (or (string-match ">" response) -1))))) | 363 | (+ 1 (or (string-match ">" response) -1))))) |
| 364 | (set-process-query-on-exit-flag process nil) | ||
| 280 | process))) | 365 | process))) |
| 281 | 366 | ||
| 282 | ;; Support functions | 367 | ;; Support functions |
| 283 | 368 | ||
| 284 | (defun pop3-process-filter (process output) | ||
| 285 | (save-excursion | ||
| 286 | (set-buffer (process-buffer process)) | ||
| 287 | (goto-char (point-max)) | ||
| 288 | (insert output))) | ||
| 289 | |||
| 290 | (defun pop3-send-command (process command) | 369 | (defun pop3-send-command (process command) |
| 291 | (set-buffer (process-buffer process)) | 370 | (set-buffer (process-buffer process)) |
| 292 | (goto-char (point-max)) | 371 | (goto-char (point-max)) |
| @@ -403,10 +482,7 @@ If NOW, use that time instead." | |||
| 403 | nil | 482 | nil |
| 404 | (goto-char (point-max)) | 483 | (goto-char (point-max)) |
| 405 | (insert "\n")) | 484 | (insert "\n")) |
| 406 | (narrow-to-region (point) (point-max)) | 485 | (let ((size (- (point-max) (point)))) |
| 407 | (let ((size (- (point-max) (point-min)))) | ||
| 408 | (goto-char (point-min)) | ||
| 409 | (widen) | ||
| 410 | (forward-line -1) | 486 | (forward-line -1) |
| 411 | (insert (format "Content-Length: %s\n" size))) | 487 | (insert (format "Content-Length: %s\n" size))) |
| 412 | ))))) | 488 | ))))) |