;;; 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
Direct connections:
- `nntp-open-network-stream' (the default),
- `nntp-open-ssl-stream',
+- `nntp-open-tls-stream',
- `nntp-open-telnet-stream'.
Indirect connections:
"*Switches given to the rlogin command `nntp-via-rlogin-command'.
If you use \"ssh\" for `nntp-via-rlogin-command', you may set this to
\(\"-C\") in order to compress all data connections, otherwise set this
-to \(\"-t\") or (\"-C\" \"-t\") if the telnet command requires a pseudo-tty
-allocation on an intermediate host.")
+to \(\"-t\" \"-e\" \"none\") or (\"-C\" \"-t\" \"-e\" \"none\") if the telnet
+command requires a pseudo-tty allocation on an intermediate host.")
(defvoo nntp-via-telnet-command "telnet"
"*Telnet command used to connect to an intermediate host.
This variable is used by the `nntp-open-via-telnet-and-telnet' method.")
(defvoo nntp-large-newsgroup 50
- "*The number of the articles which indicates a large newsgroup.
-If the number of the articles is greater than the value, verbose
+ "*The number of articles which indicates a large newsgroup.
+If the number of articles is greater than the value, verbose
messages will be shown to indicate the current status.")
(defvoo nntp-maximum-request 400
(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
(goto-char pos)
(if (looking-at (regexp-quote command))
(delete-region pos (progn (forward-line 1)
- (gnus-point-at-bol))))
- )))
+ (gnus-point-at-bol)))))))
(nnheader-report 'nntp "Couldn't open connection to %s."
nntp-address))))
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
(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."
(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.
(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.
(defun nntp-open-network-stream (buffer)
(open-network-stream "nntpd" buffer nntp-address nntp-port-number))
+(autoload 'format-spec "format")
+(autoload 'format-spec-make "format")
+(autoload 'open-tls-stream "tls")
+
(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]")
+ (let ((nntp-connection-alist (list proc buffer nil)))
+ (nntp-wait-for-string "^\r*20[01]"))
+ (beginning-of-line)
+ (delete-region (point-min) (point))
+ proc)))
+
+(defun nntp-open-tls-stream (buffer)
+ (let ((proc (open-tls-stream "nntpd" buffer nntp-address nntp-port-number)))
+ (process-kill-without-query proc)
+ (save-excursion
+ (set-buffer buffer)
+ (let ((nntp-connection-alist (list proc buffer nil)))
+ (nntp-wait-for-string "^\r*20[01]"))
(beginning-of-line)
(delete-region (point-min) (point))
proc)))
(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))
+ (nnheader-accept-process-output process)
;; 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 ()
(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."
in-process-buffer-p
(buf nntp-server-buffer)
(process-buffer (nntp-find-connection-buffer nntp-server-buffer))
- first
- last)
+ first last status)
;; We have to check `nntp-server-xover'. If it gets set to nil,
;; that means that the server does not understand XOVER, but we
;; won't know that until we try.
(while (progn
(goto-char (or last-point (point-min)))
;; Count replies.
- (while (re-search-forward "^[0-9][0-9][0-9] .*\n" nil t)
- (incf received))
+ (while (re-search-forward "^\\([0-9][0-9][0-9]\\) .*\n"
+ nil t)
+ (incf received)
+ (setq status (match-string 1))
+ (if (string-match "^[45]" status)
+ (setq status 'error)
+ (setq status 'ok)))
(setq last-point (point))
(or (< received count)
- ;; I haven't started reading the final response
- (progn
- (goto-char (point-max))
- (forward-line -1)
- (not (looking-at "^\\.\r?\n")))))
+ (if (eq status 'error)
+ nil
+ ;; 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
(nntp-accept-response)
(set-buffer process-buffer))))
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
(nntp-wait-for-string "^\r*20[01]")
(beginning-of-line)
(delete-region (point-min) (point))
- proc)))
+ (process-send-string proc "\^]")
+ (nntp-wait-for-string "^r?telnet")
+ (process-send-string proc "mode character\n")
+ (accept-process-output proc 1)
+ (sit-for 1)
+ (goto-char (point-min))
+ (forward-line 1)
+ (delete-region (point) (point-max)))
+ proc))
(defun nntp-open-via-telnet-and-telnet (buffer)
"Open a connection to an nntp server through an intermediate host.
(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"