1 21 22 package org.armedbear.j; 23 24 import java.io.IOException ; 25 import java.io.InputStreamReader ; 26 import java.io.OutputStreamWriter ; 27 import java.util.ArrayList ; 28 29 public final class Ssh 30 { 31 private InputStreamReader reader; 32 private OutputStreamWriter writer; 33 private String [] cmdarray; 34 private String password; 35 private String errorText; 36 private boolean succeeded; 37 38 public Ssh() 39 { 40 } 41 42 public final String getErrorText() 43 { 44 return errorText; 45 } 46 47 public boolean copy(File source, File destination) 48 { 49 SshFile remote = null; 50 if (source instanceof SshFile) 51 remote = (SshFile) source; 52 else if (destination instanceof SshFile) 53 remote = (SshFile) destination; 54 if (remote == null) { 55 Debug.bug("Ssh.copy no remote file"); 56 return false; 57 } 58 String userName = remote.getUserName(); 59 password = remote.getPassword(); 60 ArrayList list = new ArrayList (); 61 list.add("jpty"); 62 list.add("scp"); 63 list.add("-q"); 64 if (remote.getPort() != SshFile.DEFAULT_PORT) { 65 list.add("-P"); 66 list.add(String.valueOf(remote.getPort())); 67 } 68 FastStringBuffer sb = new FastStringBuffer(); 69 if (source instanceof SshFile) { 70 if (userName != null) { 71 sb.append(userName); 72 sb.append('@'); 73 } 74 sb.append(source.getHostName()); 75 sb.append(':'); 76 } 77 sb.append(escape(source.canonicalPath())); 78 list.add(sb.toString()); 79 sb.setLength(0); 80 if (destination instanceof SshFile) { 81 if (userName != null) { 82 sb.append(userName); 83 sb.append('@'); 84 } 85 sb.append(destination.getHostName()); 86 sb.append(':'); 87 } 88 sb.append(escape(destination.canonicalPath())); 89 list.add(sb.toString()); 90 String [] array = new String [list.size()]; 91 cmdarray = (String []) list.toArray(array); 92 run(); 93 return succeeded; 94 } 95 96 private static final String safeChars = 97 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-./\\"; 98 99 private static final String escape(String s) 101 { 102 final int length = s.length(); 103 FastStringBuffer sb = new FastStringBuffer(length * 2); 104 for (int i = 0; i < length; i++) { 105 char c = s.charAt(i); 106 if (safeChars.indexOf(c) < 0) 107 sb.append('\\'); 108 sb.append(c); 109 } 110 return sb.toString(); 111 } 112 113 public void run() 114 { 115 Process process = null; 116 int result = -1; try { 118 process = Runtime.getRuntime().exec(cmdarray); 119 } 120 catch (Throwable t) { 121 Log.error(t); 122 return; 123 } 124 writer = new OutputStreamWriter (process.getOutputStream()); 125 reader = new InputStreamReader (process.getInputStream()); 126 SshReaderThread thread = new SshReaderThread(); 127 thread.start(); 128 try { 129 thread.join(); 130 result = process.waitFor(); 131 } 132 catch (InterruptedException e) { 133 Log.error(e); 134 } 135 if (result == 0) { 136 errorText = thread.getResponse(); 137 if (errorText == null) { 138 succeeded = true; 139 } else { 140 errorText = errorText.trim(); 141 if (errorText.length() == 0) { 142 succeeded = true; 143 } else { 144 if (errorText.toLowerCase().startsWith("warning:")) 147 if (errorText.indexOf('\n') < 0) 148 succeeded = true; 149 } 150 } 151 } 152 } 153 154 private void sendPassword() 155 { 156 if (password != null) { 157 try { 158 writer.write(password); 159 writer.write("\n"); 160 writer.flush(); 161 } 162 catch (IOException e) { 163 Log.error(e); 164 } 165 } else 166 Debug.bug(); 167 } 168 169 private class SshReaderThread extends Thread 170 { 171 private char[] buf = new char[4096]; 172 private boolean done = false; 173 private String response; 174 175 SshReaderThread() 177 { 178 } 179 180 public final String getResponse() 181 { 182 return response; 183 } 184 185 public void run() 186 { 187 FastStringBuffer sb = new FastStringBuffer(); 188 while (true) { 189 final String s = read(); 190 if (s == null) { 191 response = sb.toString(); 192 return; 193 } 194 if (done) { 195 if (s.length() > 0) 196 sb.append(s); 197 response = sb.toString(); 198 return; 199 } 200 if (isPasswordPrompt(s)) { 201 sendPassword(); 202 sb.setLength(0); 203 } else 204 sb.append(s); 205 } 206 } 207 208 private String read() 209 { 210 FastStringBuffer sb = new FastStringBuffer(); 211 try { 212 do { 213 int numChars = reader.read(buf, 0, buf.length); if (numChars < 0) { 215 done = true; 216 break; 217 } 218 if (numChars > 0) 219 sb.append(buf, 0, numChars); 220 } while (reader.ready()); 221 } 222 catch (Exception e) { 223 Log.error(e); 224 return null; 225 } 226 return sb.toString(); 227 } 228 } 229 230 private boolean isPasswordPrompt(String s) 231 { 232 String trim = s.trim().toLowerCase(); 233 if (trim.endsWith("password:")) 234 return true; 235 if (trim.endsWith("response:")) 236 return true; 237 if (trim.startsWith("enter passphrase ") && trim.endsWith(":")) 238 return true; 239 return false; 240 } 241 } 242 | Popular Tags |