View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.jsch;
17  
18  import java.io.BufferedReader;
19  import java.io.BufferedWriter;
20  import java.io.IOException;
21  import java.io.InputStreamReader;
22  import java.io.OutputStreamWriter;
23  
24  import org.apache.commons.io.IOUtils;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.argeo.slc.SlcException;
28  import org.springframework.core.io.Resource;
29  import org.springframework.util.StringUtils;
30  
31  import com.jcraft.jsch.Channel;
32  import com.jcraft.jsch.Session;
33  
34  public class SshShell extends AbstractJschTask {
35  	private final static Log log = LogFactory.getLog(SshShell.class);
36  	private Resource input;
37  
38  	@Override
39  	void run(Session session) {
40  		try {
41  			final Channel channel = session.openChannel("shell");
42  
43  			// Enable agent-forwarding.
44  			// ((ChannelShell)channel).setAgentForwarding(true);
45  
46  			// channel.setInputStream(System.in);
47  			// channel.setInputStream(input.getInputStream());
48  			/*
49  			 * // a hack for MS-DOS prompt on Windows.
50  			 * channel.setInputStream(new FilterInputStream(System.in){ public
51  			 * int read(byte[] b, int off, int len)throws IOException{ return
52  			 * in.read(b, off, (len>1024?1024:len)); } });
53  			 */
54  
55  			// channel.setOutputStream(System.out);
56  
57  			/*
58  			 * // Choose the pty-type "vt102".
59  			 * ((ChannelShell)channel).setPtyType("vt102");
60  			 */
61  
62  			/*
63  			 * // Set environment variable "LANG" as "ja_JP.eucJP".
64  			 * ((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");
65  			 */
66  
67  			// Writer thread
68  			final BufferedWriter writer = new BufferedWriter(
69  					new OutputStreamWriter(channel.getOutputStream()));
70  
71  			// channel.connect();
72  			channel.connect(3 * 1000);
73  
74  			// while (!channel.isConnected())
75  			// try {
76  			// Thread.sleep(500);
77  			// } catch (InterruptedException e1) {
78  			// // silent
79  			// }
80  
81  			Thread writerThread = new Thread("Shell writer " + getSshTarget()) {
82  
83  				@Override
84  				public void run() {
85  
86  					if (log.isDebugEnabled())
87  						log.debug("Start writing to shell");
88  
89  					BufferedReader reader = null;
90  					try {
91  						reader = new BufferedReader(new InputStreamReader(input
92  								.getInputStream()));
93  						String line = null;
94  						while ((line = reader.readLine()) != null) {
95  							if (!StringUtils.hasText(line))
96  								continue;
97  							writer.write(line);
98  							writer.newLine();
99  						}
100 						writer.append("exit");
101 						writer.newLine();
102 						writer.flush();
103 						// channel.disconnect();
104 					} catch (IOException e) {
105 						throw new SlcException("Cannot write to shell on "
106 								+ getSshTarget(), e);
107 					} finally {
108 						IOUtils.closeQuietly(reader);
109 					}
110 				}
111 			};
112 			writerThread.start();
113 
114 			BufferedReader execIn = null;
115 			try {
116 				execIn = new BufferedReader(new InputStreamReader(channel
117 						.getInputStream()));
118 				String line = null;
119 				while ((line = execIn.readLine()) != null) {
120 					if (!line.trim().equals(""))
121 						log.info(line);
122 				}
123 			} catch (Exception e) {
124 				throw new SlcException("Cannot read from shell on "
125 						+ getSshTarget(), e);
126 			} finally {
127 				IOUtils.closeQuietly(execIn);
128 			}
129 
130 		} catch (Exception e) {
131 			throw new SlcException("Cannot use SSH shell on " + getSshTarget(),
132 					e);
133 		}
134 	}
135 
136 	public void setInput(Resource input) {
137 		this.input = input;
138 	}
139 
140 }