KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > RemoteShell


1 /*
2  * RemoteShell.java
3  *
4  * Copyright (C) 2000-2004 Peter Graves
5  * $Id: RemoteShell.java,v 1.7 2004/04/13 14:05:33 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.io.OutputStreamWriter JavaDoc;
25 import javax.swing.SwingUtilities JavaDoc;
26
27 public class RemoteShell extends Shell
28 {
29     private String JavaDoc host;
30
31     private RemoteShell(int type, String JavaDoc host)
32     {
33         super();
34         if (type != TYPE_TELNET && type != TYPE_SSH)
35             throw new NotSupportedException();
36         this.type = type;
37         this.host = host;
38         if (type == TYPE_TELNET) {
39             shellCommand = Editor.preferences().getStringProperty(Property.TELNET);
40             if (shellCommand == null)
41                 shellCommand = "telnet";
42         } else if (type == TYPE_SSH) {
43             shellCommand = Editor.preferences().getStringProperty(Property.SSH);
44             if (shellCommand == null)
45                 shellCommand = "ssh";
46         }
47         title = shellCommand + " " + host;
48     }
49
50     // Called in Shell constructor, so we override it here.
51
protected void initializeHistory()
52     {
53         history = new History("remoteShell.history");
54     }
55
56     protected void startProcess()
57     {
58         Process JavaDoc process = null;
59         try {
60             process = Runtime.getRuntime().exec("jpty " + shellCommand + " " + host);
61             setProcess(process);
62         }
63         catch (Throwable JavaDoc t) {
64             setProcess(null);
65             return;
66         }
67         startWatcherThread();
68         // See if the process exits right away (meaning jpty couldn't launch
69
// the program).
70
try {
71             Thread.sleep(100);
72         }
73         catch (InterruptedException JavaDoc e) {
74             Log.error(e);
75         }
76         // When the process exits, the watcher thread calls setProcess(null),
77
// so check the value of getProcess() here.
78
if (getProcess() == null)
79             return; // Process exited.
80
Property property;
81         switch (type) {
82             case TYPE_TELNET:
83                 property = Property.TELNET_PROMPT_PATTERN;
84                 break;
85             case TYPE_SSH:
86                 property = Property.SSH_PROMPT_PATTERN;
87                 break;
88             default:
89                 property = null;
90                 break;
91         }
92         if (property != null)
93             setPromptRE(Editor.preferences().getStringProperty(property));
94         try {
95             stdin = new OutputStreamWriter JavaDoc(process.getOutputStream());
96             stdoutThread = new StdoutThread(process.getInputStream());
97             stderrThread = new StderrThread(process.getErrorStream());
98             stdoutThread.start();
99             stderrThread.start();
100             readOnly = false;
101         }
102         catch (Throwable JavaDoc t) {
103             Log.error(t);
104         }
105     }
106
107     private static RemoteShell createRemoteShell(int type, String JavaDoc host)
108     {
109         RemoteShell remoteShell = new RemoteShell(type, host);
110         remoteShell.startProcess();
111         if (remoteShell.getProcess() == null) {
112             Editor.getBufferList().remove(remoteShell);
113             String JavaDoc program = null;
114             switch (type) {
115                 case TYPE_TELNET:
116                     program = "telnet";
117                     break;
118                 case TYPE_SSH:
119                     program = "ssh";
120                     break;
121                 default:
122                     program = "client"; // A nice generic name.
123
}
124             String JavaDoc message;
125             if (Utilities.haveJpty())
126                 message = "Unable to start " + program + " process";
127             else
128                 message = "Unable to start " + program + " process (jpty not found in PATH)";
129             MessageDialog.showMessageDialog(Editor.currentEditor(), message, "Error");
130             remoteShell = null;
131         }
132         return remoteShell;
133     }
134
135     private static RemoteShell findRemoteShell(int type, String JavaDoc host)
136     {
137         if (host == null)
138             return null;
139         for (BufferIterator it = new BufferIterator(); it.hasNext();) {
140             Buffer buf = it.nextBuffer();
141             if (buf instanceof RemoteShell) {
142                 RemoteShell remoteShell = (RemoteShell) buf;
143                 if (type == remoteShell.getType())
144                     if (host.equals(remoteShell.getHost()))
145                         return remoteShell;
146             }
147         }
148         return null;
149     }
150
151     private StringBuffer JavaDoc sbFilter;
152
153     private String JavaDoc telnetStdOutFilter(String JavaDoc s)
154     {
155         if (stripEcho && input != null) {
156             if (sbFilter == null)
157                 sbFilter = new StringBuffer JavaDoc(s);
158             else {
159                 sbFilter.append(s);
160                 s = sbFilter.toString();
161             }
162             if (s.startsWith(input)) {
163                 s = stripEcho(s);
164                 stripEcho = false; // Strip echo only once per command line.
165
sbFilter = null;
166             } else
167                 s = ""; // Save output until we have enough to strip echo.
168
}
169         return s;
170     }
171
172     private String JavaDoc sshStdOutFilter(String JavaDoc s)
173     {
174         if (stripEcho && input != null) {
175             if (s.startsWith(input)) {
176                 s = stripEcho(s);
177                 stripEcho = false; // Strip echo only once per command line.
178
}
179         }
180         return s;
181     }
182
183     protected String JavaDoc stdOutFilter(String JavaDoc s)
184     {
185         if (type == TYPE_TELNET)
186             return telnetStdOutFilter(s);
187         if (type == TYPE_SSH)
188             return sshStdOutFilter(s);
189         return s;
190     }
191
192     private String JavaDoc stripEcho(String JavaDoc s)
193     {
194         if (s.startsWith(input)) {
195             int begin = input.length();
196             if (s.length() > begin && s.charAt(begin) == '\r')
197                 ++begin;
198             if (s.length() > begin && s.charAt(begin) == '\n')
199                 ++begin;
200             s = s.substring(begin);
201         }
202         return s;
203     }
204
205     protected void stdOutUpdate(final String JavaDoc s)
206     {
207         // Filter to prevent two carriage returns in a row.
208
final FastStringBuffer sb = new FastStringBuffer(s.length());
209         boolean skipCR = false;
210         final int limit = s.length();
211         for (int i = 0; i < limit; i++) {
212             char c = s.charAt(i);
213             if (c == '\r') {
214                 if (skipCR)
215                     skipCR = false;
216                 else {
217                     sb.append(c);
218                     skipCR = true;
219                 }
220             } else {
221                 sb.append(c);
222                 skipCR = false;
223             }
224         }
225         Runnable JavaDoc r = new Runnable JavaDoc() {
226             public void run()
227             {
228                 appendString(sb.toString());
229                 setEndOfOutput(new Position(getEnd()));
230                 updateLineFlags();
231                 updateDisplayInAllFrames();
232                 resetUndo();
233                 checkPasswordPrompt();
234             }
235         };
236         SwingUtilities.invokeLater(r);
237     }
238
239     protected String JavaDoc stdErrFilter(String JavaDoc s)
240     {
241         return s;
242     }
243
244     private final String JavaDoc getHost()
245     {
246         return host;
247     }
248
249     public final File getCurrentDirectory()
250     {
251         return Directories.getUserHomeDirectory();
252     }
253
254     // For the buffer list.
255
public String JavaDoc toString()
256     {
257         return title;
258     }
259
260     public String JavaDoc getTitle()
261     {
262         return title;
263     }
264
265     public static void telnet()
266     {
267         if (!Editor.checkExperimental())
268             return;
269         if (Platform.isPlatformWindows()) {
270             if (Editor.preferences().getStringProperty(Property.TELNET) == null)
271                 return;
272         }
273         String JavaDoc host = InputDialog.showInputDialog(Editor.currentEditor(), "Host:", "telnet");
274         if (host == null || host.length() == 0)
275             return;
276         telnet(host);
277     }
278
279     public static void telnet(String JavaDoc host)
280     {
281         if (!Editor.checkExperimental())
282             return;
283         if (Platform.isPlatformWindows()) {
284             if (Editor.preferences().getStringProperty(Property.TELNET) == null)
285                 return;
286         }
287         RemoteShell remoteShell = findRemoteShell(TYPE_TELNET, host);
288         if (remoteShell != null) {
289             if (remoteShell.getProcess() == null)
290                 remoteShell.startProcess();
291         } else
292             remoteShell = createRemoteShell(TYPE_TELNET, host);
293         if (remoteShell != null) {
294             final Editor editor = Editor.currentEditor();
295             editor.makeNext(remoteShell);
296             editor.switchToBuffer(remoteShell);
297         }
298     }
299
300     public static void ssh()
301     {
302         if (!Editor.checkExperimental())
303             return;
304         if (Platform.isPlatformWindows()) {
305             if (Editor.preferences().getStringProperty(Property.SSH) == null)
306                 return;
307         }
308         String JavaDoc host = InputDialog.showInputDialog(Editor.currentEditor(), "Host:", "ssh");
309         if (host == null || host.length() == 0)
310             return;
311         ssh(host);
312     }
313
314     public static void ssh(String JavaDoc host)
315     {
316         if (!Editor.checkExperimental())
317             return;
318         if (Platform.isPlatformWindows()) {
319             if (Editor.preferences().getStringProperty(Property.SSH) == null)
320                 return;
321         }
322         RemoteShell remoteShell = RemoteShell.findRemoteShell(TYPE_SSH, host);
323         if (remoteShell != null) {
324             if (remoteShell.getProcess() == null)
325                 remoteShell.startProcess();
326         } else
327             remoteShell = RemoteShell.createRemoteShell(TYPE_SSH, host);
328         if (remoteShell != null) {
329             final Editor editor = Editor.currentEditor();
330             editor.makeNext(remoteShell);
331             editor.switchToBuffer(remoteShell);
332         }
333     }
334 }
335
Popular Tags