X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fpop3.el;h=dd88de3d0c350f00a50b0d802b9b146534c780fa;hb=3ad5943c4ad67b4f8d556436b31c3ca8bc4b5064;hp=391d5b85240cc14c3abb20ecc9bc3122f7919256;hpb=7ebf974f6bac5c2f61e7c7cda2962fa4d8766b81;p=elisp%2Fgnus.git- diff --git a/lisp/pop3.el b/lisp/pop3.el index 391d5b8..dd88de3 100644 --- a/lisp/pop3.el +++ b/lisp/pop3.el @@ -1,10 +1,11 @@ ;;; pop3.el --- Post Office Protocol (RFC 1460) interface -;; Copyright (C) 1996,1997,1998 Free Software Foundation, Inc. +;; Copyright (C) 1996, 97, 98, 1999 Free Software Foundation, Inc. ;; Author: Richard L. Pieri -;; Keywords: mail, pop3 -;; Version: 1.3m +;; Maintainer: FSF +;; Keywords: mail +;; Version: 1.3s ;; This file is part of GNU Emacs. @@ -35,9 +36,8 @@ ;;; Code: (require 'mail-utils) -(provide 'pop3) -(defconst pop3-version "1.3m") +(defconst pop3-version "1.3s") (defvar pop3-maildrop (or (user-login-name) (getenv "LOGNAME") (getenv "USER") nil) "*POP3 maildrop.") @@ -60,6 +60,9 @@ values are 'apop.") "Timestamp returned when initially connected to the POP server. Used for APOP authentication.") +(defvar pop3-movemail-file-coding-system nil + "Coding system for the crashbox made by `pop3-movemail'.") + (defvar pop3-read-point nil) (defvar pop3-debug nil) @@ -83,51 +86,48 @@ 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))) - (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) - (append-to-file (point-min) (point-max) crashbox) - (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) + (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 pop3-movemail-file-coding-system)) + (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)) (kill-buffer crashbuf) ) t) (defun pop3-open-server (mailhost port) - "Open TCP connection to MAILHOST. + "Open TCP connection to MAILHOST on PORT. Returns the process associated with the connection." - (let ((process-buffer - (get-buffer-create (format "trace of POP session to %s" mailhost))) - (process) - (coding-system-for-read 'binary) ;; because FSF Emacs 20 and - (coding-system-for-write 'binary) ;; XEmacs 20/1 are st00pid - ) + (let ((coding-system-for-read 'binary) + (coding-system-for-write 'binary) + process) (save-excursion - (set-buffer process-buffer) + (set-buffer (get-buffer-create (concat " trace of POP session to %s" + mailhost))) (erase-buffer) (setq pop3-read-point (point-min)) - ) - (setq process - (open-network-stream "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 - )) + (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))) ;; Support functions @@ -145,8 +145,7 @@ Returns the process associated with the connection." ;; (insert command "\r\n")) (setq pop3-read-point (point)) (goto-char (point-max)) - (process-send-string process command) - (process-send-string process "\r\n") + (process-send-string process (concat command "\r\n")) ) (defun pop3-read-response (process &optional return) @@ -163,7 +162,7 @@ Return the response string if optional second argument is non-nil." (setq match-end (point)) (goto-char pop3-read-point) (if (looking-at "-ERR") - (signal 'error (list (buffer-substring (point) (- match-end 2)))) + (error (buffer-substring (point) (- match-end 2))) (if (not (looking-at "+OK")) (progn (setq pop3-read-point match-end) nil) (setq pop3-read-point match-end) @@ -172,29 +171,15 @@ 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 (load "passwd" t) + (if (fboundp 'read-passwd) (setq pop3-read-passwd 'read-passwd) - (autoload 'ange-ftp-read-passwd "ange-ftp") - (setq pop3-read-passwd 'ange-ftp-read-passwd))) + (if (load "passwd" t) + (setq pop3-read-passwd 'read-passwd) + (autoload 'ange-ftp-read-passwd "ange-ftp") + (setq pop3-read-passwd 'ange-ftp-read-passwd)))) (funcall pop3-read-passwd prompt)) (defun pop3-clean-region (start end) @@ -221,8 +206,9 @@ Return the response string if optional second argument is non-nil." (looking-at "BABYL OPTIONS:") ; Babyl )) (let ((from (mail-strip-quoted-names (mail-fetch-field "From"))) - (date (pop3-string-to-list (or (mail-fetch-field "Date") - (message-make-date)))) + (date (split-string (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) @@ -246,7 +232,15 @@ Return the response string if optional second argument is non-nil." (setq From_ (concat (substring From_ 0 (match-beginning 0)) (substring From_ (match-end 0))))) (goto-char (point-min)) - (insert From_)))))) + (insert From_) + (re-search-forward "\n\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))) + ))))) ;; The Command Set @@ -268,21 +262,40 @@ Return the response string if optional second argument is non-nil." (defun pop3-apop (process user) "Send alternate authentication information to the server." - (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))))) + (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))))) + )) ;; TRANSACTION STATE +(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) + (or shell-file-name "/bin/sh") + t (current-buffer) nil + "-c" pop3-md5-program) + ;; The meaningful output is the first 32 characters. + ;; Don't return the newline that follows them! + (buffer-substring (point-min) (+ (point-min) 32)))) + (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 (pop3-string-to-list response))) - (string-to-int (nth 2 (pop3-string-to-list response)))) + (list (string-to-int (nth 1 (split-string response " "))) + (string-to-int (nth 2 (split-string response " ")))) )) (defun pop3-list (process &optional msg) @@ -344,7 +357,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 (pop3-string-to-list response))) + (string-to-int (nth 1 (split-string response " "))) )) (defun pop3-rset (process) @@ -445,3 +458,7 @@ and close the connection." ;; Restrictions: none ;; Possible responses: ;; +OK [TCP connection closed] + +(provide 'pop3) + +;;; pop3.el ends here