/**
* Copyright 2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package datameer.awstasks.ssh;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.log4j.Logger;
import awstasks.com.jcraft.jsch.Channel;
import awstasks.com.jcraft.jsch.Session;
import datameer.awstasks.util.SshUtil;
public class ScpFileInputStream extends InputStream {
private static final Logger LOG = Logger.getLogger(ScpFileInputStream.class);
private final Session _session;
private final Channel _execChannel;
private final OutputStream _sshOutputStream;
private final InputStream _sshInputStream;
private long _availible;
public ScpFileInputStream(Session session, String remoteFile) throws IOException {
_session = session;
String command = ScpDownloadCommand.constructScpInitCommand(remoteFile, false);
_execChannel = SshUtil.openExecChannel(session, command);
_sshOutputStream = _execChannel.getOutputStream();
_sshInputStream = _execChannel.getInputStream();
SshUtil.sendAckOk(_sshOutputStream);
String serverResponse = ScpDownloadCommand.readServerResponse(_sshInputStream);
if (serverResponse.charAt(0) != 'C') {
throw new IllegalStateException("unexpected server response: " + serverResponse);
}
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.info("opening file: " + filename + " | " + filesize);
SshUtil.sendAckOk(_sshOutputStream);
_availible = filesize;
}
@Override
public int available() throws IOException {
return (int) _availible;
}
@Override
public int read() throws IOException {
checkConnection();
if (_availible == 0) {
return -1;
}
_availible--;
return _sshInputStream.read();
}
private void checkConnection() {
if (!_session.isConnected()) {
throw new IllegalStateException("stream is already closed");
}
}
@Override
public void close() throws IOException {
if (_session.isConnected()) {
try {
SshUtil.checkAcknowledgement(_sshInputStream);
SshUtil.sendAckOk(_sshOutputStream);
} catch (IOException e) {
// happens in the middle of read
}
_execChannel.disconnect();
_session.disconnect();
}
}
@Override
protected void finalize() throws Throwable {
close();
super.finalize();
}
}