Import Oort Gnus v0.16.
[elisp/gnus.git-] / lisp / nntp.el
index ca1c917..2927dc6 100644 (file)
@@ -1,7 +1,7 @@
 ;;; nntp.el --- nntp access for Gnus
 
 ;; Copyright (C) 1987, 1988, 1989, 1990, 1992, 1993, 1994, 1995, 1996,
-;; 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
@@ -207,6 +207,13 @@ NOTE: This variable is never seen to work in Emacs 20 and XEmacs 21.")
   "*Hook run just before posting an article.  It is supposed to be used
 to insert Cancel-Lock headers.")
 
+(defvoo nntp-read-timeout (if (string-match "windows-nt\\|os/2\\|emx\\|cygwin"
+                                           (symbol-name system-type))
+                             1.0
+                           0.1)
+  "How long nntp should wait between checking for the end of output.
+Shorter values mean quicker response, but is more CPU intensive.")
+
 ;;; Internal variables.
 
 (defvar nntp-record-commands nil
@@ -247,9 +254,12 @@ noticing asynchronous data.")
 (defvar nntp-async-timer nil)
 (defvar nntp-async-process-list nil)
 
-(eval-and-compile
-  (autoload 'mail-source-read-passwd "mail-source")
-  (autoload 'open-ssl-stream "ssl"))
+(defvar nntp-ssl-program 
+  "openssl s_client -quiet -ssl3 -connect %s:%p"
+"A string containing commands for SSL connections.
+Within a string, %s is replaced with the server address and %p with
+port number on server.  The program should accept IMAP commands on
+stdin and return responses to stdout.")
 
 \f
 
@@ -576,17 +586,15 @@ command whose response triggered the error."
                                              nntp-server-buffer))
                                    (buffer  (and process
                                                  (process-buffer process))))
-                                       ; when I an able to identify
-                                       ; the connection to the server
-                                       ; AND I've received NO reponse
-                                       ; for nntp-connection-timeout
-                                       ; seconds.
+                               ;; When I an able to identify the
+                               ;; connection to the server AND I've
+                               ;; received NO reponse for
+                               ;; nntp-connection-timeout seconds.
                                (when (and buffer (eq 0 (buffer-size buffer)))
-                                       ; Close the connection.  Take
-                                       ; no other action as the
-                                       ; accept input code will
-                                       ; handle the closed
-                                       ; connection.
+                                 ;; Close the connection.  Take no
+                                 ;; other action as the accept input
+                                 ;; code will handle the closed
+                                 ;; connection.
                                  (nntp-kill-buffer buffer))))))))
                (unwind-protect
                    (setq nntp-with-open-group-internal
@@ -594,8 +602,7 @@ command whose response triggered the error."
                              (progn ,@forms)
                            (quit
                             (nntp-close-server)
-                             (signal 'quit nil)))
-                          )
+                             (signal 'quit nil))))
                  (when timer
                    (nnheader-cancel-timer timer)))
                nil))
@@ -729,7 +736,8 @@ command whose response triggered the error."
                            (set-buffer buf)
                            (goto-char (point-max))
                            (if (not nntp-server-list-active-group)
-                               (not (re-search-backward "\r?\n" (- (point) 3) t))
+                               (not (re-search-backward "\r?\n"
+                                                       (- (point) 3) t))
                              (not (re-search-backward "^\\.\r?\n"
                                                       (- (point) 4) t)))))
                (nntp-accept-response)))
@@ -1037,9 +1045,8 @@ If SEND-IF-FORCE, only send authinfo to the server if the
           (or passwd
               nntp-authinfo-password
               (setq nntp-authinfo-password
-                    (mail-source-read-passwd
-                     (format "NNTP (%s@%s) password: "
-                             user nntp-address))))))))))
+                    (read-passwd (format "NNTP (%s@%s) password: "
+                                         user nntp-address))))))))))
 
 (defun nntp-send-nosy-authinfo ()
   "Send the AUTHINFO to the nntp server."
@@ -1048,8 +1055,8 @@ If SEND-IF-FORCE, only send authinfo to the server if the
       (nntp-send-command "^3.*\r?\n" "AUTHINFO USER" user)
       (when t                          ;???Should check if AUTHINFO succeeded
        (nntp-send-command "^2.*\r?\n" "AUTHINFO PASS"
-                          (mail-source-read-passwd "NNTP (%s@%s) password: "
-                                                   user nntp-address))))))
+                          (read-passwd (format "NNTP (%s@%s) password: "
+                                               user nntp-address)))))))
 
 (defun nntp-send-authinfo-from-file ()
   "Send the AUTHINFO to the nntp server.
@@ -1063,7 +1070,7 @@ password contained in '~/.nntp-authinfo'."
       (nntp-send-command "^3.*\r?\n" "AUTHINFO USER" (user-login-name))
       (nntp-send-command
        "^2.*\r?\n" "AUTHINFO PASS"
-       (buffer-substring (point) (progn (end-of-line) (point)))))))
+       (buffer-substring (point) (gnus-point-at-eol))))))
 
 ;;; Internal functions.
 
