48
|
1 ;; Copyright (C) 1985, 1988 Free Software Foundation, Inc.
|
|
2
|
|
3 ;; This file is part of GNU Emacs.
|
|
4
|
|
5 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
6 ;; it under the terms of the GNU General Public License as published by
|
|
7 ;; the Free Software Foundation; either version 1, or (at your option)
|
|
8 ;; any later version.
|
|
9
|
|
10 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 ;; GNU General Public License for more details.
|
|
14
|
|
15 ;; You should have received a copy of the GNU General Public License
|
|
16 ;; along with GNU Emacs; see the file COPYING. If not, write to
|
|
17 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
18
|
|
19 ;; Author William F. Schelter
|
|
20
|
|
21 ;;to do fix software types for lispm:
|
|
22 ;;to eval current expression. Also to try to send escape keys correctly.
|
|
23 ;;essentially we'll want the rubout-handler off.
|
|
24
|
|
25 ;; filter is simplistic but should be okay for typical shell usage.
|
|
26 ;; needs hacking if it is going to deal with asynchronous output in a sane
|
|
27 ;; manner
|
|
28
|
|
29 (require 'comint)
|
|
30 (provide 'telnet)
|
|
31
|
|
32 (defvar telnet-new-line "\r")
|
|
33 (defvar telnet-mode-map nil)
|
|
34 (defvar telnet-prompt-pattern "^[^#$%>]*[#$%>] *")
|
|
35 (defvar telnet-replace-c-g nil)
|
|
36 (make-variable-buffer-local
|
|
37 (defvar telnet-remote-echoes t
|
|
38 "True if the telnet process will echo input."))
|
|
39 (make-variable-buffer-local
|
|
40 (defvar telnet-interrupt-string "\C-c" "String sent by C-c."))
|
|
41
|
|
42 (defvar telnet-count 0
|
|
43 "Number of output strings read from the telnet process
|
|
44 while looking for the initial password.")
|
|
45
|
|
46 (defvar telnet-initial-count -50
|
|
47 "Initial value of telnet-count. Should be set to the negative of the
|
|
48 number of terminal writes telnet will make setting up the host connection.")
|
|
49
|
|
50 (defvar telnet-maximum-count 4
|
|
51 "Maximum value telnet-count can have.
|
|
52 After this many passes, we stop looking for initial setup data.
|
|
53 Should be set to the number of terminal writes telnet will make
|
|
54 rejecting one login and prompting for the again for a username and password.")
|
|
55
|
|
56 (defun telnet-interrupt-subjob ()
|
|
57 (interactive)
|
|
58 "Interrupt the program running through telnet on the remote host."
|
|
59 (send-string nil telnet-interrupt-string))
|
|
60
|
|
61 (defun telnet-c-z ()
|
|
62 (interactive)
|
|
63 (send-string nil "\C-z"))
|
|
64
|
|
65 (defun send-process-next-char ()
|
|
66 (interactive)
|
|
67 (send-string nil
|
|
68 (char-to-string
|
|
69 (let ((inhibit-quit t))
|
|
70 (prog1 (read-char)
|
|
71 (setq quit-flag nil))))))
|
|
72
|
|
73 ; initialization on first load.
|
|
74 (if telnet-mode-map
|
|
75 nil
|
|
76 (setq telnet-mode-map (copy-keymap comint-mode-map))
|
|
77 (define-key telnet-mode-map "\C-m" 'telnet-send-input)
|
|
78 ; (define-key telnet-mode-map "\C-j" 'telnet-send-input)
|
|
79 (define-key telnet-mode-map "\C-c\C-q" 'send-process-next-char)
|
|
80 (define-key telnet-mode-map "\C-c\C-c" 'telnet-interrupt-subjob)
|
|
81 (define-key telnet-mode-map "\C-c\C-z" 'telnet-c-z))
|
|
82
|
|
83 ;;maybe should have a flag for when have found type
|
|
84 (defun telnet-check-software-type-initialize (string)
|
|
85 "Tries to put correct initializations in. Needs work."
|
|
86 (let ((case-fold-search t))
|
|
87 (cond ((string-match "unix" string)
|
|
88 (setq telnet-prompt-pattern comint-prompt-regexp)
|
|
89 (setq telnet-new-line "\n"))
|
|
90 ((string-match "tops-20" string) ;;maybe add telnet-replace-c-g
|
|
91 (setq telnet-prompt-pattern "[@>]*"))
|
|
92 ((string-match "its" string)
|
|
93 (setq telnet-prompt-pattern "^[^*>]*[*>] *"))
|
|
94 ((string-match "explorer" string) ;;explorer telnet needs work
|
|
95 (setq telnet-replace-c-g ?\n))))
|
|
96 (setq comint-prompt-regexp telnet-prompt-pattern))
|
|
97
|
|
98 (defun telnet-initial-filter (proc string)
|
|
99 ;For reading up to and including password; also will get machine type.
|
|
100 (cond ((string-match "No such host" string)
|
|
101 (kill-buffer (process-buffer proc))
|
|
102 (error "No such host."))
|
|
103 ((string-match "passw" string)
|
|
104 (telnet-filter proc string)
|
|
105 (let* ((echo-keystrokes 0)
|
|
106 (password (read-password)))
|
|
107 (setq telnet-count 0)
|
|
108 (send-string proc (concat password telnet-new-line))))
|
|
109 (t (telnet-check-software-type-initialize string)
|
|
110 (telnet-filter proc string)
|
|
111 (cond ((> telnet-count telnet-maximum-count)
|
|
112 (set-process-filter proc 'telnet-filter))
|
|
113 (t (setq telnet-count (1+ telnet-count)))))))
|
|
114
|
|
115 (defun telnet-filter (proc string)
|
|
116 (let ((at-end
|
|
117 (and (eq (process-buffer proc) (current-buffer))
|
|
118 (= (point) (point-max)))))
|
|
119 (save-excursion
|
|
120 (set-buffer (process-buffer proc))
|
|
121 (goto-char (process-mark proc))
|
|
122 (let ((now (point)))
|
|
123 (let ((index 0) c-m)
|
|
124 (while (setq c-m (string-match "\C-m" string index))
|
|
125 (insert-before-markers (substring string index c-m))
|
|
126 (setq index (1+ c-m)))
|
|
127 (insert-before-markers (substring string index)))
|
|
128 (and telnet-replace-c-g
|
|
129 (subst-char-in-region now (point) ?\C-g telnet-replace-c-g)))
|
|
130 ; (if (and (integer-or-marker-p last-input-start)
|
|
131 ; (marker-position last-input-start)
|
|
132 ; telnet-remote-echoes)
|
|
133 ; (delete-region last-input-start last-input-end))
|
|
134 )
|
|
135 (if at-end
|
|
136 (goto-char (point-max)))))
|
|
137
|
|
138 (defun telnet-send-input ()
|
|
139 (interactive)
|
|
140 (comint-send-input telnet-new-line telnet-remote-echoes))
|
|
141
|
258
|
142 ;;;###autoload
|
48
|
143 (defun telnet (arg)
|
|
144 "Open a network login connection to host named HOST (a string).
|
|
145 Communication with HOST is recorded in a buffer *HOST-telnet*.
|
|
146 Normally input is edited in Emacs and sent a line at a time."
|
|
147 (interactive "sOpen telnet connection to host: ")
|
|
148 (let ((name (concat arg "-telnet" )))
|
|
149 (switch-to-buffer (make-comint name "telnet"))
|
|
150 (set-process-filter (get-process name) 'telnet-initial-filter)
|
|
151 (erase-buffer)
|
|
152 (send-string name (concat "open " arg "\n"))
|
|
153 (telnet-mode)
|
|
154 (setq telnet-count telnet-initial-count)))
|
|
155
|
|
156 (defun telnet-mode ()
|
|
157 "This mode is for use during telnet from a buffer to another
|
|
158 host. It has most of the same commands as comint-mode.
|
|
159 There is a variable ``telnet-interrupt-string'' which is the character
|
|
160 sent to try to stop execution of a job on the remote host.
|
|
161 Data is sent to the remote host when RET is typed.
|
|
162
|
|
163 \\{telnet-mode-map}
|
|
164
|
|
165 Bugs:
|
|
166 --Replaces
by a space, really should remove."
|
|
167 (interactive)
|
|
168 (comint-mode)
|
|
169 (setq major-mode 'telnet-mode
|
|
170 mode-name "Telnet"
|
|
171 comint-prompt-regexp telnet-prompt-pattern)
|
|
172 (use-local-map telnet-mode-map)
|
|
173 (run-hooks 'telnet-mode-hook))
|
|
174
|
|
175 (defun read-password ()
|
|
176 (let ((answ "") tem)
|
|
177 (message "Reading password...")
|
|
178 (while (not (or (= (setq tem (read-char)) ?\^m)
|
|
179 (= tem ?\n)))
|
|
180 (setq answ (concat answ (char-to-string tem))))
|
|
181 answ))
|