view app/src/main/java/ch/ethz/ssh2/SCPInputStream.java @ 518:9acc51a5a98f

Added tag stable-1.9.4-6 for changeset 947ea334735d
author Carl Byington <carl@five-ten-sg.com>
date Fri, 31 May 2024 13:35:44 -0600
parents d29cce60f393
children
line wrap: on
line source

/*
 * Copyright (c) 2011 David Kocher. All rights reserved.
 * Please refer to the LICENSE.txt for licensing details.
 */
package ch.ethz.ssh2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @version $Id: SCPInputStream.java 151 2014-04-28 10:03:39Z dkocher@sudo.ch $
 */
public class SCPInputStream extends BufferedInputStream {
    private Session session;

    /**
     * Bytes remaining to be read from the stream
     */
    private long remaining;

    public SCPInputStream(SCPClient client, Session session) throws IOException {
        super(session.getStdout());
        this.session = session;
        OutputStream os = new BufferedOutputStream(session.getStdin(), 512);
        os.write(0x0);
        os.flush();
        final SCPClient.LenNamePair lnp;

        while (true) {
            int c = session.getStdout().read();

            if (c < 0) {
                throw new IOException("Remote scp terminated unexpectedly.");
            }

            String line = client.receiveLine(session.getStdout());

            if (c == 'T') {
                /* Ignore modification times */
                continue;
            }

            if ((c == 1) || (c == 2)) {
                throw new IOException("Remote SCP error: " + line);
            }

            if (c == 'C') {
                lnp = client.parseCLine(line);
                break;
            }

            throw new IOException("Remote SCP error: " + ((char) c) + line);
        }

        os.write(0x0);
        os.flush();
        this.remaining = lnp.length;
    }

    @Override
    public int read() throws IOException {
        if (!(remaining > 0)) {
            return -1;
        }

        int b = super.read();

        if (b < 0) {
            throw new IOException("Remote scp terminated connection unexpectedly");
        }

        remaining -= 1;
        return b;
    }

    @Override
    public int read(byte b[], int off, int len) throws IOException {
        if (!(remaining > 0)) {
            return -1;
        }

        int trans = (int) remaining;

        if (remaining > len) {
            trans = len;
        }

        int read = super.read(b, off, trans);

        if (read < 0) {
            throw new IOException("Remote scp terminated connection unexpectedly");
        }

        remaining -= read;
        return read;
    }

    @Override
    public void close() throws IOException {
        try {
            session.getStdin().write(0x0);
            session.getStdin().flush();
        }
        finally {
            if (session != null) {
                session.close();
            }
        }
    }
}