Commit | Line | Data |
---|---|---|
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 | |
0b899bd2 | 7 | ;; Copyright (C) 1992, 1993 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 ER |
22 | |
23 | ;;; Commentary: | |
24 | ||
0b899bd2 | 25 | ;; Support for remote logins using `rlogin'. |
d9ecc911 ER |
26 | ;; |
27 | ;; Todo: add directory tracking using ange-ftp style patchnames for the cwd. | |
c7986c18 | 28 | |
76550a57 ER |
29 | ;;; Code: |
30 | ||
c7986c18 ER |
31 | (require 'comint) |
32 | ||
8ae3bc9f | 33 | ;;;###autoload |
c7986c18 ER |
34 | (defvar rlogin-program "rlogin" |
35 | "*Name of program to invoke rlogin") | |
36 | ||
8ae3bc9f | 37 | ;;;###autoload |
8d30fe17 NF |
38 | (defvar rlogin-explicit-args nil |
39 | "*List of arguments to pass to rlogin on the command line.") | |
40 | ||
8ae3bc9f | 41 | ;;;###autoload |
c7986c18 ER |
42 | (defvar rlogin-mode-hook nil |
43 | "*Hooks to run after setting current buffer to rlogin-mode.") | |
44 | ||
8ae3bc9f NF |
45 | ;;;###autoload |
46 | (defvar rlogin-process-connection-type nil | |
47 | "*If non-`nil', use a pty for the local rlogin process. | |
48 | If `nil', use a pipe (if pipes are supported on the local system). | |
8d30fe17 | 49 | |
8ae3bc9f NF |
50 | Generally it is better not to waste ptys on systems which have a static |
51 | number of them. On the other hand, some implementations of `rlogin' assume | |
52 | a pty is being used, and errors will result from using a pipe instead.") | |
8d30fe17 | 53 | |
8ae3bc9f NF |
54 | ;; Leave this nil because it makes rlogin-filter a tiny bit faster. Plus |
55 | ;; you can still call rlogin-password by hand. | |
56 | ;;;###autoload | |
57 | (defvar rlogin-password-paranoia nil | |
58 | "*If non-`nil', query user for a password in the minibuffer when a Password: prompt appears. | |
59 | It's also possible to selectively enter passwords without echoing them in | |
60 | the minibuffer using the command `rlogin-password' explicitly.") | |
8d30fe17 | 61 | |
c7986c18 | 62 | ;; Initialize rlogin mode map. |
8ae3bc9f | 63 | ;;;###autoload |
c7986c18 ER |
64 | (defvar rlogin-mode-map '()) |
65 | (cond ((not rlogin-mode-map) | |
66 | (setq rlogin-mode-map (full-copy-sparse-keymap comint-mode-map)) | |
67 | ;(define-key rlogin-mode-map "\M-\t" 'comint-dynamic-complete) | |
68 | ;(define-key rlogin-mode-map "\M-?" 'comint-dynamic-list-completions) | |
69 | (define-key rlogin-mode-map "\C-c\C-c" 'rlogin-send-Ctrl-C) | |
70 | (define-key rlogin-mode-map "\C-c\C-z" 'rlogin-send-Ctrl-Z) | |
71 | (define-key rlogin-mode-map "\C-c\C-\\" 'rlogin-send-Ctrl-backslash) | |
72 | (define-key rlogin-mode-map "\C-d" 'rlogin-delchar-or-send-Ctrl-D))) | |
73 | ||
0b899bd2 | 74 | ;;;###autoload |
8d30fe17 NF |
75 | (defun rlogin (&optional prefix host) |
76 | "Open a network login connection to HOST via the `rlogin' program. | |
77 | Input is sent line-at-a-time to the remote connection. | |
78 | ||
79 | Communication with HOST is recorded in a buffer *rlogin-HOST*. | |
80 | If a prefix argument is given and the buffer *rlogin-HOST* already exists, | |
81 | a new buffer with a different connection will be made. | |
82 | ||
83 | The variable `rlogin-program' contains the name of the actual program to | |
84 | run. It can be a relative or absolute path. | |
85 | ||
86 | The variable `rlogin-explicit-args' is a list of arguments to give to | |
87 | the rlogin when starting." | |
88 | (interactive (list current-prefix-arg | |
89 | (read-from-minibuffer "Open rlogin connection to host: "))) | |
8ae3bc9f NF |
90 | (let* ((process-connection-type rlogin-process-connection-type) |
91 | (buffer-name (format "*rlogin-%s*" host)) | |
8d30fe17 NF |
92 | (args (if (and rlogin-explicit-args (listp rlogin-explicit-args)) |
93 | (cons host rlogin-explicit-args) | |
6fc81d6b NF |
94 | (list host))) |
95 | proc) | |
8d30fe17 NF |
96 | (and prefix (setq buffer-name |
97 | (buffer-name (generate-new-buffer buffer-name)))) | |
98 | (switch-to-buffer buffer-name) | |
99 | (or (comint-check-proc buffer-name) | |
100 | (progn | |
101 | (comint-mode) | |
102 | (comint-exec (current-buffer) buffer-name rlogin-program nil args) | |
103 | (setq proc (get-process buffer-name)) | |
8ae3bc9f NF |
104 | ;; Set process-mark to point-max in case there is text in the |
105 | ;; buffer from a previous exited process. | |
106 | (set-marker (process-mark proc) (point-max)) | |
8d30fe17 NF |
107 | (set-process-filter proc 'rlogin-filter) |
108 | (rlogin-mode))))) | |
109 | ||
110 | ;;;###autoload | |
111 | (defun rlogin-with-args (host args) | |
112 | "Open a new rlogin connection to HOST, even if one already exists. | |
113 | String ARGS is given as arguments to the `rlogin' program, overriding the | |
114 | value of `rlogin-explicit-args'." | |
115 | (interactive (list (read-from-minibuffer "Open rlogin connection to host: ") | |
116 | (read-from-minibuffer "with arguments: "))) | |
117 | (let ((old-match-data (match-data)) | |
118 | (rlogin-explicit-args nil)) | |
119 | (unwind-protect | |
120 | (progn | |
8ae3bc9f | 121 | (while (string-match "[ \t]*\\([^ \t]+\\)$" args) |
8d30fe17 NF |
122 | (setq rlogin-explicit-args |
123 | (cons (substring args | |
124 | (match-beginning 1) | |
125 | (match-end 1)) | |
126 | rlogin-explicit-args) | |
127 | args (substring args 0 (match-beginning 0))))) | |
128 | (store-match-data old-match-data)) | |
129 | (rlogin 1 host))) | |
130 | ||
131 | ;;;###autoload | |
8ae3bc9f NF |
132 | (defun rlogin-password (&optional proc) |
133 | "Read a password and send it to an rlogin session. | |
134 | For each character typed, a `*' is echoed in the minibuffer. | |
135 | End with RET, LFD, or ESC. DEL or C-h rubs out. C-u kills line. | |
136 | C-g aborts attempt to read and send password. | |
137 | ||
138 | Optional argument PROC is the process to which the password should be sent. | |
139 | If not provided, send to the process in the current buffer. This argument | |
140 | is intended primarily for use by `rlogin-filter'." | |
8d30fe17 | 141 | (interactive) |
8ae3bc9f NF |
142 | (or proc (setq proc (get-buffer-process (current-buffer)))) |
143 | (let* ((buffer-name (buffer-name (process-buffer proc))) | |
144 | (pass (comint-read-noecho (format "Password for buffer \"%s\": " | |
145 | buffer-name) | |
146 | 'stars))) | |
147 | (and pass | |
148 | (save-excursion | |
149 | (set-buffer buffer-name) | |
150 | (insert-before-markers "\n") | |
151 | (comint-send-string proc (format "%s\n" pass)))))) | |
c7986c18 | 152 | |
0b899bd2 | 153 | ;;;###autoload |
c7986c18 | 154 | (defun rlogin-mode () |
8ae3bc9f NF |
155 | "Set major-mode for rlogin sessions. |
156 | If `rlogin-mode-hook' is set, run it." | |
c7986c18 | 157 | (interactive) |
8d30fe17 | 158 | (kill-all-local-variables) |
c7986c18 ER |
159 | (comint-mode) |
160 | (setq comint-prompt-regexp shell-prompt-pattern) | |
161 | (setq major-mode 'rlogin-mode) | |
8d30fe17 | 162 | (setq mode-name "rlogin") |
c7986c18 ER |
163 | (use-local-map rlogin-mode-map) |
164 | (run-hooks 'rlogin-mode-hook)) | |
165 | ||
8ae3bc9f | 166 | \f |
c7986c18 | 167 | (defun rlogin-filter (proc string) |
8ae3bc9f NF |
168 | (save-excursion |
169 | (set-buffer (process-buffer proc)) | |
170 | (let ((proc-mark (process-mark proc)) | |
171 | (region-begin (point))) | |
172 | (goto-char proc-mark) | |
173 | (insert-before-markers string) | |
174 | (goto-char region-begin) | |
175 | (while (search-forward "\C-m" proc-mark t) | |
176 | (delete-char -1)))) | |
177 | ;; Kludgy workaround for scroll-step bug in emacs. If point is at the | |
178 | ;; top of the window, scroll step is nonzero, and you call | |
179 | ;; insert-before-markers, the text is inserted off-screen. If | |
180 | ;; scroll-step is 0, this doesn't happen. | |
181 | (and (/= scroll-step 0) | |
182 | (eq (process-buffer proc) (window-buffer (selected-window))) | |
183 | (eq (point) (window-start)) | |
184 | (set-window-start (selected-window) | |
185 | (save-excursion | |
186 | (beginning-of-line) | |
187 | (point)) | |
188 | 'noforce)) | |
8d30fe17 NF |
189 | (and rlogin-password-paranoia |
190 | (string= "Password:" string) | |
8ae3bc9f | 191 | (rlogin-password proc))) |
c7986c18 | 192 | |
8ae3bc9f | 193 | ;;;###autoload |
c7986c18 ER |
194 | (defun rlogin-send-Ctrl-C () |
195 | (interactive) | |
196 | (send-string nil "\C-c")) | |
197 | ||
8ae3bc9f | 198 | ;;;###autoload |
c7986c18 ER |
199 | (defun rlogin-send-Ctrl-Z () |
200 | (interactive) | |
201 | (send-string nil "\C-z")) | |
202 | ||
8ae3bc9f | 203 | ;;;###autoload |
c7986c18 ER |
204 | (defun rlogin-send-Ctrl-backslash () |
205 | (interactive) | |
206 | (send-string nil "\C-\\")) | |
207 | ||
8ae3bc9f | 208 | ;;;###autoload |
c7986c18 ER |
209 | (defun rlogin-delchar-or-send-Ctrl-D (arg) |
210 | "Delete ARG characters forward, or send a C-d to process if at end of | |
211 | buffer." | |
212 | (interactive "p") | |
213 | (if (eobp) | |
214 | (send-string nil "\C-d") | |
215 | (delete-char arg))) | |
216 | ||
76550a57 | 217 | ;;; rlogin.el ends here |