Put isearch before menu-bar.
[bpt/emacs.git] / lisp / rlogin.el
CommitLineData
76550a57
ER
1;;; rlogin.el --- remote login interface
2
8ae3bc9f 3;; Author: Noah Friedman
76550a57 4;; Maintainer: Noah Friedman <friedman@prep.ai.mit.edu>
5d1dd3c0 5;; Keywords: unix, comm
76550a57 6
32992017 7;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
d9ecc911
ER
8;;
9;; This program is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
13;;
14;; This program is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
8d30fe17
NF
20;; along with this program; if not, write to: The Free Software Foundation,
21;; Inc.; 675 Massachusetts Avenue.; Cambridge, MA 02139, USA.
d9ecc911 22
965f7ac9 23;; $Id: rlogin.el,v 1.28 1995/05/12 17:51:12 roland Exp roland $
32992017 24
d9ecc911
ER
25;;; Commentary:
26
0b899bd2 27;; Support for remote logins using `rlogin'.
32992017
NF
28;; This program is layered on top of shell.el; the code here only accounts
29;; for the variations needed to handle a remote process, e.g. directory
30;; tracking and the sending of some special characters.
97b83d9d 31
d933a756
NF
32;; If you wish for rlogin mode to prompt you in the minibuffer for
33;; passwords when a password prompt appears, just enter m-x send-invisible
34;; and type in your line, or add `comint-watch-for-password-prompt' to
35;; `comint-output-filter-functions'.
c7986c18 36
76550a57
ER
37;;; Code:
38
c7986c18 39(require 'comint)
10939dc6 40(require 'shell)
c7986c18
ER
41
42(defvar rlogin-program "rlogin"
43 "*Name of program to invoke rlogin")
44
8d30fe17
NF
45(defvar rlogin-explicit-args nil
46 "*List of arguments to pass to rlogin on the command line.")
47
c7986c18
ER
48(defvar rlogin-mode-hook nil
49 "*Hooks to run after setting current buffer to rlogin-mode.")
50
8ae3bc9f 51(defvar rlogin-process-connection-type nil
2601d12e
NF
52 "*If non-`nil', use a pty for the local rlogin process.
53If `nil', use a pipe (if pipes are supported on the local system).
8d30fe17 54
8ae3bc9f
NF
55Generally it is better not to waste ptys on systems which have a static
56number of them. On the other hand, some implementations of `rlogin' assume
57a pty is being used, and errors will result from using a pipe instead.")
8d30fe17 58
32992017 59(defvar rlogin-directory-tracking-mode 'local
ce992678 60 "*Control whether and how to do directory tracking in an rlogin buffer.
32992017 61
ce992678 62nil means don't do directory tracking.
32992017 63
ce992678 64t means do so using an ftp remote file name.
32992017 65
ce992678
RS
66Any other value means do directory tracking using local file names.
67This works only if the remote machine and the local one
32992017
NF
68share the same directories (through NFS). This is the default.
69
70This variable becomes local to a buffer when set in any fashion for it.
71
72It is better to use the function of the same name to change the behavior of
73directory tracking in an rlogin session once it has begun, rather than
74simply setting this variable, since the function does the necessary
75re-synching of directories.")
76
77(make-variable-buffer-local 'rlogin-directory-tracking-mode)
78
79(defvar rlogin-host nil
80 "*The name of the remote host. This variable is buffer-local.")
81
82(defvar rlogin-remote-user nil
83 "*The username used on the remote host.
84This variable is buffer-local and defaults to your local user name.
85If rlogin is invoked with the `-l' option to specify the remote username,
86this variable is set from that.")
97b83d9d 87
c7986c18
ER
88;; Initialize rlogin mode map.
89(defvar rlogin-mode-map '())
2601d12e 90(cond
32992017
NF
91 ((null rlogin-mode-map)
92 (setq rlogin-mode-map (if (consp shell-mode-map)
93 (cons 'keymap shell-mode-map)
94 (copy-keymap shell-mode-map)))
95 (define-key rlogin-mode-map "\C-c\C-c" 'rlogin-send-Ctrl-C)
96 (define-key rlogin-mode-map "\C-c\C-d" 'rlogin-send-Ctrl-D)
97 (define-key rlogin-mode-map "\C-c\C-z" 'rlogin-send-Ctrl-Z)
98 (define-key rlogin-mode-map "\C-c\C-\\" 'rlogin-send-Ctrl-backslash)
99 (define-key rlogin-mode-map "\C-d" 'rlogin-delchar-or-send-Ctrl-D)
100 (define-key rlogin-mode-map "\C-i" 'rlogin-tab-or-complete)))
c7986c18 101
32992017 102\f
67398f34
RS
103;;;###autoload (add-hook 'same-window-regexps "^\\*rlogin-.*\\*\\(\\|<[0-9]+>\\)")
104
cd17ae3f
RM
105(defvar rlogin-history nil)
106
0b899bd2 107;;;###autoload
965f7ac9 108(defun rlogin (input-args &optional buffer)
8d30fe17
NF
109 "Open a network login connection to HOST via the `rlogin' program.
110Input is sent line-at-a-time to the remote connection.
111
67398f34
RS
112Communication with the remote host is recorded in a buffer `*rlogin-HOST*'
113\(or `*rlogin-USER@HOST*' if the remote username differs\).
114If a prefix argument is given and the buffer `*rlogin-HOST*' already exists,
32992017 115a new buffer with a different connection will be made.
8d30fe17 116
965f7ac9
RM
117When called from a program, if the optional second argument is a string or
118buffer, it names the buffer to use.
119
8d30fe17 120The variable `rlogin-program' contains the name of the actual program to
2601d12e 121run. It can be a relative or absolute path.
8d30fe17
NF
122
123The variable `rlogin-explicit-args' is a list of arguments to give to
ce992678
RS
124the rlogin when starting. They are added after any arguments given in
125INPUT-ARGS.
b79164c7 126
32992017
NF
127If the default value of `rlogin-directory-tracking-mode' is t, then the
128default directory in that buffer is set to a remote (FTP) file name to
129access your home directory on the remote machine. Occasionally this causes
130an error, if you cannot access the home directory on that machine. This
131error is harmless as long as you don't try to use that default directory.
ce992678 132
32992017 133If `rlogin-directory-tracking-mode' is neither t nor nil, then the default
ce992678
RS
134directory is initially set up to your (local) home directory.
135This is useful if the remote machine and your local machine
32992017
NF
136share the same files via NFS. This is the default.
137
138If you wish to change directory tracking styles during a session, use the
139function `rlogin-directory-tracking-mode' rather than simply setting the
140variable."
5236f937 141 (interactive (list
cd17ae3f
RM
142 (read-from-minibuffer "rlogin arguments (hostname first): "
143 nil nil nil 'rlogin-history)
5236f937 144 current-prefix-arg))
32992017 145
8ae3bc9f 146 (let* ((process-connection-type rlogin-process-connection-type)
32992017
NF
147 (args (if rlogin-explicit-args
148 (append (rlogin-parse-words input-args)
149 rlogin-explicit-args)
150 (rlogin-parse-words input-args)))
151 (host (car args))
152 (user (or (car (cdr (member "-l" args)))
153 (user-login-name)))
154 (buffer-name (if (string= user (user-login-name))
155 (format "*rlogin-%s*" host)
156 (format "*rlogin-%s@%s*" user host)))
157 proc)
158
965f7ac9
RM
159 (cond ((null buffer))
160 ((or (stringp buffer) (bufferp buffer))
161 (setq buffer-name buffer))
162 ((numberp buffer)
163 (setq buffer-name (format "%s<%d>" buffer-name buffer)))
e1f06ce8
NF
164 (t
165 (setq buffer-name (generate-new-buffer-name buffer-name))))
166
167 (pop-to-buffer buffer-name)
32992017 168 (cond
e1f06ce8 169 ((comint-check-proc buffer-name))
32992017 170 (t
32992017
NF
171 (comint-exec (current-buffer) buffer-name rlogin-program nil args)
172 (setq proc (get-process buffer-name))
173 ;; Set process-mark to point-max in case there is text in the
174 ;; buffer from a previous exited process.
175 (set-marker (process-mark proc) (point-max))
176 (rlogin-mode)
2601d12e 177
32992017
NF
178 ;; comint-output-filter-functions is just like a hook, except that the
179 ;; functions in that list are passed arguments. add-hook serves well
180 ;; enough for modifying it.
181 (add-hook 'comint-output-filter-functions 'rlogin-carriage-filter)
182
183 (make-local-variable 'rlogin-host)
184 (setq rlogin-host host)
60667917
NF
185 (make-local-variable 'rlogin-remote-user)
186 (setq rlogin-remote-user user)
32992017
NF
187
188 (cond
189 ((eq rlogin-directory-tracking-mode t)
190 ;; Do this here, rather than calling the tracking mode function, to
191 ;; avoid a gratuitous resync check; the default should be the
192 ;; user's home directory, be it local or remote.
2601d12e 193 (setq comint-file-name-prefix
60667917 194 (concat "/" rlogin-remote-user "@" rlogin-host ":"))
32992017
NF
195 (cd-absolute comint-file-name-prefix))
196 ((null rlogin-directory-tracking-mode))
197 (t
198 (cd-absolute (concat comint-file-name-prefix "~/"))))))))
ce992678 199
c7986c18 200(defun rlogin-mode ()
2601d12e 201 "Set major-mode for rlogin sessions.
8ae3bc9f 202If `rlogin-mode-hook' is set, run it."
c7986c18 203 (interactive)
8d30fe17 204 (kill-all-local-variables)
09567b5c 205 (shell-mode)
c7986c18 206 (setq major-mode 'rlogin-mode)
8d30fe17 207 (setq mode-name "rlogin")
c7986c18 208 (use-local-map rlogin-mode-map)
32992017 209 (setq shell-dirtrackp rlogin-directory-tracking-mode)
f3417b13 210 (make-local-variable 'comint-file-name-prefix)
c7986c18
ER
211 (run-hooks 'rlogin-mode-hook))
212
32992017
NF
213(defun rlogin-directory-tracking-mode (&optional prefix)
214 "Do remote or local directory tracking, or disable entirely.
215
216If called with no prefix argument or a unspecified prefix argument (just
217``\\[universal-argument]'' with no number) do remote directory tracking via
218ange-ftp. If called as a function, give it no argument.
219
220If called with a negative prefix argument, disable directory tracking
221entirely.
222
2601d12e 223If called with a positive, numeric prefix argument, e.g.
32992017
NF
224``\\[universal-argument] 1 M-x rlogin-directory-tracking-mode\'',
225then do directory tracking but assume the remote filesystem is the same as
226the local system. This only works in general if the remote machine and the
227local one share the same directories (through NFS)."
228 (interactive "P")
229 (cond
230 ((or (null prefix)
231 (consp prefix))
232 (setq rlogin-directory-tracking-mode t)
f9c4665a 233 (setq shell-dirtrackp t)
2601d12e 234 (setq comint-file-name-prefix
60667917 235 (concat "/" rlogin-remote-user "@" rlogin-host ":")))
32992017
NF
236 ((< prefix 0)
237 (setq rlogin-directory-tracking-mode nil)
f9c4665a 238 (setq shell-dirtrackp nil))
32992017
NF
239 (t
240 (setq rlogin-directory-tracking-mode 'local)
241 (setq comint-file-name-prefix "")
f9c4665a 242 (setq shell-dirtrackp t)))
2601d12e 243 (cond
f9c4665a 244 (shell-dirtrackp
32992017
NF
245 (let* ((proc (get-buffer-process (current-buffer)))
246 (proc-mark (process-mark proc))
247 (current-input (buffer-substring proc-mark (point-max)))
248 (orig-point (point))
249 (offset (and (>= orig-point proc-mark)
250 (- (point-max) orig-point))))
251 (unwind-protect
252 (progn
253 (delete-region proc-mark (point-max))
254 (goto-char (point-max))
255 (shell-resync-dirs))
256 (goto-char proc-mark)
257 (insert current-input)
258 (if offset
259 (goto-char (- (point-max) offset))
260 (goto-char orig-point)))))))
261
8ae3bc9f 262\f
32992017
NF
263;; Parse a line into its constituent parts (words separated by
264;; whitespace). Return a list of the words.
265(defun rlogin-parse-words (line)
266 (let ((list nil)
267 (posn 0)
268 (match-data (match-data)))
269 (while (string-match "[^ \t\n]+" line posn)
270 (setq list (cons (substring line (match-beginning 0) (match-end 0))
271 list))
272 (setq posn (match-end 0)))
273 (store-match-data (match-data))
274 (nreverse list)))
275
2601d12e
NF
276(defun rlogin-carriage-filter (string)
277 (let* ((point-marker (point-marker))
278 (end (process-mark (get-buffer-process (current-buffer))))
279 (beg (or (and (boundp 'comint-last-output-start)
280 comint-last-output-start)
281 (- end (length string)))))
282 (goto-char beg)
283 (while (search-forward "\C-m" end t)
32992017
NF
284 (delete-char -1))
285 (goto-char point-marker)))
286
c7986c18
ER
287(defun rlogin-send-Ctrl-C ()
288 (interactive)
289 (send-string nil "\C-c"))
290
099dcd39
RM
291(defun rlogin-send-Ctrl-D ()
292 (interactive)
293 (send-string nil "\C-d"))
294
c7986c18
ER
295(defun rlogin-send-Ctrl-Z ()
296 (interactive)
297 (send-string nil "\C-z"))
298
299(defun rlogin-send-Ctrl-backslash ()
300 (interactive)
301 (send-string nil "\C-\\"))
302
303(defun rlogin-delchar-or-send-Ctrl-D (arg)
057795ba 304 "\
2601d12e
NF
305Delete ARG characters forward, or send a C-d to process if at end of buffer."
306 (interactive "p")
c7986c18 307 (if (eobp)
057795ba 308 (rlogin-send-Ctrl-D)
c7986c18
ER
309 (delete-char arg)))
310
32992017 311(defun rlogin-tab-or-complete ()
60667917 312 "Complete file name if doing directory tracking, or just insert TAB."
32992017
NF
313 (interactive)
314 (if rlogin-directory-tracking-mode
315 (comint-dynamic-complete)
60667917 316 (insert "\C-i")))
32992017 317
76550a57 318;;; rlogin.el ends here