001: /*
002: * Created on Aug 14, 2004
003: *
004: * This file is part of Thingamablog. ( http://thingamablog.sf.net )
005: *
006: * Copyright (c) 2004, Bob Tantlinger All Rights Reserved.
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or (at your option) any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
021: * USA.
022: *
023: */
024: package net.sf.thingamablog.transport;
025:
026: import java.io.File;
027: import java.io.FileInputStream;
028: import java.io.InputStream;
029: import java.util.logging.Level;
030: import java.util.logging.Logger;
031:
032: import com.jcraft.jsch.Channel;
033: import com.jcraft.jsch.ChannelSftp;
034: import com.jcraft.jsch.JSch;
035: import com.jcraft.jsch.Session;
036: import com.jcraft.jsch.SftpProgressMonitor;
037: import com.jcraft.jsch.UserInfo;
038:
039: /**
040: * Transport for publishing weblogs via SFTP
041: *
042: * @author Bob Tantlinger
043: */
044: public class SFTPTransport extends RemotePublishTransport {
045: private static Logger logger = Logger
046: .getLogger("net.sf.thingamablog.transport");
047: private ChannelSftp sftp;
048: private String failMsg = "";
049:
050: /* (non-Javadoc)
051: * @see net.sf.thingamablog.transport.PublishTransport#connect()
052: */
053: public boolean connect() {
054: failMsg = "";
055: if (isConnected) {
056: failMsg = "Already connected";
057: return false;
058: }
059:
060: try {
061: JSch jsch = new JSch();
062: Session session = jsch.getSession(getUserName(),
063: getAddress(), getPort());
064:
065: // password will be given via UserInfo interface.
066: UserInfo ui = new MyUserInfo(getPassword());
067: session.setUserInfo(ui);
068:
069: logger.info("Connecting to SFTP");
070: session.connect();
071: logger.info("Logged in to SFTP");
072:
073: Channel channel = session.openChannel("sftp");
074: channel.connect();
075: sftp = (ChannelSftp) channel;
076:
077: isConnected = true;
078: return true;
079: } catch (Exception ex) {
080: failMsg = "Error logging in to " + getAddress();
081: failMsg += "\n" + ex.getMessage();
082: logger.log(Level.WARNING, failMsg, ex);
083: ex.printStackTrace();
084: }
085:
086: return false;
087: }
088:
089: /* (non-Javadoc)
090: * @see net.sf.thingamablog.transport.PublishTransport#publishFile(java.lang.String, java.io.File, net.sf.thingamablog.transport.TransportProgress)
091: */
092: public boolean publishFile(String pubPath, File file,
093: TransportProgress tp) {
094: if (sftp == null) {
095: failMsg = "SFTP Client not initialized!";
096: return false;
097: }
098:
099: if (!isConnected()) {
100: failMsg = "Not Connected!!!";
101: return false;
102: }
103:
104: if (tp.isAborted()) {
105: failMsg = "Aborted";
106: return false;
107: }
108:
109: if (!pubPath.endsWith("/"))
110: pubPath += "/"; //append a trailing slash if needed
111:
112: try {
113: String cwd = sftp.pwd();
114: if (!cwd.endsWith("/"))
115: cwd += "/";
116: if (!pubPath.equals(cwd)) {
117: boolean changedDir = false;
118: try {
119: sftp.cd(pubPath); //try to change to the pub path
120: changedDir = true; //changed dir OK
121: System.out.println("Changed to " + pubPath);
122: } catch (Exception cdEx) {
123: logger.log(Level.WARNING,
124: "Problem changing SFTP dir", cdEx);
125: }
126:
127: if (!changedDir) {
128: //was unable to change dir. the dir likely does not exist
129: //so we'll try making the dir structure of pubPath
130: mkdirs(pubPath);
131: //sftp.cd(pubPath);
132: }
133: }
134:
135: int mode = ChannelSftp.OVERWRITE;
136: //String dest = pubPath + file.getName();
137: InputStream is = new FileInputStream(file);
138: sftp.put(is, file.getName(), new MyProgressMonitor(tp),
139: mode);
140: is.close();
141:
142: return true;
143: } catch (Exception ex) {
144: failMsg = "Error publishing file to " + pubPath;
145: failMsg += "\n" + ex.getMessage();
146: logger.log(Level.WARNING, failMsg, ex);
147: ex.printStackTrace();
148: }
149:
150: return false;
151: }
152:
153: private void mkdirs(String path) throws Exception {
154: //sftp.cd("/"); //change to the root dir
155:
156: //String dirs[] = splitPath(path);
157:
158: String cwd = sftp.pwd();
159: //System.out.println("CWD: " + cwd);
160:
161: while (!path.startsWith(cwd)) {
162: System.out.println(cwd + " " + path);
163: sftp.cd("..");//should throw exception if can't cdup
164: System.out.println("CDUP!");
165: cwd = sftp.pwd();
166: }
167:
168: String mkPath = path.substring(cwd.length(), path.length());
169: System.out.println("DIRS TO MAKE: " + mkPath);
170:
171: String dirs[] = splitPath(mkPath);
172:
173: for (int i = 0; i < dirs.length; i++) {
174: System.out.println("mkdir " + dirs[i]);
175: logger.info("mkdir " + dirs[i]);
176: //swallow exception that results from trying to
177: //make a dir that already exists
178: try {
179: sftp.mkdir(dirs[i]);
180: } catch (Exception ex) {
181: }
182:
183: //change to the new dir
184: //throws an exception if something went wrong
185: sftp.cd(dirs[i]);
186: }
187: }
188:
189: public String getFailureReason() {
190: return failMsg;
191: }
192:
193: /* (non-Javadoc)
194: * @see net.sf.thingamablog.transport.PublishTransport#disconnect()
195: */
196: public boolean disconnect() {
197: try {
198: System.out.println("Disconnecting SFTP...");
199: if (sftp != null)
200: sftp.exit();
201: } catch (Exception ioe) {
202: logger.log(Level.WARNING,
203: "Problem disconnecting from SFTP", ioe);
204: }
205:
206: if (!isSavePassword())
207: setPassword("");
208:
209: System.out.println("Disconnected SFTP");
210: logger.info("Disconnected SFTP");
211: isConnected = false;
212: return true;
213: }
214:
215: private class MyProgressMonitor implements SftpProgressMonitor {
216: private TransportProgress progress;
217:
218: public MyProgressMonitor(TransportProgress tp) {
219: progress = tp;
220: }
221:
222: public void init(int op, String src, String dest, long max) {
223: }
224:
225: public boolean count(long count) {
226: progress.bytesTransferred(count);
227: return !progress.isAborted();
228: }
229:
230: public void end() {
231: }
232: }
233:
234: private class MyUserInfo implements UserInfo {
235: String pw;
236:
237: public MyUserInfo(String p) {
238: pw = p;
239: }
240:
241: public String getPassword() {
242: return pw;
243: }
244:
245: public boolean promptYesNo(String str) {
246: return true;
247: }
248:
249: public String getPassphrase() {
250: return null;
251: }
252:
253: public boolean promptPassphrase(String message) {
254: return true;
255: }
256:
257: public boolean promptPassword(String message) {
258: return true;
259: }
260:
261: public void showMessage(String message) {
262: }
263: }
264:
265: }
|