/******************************************************************************* * Copyright (c) 2006 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.systemtap.ui.consolelog; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.eclipse.linuxtools.systemtap.ui.consolelog.structures.RemoteScriptOptions; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; public class ScpClient { private Session session; /** * Creates ScpClient with given options. * @param remoteOptions Connection properties. * @throws JSchException If connection problem occurred. * @since 3.0 */ public ScpClient(RemoteScriptOptions remoteOptions) throws JSchException { JSch jsch = new JSch(); session = jsch.getSession(remoteOptions.userName, remoteOptions.hostName, 22); session.setPassword(remoteOptions.password); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); //$NON-NLS-1$ //$NON-NLS-2$ session.setConfig(config); session.connect(); } public void transfer(String fromFile, String toFile) throws IOException, JSchException { String rfile = toFile; String lfile = fromFile; String command = "scp -t " + rfile; //$NON-NLS-1$ Channel channel = session.openChannel("exec"); //$NON-NLS-1$ ((ChannelExec) channel).setCommand(command); // get I/O streams for remote scp try (OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream()) { channel.connect(); if (checkAck(in) != 0) { System.out.println("err"); //$NON-NLS-1$ } // send "C0644 filesize filename", where filename should not include // '/' long filesize = (new File(lfile)).length(); command = "C0644 " + filesize + " "; //$NON-NLS-1$ //$NON-NLS-2$ if (lfile.lastIndexOf('/') > 0) { command += lfile.substring(lfile.lastIndexOf('/') + 1); } else { command += lfile; } command += "\n"; //$NON-NLS-1$ out.write(command.getBytes()); out.flush(); if (checkAck(in) != 0) { System.out.println("err"); //$NON-NLS-1$ } // send a content of lfile byte[] buf = new byte[1024]; try (FileInputStream fis = new FileInputStream(lfile)) { while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) { break; } out.write(buf, 0, len); } } // send '\0' buf[0] = 0; out.write(buf, 0, 1); out.flush(); if (checkAck(in) != 0) { System.out.println("err"); //$NON-NLS-1$ } } channel.disconnect(); session.disconnect(); } private static int checkAck(InputStream in) throws IOException { int b = in.read(); // b may be 0 for success, // 1 for error, // 2 for fatal error, // -1 if (b == 0) { return b; } if (b == -1) { return b; } if (b == 1 || b == 2) { StringBuilder sb = new StringBuilder(); int c; do { c = in.read(); sb.append((char) c); } while (c != '\n'); } return b; } }