import java.net.*; import java.io.*; import java.util.*; import java.applet.*; //-- the j2ssh tools import com.sshtools.j2ssh.SshClient; import com.sshtools.j2ssh.authentication.AuthenticationProtocolState; import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient; import com.sshtools.j2ssh.io.UnsignedInteger32; import com.sshtools.j2ssh.session.SessionChannelClient; import com.sshtools.j2ssh.sftp.FileAttributes; import com.sshtools.j2ssh.sftp.SftpFile; import com.sshtools.j2ssh.sftp.SftpFileOutputStream; import com.sshtools.j2ssh.SftpClient; import com.sshtools.j2ssh.configuration.ConfigurationLoader; import com.sshtools.j2ssh.configuration.ConfigurationException; import com.sshtools.j2ssh.transport.IgnoreHostKeyVerification; //-------------------------------------------- /** * This class represents the attempted upload of a single * file to an ssh server via sftp. It uses the j2ssh toolset * * www.math.uni-klu.ac.at/alph/java/sshtools/ * * rather than the jsch ('java secure chanel') toolset. This was * a decision taken without real understanding. * * The class stores information about the upload attempt. * The code design was based on the WebDownload class. * * This was adapted from the SoundDownload class * @see "SoundDownload", "WebDownload" * @author matth3wbishopyahoocom */ public class SftpUpload extends Object { //-------------------------------------------- /** the file to put */ private String fileName; //-------------------------------------------- private long fileSize; //-------------------------------------------- private boolean invalidFileName; //-------------------------------------------- /** the sftp server */ private String serverName; //-------------------------------------------- /** ssh account name */ private String accountName; //-------------------------------------------- /** the ssh account password */ private String accountPassword; //-------------------------------------------- /** ssh save path */ private String serverPath; //-------------------------------------------- /** The time at which the attempted upload was begun */ private Date startTime; //-------------------------------------------- /** The time at which the attempted upload was terminated * whether successfully or unsuccessfully */ private Date finishTime; //-------------------------------------------- /** A directory in which to put files */ private String directoryName = ""; //-------------------------------------------- /** the reason the upload failed */ private String failureCause; //-------------------------------------------- /** will store error messages produced when attempting the upload * the file, such as those produced by the Url class in * attempting to make a connection to the resource. */ private StringBuffer errorMessage; //-------------------------------------------- /** a chunk for reading from the target, in bytes */ private static int CHUNK_SIZE = 10000; //-------------------------------------------- /** the progress marker */ private String PROGRESS_MARKER = "."; //-------------------------------------------- private boolean wasSuccessful; //-------------------------------------------- /** whether the download has started */ private boolean hasStarted; //-------------------------------------------- private boolean hasFinished; //-------------------------------------------- private boolean showProgress = true; //-------------------------------------------- public static String NEWLINE = System.getProperty("line.separator"); //-------------------------------------------- //-- CONSTRUCTORS public SftpUpload() { this.reset(); } //-- constr: () //-------------------------------------------- public SftpUpload(String sServer, String sAccountName) { this.reset(); this.serverName = sServer; this.accountName = sAccountName; } //-------------------------------------------- public SftpUpload( String sFileName, String sServer, String sAccountName, String sServerPath) { this.reset(); this.setLocalFileName(sFileName); this.serverName = sServer; this.accountName = sAccountName; this.serverPath = sServerPath; } //-- METHODS //-------------------------------------------- /** this method sets most of the internal fields to * nothing */ public void reset() { this.fileName = ""; this.serverName = ""; this.serverPath = ""; this.accountName = ""; this.accountPassword = ""; this.failureCause = ""; this.errorMessage = new StringBuffer(""); this.hasStarted = false; this.wasSuccessful = false; this.hasFinished = false; this.startTime = new Date(0); this.finishTime = new Date(0); //-- show progress should not be reset //this.showProgress = false; } //-- method: reset //-------------------------------------------- /* return the target to download */ public String getLocalFileName() { return this.fileName; } //-------------------------------------------- public void setLocalFileName(String sLocalFileName) { File fLocalFile; this.reset(); fLocalFile = new File(sLocalFileName); if (!fLocalFile.exists()) { this.failureCause = "Local file doesnt exist"; this.errorMessage.append("The local file " + sLocalFileName); this.errorMessage.append(" does not appear to exist "); this.invalidFileName = true; return; } if (!fLocalFile.canRead()) { this.failureCause = "Local file cannot be read"; this.errorMessage.append("The local file " + sLocalFileName); this.errorMessage.append(" does not appear to be readable "); this.invalidFileName = true; return; } if (fLocalFile.isDirectory()) { this.failureCause = "Local file path is a directory"; this.errorMessage.append("The local file " + sLocalFileName); this.errorMessage.append( " appears to be a directory. This object does not attempt "); this.errorMessage.append( " to handle the uploading of entire directories. "); this.invalidFileName = true; return; } this.invalidFileName = false; this.fileSize = fLocalFile.length(); this.fileName = fLocalFile.getAbsolutePath(); } //-------------------------------------------- public void setAccountName(String sAccountName) { this.accountName = sAccountName; } //-------------------------------------------- public String getAccountName() { return this.accountName; } //-------------------------------------------- public void setPassword(String sPassword) { this.accountPassword = sPassword; } //-------------------------------------------- public String getPassword() { return this.accountPassword; } //-------------------------------------------- //-------------------------------------------- /** tries to set the local directory. If a bad string is * given it returns false. a legacy from WebDownload */ public boolean setLocalDirectory(String sLocalDirectoryName) { File fDirectory = new File(sLocalDirectoryName); if (!fDirectory.exists()) { return false; } if (!fDirectory.isDirectory()) { return false; } //-- remove a final path separator from the name if (sLocalDirectoryName.endsWith(File.separator)) { this.directoryName = sLocalDirectoryName.substring(0, sLocalDirectoryName.length() - 1); } else { this.directoryName = sLocalDirectoryName; } return true; } //-- //-------------------------------------------- /* advises whether the attempted download was carried out successfully */ public boolean wasSuccessful() { return this.wasSuccessful; } //-------------------------------------------- /** whether some indicator is printed to the console */ public void showProgress() { this.showProgress = true; } //-------------------------------------------- public void showProgress(boolean bShow) { this.showProgress = bShow; } //-------------------------------------------- public void setProgressMarker(String sMarker) { this.PROGRESS_MARKER = sMarker; } //-------------------------------------------- /* informs of the average upload speed */ public int getAverageSpeed() { int iAverageSpeed = 0; long lUploadDuration = this.getUploadDuration(); if (!this.wasSuccessful) { return 0; } if (lUploadDuration == 0) { return 0; } //-- iAverageSpeed = (int)(this.fileSize/this.getUploadDuration()); return iAverageSpeed; } //-------------------------------------------- /** attempt the upload and fail with dignity and grace */ public void upload() { this.hasStarted = true; this.startTime = new Date(); if (this.invalidFileName) { return; } if (this.fileName.equals("")) { this.failureCause = "No local file name specified"; this.errorMessage.append( "No local file was specified for uploading to the "); this.errorMessage.append("sftp server. "); return; } // try // { // Configure J2SSH (This will attempt to install the // bouncycastle provider under jdk 1.3.1) /* BufferedReader brConsole; brConsole = new BufferedReader( new InputStreamReader(System.out)); String sMessageLine; */ try { ConfigurationLoader.initialize(false); } catch (ConfigurationException e) { this.failureCause = "The ssh tools could not be configured"; this.errorMessage.append(e); this.wasSuccessful = false; return; } /* sMessageLine = brConsole.readLine(); while (sMessageLine != null) { System.out.println("**" + sMessageLine); sMessageLine.readLine(); } */ SshClient ssh = new SshClient(); try { //-- the line below should be changed to allow the //-- user to choose whether to accept the hosts key //-- ssh.connect(this.serverName, new IgnoreHostKeyVerification()); } catch (IOException e) { this.failureCause = "A connection to the host could not be established"; this.errorMessage.append( "A connection to the host " + this.serverName); this.errorMessage.append( " could not be established "); this.errorMessage.append(e); this.wasSuccessful = false; return; } // Create a password authentication instance PasswordAuthenticationClient pwd = new PasswordAuthenticationClient(); pwd.setUsername(this.accountName); pwd.setPassword(this.accountPassword); int iAuthenticationResult; try { iAuthenticationResult = ssh.authenticate(pwd); } catch (IOException e) { this.failureCause = "A connection to the host for authentication could not be established"; this.errorMessage.append( "A connection to the host " + this.serverName); this.errorMessage.append( " could not be established during authentication "); this.errorMessage.append(e); this.wasSuccessful = false; return; } if (iAuthenticationResult != AuthenticationProtocolState.COMPLETE) { this.failureCause = "The authentication failed "; this.errorMessage.append( "The authentication failed for account "); this.errorMessage.append(this.accountName + " on the server "); this.errorMessage.append(this.serverName); this.wasSuccessful = false; return; } SftpClient sftp; try { sftp = ssh.openSftpClient(); } catch (IOException e) { this.failureCause = "IOException while opening sftp client "; this.errorMessage.append( "IOException while opening sftp client "); this.errorMessage.append(e); this.wasSuccessful = false; return; } if (this.showProgress) { System.out.println( "Changing directory to " + this.serverPath); } try { sftp.cd(this.serverPath); } catch (IOException e) { this.failureCause = "IOException changing directory "; this.errorMessage.append( "IOException while changing directory "); this.errorMessage.append(e); this.wasSuccessful = false; return; } if (this.showProgress) { System.out.println( "Current directory now " + sftp.pwd()); } if (this.showProgress) { System.out.println("putting " + this.fileName); } try { sftp.put(this.fileName); } catch (IOException e) { this.failureCause = "IOException while putting the file "; this.errorMessage.append( "IOException while putting the file "); this.errorMessage.append(e); this.wasSuccessful = false; return; } if (this.showProgress) { System.out.println("quitting ..."); } try { sftp.quit(); } catch (IOException e) { this.failureCause = "IOException while quiting the sftp connection "; this.errorMessage.append( "IOException while quiting the sftp connection "); this.errorMessage.append(e); this.wasSuccessful = false; return; } if (this.showProgress) { System.out.println("disconnecting ..."); } ssh.disconnect(); //sftp.mkdir("j2ssh"); //sftp.chmod(0777, "j2ssh"); //sftp.lcd("c:/"); //sftp.get("somefile.txt", "anotherfile.txt"); //sftp.rm("j2ssh"); this.finishTime = new Date(); this.wasSuccessful = true; this.hasFinished = true; } //-- method: upload() //-------------------------------------------- /** prints information such as the start time, the finish * time, the duration and the success or failure of the * download. */ public String printStatistics() { StringBuffer sbOutput = new StringBuffer(""); sbOutput.append(NEWLINE); sbOutput.append("Attempted to put file >"); sbOutput.append(this.fileName); sbOutput.append(NEWLINE); sbOutput.append("to server >"); sbOutput.append(this.serverName); sbOutput.append(NEWLINE); sbOutput.append("with account name >"); sbOutput.append(this.accountName); sbOutput.append(" ("); sbOutput.append(this.accountPassword); sbOutput.append(")"); sbOutput.append(NEWLINE); sbOutput.append("using server path >"); sbOutput.append(this.serverPath); sbOutput.append(NEWLINE); if (this.wasSuccessful) { sbOutput.append("Result of the download >"); sbOutput.append("SUCCESS"); sbOutput.append(NEWLINE); } else { sbOutput.append("Result of the download >"); sbOutput.append("FAILURE"); sbOutput.append(NEWLINE); } sbOutput.append("Download duration (s) >"); sbOutput.append((float)this.getUploadDuration()/1000); sbOutput.append(NEWLINE); sbOutput.append("File size >"); sbOutput.append(this.fileSize); sbOutput.append(NEWLINE); sbOutput.append("Start Time >"); sbOutput.append(this.startTime); sbOutput.append(NEWLINE); sbOutput.append("Finish Time >"); sbOutput.append(this.finishTime); sbOutput.append(NEWLINE); sbOutput.append("Average upload speed (kbyte/s) >"); sbOutput.append(this.getAverageSpeed()); sbOutput.append(NEWLINE); if (!this.failureCause.equals("")) { sbOutput.append("Cause of download failure >"); sbOutput.append(this.failureCause); sbOutput.append(NEWLINE); } if (!this.errorMessage.toString().equals("")) { sbOutput.append("Error Messages generated during the download >"); sbOutput.append(NEWLINE); sbOutput.append(this.errorMessage); sbOutput.append(NEWLINE); } sbOutput.append(""); sbOutput.append(""); sbOutput.append(""); return sbOutput.toString(); } //-------------------------------------------- /* return the number of milliseconds taken to download the file. */ public long getUploadDuration() { if (this.finishTime.getTime() == 0) { return 0; } if (this.startTime.getTime() == 0) { return 0; } return this.finishTime.getTime() - this.startTime.getTime(); } //-------------------------------------------- /** print a message to reassure the user */ public String printStartMessage() { StringBuffer sbReturn = new StringBuffer(""); sbReturn.append("Attempting to put " + this.fileName); if (this.showProgress) { //sbReturn.append(", each [" + this.PROGRESS_MARKER + "]"); //sbReturn.append("=" + this.CHUNK_SIZE + " bytes"); } else { sbReturn.append(" (no progress marker)"); } sbReturn.append(NEWLINE); return sbReturn.toString(); } //-- method: printStartMessage //-------------------------------------------- /* how is this different from toString */ public String print() { return this.printStatistics(); } //-------------------------------------------- /** a concise summary of what happened */ public String toString() { StringBuffer sbOutput = new StringBuffer(""); sbOutput.append("sftp upload "); sbOutput.append("(file="); sbOutput.append(this.fileName); sbOutput.append(")"); sbOutput.append(" --> "); sbOutput.append(this.serverName); sbOutput.append(" path:"); sbOutput.append(this.serverPath); sbOutput.append(" account:"); sbOutput.append(this.accountName); sbOutput.append(""); if (this.wasSuccessful) { sbOutput.append(" -successful-"); } else { sbOutput.append(" -failed-"); } sbOutput.append(" took:"); sbOutput.append((float)this.getUploadDuration()/1000); sbOutput.append("s"); sbOutput.append(", size:"); sbOutput.append(this.fileSize); //sbOutput.append(", speed (kb/s):"); //sbOutput.append(this.getAverageSpeed()); sbOutput.append(" -at- "); sbOutput.append(this.startTime); sbOutput.append(NEWLINE); sbOutput.append(""); return sbOutput.toString(); } //-- method: toString() //-------------------------------------------- /** to allow for testing and one-off downloads */ public static void main(String[] args) throws Exception { String sUsageMessage = "usage: java SftpUpload file server account pwd path"; String sFileName; String sServerName; String sAccountName; String sPassword; String sServerPath; if (args.length < 5) { System.out.println(sUsageMessage); System.exit(-1); } sFileName = args[0]; sServerName = args[1]; sAccountName = args[2]; sPassword = args[3]; sServerPath = args[4]; SftpUpload suTest = new SftpUpload(sFileName, sServerName, sAccountName, sServerPath); suTest.setPassword(sPassword); suTest.showProgress(); System.out.println(suTest.printStartMessage()); suTest.upload(); System.out.println(suTest.printStatistics()); System.out.println(suTest.toString()); } //-- main() } //-- WebDownload class