/* * Copyright (C) 2012 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://openbd.rg/ * $Id: cfFTPData.java 2275 2012-09-04 00:20:26Z alan $ */ package com.naryx.tagfusion.cfm.tag.net.ftp; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import com.naryx.tagfusion.cfm.engine.cfBooleanData; import com.naryx.tagfusion.cfm.engine.cfNumberData; import com.naryx.tagfusion.cfm.engine.cfStringData; import com.naryx.tagfusion.cfm.engine.cfStructReadOnlyData; import com.naryx.tagfusion.cfm.engine.dataNotSupportedException; public class cfFTPData extends cfStructReadOnlyData { private static final long serialVersionUID = 1L; private FTPClient ftpclient = null; private boolean succeeded = true; private int errorCode = 0; private String errorText = ""; private String username, password; private int inUse = 0; private Object semaphore; public cfFTPData( String _Server, int _Port, String _Username, String _Password ){ setPrivateData( "server", new cfStringData(_Server) ); setPrivateData( "port", new cfNumberData(_Port) ); this.username = _Username; this.password = _Password; ftpclient = new FTPClient(); } public cfFTPData(boolean b, int i, String string) { succeeded = b; errorCode = i; errorText = string; } public void finalize() throws Throwable { close(); } public synchronized void lock(){ while ( inUse != 0 ) try{ semaphore.wait(); }catch(Exception E){} inUse++; } public synchronized void unlock(){ inUse -= 1; if ( inUse < 0 ) inUse = 0; try{ semaphore.notify(); }catch(Exception E){} } public void setTimeout( int timeoutMS ){ ftpclient.setDataTimeout(timeoutMS); } private void setStatusData(){ setPrivateData( "succeeded", cfBooleanData.getcfBooleanData(succeeded) ); setPrivateData( "connected", cfBooleanData.getcfBooleanData(ftpclient.isConnected()) ); setPrivateData( "errorcode", new cfNumberData(errorCode) ); setPrivateData( "errortext", new cfStringData(errorText) ); } public boolean isOpen(){ return ftpclient.isConnected(); } public void close(){ if ( ftpclient.isConnected() ){ try { ftpclient.disconnect(); } catch (IOException e) {} } } public void open(){ if ( !ftpclient.isConnected() ){ try { ftpclient.connect( getData("server").getString(), getData("port").getInt() ); errorCode = ftpclient.getReplyCode(); if (!FTPReply.isPositiveCompletion(errorCode)) throw new Exception( ftpclient.getReplyString() ); succeeded = ftpclient.login(username, password); errorCode = ftpclient.getReplyCode(); } catch (Exception e) { succeeded = false; errorText = e.getMessage(); } setStatusData(); } } public boolean isSucceeded() { return succeeded; } public int getErrorCode() { return errorCode; } public String getErrorText() { return errorCode + " " + ec.get( String.valueOf(errorCode) ) + " " + errorText; } public void setPassive(boolean passive) { if ( passive ) ftpclient.enterLocalPassiveMode(); else ftpclient.enterLocalActiveMode(); } public FTPFile[] listFiles(String directory) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return null; } FTPFile[] files = null; try{ files = ftpclient.listFiles(directory); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return files; } public String getServer() throws dataNotSupportedException { return getData("server").getString(); } public String getCurrentDirectory() { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return null; } String curdir = null; try{ curdir = ftpclient.printWorkingDirectory(); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return curdir; } public boolean setCurrentDirectory(String directory) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.changeWorkingDirectory(directory); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public boolean makeDirectory(String file) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.makeDirectory(file); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public boolean removeDirectory(String file) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.removeDirectory(file); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public boolean removeFile(String file) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.deleteFile(file); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public boolean renameFile(String oldfile, String newfile) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.rename(oldfile, newfile); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public boolean setTransferMode(int transferMode) { try { ftpclient.setFileTransferMode(transferMode); ftpclient.setFileType(transferMode); return true; } catch (IOException e) { errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); return false; }finally{ setStatusData(); } } public void downloadFile(File fileLocal, String remoteFile) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return; } FileOutputStream fos = null; BufferedOutputStream bos = null; try{ ftpclient.setAutodetectUTF8(true); fos = new FileOutputStream( fileLocal ); bos = new BufferedOutputStream(fos); ftpclient.retrieveFile(remoteFile, bos); bos.flush(); bos.close(); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ if ( fos != null ){ try { fos.close(); } catch (IOException e) {} } setStatusData(); } } public void uploadFile(File fileLocal, String remoteFile) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return; } FileInputStream fis = null; BufferedInputStream bis = null; try{ ftpclient.setAutodetectUTF8(true); fis = new FileInputStream( fileLocal ); bis = new BufferedInputStream(fis); ftpclient.storeFile(remoteFile, bis); bis.close(); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ if ( fis != null ){ try { fis.close(); } catch (IOException e) {} } setStatusData(); } } public boolean siteCmd(String cmd) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return false; } boolean bResult = false; try{ bResult = ftpclient.sendSiteCommand(cmd); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } public String cmd(String cmd) { if ( !ftpclient.isConnected() ){ errorText = "not connected"; succeeded = false; return ""; } String params = ""; if ( cmd.indexOf(" ") != -1){ params = cmd.substring( cmd.indexOf(" ") + 1 ); cmd = cmd.substring( 0, cmd.indexOf(" ") ); } String bResult = ""; try{ ftpclient.doCommand(cmd, params); bResult = ftpclient.getReplyString(); errorCode = ftpclient.getReplyCode(); succeeded = FTPReply.isPositiveCompletion(errorCode); }catch(Exception e){ errorCode = ftpclient.getReplyCode(); errorText = e.getMessage(); }finally{ setStatusData(); } return bResult; } private static HashMap<String,String> ec; static{ ec = new HashMap<String,String>(); ec.put("100","Series: The requested action is being initiated, expect another reply before proceeding with a new command."); ec.put("110","Restart marker replay . In this case, the text is exact and not left to the particular implementation; it must read: MARK yyyy = mmmm where yyyy is User-process data stream marker, and mmmm server's equivalent marker (note the spaces between markers and =)."); ec.put("120","Service ready in nnn minutes."); ec.put("125","Data connection already open; transfer starting."); ec.put("150","File status okay; about to open data connection."); ec.put("200","Command okay."); ec.put("202","Command not implemented, superfluous at this site."); ec.put("211","System status, or system help reply."); ec.put("212","Directory status."); ec.put("213","File status."); ec.put("214","Help message.On how to use the server or the meaning of a particular non-standard command. This reply is useful only to the human user."); ec.put("215","NAME system type. Where NAME is an official system name from the registry kept by IANA."); ec.put("220","Service ready for new user."); ec.put("221","Service closing control connection."); ec.put("225","Data connection open; no transfer in progress."); ec.put("226","Closing data connection. Requested file action successful (for example, file transfer or file abort)."); ec.put("227","Entering Passive Mode (h1,h2,h3,h4,p1,p2)."); ec.put("228","Entering Long Passive Mode (long address, port)."); ec.put("229","Entering Extended Passive Mode (|||port|)."); ec.put("230","User logged in, proceed. Logged out if appropriate."); ec.put("231","User logged out; service terminated."); ec.put("232","Logout command noted, will complete when transfer done."); ec.put("250","Requested file action okay, completed."); ec.put("257","\"PATHNAME\" created."); ec.put("331","User name okay, need password."); ec.put("332","Need account for login."); ec.put("350","Requested file action pending further information"); ec.put("421","Service not available, closing control connection. This may be a reply to any command if the service knows it must shut down."); ec.put("425","Can't open data connection."); ec.put("426","Connection closed; transfer aborted."); ec.put("430","Invalid username or password"); ec.put("434","Requested host unavailable."); ec.put("450","Requested file action not taken."); ec.put("451","Requested action aborted. Local error in processing."); ec.put("452","Requested action not taken. Insufficient storage space in system.File unavailable (e.g., file busy)."); ec.put("500","Syntax error, command unrecognized. This may include errors such as command line too long."); ec.put("501","Syntax error in parameters or arguments."); ec.put("502","Command not implemented."); ec.put("503","Bad sequence of commands."); ec.put("504","Command not implemented for that parameter."); ec.put("530","Not logged in."); ec.put("532","Need account for storing files."); ec.put("550","Requested action not taken. File unavailable (e.g., file not found, no access)."); ec.put("551","Requested action aborted. Page type unknown."); ec.put("552","Requested file action aborted. Exceeded storage allocation (for current directory or dataset)."); ec.put("553","Requested action not taken. File name not allowed."); ec.put("631","Integrity protected reply."); ec.put("632","Confidentiality and integrity protected reply."); ec.put("633","Confidentiality protected reply."); } }