@@ -1143,7 +1150,15 @@ password contained in '~/.nntp-authinfo'."
   (open-network-stream "nntpd" buffer nntp-address nntp-port-number))
 
 (defun nntp-open-ssl-stream (buffer)
-  (let ((proc (open-ssl-stream "nntpd" buffer nntp-address nntp-port-number)))
+  (let* ((process-connection-type nil)
+        (proc (start-process "nntpd" buffer 
+                             shell-file-name
+                             shell-command-switch
+                             (format-spec nntp-ssl-program 
+                                          (format-spec-make
+                                           ?s nntp-address
+                                           ?p nntp-port-number)))))
+    (process-kill-without-query proc)
     (save-excursion
       (set-buffer buffer)
       (nntp-wait-for-string "^\r*20[01]")
@@ -1270,25 +1285,28 @@ password contained in '~/.nntp-authinfo'."
     (nnheader-report 'nntp message)
     message))
 
-(defun nntp-accept-process-output (process &optional timeout)
+(defun nntp-accept-process-output (process)
   "Wait for output from PROCESS and message some dots."
   (save-excursion
     (set-buffer (or (nntp-find-connection-buffer nntp-server-buffer)
                    nntp-server-buffer))
-    (let ((len (/ (point-max) 1024))
+    (let ((len (/ (buffer-size) 1024))
          message-log-max)
       (unless (< len 10)
        (setq nntp-have-messaged t)
        (nnheader-message 7 "nntp read: %dk" len)))
-    (if timeout
-       (accept-process-output process timeout)
-      (accept-process-output process 0 100))
+    (accept-process-output
+     process
+     (truncate nntp-read-timeout)
+     (truncate (* (- nntp-read-timeout
+                    (truncate nntp-read-timeout))
+                 1000)))
     ;; accept-process-output may update status of process to indicate
     ;; that the server has closed the connection.  This MUST be
     ;; handled here as the buffer restored by the save-excursion may
     ;; be the process's former output buffer (i.e. now killed)
     (or (and process 
-            (memq (process-status process) '(open run)))
+            (memq (process-status process) '(open run)))
         (nntp-report "Server closed connection"))))
 
 (defun nntp-accept-response ()
@@ -1307,16 +1325,18 @@ password contained in '~/.nntp-authinfo'."
 
   (when group
     (let ((entry (nntp-find-connection-entry nntp-server-buffer)))
-      (when (not (equal group (caddr entry)))
-       (save-excursion
-         (set-buffer (process-buffer (car entry)))
-         (erase-buffer)
-         (nntp-send-command "^[245].*\n" "GROUP" group)
-         (setcar (cddr entry) group)
-         (erase-buffer)
-         (save-excursion
-           (set-buffer nntp-server-buffer)
-           (erase-buffer)))))))
+      (cond ((not entry)
+             (nntp-report "Server closed connection"))
+            ((not (equal group (caddr entry)))
+             (save-excursion
+               (set-buffer (process-buffer (car entry)))
+               (erase-buffer)
+               (nntp-send-command "^[245].*\n" "GROUP" group)
+               (setcar (cddr entry) group)
+               (erase-buffer)
+               (save-excursion
+                 (set-buffer nntp-server-buffer)
+                 (erase-buffer))))))))
 
 (defun nntp-decode-text (&optional cr-only)
   "Decode the text in the current buffer."
@@ -1438,12 +1458,13 @@ password contained in '~/.nntp-authinfo'."
                     (while (re-search-forward "^[0-9][0-9][0-9] .*\n" nil t)
                       (incf received))
                     (setq last-point (point))
-                    (or (< received count) ;; I haven't started reading the final response
+                    (or (< received count)
+                        ;; I haven't started reading the final response
                          (progn
                            (goto-char (point-max))
                            (forward-line -1)
-                           (not (looking-at "^\\.\r?\n"))) ;; I haven't read the end of the final response
-                         ))
+                           (not (looking-at "^\\.\r?\n")))))
+             ;; I haven't read the end of the final response
              (nntp-accept-response)
              (set-buffer process-buffer))))
 
@@ -1461,8 +1482,9 @@ password contained in '~/.nntp-authinfo'."
         (when (<= count 1)
           (goto-char (point-min))
           (when (re-search-forward "^[0-9][0-9][0-9] .*\n\\([0-9]+\\)" nil t)
-            (let ((low-limit (string-to-int (buffer-substring (match-beginning 1) 
-                                                              (match-end 1)))))
+            (let ((low-limit (string-to-int
+                             (buffer-substring (match-beginning 1) 
+                                               (match-end 1)))))
               (while (and articles (<= (car articles) low-limit))
                 (setq articles (cdr articles))))))
         (set-buffer buf))
@@ -1659,7 +1681,7 @@ via telnet.")
         proc (concat
               (or nntp-telnet-passwd
                   (setq nntp-telnet-passwd
-                        (mail-source-read-passwd "Password: ")))
+                        (read-passwd "Password: ")))
               "\n"))
        (nntp-wait-for-string nntp-telnet-shell-prompt)
        (process-send-string
@@ -1811,8 +1833,7 @@ Please refer to the following variables to customize the connection:
                             (concat
                              (or nntp-via-user-password
                                  (setq nntp-via-user-password
-                                       (mail-source-read-passwd
-                                        "Password: ")))
+                                       (read-passwd "Password: ")))
                              "\n"))
        (nntp-wait-for-string nntp-via-shell-prompt)
        (let ((real-telnet-command `("exec"