001/* 002 * Version 0.70 01/04/2002 003 * 004 * Visit my url for update: http://www.geocities.com/beapetrovicova/ 005 * 006 * jFtp was developed by Bea Petrovicova <beapetrovicova@yahoo.com>. 007 * The design and implementation of jFtp are available for royalty-free 008 * adoption and use. This software is provided 'as is' without any 009 * guarantees. Copyright is retained by Bea Petrovicova. Redistribution 010 * of any part of jFtp or any derivative works must include this notice. 011 * 012 */ 013 014package cz.dhl.ftp; 015 016import cz.dhl.io.CoSource; 017import java.io.IOException; 018 019/** 020 * Allows connect to FTP server and 021 * maintains control connection. 022 * 023 * @Version 0.70 01/04/2002 024 * @author Bea Petrovicova <beapetrovicova@yahoo.com> 025 */ 026public final class Ftp implements CoSource 027{ 028 /** Default FTP port number. */ 029 public static final int PORT = 21; 030 031 private FtpContext context = new FtpContext(); 032 FtpControlSocket control = new FtpControlSocket(context); 033 034 /** Creates a new Ftp instance. */ 035 public Ftp() {} 036 037 /** Connect & login. 038 * @param connect Connection details. 039 * @return port Server FTP port number normally 21. */ 040 public boolean connect(FtpConnect connect) throws IOException 041 { if(connect(connect.getHostName(),connect.getPortNum())) 042 if(login(connect.getUserName(),connect.getPassWord())) 043 { String pathname = connect.getPathName(); 044 if(connect.getPathName().length() > 0) 045 cd(connect.getPathName()); 046 } else disconnect(); 047 return isConnected(); 048 } 049 050 /** Connect to server, open control connection. 051 * @param server Server DNS server name or dot delimited IP address. 052 * @return port Server FTP port number normally 21. */ 053 public boolean connect(String server,int port) throws IOException 054 { if(!isConnected() && server!=null) 055 { if(control.connect(server, port)) 056 { if(!control.completeCommand(FtpInterpret.getReplies("login-done"))) 057 { printlog("< Can't obtain welcome message from host! >"); 058 control.disconnect(); return false; 059 } else return true; 060 } else return false; 061 } else return false; 062 } 063 064 /** Disconnect from server, close control connection. */ 065 public void disconnect() 066 { control.disconnect(); } 067 068 /** Abort connection. */ 069 public void abort() 070 { //context.setConsole(null); 071 disconnect(); 072 } 073 074 /** Log in to server, enter username and password. 075 * <P><B>USER</B> - user name.</P> 076 * <P>The argument field is a Telnet string identifying the 077 * user. The user identification is that does require the 078 * server for access to its file system. This command will 079 * normally be the first command transmitted by the user after 080 * the control connections are made (some servers may require 081 * this). Additional identification information in the form of 082 * a password and/or an account command may also be required 083 * by some servers. Servers may allow a new USER command to 084 * be entered at any point in order to change the access 085 * control and/or accounting information. This has the effect 086 * of flushing any user, password, and account information 087 * already supplied and beginning the login sequence again. 088 * All transfer parameters are unchanged and any file transfer 089 * in progress is completed under the old access control 090 * parameters.</P> 091 * <P><B>PASS</B> - password.</P> 092 * <P>The argument field is a Telnet string specifying the user's 093 * password. This command must be immediately preceded by the 094 * user name command, and, for some sites, completes the 095 * user's identification for access control. Since password 096 * information is quite sensitive, it is desirable in general 097 * to "mask" it or suppress typeout. It appears that the 098 * server has no foolproof way to achieve this. It is 099 * therefore the responsibility of the user-FTP process to 100 * hide the sensitive password information.</P> 101 * @param username Server account username. 102 * @param password Server account password. 103 * @return True on success. */ 104 public boolean login(String username,String password) throws IOException 105 { if(control.executeCommand("USER " + username)) 106 if(control.executeCommand("PASS " + password)) 107 { syst(); return true; } 108 else { printlog("< Can't login to host. >"); return false; } 109 else { printlog("< Can't login to host. >"); return false; } 110 } 111 112 /** Returns server host name. 113 * @return Server host name on success. */ 114 public String host() throws IOException 115 { if(isConnected()) 116 return control.server; 117 else throw new IOException("Ctrl: No Connection!"); 118 } 119 120 /** Enter custom server command. 121 * <P>Not all FTP commands are accepted. 122 * Exceptions are especially commands for transferring 123 * files and altering way data transfer is performed.</P> 124 * @return True on success. */ 125 public boolean command(String commandline) 126 { return control.manualCommand(commandline); } 127 128 /** Remove server directory. 129 * <P><B>RMD</B> - remove directory.</P> 130 * <P>This command causes the directory specified in the pathname 131 * to be removed as a directory (if the pathname is absolute) 132 * or as a subdirectory of the current working directory (if 133 * the pathname is relative).</P> 134 * @param directory Name of directory to be removed. 135 * @return True on success. */ 136 public boolean rmdir(String directory) 137 { return control.executeCommand("RMD " + directory); } 138 139 /** Make server working directory. 140 * <P><B>MKD</B> - make directory.</P> 141 * <P>This command causes the directory specified in the 142 * pathname to be created as a directory (if the pathname is 143 * absolute) or as a subdirectory of the current working 144 * directory (if the pathname is relative).</P> 145 * @param directory Name of newly created directory. 146 * @return True on success. */ 147 public boolean mkdir(String directory) 148 { return control.executeCommand("MKD " + directory); } 149 150 /** Print server working directory. 151 * <P><B>PWD</B> - print working directory.</P> 152 * <P>This command causes the name of the current working 153 * directory to be returned in the reply.</P> 154 * @return Current working directory. */ 155 public String pwd() throws IOException 156 { if(isConnected()) 157 { String directory = null, replyline; 158 control.executeCommand("PWD"); 159 replyline = control.replyOfCommand(); 160 try 161 { directory = replyline.substring( 162 replyline.indexOf('\"')+1,replyline.lastIndexOf('\"')); } 163 catch (StringIndexOutOfBoundsException e) 164 { throw new IOException("Ctrl: PWD, Invalid Format!"); } 165 return directory; 166 } else throw new IOException("Ctrl: PWD, No Connection!"); 167 } 168 169 /** Print server system. 170 * <P><B>SYST</B> - print server system.</P> 171 * <P>This command causes the name name and version of 172 * the server system to be returned in the reply.</P> 173 * @return Server system. */ 174 public String syst() throws IOException 175 { if(isConnected()) 176 { control.executeCommand("SYST"); 177 String system = control.replyOfCommand(); 178 getContext().setServerSystemMode(FtpSetting.UNIX); 179 if(system!=null && system.toUpperCase().indexOf("WINDOWS") >=0) 180 { getContext().setServerSystemMode(FtpSetting.WIN); 181 printlog("< File: Setting 'WIN' Server Mode >"); } 182 return system; 183 } else throw new IOException("Ctrl: PWD, No Connection!"); 184 } 185 186 /** Change server working directory. 187 * <P><B>CWD</B> - change working directory.</P> 188 * <P>This command allows the user to work with a different 189 * directory or dataset for file storage or retrieval without 190 * altering his login or accounting information. Transfer 191 * parameters are similarly unchanged. The argument is a 192 * pathname specifying a directory or other system dependent 193 * file group designator.</P> 194 * @param directory Name of new working directory.</P> 195 * @return True on success. */ 196 public boolean cd(String directory) 197 { return control.executeCommand("CWD " + directory); } 198 199 /** Change server directory to parent. 200 * <P><B>CDUP</B> - change up.</P> 201 * <P>This command is a special case of CWD, and is included to 202 * simplify the implementation of programs for transferring 203 * directory trees between operating systems having different 204 * File Transfer Protocol syntaxes for naming the parent 205 * directory.</P> 206 * @return True on success. */ 207 public boolean cdup() 208 { return control.executeCommand("CDUP"); } 209 210 /** Delete server file. 211 * <P><B>DELE</B> - delete.</P> 212 * <P>This command causes the file specified in the pathname 213 * to be deleted at the server site. If an extra level of 214 * protection is desired (such as the query, "Do you really 215 * wish to delete?"), it should be provided by the user-FTP 216 * process.</P> 217 * @param filename Name of file to be deleted. 218 * @return True on success. */ 219 public boolean rm(String filename) 220 { return control.executeCommand("DELE " + filename); } 221 222 /** Rename server file. 223 * <P><B>RNFR</B> - rename from.</P> 224 * <P>This command specifies the old pathname of the file, 225 * which is to be renamed. This command must be immediately 226 * followed by a "rename to" command specifying the new file 227 * pathname.</P> 228 * <P><B>RNTO</B> - rename to.</P> 229 * <P>This command specifies the new pathname of the file 230 * specified in the immediately preceding "rename from" 231 * command. Together the two commands cause a file to be 232 * renamed.</P> 233 * @param oldfilename Old name of file. 234 * @param newfilename New name of file. 235 * @return True on success. */ 236 public boolean mv(String oldfilename, String newfilename) 237 { if(control.executeCommand("RNFR " + oldfilename)) 238 return control.executeCommand("RNTO " + newfilename); 239 else return false; 240 } 241 242 /** Change server file mode. 243 * @param filename Name of file to change mode. 244 * @param mode Mode is UNIX "777" format string. 245 * @return True on success. */ 246 public boolean chmod(String filename, String mode) 247 { return control.executeCommand("SITE CHMOD " + mode + " " + filename); } 248 249 /** Tests connection. */ 250 public boolean isConnected() 251 { return control.isConnected(); } 252 253 /** Return FtpContext object. 254 * @return context 255 * @see cz.dhl.ftp.FtpContext */ 256 public FtpContext getContext() { return context; } 257 258 /* Print message line to output console. */ 259 void printlog(String message) { context.printlog(message); } 260 261 /* Print object to standard output. */ 262 void printerr(Exception exception) { context.printerr(exception); } 263};