FileDocCategorySizeDatePackage
ScpFromMessage.javaAPI DocApache Ant 1.708788Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant.taskdefs.optional.ssh

ScpFromMessage

public class ScpFromMessage extends AbstractSshMessage
A helper object representing an scp download.

Fields Summary
private static final byte
LINE_FEED
private static final int
BUFFER_SIZE
private String
remoteFile
private File
localFile
private boolean
isRecursive
Constructors Summary
public ScpFromMessage(com.jcraft.jsch.Session session)
Constructor for ScpFromMessage

param
session the ssh session to use


                   
       
        super(session);
    
public ScpFromMessage(boolean verbose, com.jcraft.jsch.Session session)
Constructor for ScpFromMessage

param
verbose if true do verbose logging
param
session the ssh session to use
since
Ant 1.7

        super(verbose, session);
    
public ScpFromMessage(boolean verbose, com.jcraft.jsch.Session session, String aRemoteFile, File aLocalFile, boolean recursive)
Constructor for ScpFromMessage.

param
verbose if true log extra information
param
session the Scp session to use
param
aRemoteFile the remote file name
param
aLocalFile the local file
param
recursive if true use recursion (-r option to scp)
since
Ant 1.6.2

        super(verbose, session);
        this.remoteFile = aRemoteFile;
        this.localFile = aLocalFile;
        this.isRecursive = recursive;
    
public ScpFromMessage(com.jcraft.jsch.Session session, String aRemoteFile, File aLocalFile, boolean recursive)
Constructor for ScpFromMessage.

param
session the Scp session to use
param
aRemoteFile the remote file name
param
aLocalFile the local file
param
recursive if true use recursion (-r option to scp)

        this(false, session, aRemoteFile, aLocalFile, recursive);
    
Methods Summary
public voidexecute()
Carry out the transfer.

throws
IOException on i/o errors
throws
JSchException on errors detected by scp

        String command = "scp -f ";
        if (isRecursive) {
            command += "-r ";
        }
        command += remoteFile;
        Channel channel = openExecChannel(command);
        try {
            // get I/O streams for remote scp
            OutputStream out = channel.getOutputStream();
            InputStream in = channel.getInputStream();

            channel.connect();

            sendAck(out);
            startRemoteCpProtocol(in, out, localFile);
        } finally {
            if (channel != null) {
                channel.disconnect();
            }
        }
        log("done\n");
    
private voidfetchFile(java.io.File localFile, long filesize, java.io.OutputStream out, java.io.InputStream in)

        byte[] buf = new byte[BUFFER_SIZE];
        sendAck(out);

        // read a content of lfile
        FileOutputStream fos = new FileOutputStream(localFile);
        int length;
        long totalLength = 0;
        long startTime = System.currentTimeMillis();

        // only track progress for files larger than 100kb in verbose mode
        boolean trackProgress = getVerbose() && filesize > 102400;
        // since filesize keeps on decreasing we have to store the
        // initial filesize
        long initFilesize = filesize;
        int percentTransmitted = 0;

        try {
            while (true) {
                length = in.read(buf, 0,
                                 (BUFFER_SIZE < filesize) ? BUFFER_SIZE
                                                          : (int) filesize);
                if (length < 0) {
                    throw new EOFException("Unexpected end of stream.");
                }
                fos.write(buf, 0, length);
                filesize -= length;
                totalLength += length;
                if (filesize == 0) {
                    break;
                }

                if (trackProgress) {
                    percentTransmitted = trackProgress(initFilesize,
                                                       totalLength,
                                                       percentTransmitted);
                }
            }
        } finally {
            long endTime = System.currentTimeMillis();
            logStats(startTime, endTime, totalLength);
            fos.flush();
            fos.close();
        }
    
private java.io.FileparseAndCreateDirectory(java.lang.String serverResponse, java.io.File localFile)

        int start = serverResponse.indexOf(" ");
        // appears that the next token is not used and it's zero.
        start = serverResponse.indexOf(" ", start + 1);
        String directoryName = serverResponse.substring(start + 1);
        if (localFile.isDirectory()) {
            File dir = new File(localFile, directoryName);
            dir.mkdir();
            log("Creating: " + dir);
            return dir;
        }
        return null;
    
private voidparseAndFetchFile(java.lang.String serverResponse, java.io.File localFile, java.io.OutputStream out, java.io.InputStream in)

        int start = 0;
        int end = serverResponse.indexOf(" ", start + 1);
        start = end + 1;
        end = serverResponse.indexOf(" ", start + 1);
        long filesize = Long.parseLong(serverResponse.substring(start, end));
        String filename = serverResponse.substring(end + 1);
        log("Receiving: " + filename + " : " + filesize);
        File transferFile = (localFile.isDirectory())
                ? new File(localFile, filename)
                : localFile;
        fetchFile(transferFile, filesize, out, in);
        waitForAck(in);
        sendAck(out);
    
private voidstartRemoteCpProtocol(java.io.InputStream in, java.io.OutputStream out, java.io.File localFile)

        File startFile = localFile;
        while (true) {
            // C0644 filesize filename - header for a regular file
            // T time 0 time 0\n - present if perserve time.
            // D directory - this is the header for a directory.
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            while (true) {
                int read = in.read();
                if (read < 0) {
                    return;
                }
                if ((byte) read == LINE_FEED) {
                    break;
                }
                stream.write(read);
            }
            String serverResponse = stream.toString("UTF-8");
            if (serverResponse.charAt(0) == 'C") {
                parseAndFetchFile(serverResponse, startFile, out, in);
            } else if (serverResponse.charAt(0) == 'D") {
                startFile = parseAndCreateDirectory(serverResponse,
                        startFile);
                sendAck(out);
            } else if (serverResponse.charAt(0) == 'E") {
                startFile = startFile.getParentFile();
                sendAck(out);
            } else if (serverResponse.charAt(0) == '\01"
                    || serverResponse.charAt(0) == '\02") {
                // this indicates an error.
                throw new IOException(serverResponse.substring(1));
            }
        }