1 18 19 package org.apache.tools.ant.taskdefs.optional.ssh; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.EOFException ; 24 import java.io.InputStream ; 25 import java.io.OutputStream ; 26 import java.io.FileOutputStream ; 27 import java.io.ByteArrayOutputStream ; 28 import com.jcraft.jsch.JSchException; 29 import com.jcraft.jsch.Session; 30 import com.jcraft.jsch.Channel; 31 32 35 public class ScpFromMessage extends AbstractSshMessage { 36 37 private static final byte LINE_FEED = 0x0a; 38 private static final int BUFFER_SIZE = 1024; 39 40 private String remoteFile; 41 private File localFile; 42 private boolean isRecursive = false; 43 44 48 public ScpFromMessage(Session session) { 49 super(session); 50 } 51 52 58 public ScpFromMessage(boolean verbose, Session session) { 59 super(verbose, session); 60 } 61 62 71 public ScpFromMessage(boolean verbose, 72 Session session, 73 String aRemoteFile, 74 File aLocalFile, 75 boolean recursive) { 76 super(verbose, session); 77 this.remoteFile = aRemoteFile; 78 this.localFile = aLocalFile; 79 this.isRecursive = recursive; 80 } 81 82 89 public ScpFromMessage(Session session, 90 String aRemoteFile, 91 File aLocalFile, 92 boolean recursive) { 93 this(false, session, aRemoteFile, aLocalFile, recursive); 94 } 95 96 101 public void execute() throws IOException , JSchException { 102 String command = "scp -f "; 103 if (isRecursive) { 104 command += "-r "; 105 } 106 command += remoteFile; 107 Channel channel = openExecChannel(command); 108 try { 109 OutputStream out = channel.getOutputStream(); 111 InputStream in = channel.getInputStream(); 112 113 channel.connect(); 114 115 sendAck(out); 116 startRemoteCpProtocol(in, out, localFile); 117 } finally { 118 if (channel != null) { 119 channel.disconnect(); 120 } 121 } 122 log("done\n"); 123 } 124 125 private void startRemoteCpProtocol(InputStream in, 126 OutputStream out, 127 File localFile) throws IOException { 128 File startFile = localFile; 129 while (true) { 130 ByteArrayOutputStream stream = new ByteArrayOutputStream (); 134 while (true) { 135 int read = in.read(); 136 if (read < 0) { 137 return; 138 } 139 if ((byte) read == LINE_FEED) { 140 break; 141 } 142 stream.write(read); 143 } 144 String serverResponse = stream.toString("UTF-8"); 145 if (serverResponse.charAt(0) == 'C') { 146 parseAndFetchFile(serverResponse, startFile, out, in); 147 } else if (serverResponse.charAt(0) == 'D') { 148 startFile = parseAndCreateDirectory(serverResponse, 149 startFile); 150 sendAck(out); 151 } else if (serverResponse.charAt(0) == 'E') { 152 startFile = startFile.getParentFile(); 153 sendAck(out); 154 } else if (serverResponse.charAt(0) == '\01' 155 || serverResponse.charAt(0) == '\02') { 156 throw new IOException (serverResponse.substring(1)); 158 } 159 } 160 } 161 162 private File parseAndCreateDirectory(String serverResponse, 163 File localFile) { 164 int start = serverResponse.indexOf(" "); 165 start = serverResponse.indexOf(" ", start + 1); 167 String directoryName = serverResponse.substring(start + 1); 168 if (localFile.isDirectory()) { 169 File dir = new File (localFile, directoryName); 170 dir.mkdir(); 171 log("Creating: " + dir); 172 return dir; 173 } 174 return null; 175 } 176 177 private void parseAndFetchFile(String serverResponse, 178 File localFile, 179 OutputStream out, 180 InputStream in) throws IOException { 181 int start = 0; 182 int end = serverResponse.indexOf(" ", start + 1); 183 start = end + 1; 184 end = serverResponse.indexOf(" ", start + 1); 185 long filesize = Long.parseLong(serverResponse.substring(start, end)); 186 String filename = serverResponse.substring(end + 1); 187 log("Receiving: " + filename + " : " + filesize); 188 File transferFile = (localFile.isDirectory()) 189 ? new File (localFile, filename) 190 : localFile; 191 fetchFile(transferFile, filesize, out, in); 192 waitForAck(in); 193 sendAck(out); 194 } 195 196 private void fetchFile(File localFile, 197 long filesize, 198 OutputStream out, 199 InputStream in) throws IOException { 200 byte[] buf = new byte[BUFFER_SIZE]; 201 sendAck(out); 202 203 FileOutputStream fos = new FileOutputStream (localFile); 205 int length; 206 long totalLength = 0; 207 long startTime = System.currentTimeMillis(); 208 209 boolean trackProgress = getVerbose() && filesize > 102400; 211 long initFilesize = filesize; 214 int percentTransmitted = 0; 215 216 try { 217 while (true) { 218 length = in.read(buf, 0, 219 (BUFFER_SIZE < filesize) ? BUFFER_SIZE 220 : (int) filesize); 221 if (length < 0) { 222 throw new EOFException ("Unexpected end of stream."); 223 } 224 fos.write(buf, 0, length); 225 filesize -= length; 226 totalLength += length; 227 if (filesize == 0) { 228 break; 229 } 230 231 if (trackProgress) { 232 percentTransmitted = trackProgress(initFilesize, 233 totalLength, 234 percentTransmitted); 235 } 236 } 237 } finally { 238 long endTime = System.currentTimeMillis(); 239 logStats(startTime, endTime, totalLength); 240 fos.flush(); 241 fos.close(); 242 } 243 } 244 245 } 246 | Popular Tags |