in src/main/java/com/awslabs/aws/greengrass/provisioner/implementations/helpers/BasicIoHelper.java [287:351]
public void sendFile(Session session, InputStream inputFileStream, String localFilename, String remoteFilename) throws JSchException, IOException {
byte[] byteArrayFromInputStream = getByteArrayFromInputStream(inputFileStream);
// exec 'scp -t rfile' remotely
remoteFilename = remoteFilename.replace("'", "'\"'\"'");
remoteFilename = String.join("", "'", remoteFilename, "'");
String command = String.join("", "scp ", " -t ", remoteFilename);
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
// get I/O streams for remote scp
try (OutputStream outputStream = channel.getOutputStream();
InputStream inputStream = channel.getInputStream()) {
channel.connect();
if (checkAck(inputStream) != 0) {
throw new RuntimeException("Bad acknowledgement while secure copying file, bailing out");
}
// send "C0644 filesize filename", where filename should not include '/'
long filesize = byteArrayFromInputStream.length;
command = String.join("", "C0644 ", String.valueOf(filesize), " ");
if (localFilename.lastIndexOf('/') > 0) {
command += localFilename.substring(localFilename.lastIndexOf('/') + 1);
} else {
command += localFilename;
}
command += "\n";
outputStream.write(command.getBytes());
outputStream.flush();
if (checkAck(inputStream) != 0) {
throw new RuntimeException("Failure when calling checkAck in sendFile [2]");
}
byte[] bytes = new byte[1024];
// send a content of localFilename
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayFromInputStream)) {
while (true) {
int length = byteArrayInputStream.read(bytes, 0, bytes.length);
if (length <= 0) break;
outputStream.write(bytes, 0, length); //out.flush();
}
}
// send '\0'
bytes[0] = 0;
outputStream.write(bytes, 0, 1);
outputStream.flush();
if (checkAck(inputStream) != 0) {
throw new RuntimeException("Failure when calling checkAck in sendFile [3]");
}
}
channel.disconnect();
}