1 /*
2 * SSHTools - Java SSH2 API
3 *
4 * Copyright (C) 2002-2003 Lee David Painter and Contributors.
5 *
6 * Contributions made by:
7 *
8 * Brett Smith
9 * Richard Pernavas
10 * Erwin Bolwidt
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26 package com.sshtools.j2ssh.session;
27
28 import com.sshtools.j2ssh.connection;
29
30
31 /**
32 * <p>
33 * This class provides a utility to read and parse the output a session,
34 * providing methods to wait for specific strings such as the prompt or
35 * command input requests.
36 * </p>
37 *
38 * @author Lee David Painter
39 * @version $Revision: 1.13 $
40 *
41 * @since 0.2.1
42 */
43 public class SessionOutputReader {
44 SessionChannelClient session;
45 int pos = 0;
46 int mark = 0;
47 String output = "";
48
49 /**
50 * <p>
51 * Contructs the session reader.
52 * </p>
53 *
54 * @param session the to read
55 */
56 public SessionOutputReader(SessionChannelClient session) {
57 this.session = session;
58 session.addEventListener(new SessionOutputListener());
59 }
60
61 /**
62 * Returns the output of the entire session.
63 *
64 * @return a string containing the entire output of the session so far.
65 */
66 public String getOutput() {
67 return output;
68 }
69
70 /**
71 * <p>
72 * Returns the current position of the session input pointer. This pointer
73 * is set to the position of the matched string everytime a match is found
74 * during a call by <code>waitForString</code>
75 * </p>
76 *
77 * @return the current input reader pointer
78 */
79 public int getPosition() {
80 return pos;
81 }
82
83 /**
84 * Mark the postion specified for filtering session output.
85 *
86 * @param mark output position to mark
87 */
88 public void markPosition(int mark) {
89 this.mark = mark;
90 }
91
92 /**
93 * Marks the current position.
94 */
95 public void markCurrentPosition() {
96 this.mark = pos;
97 }
98
99 /**
100 * <p>
101 * Returns a string containing the session output from the current marked
102 * position to the end of the output.
103 * </p>
104 *
105 * @return a string containing the session output from the marked position
106 * to current position
107 */
108 public String getMarkedOutput() {
109 return output.substring(mark, pos);
110 }
111
112 /**
113 * <p>
114 * Wait for a given String in the output buffer.
115 * </p>
116 *
117 * @param str the string to wait for
118 * @param echo a callback interface to receive the session output whilst
119 * the no match for the string is found
120 *
121 * @return true if the string was found, otherwise false
122 *
123 * @throws InterruptedException if the thread is interrupted
124 *
125 * @see waitForString(String, int, SessionOutputEcho)
126 */
127 public synchronized boolean waitForString(String str, SessionOutputEcho echo)
128 throws InterruptedException {
129 return waitForString(str, 0, echo);
130 }
131
132 /**
133 * <p>
134 * Wait for a given String in the output buffer. This method will block
135 * until the string is found.
136 * </p>
137 *
138 * @param str the string to wait for
139 *
140 * @return true if the string was found, otherwise false
141 *
142 * @throws InterruptedException if the thread is interrupted
143 *
144 * @see waitForString(String, int, SessionOutputEcho)
145 */
146 public synchronized boolean waitForString(String str)
147 throws InterruptedException {
148 return waitForString(str, 0, null);
149 }
150
151 /**
152 * <p>
153 * Wait for a given String in the output buffer.
154 * </p>
155 *
156 * @param str the string to wait for
157 * @param timeout the number of milliseconds to wait
158 *
159 * @return true if the string was found, otherwise false
160 *
161 * @throws InterruptedException if the thread is interrupted
162 *
163 * @see waitForString(String, int, SessionOutputEcho)
164 */
165 public synchronized boolean waitForString(String str, int timeout)
166 throws InterruptedException {
167 return waitForString(str, timeout, null);
168 }
169
170 /**
171 * <p>
172 * Wait for a given String in the output buffer. When this method is called
173 * the method will block unitil either the String arrives in the input
174 * buffer or the timeout specified has elasped.
175 * </p>
176 *
177 * @param str the string to wait for
178 * @param timeout the number of milliseconds to wait, 0=infinite
179 * @param echo a callback interface to receive the session output whilst
180 * the no match for the string is found
181 *
182 * @return true if the string was found, otherwise false
183 *
184 * @throws InterruptedException if the thread is interrupted
185 */
186 public synchronized boolean waitForString(String str, int timeout,
187 SessionOutputEcho echo) throws InterruptedException {
188 long time = System.currentTimeMillis();
189
190 while ((output.indexOf(str, pos) == -1) &&
191 (((System.currentTimeMillis() - time) < timeout) ||
192 (timeout == 0))) {
193 int tmp = output.length();
194 wait((timeout > 0) ? (timeout -
195 (System.currentTimeMillis() - time)) : 0);
196
197 if ((output.length() > tmp) && (echo != null)) {
198 echo.echo(output.substring(tmp, output.length()));
199 }
200 }
201
202 if (output.indexOf(str, pos) > -1) {
203 pos = output.indexOf(str, pos) + str.length();
204
205 return true;
206 } else {
207 return false;
208 }
209 }
210
211 /**
212 *
213 *
214 * @param echo
215 *
216 * @throws InterruptedException
217 */
218 public synchronized void echoLineByLineToClose(SessionOutputEcho echo)
219 throws InterruptedException {
220 while (session.isOpen()) {
221 waitForString("\n", 1000, echo);
222 }
223 }
224
225 private synchronized void breakWaiting() {
226 notifyAll();
227 }
228
229 /**
230 * The ChannelEventListener to receive event notifications
231 */
232 class SessionOutputListener implements ChannelEventListener {
233 public void onChannelOpen(Channel channel) {
234 }
235
236 public void onChannelClose(Channel channel) {
237 breakWaiting();
238 }
239
240 public void onChannelEOF(Channel channel) {
241 // Timeout
242 breakWaiting();
243 }
244
245 public void onDataSent(Channel channel, byte[] data) {
246 // Do nothing
247 }
248
249 public void onDataReceived(Channel channel, byte[] data) {
250 output += new String(data);
251 breakWaiting();
252 }
253 }
254 }