X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fpop3.el;h=a07b80573b016346a8ab982f096a77ce0eb14e56;hb=5ba80bd14f5c16af56d84c4c97b4be4094c257ee;hp=685fefbb834743943a36dd28ece852a5e09b5a9d;hpb=4a9268a5cbbcc7c74fc6fa94d7a3409cda1d6dbf;p=elisp%2Fgnus.git- diff --git a/lisp/pop3.el b/lisp/pop3.el index 685fefb..a07b805 100644 --- a/lisp/pop3.el +++ b/lisp/pop3.el @@ -1,11 +1,10 @@ ;;; pop3.el --- Post Office Protocol (RFC 1460) interface -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 -;; Free Software Foundation, Inc. +;; Copyright (C) 1996,1997,1998 Free Software Foundation, Inc. ;; Author: Richard L. Pieri -;; Maintainer: FSF -;; Keywords: mail +;; Keywords: mail, pop3 +;; Version: 1.3m+ ;; This file is part of GNU Emacs. @@ -36,6 +35,9 @@ ;;; Code: (require 'mail-utils) +(provide 'pop3) + +(defconst pop3-version "1.3m+") (defvar pop3-maildrop (or (user-login-name) (getenv "LOGNAME") (getenv "USER") nil) "*POP3 maildrop.") @@ -81,70 +83,47 @@ Used for APOP authentication.") ((equal 'pass pop3-authentication-scheme) (pop3-user process pop3-maildrop) (pop3-pass process)) - (t (error "Invalid POP3 authentication scheme"))) + (t (error "Invalid POP3 authentication scheme."))) (setq message-count (car (pop3-stat process))) - (unwind-protect - (while (<= n message-count) - (message (format "Retrieving message %d of %d from %s..." - n message-count pop3-mailhost)) - (pop3-retr process n crashbuf) - (save-excursion - (set-buffer crashbuf) - (let ((coding-system-for-write 'binary)) - (write-region (point-min) (point-max) crashbox t 'nomesg)) - (set-buffer (process-buffer process)) - (while (> (buffer-size) 5000) - (goto-char (point-min)) - (forward-line 50) - (delete-region (point-min) (point)))) - (pop3-dele process n) - (setq n (+ 1 n)) - (if pop3-debug (sit-for 1) (sit-for 0.1)) - ) - (pop3-quit process)) + (while (<= n message-count) + (message (format "Retrieving message %d of %d from %s..." + n message-count pop3-mailhost)) + (pop3-retr process n crashbuf) + (save-excursion + (set-buffer crashbuf) + (write-region-as-binary (point-min) (point-max) crashbox 'append) + (set-buffer (process-buffer process)) + (while (> (buffer-size) 5000) + (goto-char (point-min)) + (forward-line 50) + (delete-region (point-min) (point)))) + (pop3-dele process n) + (setq n (+ 1 n)) + (if pop3-debug (sit-for 1) (sit-for 0.1)) + ) + (pop3-quit process) (kill-buffer crashbuf) ) - t) - -(defun pop3-get-message-count () - "Return the number of messages in the maildrop." - (let* ((process (pop3-open-server pop3-mailhost pop3-port)) - message-count - (pop3-password pop3-password) - ) - ;; for debugging only - (if pop3-debug (switch-to-buffer (process-buffer process))) - ;; query for password - (if (and pop3-password-required (not pop3-password)) - (setq pop3-password - (pop3-read-passwd (format "Password for %s: " pop3-maildrop)))) - (cond ((equal 'apop pop3-authentication-scheme) - (pop3-apop process pop3-maildrop)) - ((equal 'pass pop3-authentication-scheme) - (pop3-user process pop3-maildrop) - (pop3-pass process)) - (t (error "Invalid POP3 authentication scheme"))) - (setq message-count (car (pop3-stat process))) - (pop3-quit process) - message-count)) + ) (defun pop3-open-server (mailhost port) - "Open TCP connection to MAILHOST on PORT. + "Open TCP connection to MAILHOST. Returns the process associated with the connection." - (let ((coding-system-for-read 'binary) - (coding-system-for-write 'binary) - process) + (let ((process-buffer + (get-buffer-create (format "trace of POP session to %s" mailhost))) + (process)) (save-excursion - (set-buffer (get-buffer-create (concat " trace of POP session to " - mailhost))) + (set-buffer process-buffer) (erase-buffer) (setq pop3-read-point (point-min)) - (setq process (open-network-stream "POP"(current-buffer) mailhost port)) - (let ((response (pop3-read-response process t))) - (setq pop3-timestamp - (substring response (or (string-match "<" response) 0) - (+ 1 (or (string-match ">" response) -1))))) - process))) + ) + (setq process + (open-network-stream-as-binary "POP" process-buffer mailhost port)) + (let ((response (pop3-read-response process t))) + (setq pop3-timestamp + (substring response (or (string-match "<" response) 0) + (+ 1 (or (string-match ">" response) -1))))) + process)) ;; Support functions @@ -162,7 +141,8 @@ Returns the process associated with the connection." ;; (insert command "\r\n")) (setq pop3-read-point (point)) (goto-char (point-max)) - (process-send-string process (concat command "\r\n")) + (process-send-string process command) + (process-send-string process "\r\n") ) (defun pop3-read-response (process &optional return) @@ -188,10 +168,26 @@ Return the response string if optional second argument is non-nil." t) ))))) +(defun pop3-string-to-list (string &optional regexp) + "Chop up a string into a list." + (let ((list) + (regexp (or regexp " ")) + (string (if (string-match "\r" string) + (substring string 0 (match-beginning 0)) + string))) + (store-match-data nil) + (while string + (if (string-match regexp string) + (setq list (cons (substring string 0 (- (match-end 0) 1)) list) + string (substring string (match-end 0))) + (setq list (cons string list) + string nil))) + (nreverse list))) + (defvar pop3-read-passwd nil) (defun pop3-read-passwd (prompt) (if (not pop3-read-passwd) - (if (fboundp 'read-passwd) + (if (functionp 'read-passwd) (setq pop3-read-passwd 'read-passwd) (if (load "passwd" t) (setq pop3-read-passwd 'read-passwd) @@ -211,31 +207,9 @@ Return the response string if optional second argument is non-nil." (forward-char))) (set-marker end nil)) -(eval-when-compile (defvar parse-time-months)) - -;; Copied from message-make-date. -(defun pop3-make-date (&optional now) - "Make a valid date header. -If NOW, use that time instead." - (require 'parse-time) - (let* ((now (or now (current-time))) - (zone (nth 8 (decode-time now))) - (sign "+")) - (when (< zone 0) - (setq sign "-") - (setq zone (- zone))) - (concat - (format-time-string "%d" now) - ;; The month name of the %b spec is locale-specific. Pfff. - (format " %s " - (capitalize (car (rassoc (nth 4 (decode-time now)) - parse-time-months)))) - (format-time-string "%Y %H:%M:%S " now) - ;; We do all of this because XEmacs doesn't have the %z spec. - (format "%s%02d%02d" sign (/ zone 3600) (/ (% zone 3600) 60))))) - (defun pop3-munge-message-separator (start end) "Check to see if a message separator exists. If not, generate one." + (if (not (fboundp 'message-make-date)) (autoload 'message-make-date "message")) (save-excursion (save-restriction (narrow-to-region start end) @@ -244,23 +218,17 @@ If NOW, use that time instead." (looking-at "\001\001\001\001\n") ; MMDF (looking-at "BABYL OPTIONS:") ; Babyl )) - (let* ((from (mail-strip-quoted-names (mail-fetch-field "From"))) - (tdate (mail-fetch-field "Date")) - (date (split-string (or (and tdate - (not (string= "" tdate)) - tdate) - (pop3-make-date)) - " ")) - (From_)) + (let ((from (mail-strip-quoted-names (mail-fetch-field "From"))) + (date (pop3-string-to-list (or (mail-fetch-field "Date") + (message-make-date)))) + (From_)) ;; sample date formats I have seen ;; Date: Tue, 9 Jul 1996 09:04:21 -0400 (EDT) ;; Date: 08 Jul 1996 23:22:24 -0400 ;; should be ;; Tue Jul 9 09:04:21 1996 (setq date - (cond ((not date) - "Tue Jan 1 00:00:0 1900") - ((string-match "[A-Z]" (nth 0 date)) + (cond ((string-match "[A-Z]" (nth 0 date)) (format "%s %s %s %s %s" (nth 0 date) (nth 2 date) (nth 1 date) (nth 4 date) (nth 3 date))) @@ -276,18 +244,7 @@ If NOW, use that time instead." (setq From_ (concat (substring From_ 0 (match-beginning 0)) (substring From_ (match-end 0))))) (goto-char (point-min)) - (insert From_) - (if (search-forward "\n\n" nil t) - nil - (goto-char (point-max)) - (insert "\n")) - (narrow-to-region (point) (point-max)) - (let ((size (- (point-max) (point-min)))) - (goto-char (point-min)) - (widen) - (forward-line -1) - (insert (format "Content-Length: %s\n" size))) - ))))) + (insert From_)))))) ;; The Command Set @@ -298,7 +255,7 @@ If NOW, use that time instead." (pop3-send-command process (format "USER %s" user)) (let ((response (pop3-read-response process t))) (if (not (and response (string-match "+OK" response))) - (error (format "USER %s not valid" user))))) + (error (format "USER %s not valid." user))))) (defun pop3-pass (process) "Send authentication information to the server." @@ -309,42 +266,21 @@ If NOW, use that time instead." (defun pop3-apop (process user) "Send alternate authentication information to the server." - (let ((pass pop3-password)) - (if (and pop3-password-required (not pass)) - (setq pass - (pop3-read-passwd (format "Password for %s: " pop3-maildrop)))) - (if pass - (let ((hash (pop3-md5 (concat pop3-timestamp pass)))) - (pop3-send-command process (format "APOP %s %s" user hash)) - (let ((response (pop3-read-response process t))) - (if (not (and response (string-match "+OK" response))) - (pop3-quit process))))) - )) + (if (not (fboundp 'md5)) (autoload 'md5 "md5")) + (let ((hash (md5 (concat pop3-timestamp pop3-password)))) + (pop3-send-command process (format "APOP %s %s" user hash)) + (let ((response (pop3-read-response process t))) + (if (not (and response (string-match "+OK" response))) + (pop3-quit process))))) ;; TRANSACTION STATE -(eval-and-compile - (if (fboundp 'md5) - (defalias 'pop3-md5 'md5) - (defvar pop3-md5-program "md5" - "*Program to encode its input in MD5.") - - (defun pop3-md5 (string) - (with-temp-buffer - (insert string) - (call-process-region (point-min) (point-max) - pop3-md5-program - t (current-buffer) nil) - ;; The meaningful output is the first 32 characters. - ;; Don't return the newline that follows them! - (buffer-substring (point-min) (+ 32 (point-min))))))) - (defun pop3-stat (process) "Return the number of messages in the maildrop and the maildrop's size." (pop3-send-command process "STAT") (let ((response (pop3-read-response process t))) - (list (string-to-int (nth 1 (split-string response " "))) - (string-to-int (nth 2 (split-string response " ")))) + (list (string-to-int (nth 1 (pop3-string-to-list response))) + (string-to-int (nth 2 (pop3-string-to-list response)))) )) (defun pop3-list (process &optional msg) @@ -406,7 +342,7 @@ This function currently does nothing.") "Return highest accessed message-id number for the session." (pop3-send-command process "LAST") (let ((response (pop3-read-response process t))) - (string-to-int (nth 1 (split-string response " "))) + (string-to-int (nth 1 (pop3-string-to-list response))) )) (defun pop3-rset (process) @@ -507,7 +443,3 @@ and close the connection." ;; Restrictions: none ;; Possible responses: ;; +OK [TCP connection closed] - -(provide 'pop3) - -;;; pop3.el ends here