/* * Created on Aug 14, 2004 * * This file is part of Thingamablog. ( http://thingamablog.sf.net ) * * Copyright (c) 2004, Bob Tantlinger All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * */ package net.sf.thingamablog.transport; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpProgressMonitor; import com.jcraft.jsch.UserInfo; /** * Transport for publishing weblogs via SFTP * * @author Bob Tantlinger */ public class SFTPTransport extends RemotePublishTransport { private static Logger logger = Logger.getLogger("net.sf.thingamablog.transport"); private ChannelSftp sftp; private String failMsg = ""; /* (non-Javadoc) * @see net.sf.thingamablog.transport.PublishTransport#connect() */ public boolean connect() { failMsg = ""; if(isConnected) { failMsg = "Already connected"; return false; } try { JSch jsch = new JSch(); Session session = jsch.getSession(getUserName(), getAddress(), getPort()); // password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(getPassword()); session.setUserInfo(ui); logger.info("Connecting to SFTP"); session.connect(); logger.info("Logged in to SFTP"); Channel channel = session.openChannel("sftp"); channel.connect(); sftp = (ChannelSftp)channel; isConnected = true; return true; } catch(Exception ex) { failMsg = "Error logging in to " + getAddress(); failMsg += "\n" + ex.getMessage(); logger.log(Level.WARNING, failMsg, ex); ex.printStackTrace(); } return false; } /* (non-Javadoc) * @see net.sf.thingamablog.transport.PublishTransport#publishFile(java.lang.String, java.io.File, net.sf.thingamablog.transport.TransportProgress) */ public boolean publishFile(String pubPath, File file, TransportProgress tp) { if(sftp == null) { failMsg = "SFTP Client not initialized!"; return false; } if(!isConnected()) { failMsg = "Not Connected!!!"; return false; } if(tp.isAborted()) { failMsg = "Aborted"; return false; } if(!pubPath.endsWith("/")) pubPath += "/"; //append a trailing slash if needed try { String cwd = sftp.pwd(); if(!cwd.endsWith("/")) cwd += "/"; if(!pubPath.equals(cwd)) { boolean changedDir = false; try { sftp.cd(pubPath); //try to change to the pub path changedDir = true; //changed dir OK System.out.println("Changed to " + pubPath); } catch(Exception cdEx) { logger.log(Level.WARNING, "Problem changing SFTP dir", cdEx); } if(!changedDir) { //was unable to change dir. the dir likely does not exist //so we'll try making the dir structure of pubPath mkdirs(pubPath); //sftp.cd(pubPath); } } int mode = ChannelSftp.OVERWRITE; //String dest = pubPath + file.getName(); InputStream is = new FileInputStream(file); sftp.put(is, file.getName(), new MyProgressMonitor(tp), mode); is.close(); return true; } catch(Exception ex) { failMsg = "Error publishing file to " + pubPath; failMsg += "\n" + ex.getMessage(); logger.log(Level.WARNING, failMsg, ex); ex.printStackTrace(); } return false; } private void mkdirs(String path) throws Exception { //sftp.cd("/"); //change to the root dir //String dirs[] = splitPath(path); String cwd = sftp.pwd(); //System.out.println("CWD: " + cwd); while(!path.startsWith(cwd)) { System.out.println(cwd + " " + path); sftp.cd("..");//should throw exception if can't cdup System.out.println("CDUP!"); cwd = sftp.pwd(); } String mkPath = path.substring(cwd.length(), path.length()); System.out.println("DIRS TO MAKE: " + mkPath); String dirs[] = splitPath(mkPath); for(int i = 0; i < dirs.length; i++) { System.out.println("mkdir " + dirs[i]); logger.info("mkdir " + dirs[i]); //swallow exception that results from trying to //make a dir that already exists try { sftp.mkdir(dirs[i]); } catch(Exception ex) {} //change to the new dir //throws an exception if something went wrong sftp.cd(dirs[i]); } } public String getFailureReason() { return failMsg; } /* (non-Javadoc) * @see net.sf.thingamablog.transport.PublishTransport#disconnect() */ public boolean disconnect() { try { System.out.println("Disconnecting SFTP..."); if (sftp != null) sftp.exit(); } catch(Exception ioe) { logger.log(Level.WARNING, "Problem disconnecting from SFTP", ioe); } if (!isSavePassword()) setPassword(""); System.out.println("Disconnected SFTP"); logger.info("Disconnected SFTP"); isConnected = false; return true; } private class MyProgressMonitor implements SftpProgressMonitor { private TransportProgress progress; public MyProgressMonitor(TransportProgress tp) { progress = tp; } public void init(int op, String src, String dest, long max) {} public boolean count(long count) { progress.bytesTransferred(count); return !progress.isAborted(); } public void end() {} } private class MyUserInfo implements UserInfo { String pw; public MyUserInfo(String p) { pw = p; } public String getPassword() { return pw; } public boolean promptYesNo(String str) { return true; } public String getPassphrase() { return null; } public boolean promptPassphrase(String message) { return true; } public boolean promptPassword(String message) { return true; } public void showMessage(String message) {} } }