001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.net.ftp; 019 020import java.io.BufferedReader; 021import java.io.BufferedWriter; 022import java.io.IOException; 023import java.io.InputStreamReader; 024import java.io.OutputStreamWriter; 025import java.io.Reader; 026import java.net.Inet4Address; 027import java.net.Inet6Address; 028import java.net.InetAddress; 029import java.net.SocketException; 030import java.net.SocketTimeoutException; 031import java.util.ArrayList; 032 033import org.apache.commons.net.MalformedServerReplyException; 034import org.apache.commons.net.ProtocolCommandSupport; 035import org.apache.commons.net.SocketClient; 036import org.apache.commons.net.io.CRLFLineReader; 037import org.apache.commons.net.util.NetConstants; 038 039/** 040 * FTP provides the basic the functionality necessary to implement your own FTP client. It extends org.apache.commons.net.SocketClient since extending 041 * TelnetClient was causing unwanted behavior (like connections that did not time out properly). 042 * <p> 043 * To derive the full benefits of the FTP class requires some knowledge of the FTP protocol defined in RFC 959. However, there is no reason why you should have 044 * to use the FTP class. The {@link org.apache.commons.net.ftp.FTPClient} class, derived from FTP, implements all the functionality required of an FTP client. 045 * The FTP class is made public to provide access to various FTP constants and to make it easier for adventurous programmers (or those with special needs) to 046 * interact with the FTP protocol and implement their own clients. A set of methods with names corresponding to the FTP command names are provided to facilitate 047 * this interaction. 048 * <p> 049 * You should keep in mind that the FTP server may choose to prematurely close a connection if the client has been idle for longer than a given time period 050 * (usually 900 seconds). The FTP class will detect a premature FTP server connection closing when it receives a 051 * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE } response to a command. When that occurs, the FTP class 052 * method encountering that reply will throw an {@link org.apache.commons.net.ftp.FTPConnectionClosedException} . <code>FTPConectionClosedException</code> is a 053 * subclass of <code> IOException </code> and therefore need not be caught separately, but if you are going to catch it separately, its catch block must appear 054 * before the more general <code> IOException </code> catch block. When you encounter an {@link org.apache.commons.net.ftp.FTPConnectionClosedException} , you 055 * must disconnect the connection with {@link #disconnect disconnect() } to properly clean up the system resources used by FTP. Before disconnecting, you may 056 * check the last reply code and text with {@link #getReplyCode getReplyCode }, {@link #getReplyString getReplyString }, and {@link #getReplyStrings 057 * getReplyStrings}. You may avoid server disconnections while the client is idle by periodically sending NOOP commands to the server. 058 * <p> 059 * Rather than list it separately for each method, we mention here that every method communicating with the server and throwing an IOException can also throw a 060 * {@link org.apache.commons.net.MalformedServerReplyException} , which is a subclass of IOException. A MalformedServerReplyException will be thrown when the 061 * reply received from the server deviates enough from the protocol specification that it cannot be interpreted in a useful manner despite attempts to be as 062 * lenient as possible. 063 * 064 * @see FTPClient 065 * @see FTPConnectionClosedException 066 * @see org.apache.commons.net.MalformedServerReplyException 067 */ 068 069public class FTP extends SocketClient { 070 /** The default FTP data port (20). */ 071 public static final int DEFAULT_DATA_PORT = 20; 072 /** The default FTP control port (21). */ 073 public static final int DEFAULT_PORT = 21; 074 075 /** 076 * A constant used to indicate the file(s) being transferred should be treated as ASCII. This is the default file type. All constants ending in 077 * <code>FILE_TYPE</code> are used to indicate file types. 078 */ 079 public static final int ASCII_FILE_TYPE = 0; 080 081 /** 082 * A constant used to indicate the file(s) being transferred should be treated as EBCDIC. Note however that there are several EBCDIC formats. All 083 * constants ending in <code>FILE_TYPE</code> are used to indicate file types. 084 */ 085 public static final int EBCDIC_FILE_TYPE = 1; 086 087 /** 088 * A constant used to indicate the file(s) being transferred should be treated as a binary image, i.e., no translations should be performed. All constants 089 * ending in <code>FILE_TYPE</code> are used to indicate file types. 090 */ 091 public static final int BINARY_FILE_TYPE = 2; 092 093 /** 094 * A constant used to indicate the file(s) being transferred should be treated as a local type. All constants ending in <code>FILE_TYPE</code> are used to 095 * indicate file types. 096 */ 097 public static final int LOCAL_FILE_TYPE = 3; 098 099 /** 100 * A constant used for text files to indicate a non-print text format. This is the default format. All constants ending in <code>TEXT_FORMAT</code> are used 101 * to indicate text formatting for text transfers (both ASCII and EBCDIC). 102 */ 103 public static final int NON_PRINT_TEXT_FORMAT = 4; 104 105 /** 106 * A constant used to indicate a text file contains format vertical format control characters. All constants ending in <code>TEXT_FORMAT</code> are used to 107 * indicate text formatting for text transfers (both ASCII and EBCDIC). 108 */ 109 public static final int TELNET_TEXT_FORMAT = 5; 110 111 /** 112 * A constant used to indicate a text file contains ASA vertical format control characters. All constants ending in <code>TEXT_FORMAT</code> are used to 113 * indicate text formatting for text transfers (both ASCII and EBCDIC). 114 */ 115 public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6; 116 117 /** 118 * A constant used to indicate a file is to be treated as a continuous sequence of bytes. This is the default structure. All constants ending in 119 * <code>_STRUCTURE</code> are used to indicate file structure for file transfers. 120 */ 121 public static final int FILE_STRUCTURE = 7; 122 123 /** 124 * A constant used to indicate a file is to be treated as a sequence of records. All constants ending in <code>_STRUCTURE</code> are used to indicate file 125 * structure for file transfers. 126 */ 127 public static final int RECORD_STRUCTURE = 8; 128 129 /** 130 * A constant used to indicate a file is to be treated as a set of independent indexed pages. All constants ending in <code>_STRUCTURE</code> are used to 131 * indicate file structure for file transfers. 132 */ 133 public static final int PAGE_STRUCTURE = 9; 134 135 /** 136 * A constant used to indicate a file is to be transferred as a stream of bytes. This is the default transfer mode. All constants ending in 137 * <code>TRANSFER_MODE</code> are used to indicate file transfer modes. 138 */ 139 public static final int STREAM_TRANSFER_MODE = 10; 140 141 /** 142 * A constant used to indicate a file is to be transferred as a series of blocks. All constants ending in <code>TRANSFER_MODE</code> are used to indicate 143 * file transfer modes. 144 */ 145 public static final int BLOCK_TRANSFER_MODE = 11; 146 147 /** 148 * A constant used to indicate a file is to be transferred as FTP compressed data. All constants ending in <code>TRANSFER_MODE</code> are used to indicate 149 * file transfer modes. 150 */ 151 public static final int COMPRESSED_TRANSFER_MODE = 12; 152 153 // We have to ensure that the protocol communication is in ASCII, 154 // but we use ISO-8859-1 just in case 8-bit characters cross 155 // the wire. 156 /** 157 * The default character encoding used for communicating over an FTP control connection. The default encoding is an ASCII-compatible encoding. Some FTP 158 * servers expect other encodings. You can change the encoding used by an FTP instance with {@link #setControlEncoding setControlEncoding}. 159 */ 160 public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1"; 161 162 /** Length of the FTP reply code (3 alphanumerics) */ 163 public static final int REPLY_CODE_LEN = 3; 164 165 private static final String modes = "AEILNTCFRPSBC"; 166 protected int _replyCode; 167 protected ArrayList<String> _replyLines; 168 protected boolean _newReplyString; 169 protected String _replyString; 170 protected String _controlEncoding; 171 172 /** 173 * A ProtocolCommandSupport object used to manage the registering of ProtocolCommandListeners and the firing of ProtocolCommandEvents. 174 */ 175 protected ProtocolCommandSupport _commandSupport_; 176 177 /** 178 * This is used to signal whether a block of multiline responses beginning with xxx must be terminated by the same numeric code xxx See section 4.2 of RFC 179 * 959 for details. 180 */ 181 protected boolean strictMultilineParsing; 182 183 /** 184 * If this is true, then non-multiline replies must have the format: 3-digit code <space> <text> If false, then the 3-digit code does not have to be 185 * followed by space See section 4.2 of RFC 959 for details. 186 */ 187 private boolean strictReplyParsing = true; 188 189 /** 190 * Wraps SocketClient._input_ to facilitate the reading of text from the FTP control connection. Do not access the control connection via 191 * SocketClient._input_. This member starts with a null value, is initialized in {@link #_connectAction_}, and set to null in {@link #disconnect}. 192 */ 193 protected BufferedReader _controlInput_; 194 195 /** 196 * Wraps SocketClient._output_ to facilitate the writing of text to the FTP control connection. Do not access the control connection via 197 * SocketClient._output_. This member starts with a null value, is initialized in {@link #_connectAction_}, and set to null in {@link #disconnect}. 198 */ 199 protected BufferedWriter _controlOutput_; 200 201 /** 202 * The default FTP constructor. Sets the default port to <code>DEFAULT_PORT</code> and initializes internal data structures for saving FTP reply 203 * information. 204 */ 205 public FTP() { 206 setDefaultPort(DEFAULT_PORT); 207 _replyLines = new ArrayList<>(); 208 _newReplyString = false; 209 _replyString = null; 210 _controlEncoding = DEFAULT_CONTROL_ENCODING; 211 _commandSupport_ = new ProtocolCommandSupport(this); 212 } 213 214 /** 215 * Get the reply, but don't pass it to command listeners. Used for keep-alive processing only. 216 * 217 * @since 3.0 218 * @throws IOException on error 219 */ 220 protected void __getReplyNoReport() throws IOException { 221 getReply(false); 222 } 223 224 /** 225 * Send a noop and get the reply without reporting to the command listener. Intended for use with keep-alive. 226 * 227 * @throws IOException on error 228 * @since 3.0 229 */ 230 protected void __noop() throws IOException { 231 final String msg = buildMessage(FTPCmd.NOOP.getCommand(), null); 232 send(msg); 233 __getReplyNoReport(); // This may time out 234 } 235 236 /** 237 * Initiates control connections and gets initial reply. Initializes {@link #_controlInput_} and {@link #_controlOutput_}. 238 */ 239 @Override 240 protected void _connectAction_() throws IOException { 241 _connectAction_(null); 242 } 243 244 /** 245 * Initiates control connections and gets initial reply. Initializes {@link #_controlInput_} and {@link #_controlOutput_}. 246 * 247 * @param socketIsReader the reader to reuse (if non-null) 248 * @throws IOException on error 249 * @since 3.4 250 */ 251 protected void _connectAction_(final Reader socketIsReader) throws IOException { 252 super._connectAction_(); // sets up _input_ and _output_ 253 if (socketIsReader == null) { 254 _controlInput_ = new CRLFLineReader(new InputStreamReader(_input_, getControlEncoding())); 255 } else { 256 _controlInput_ = new CRLFLineReader(socketIsReader); 257 } 258 _controlOutput_ = new BufferedWriter(new OutputStreamWriter(_output_, getControlEncoding())); 259 if (connectTimeout > 0) { // NET-385 260 final int original = _socket_.getSoTimeout(); 261 _socket_.setSoTimeout(connectTimeout); 262 try { 263 getReply(); 264 // If we received code 120, we have to fetch completion reply. 265 if (FTPReply.isPositivePreliminary(_replyCode)) { 266 getReply(); 267 } 268 } catch (final SocketTimeoutException e) { 269 final IOException ioe = new IOException("Timed out waiting for initial connect reply"); 270 ioe.initCause(e); 271 throw ioe; 272 } finally { 273 _socket_.setSoTimeout(original); 274 } 275 } else { 276 getReply(); 277 // If we received code 120, we have to fetch completion reply. 278 if (FTPReply.isPositivePreliminary(_replyCode)) { 279 getReply(); 280 } 281 } 282 } 283 284 /** 285 * A convenience method to send the FTP ABOR command to the server, receive the reply, and return the reply code. 286 * 287 * @return The reply code received from the server. 288 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 289 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 290 * independently as itself. 291 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 292 */ 293 public int abor() throws IOException { 294 return sendCommand(FTPCmd.ABOR); 295 } 296 297 /** 298 * A convenience method to send the FTP ACCT command to the server, receive the reply, and return the reply code. 299 * 300 * @param account The account name to access. 301 * @return The reply code received from the server. 302 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 303 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 304 * independently as itself. 305 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 306 */ 307 public int acct(final String account) throws IOException { 308 return sendCommand(FTPCmd.ACCT, account); 309 } 310 311 /** 312 * A convenience method to send the FTP ALLO command to the server, receive the reply, and return the reply code. 313 * 314 * @param bytes The number of bytes to allocate. 315 * @return The reply code received from the server. 316 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 317 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 318 * independently as itself. 319 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 320 */ 321 public int allo(final int bytes) throws IOException { 322 return sendCommand(FTPCmd.ALLO, Integer.toString(bytes)); 323 } 324 325 /** 326 * A convenience method to send the FTP ALLO command to the server, receive the reply, and return the reply code. 327 * 328 * @param bytes The number of bytes to allocate. 329 * @param recordSize The size of a record. 330 * @return The reply code received from the server. 331 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 332 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 333 * independently as itself. 334 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 335 */ 336 public int allo(final int bytes, final int recordSize) throws IOException { 337 return sendCommand(FTPCmd.ALLO, Integer.toString(bytes) + " R " + Integer.toString(recordSize)); 338 } 339 340 /** 341 * A convenience method to send the FTP ALLO command to the server, receive the reply, and return the reply code. 342 * 343 * @param bytes The number of bytes to allocate. 344 * @return The reply code received from the server. 345 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 346 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 347 * independently as itself. 348 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 349 */ 350 public int allo(final long bytes) throws IOException { 351 return sendCommand(FTPCmd.ALLO, Long.toString(bytes)); 352 } 353 354 /** 355 * A convenience method to send the FTP ALLO command to the server, receive the reply, and return the reply code. 356 * 357 * @param bytes The number of bytes to allocate. 358 * @param recordSize The size of a record. 359 * @return The reply code received from the server. 360 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 361 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 362 * independently as itself. 363 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 364 */ 365 public int allo(final long bytes, final int recordSize) throws IOException { 366 return sendCommand(FTPCmd.ALLO, Long.toString(bytes) + " R " + Integer.toString(recordSize)); 367 } 368 369 /** 370 * A convenience method to send the FTP APPE command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 371 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 372 * for you. 373 * 374 * @param pathname The pathname to use for the file when stored at the remote end of the transfer. 375 * @return The reply code received from the server. 376 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 377 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 378 * independently as itself. 379 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 380 */ 381 public int appe(final String pathname) throws IOException { 382 return sendCommand(FTPCmd.APPE, pathname); 383 } 384 385 private String buildMessage(final String command, final String args) { 386 final StringBuilder __commandBuffer = new StringBuilder(); 387 388 __commandBuffer.append(command); 389 390 if (args != null) { 391 __commandBuffer.append(' '); 392 __commandBuffer.append(args); 393 } 394 __commandBuffer.append(SocketClient.NETASCII_EOL); 395 return __commandBuffer.toString(); 396 } 397 398 /** 399 * A convenience method to send the FTP CDUP command to the server, receive the reply, and return the reply code. 400 * 401 * @return The reply code received from the server. 402 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 403 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 404 * independently as itself. 405 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 406 */ 407 public int cdup() throws IOException { 408 return sendCommand(FTPCmd.CDUP); 409 } 410 411 /** 412 * A convenience method to send the FTP CWD command to the server, receive the reply, and return the reply code. 413 * 414 * @param directory The new working directory. 415 * @return The reply code received from the server. 416 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 417 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 418 * independently as itself. 419 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 420 */ 421 public int cwd(final String directory) throws IOException { 422 return sendCommand(FTPCmd.CWD, directory); 423 } 424 425 /** 426 * A convenience method to send the FTP DELE command to the server, receive the reply, and return the reply code. 427 * 428 * @param pathname The pathname to delete. 429 * @return The reply code received from the server. 430 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 431 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 432 * independently as itself. 433 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 434 */ 435 public int dele(final String pathname) throws IOException { 436 return sendCommand(FTPCmd.DELE, pathname); 437 } 438 439 /** 440 * Closes the control connection to the FTP server and sets to null some internal data so that the memory may be reclaimed by the garbage collector. The 441 * reply text and code information from the last command is voided so that the memory it used may be reclaimed. Also sets {@link #_controlInput_} and 442 * {@link #_controlOutput_} to null. 443 * 444 * @throws IOException If an error occurs while disconnecting. 445 */ 446 @Override 447 public void disconnect() throws IOException { 448 super.disconnect(); 449 _controlInput_ = null; 450 _controlOutput_ = null; 451 _newReplyString = false; 452 _replyString = null; 453 } 454 455 /** 456 * A convenience method to send the FTP EPRT command to the server, receive the reply, and return the reply code. 457 * 458 * Examples: 459 * <ul> 460 * <li>EPRT |1|132.235.1.2|6275|</li> 461 * <li>EPRT |2|1080::8:800:200C:417A|5282|</li> 462 * </ul> 463 * 464 * @see "http://www.faqs.org/rfcs/rfc2428.html" 465 * 466 * @param host The host owning the port. 467 * @param port The new port. 468 * @return The reply code received from the server. 469 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 470 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 471 * independently as itself. 472 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 473 * @since 2.2 474 */ 475 public int eprt(final InetAddress host, final int port) throws IOException { 476 final int num; 477 final StringBuilder info = new StringBuilder(); 478 String h; 479 480 // If IPv6, trim the zone index 481 h = host.getHostAddress(); 482 num = h.indexOf('%'); 483 if (num > 0) { 484 h = h.substring(0, num); 485 } 486 487 info.append("|"); 488 489 if (host instanceof Inet4Address) { 490 info.append("1"); 491 } else if (host instanceof Inet6Address) { 492 info.append("2"); 493 } 494 info.append("|"); 495 info.append(h); 496 info.append("|"); 497 info.append(port); 498 info.append("|"); 499 500 return sendCommand(FTPCmd.EPRT, info.toString()); 501 } 502 503 /** 504 * A convenience method to send the FTP EPSV command to the server, receive the reply, and return the reply code. Remember, it's up to you to interpret the 505 * reply string containing the host/port information. 506 * 507 * @return The reply code received from the server. 508 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 509 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 510 * independently as itself. 511 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 512 * @since 2.2 513 */ 514 public int epsv() throws IOException { 515 return sendCommand(FTPCmd.EPSV); 516 } 517 518 /** 519 * A convenience method to send the FTP FEAT command to the server, receive the reply, and return the reply code. 520 * 521 * @return The reply code received by the server 522 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 523 * @since 2.2 524 */ 525 public int feat() throws IOException { 526 return sendCommand(FTPCmd.FEAT); 527 } 528 529 /** 530 * Provide command support to super-class 531 */ 532 @Override 533 protected ProtocolCommandSupport getCommandSupport() { 534 return _commandSupport_; 535 } 536 537 /** 538 * @return The character encoding used to communicate over the control connection. 539 */ 540 public String getControlEncoding() { 541 return _controlEncoding; 542 } 543 544 /** 545 * Fetches a reply from the FTP server and returns the integer reply code. After calling this method, the actual reply text can be accessed from either 546 * calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. Only use this method if you are implementing your own FTP 547 * client or if you need to fetch a secondary response from the FTP server. 548 * 549 * @return The integer value of the reply code of the fetched FTP reply. 550 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 551 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 552 * independently as itself. 553 * @throws IOException If an I/O error occurs while receiving the server reply. 554 */ 555 public int getReply() throws IOException { 556 return getReply(true); 557 } 558 559 private int getReply(final boolean reportReply) throws IOException { 560 final int length; 561 562 _newReplyString = true; 563 _replyLines.clear(); 564 565 String line = _controlInput_.readLine(); 566 567 if (line == null) { 568 throw new FTPConnectionClosedException("Connection closed without indication."); 569 } 570 571 // In case we run into an anomaly we don't want fatal index exceptions 572 // to be thrown. 573 length = line.length(); 574 if (length < REPLY_CODE_LEN) { 575 throw new MalformedServerReplyException("Truncated server reply: " + line); 576 } 577 578 String code; 579 try { 580 code = line.substring(0, REPLY_CODE_LEN); 581 _replyCode = Integer.parseInt(code); 582 } catch (final NumberFormatException e) { 583 throw new MalformedServerReplyException("Could not parse response code.\nServer Reply: " + line); 584 } 585 586 _replyLines.add(line); 587 588 // Check the server reply type 589 if (length > REPLY_CODE_LEN) { 590 final char sep = line.charAt(REPLY_CODE_LEN); 591 // Get extra lines if message continues. 592 if (sep == '-') { 593 do { 594 line = _controlInput_.readLine(); 595 596 if (line == null) { 597 throw new FTPConnectionClosedException("Connection closed without indication."); 598 } 599 600 _replyLines.add(line); 601 602 // The length() check handles problems that could arise from readLine() 603 // returning too soon after encountering a naked CR or some other 604 // anomaly. 605 } while (isStrictMultilineParsing() ? strictCheck(line, code) : lenientCheck(line)); 606 607 } else if (isStrictReplyParsing()) { 608 if (length == REPLY_CODE_LEN + 1) { // expecting some text 609 throw new MalformedServerReplyException("Truncated server reply: '" + line + "'"); 610 } 611 if (sep != ' ') { 612 throw new MalformedServerReplyException("Invalid server reply: '" + line + "'"); 613 } 614 } 615 } else if (isStrictReplyParsing()) { 616 throw new MalformedServerReplyException("Truncated server reply: '" + line + "'"); 617 } 618 619 if (reportReply) { 620 fireReplyReceived(_replyCode, getReplyString()); 621 } 622 623 if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE) { 624 throw new FTPConnectionClosedException("FTP response 421 received. Server closed connection."); 625 } 626 return _replyCode; 627 } 628 629 /** 630 * Returns the integer value of the reply code of the last FTP reply. You will usually only use this method after you connect to the FTP server to check 631 * that the connection was successful since <code> connect </code> is of type void. 632 * 633 * @return The integer value of the reply code of the last FTP reply. 634 */ 635 public int getReplyCode() { 636 return _replyCode; 637 } 638 639 /** 640 * Returns the entire text of the last FTP server response exactly as it was received, including all end of line markers in NETASCII format. 641 * 642 * @return The entire text from the last FTP response as a String. 643 */ 644 public String getReplyString() { 645 final StringBuilder buffer; 646 647 if (!_newReplyString) { 648 return _replyString; 649 } 650 651 buffer = new StringBuilder(256); 652 653 for (final String line : _replyLines) { 654 buffer.append(line); 655 buffer.append(SocketClient.NETASCII_EOL); 656 } 657 658 _newReplyString = false; 659 660 return _replyString = buffer.toString(); 661 } 662 663 /** 664 * Returns the nth line of text from the last FTP server response as a string. The end of line markers of each are stripped from the line. 665 * 666 * @param index The index of the line to return, 0-based. 667 * 668 * @return The lines of text from the last FTP response as an array. 669 */ 670 String getReplyString(final int index) { 671 return _replyLines.get(index); 672 } 673 674 /** 675 * Returns the lines of text from the last FTP server response as an array of strings, one entry per line. The end of line markers of each are stripped from 676 * each line. 677 * 678 * @return The lines of text from the last FTP response as an array. 679 */ 680 public String[] getReplyStrings() { 681 return _replyLines.toArray(NetConstants.EMPTY_STRING_ARRAY); 682 } 683 684 /** 685 * A convenience method to send the FTP HELP command to the server, receive the reply, and return the reply code. 686 * 687 * @return The reply code received from the server. 688 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 689 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 690 * independently as itself. 691 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 692 */ 693 public int help() throws IOException { 694 return sendCommand(FTPCmd.HELP); 695 } 696 697 /** 698 * A convenience method to send the FTP HELP command to the server, receive the reply, and return the reply code. 699 * 700 * @param command The command name on which to request help. 701 * @return The reply code received from the server. 702 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 703 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 704 * independently as itself. 705 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 706 */ 707 public int help(final String command) throws IOException { 708 return sendCommand(FTPCmd.HELP, command); 709 } 710 711 /** 712 * Return whether strict multiline parsing is enabled, as per RFC 959, section 4.2. 713 * 714 * @return True if strict, false if lenient 715 * @since 2.0 716 */ 717 public boolean isStrictMultilineParsing() { 718 return strictMultilineParsing; 719 } 720 721 /** 722 * Return whether strict non-multiline parsing is enabled, as per RFC 959, section 4.2. 723 * <p> 724 * The default is true, which requires the 3-digit code be followed by space and some text. <br> 725 * If false, only the 3-digit code is required (as was the case for versions up to 3.5) <br> 726 * 727 * @return True if strict (default), false if additional checks are not made 728 * @since 3.6 729 */ 730 public boolean isStrictReplyParsing() { 731 return strictReplyParsing; 732 } 733 734 // The strict check is too strong a condition because of non-conforming ftp 735 // servers like ftp.funet.fi which sent 226 as the last line of a 736 // 426 multi-line reply in response to ls /. We relax the condition to 737 // test that the line starts with a digit rather than starting with 738 // the code. 739 private boolean lenientCheck(final String line) { 740 return !(line.length() > REPLY_CODE_LEN && line.charAt(REPLY_CODE_LEN) != '-' && Character.isDigit(line.charAt(0))); 741 } 742 743 /** 744 * A convenience method to send the FTP LIST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 745 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 746 * for you. 747 * 748 * @return The reply code received from the server. 749 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 750 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 751 * independently as itself. 752 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 753 */ 754 public int list() throws IOException { 755 return sendCommand(FTPCmd.LIST); 756 } 757 758 /** 759 * A convenience method to send the FTP LIST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 760 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 761 * for you. 762 * 763 * @param pathname The pathname to list, may be {@code null} in which case the command is sent with no parameters 764 * @return The reply code received from the server. 765 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 766 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 767 * independently as itself. 768 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 769 */ 770 public int list(final String pathname) throws IOException { 771 return sendCommand(FTPCmd.LIST, pathname); 772 } 773 774 /** 775 * Sends the MDTM command for the given file. 776 * 777 * @param file name of file 778 * @return the status 779 * @throws IOException on error 780 * @since 2.0 781 **/ 782 public int mdtm(final String file) throws IOException { 783 return sendCommand(FTPCmd.MDTM, file); 784 } 785 786 /** 787 * A convenience method to send the FTP MFMT command to the server, receive the reply, and return the reply code. 788 * 789 * @param pathname The pathname for which mtime is to be changed 790 * @param timeval Timestamp in <code>yyyyMMDDhhmmss</code> format 791 * @return The reply code received from the server. 792 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 793 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 794 * independently as itself. 795 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 796 * @since 2.2 797 * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a> 798 **/ 799 public int mfmt(final String pathname, final String timeval) throws IOException { 800 return sendCommand(FTPCmd.MFMT, timeval + " " + pathname); 801 } 802 803 /** 804 * A convenience method to send the FTP MKD command to the server, receive the reply, and return the reply code. 805 * 806 * @param pathname The pathname of the new directory to create. 807 * @return The reply code received from the server. 808 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 809 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 810 * independently as itself. 811 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 812 */ 813 public int mkd(final String pathname) throws IOException { 814 return sendCommand(FTPCmd.MKD, pathname); 815 } 816 817 /** 818 * A convenience method to send the FTP MLSD command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 819 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 820 * for you. 821 * 822 * @return The reply code received from the server. 823 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 824 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 825 * independently as itself. 826 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 827 * @since 3.0 828 */ 829 public int mlsd() throws IOException { 830 return sendCommand(FTPCmd.MLSD); 831 } 832 833 /** 834 * A convenience method to send the FTP MLSD command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 835 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 836 * for you. 837 * 838 * @param path the path to report on 839 * @return The reply code received from the server, may be {@code null} in which case the command is sent with no parameters 840 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 841 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 842 * independently as itself. 843 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 844 * @since 3.0 845 */ 846 public int mlsd(final String path) throws IOException { 847 return sendCommand(FTPCmd.MLSD, path); 848 } 849 850 /** 851 * A convenience method to send the FTP MLST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 852 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 853 * for you. 854 * 855 * @return The reply code received from the server. 856 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 857 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 858 * independently as itself. 859 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 860 * @since 3.0 861 */ 862 public int mlst() throws IOException { 863 return sendCommand(FTPCmd.MLST); 864 } 865 866 /** 867 * A convenience method to send the FTP MLST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 868 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 869 * for you. 870 * 871 * @param path the path to report on 872 * @return The reply code received from the server, may be {@code null} in which case the command is sent with no parameters 873 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 874 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 875 * independently as itself. 876 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 877 * @since 3.0 878 */ 879 public int mlst(final String path) throws IOException { 880 return sendCommand(FTPCmd.MLST, path); 881 } 882 883 /** 884 * A convenience method to send the FTP MODE command to the server, receive the reply, and return the reply code. 885 * 886 * @param mode The transfer mode to use (one of the <code>TRANSFER_MODE</code> constants). 887 * @return The reply code received from the server. 888 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 889 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 890 * independently as itself. 891 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 892 */ 893 public int mode(final int mode) throws IOException { 894 return sendCommand(FTPCmd.MODE, modes.substring(mode, mode + 1)); 895 } 896 897 /** 898 * A convenience method to send the FTP NLST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 899 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 900 * for you. 901 * 902 * @return The reply code received from the server. 903 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 904 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 905 * independently as itself. 906 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 907 */ 908 public int nlst() throws IOException { 909 return sendCommand(FTPCmd.NLST); 910 } 911 912 /** 913 * A convenience method to send the FTP NLST command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 914 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 915 * for you. 916 * 917 * @param pathname The pathname to list, may be {@code null} in which case the command is sent with no parameters 918 * @return The reply code received from the server. 919 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 920 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 921 * independently as itself. 922 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 923 */ 924 public int nlst(final String pathname) throws IOException { 925 return sendCommand(FTPCmd.NLST, pathname); 926 } 927 928 /** 929 * A convenience method to send the FTP NOOP command to the server, receive the reply, and return the reply code. 930 * 931 * @return The reply code received from the server. 932 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 933 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 934 * independently as itself. 935 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 936 */ 937 public int noop() throws IOException { 938 return sendCommand(FTPCmd.NOOP); 939 } 940 941 /** 942 * A convenience method to send the FTP PASS command to the server, receive the reply, and return the reply code. 943 * 944 * @param password The plain text password of the user being logged into. 945 * @return The reply code received from the server. 946 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 947 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 948 * independently as itself. 949 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 950 */ 951 public int pass(final String password) throws IOException { 952 return sendCommand(FTPCmd.PASS, password); 953 } 954 955 /** 956 * A convenience method to send the FTP PASV command to the server, receive the reply, and return the reply code. Remember, it's up to you to interpret the 957 * reply string containing the host/port information. 958 * 959 * @return The reply code received from the server. 960 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 961 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 962 * independently as itself. 963 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 964 */ 965 public int pasv() throws IOException { 966 return sendCommand(FTPCmd.PASV); 967 } 968 969 /** 970 * A convenience method to send the FTP PORT command to the server, receive the reply, and return the reply code. 971 * 972 * @param host The host owning the port. 973 * @param port The new port. 974 * @return The reply code received from the server. 975 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 976 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 977 * independently as itself. 978 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 979 */ 980 public int port(final InetAddress host, final int port) throws IOException { 981 int num; 982 final StringBuilder info = new StringBuilder(24); 983 984 info.append(host.getHostAddress().replace('.', ',')); 985 num = port >>> 8; 986 info.append(','); 987 info.append(num); 988 info.append(','); 989 num = port & 0xff; 990 info.append(num); 991 992 return sendCommand(FTPCmd.PORT, info.toString()); 993 } 994 995 /** 996 * A convenience method to send the FTP PWD command to the server, receive the reply, and return the reply code. 997 * 998 * @return The reply code received from the server. 999 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1000 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1001 * independently as itself. 1002 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1003 */ 1004 public int pwd() throws IOException { 1005 return sendCommand(FTPCmd.PWD); 1006 } 1007 1008 /** 1009 * A convenience method to send the FTP QUIT command to the server, receive the reply, and return the reply code. 1010 * 1011 * @return The reply code received from the server. 1012 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1013 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1014 * independently as itself. 1015 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1016 */ 1017 public int quit() throws IOException { 1018 return sendCommand(FTPCmd.QUIT); 1019 } 1020 1021 /** 1022 * A convenience method to send the FTP REIN command to the server, receive the reply, and return the reply code. 1023 * 1024 * @return The reply code received from the server. 1025 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1026 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1027 * independently as itself. 1028 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1029 */ 1030 public int rein() throws IOException { 1031 return sendCommand(FTPCmd.REIN); 1032 } 1033 1034 /** 1035 * A convenience method to send the FTP REST command to the server, receive the reply, and return the reply code. 1036 * 1037 * @param marker The marker at which to restart a transfer. 1038 * @return The reply code received from the server. 1039 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1040 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1041 * independently as itself. 1042 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1043 */ 1044 public int rest(final String marker) throws IOException { 1045 return sendCommand(FTPCmd.REST, marker); 1046 } 1047 1048 /** 1049 * A convenience method to send the FTP RETR command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 1050 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 1051 * for you. 1052 * 1053 * @param pathname The pathname of the file to retrieve. 1054 * @return The reply code received from the server. 1055 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1056 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1057 * independently as itself. 1058 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1059 */ 1060 public int retr(final String pathname) throws IOException { 1061 return sendCommand(FTPCmd.RETR, pathname); 1062 } 1063 1064 /** 1065 * A convenience method to send the FTP RMD command to the server, receive the reply, and return the reply code. 1066 * 1067 * @param pathname The pathname of the directory to remove. 1068 * @return The reply code received from the server. 1069 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1070 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1071 * independently as itself. 1072 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1073 */ 1074 public int rmd(final String pathname) throws IOException { 1075 return sendCommand(FTPCmd.RMD, pathname); 1076 } 1077 1078 /** 1079 * A convenience method to send the FTP RNFR command to the server, receive the reply, and return the reply code. 1080 * 1081 * @param pathname The pathname to rename from. 1082 * @return The reply code received from the server. 1083 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1084 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1085 * independently as itself. 1086 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1087 */ 1088 public int rnfr(final String pathname) throws IOException { 1089 return sendCommand(FTPCmd.RNFR, pathname); 1090 } 1091 1092 /** 1093 * A convenience method to send the FTP RNTO command to the server, receive the reply, and return the reply code. 1094 * 1095 * @param pathname The pathname to rename to 1096 * @return The reply code received from the server. 1097 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1098 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1099 * independently as itself. 1100 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1101 */ 1102 public int rnto(final String pathname) throws IOException { 1103 return sendCommand(FTPCmd.RNTO, pathname); 1104 } 1105 1106 private void send(final String message) throws IOException, FTPConnectionClosedException, SocketException { 1107 try { 1108 _controlOutput_.write(message); 1109 _controlOutput_.flush(); 1110 } catch (final SocketException e) { 1111 if (!isConnected()) { 1112 throw new FTPConnectionClosedException("Connection unexpectedly closed."); 1113 } 1114 throw e; 1115 } 1116 } 1117 1118 /** 1119 * Sends an FTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 1120 * actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1121 * 1122 * @param command The FTPCmd enum corresponding to the FTP command to send. 1123 * @return The integer value of the FTP reply code returned by the server in response to the command. 1124 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1125 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1126 * independently as itself. 1127 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1128 * @since 3.3 1129 */ 1130 public int sendCommand(final FTPCmd command) throws IOException { 1131 return sendCommand(command, null); 1132 } 1133 1134 /** 1135 * Sends an FTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 1136 * actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1137 * 1138 * @param command The FTPCmd enum corresponding to the FTP command to send. 1139 * @param args The arguments to the FTP command. If this parameter is set to null, then the command is sent with no argument. 1140 * @return The integer value of the FTP reply code returned by the server in response to the command. 1141 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1142 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1143 * independently as itself. 1144 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1145 * @since 3.3 1146 */ 1147 public int sendCommand(final FTPCmd command, final String args) throws IOException { 1148 return sendCommand(command.getCommand(), args); 1149 } 1150 1151 /** 1152 * Sends an FTP command with no arguments to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed 1153 * information, the actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1154 * 1155 * @param command The FTPCommand constant corresponding to the FTP command to send. 1156 * @return The integer value of the FTP reply code returned by the server in response to the command. 1157 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1158 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1159 * independently as itself. 1160 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1161 */ 1162 public int sendCommand(final int command) throws IOException { 1163 return sendCommand(command, null); 1164 } 1165 1166 /** 1167 * Sends an FTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 1168 * actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1169 * 1170 * @param command The FTPCommand constant corresponding to the FTP command to send. 1171 * @param args The arguments to the FTP command. If this parameter is set to null, then the command is sent with no argument. 1172 * @return The integer value of the FTP reply code returned by the server in response to the command. 1173 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1174 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1175 * independently as itself. 1176 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1177 * @deprecated (3.3) Use {@link #sendCommand(FTPCmd, String)} instead 1178 */ 1179 @Deprecated 1180 public int sendCommand(final int command, final String args) throws IOException { 1181 return sendCommand(FTPCommand.getCommand(command), args); 1182 } 1183 1184 /** 1185 * Sends an FTP command with no arguments to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed 1186 * information, the actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1187 * 1188 * @param command The text representation of the FTP command to send. 1189 * @return The integer value of the FTP reply code returned by the server in response to the command. 1190 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1191 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1192 * independently as itself. 1193 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1194 */ 1195 public int sendCommand(final String command) throws IOException { 1196 return sendCommand(command, null); 1197 } 1198 1199 /** 1200 * Sends an FTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 1201 * actual reply text can be accessed by calling {@link #getReplyString getReplyString } or {@link #getReplyStrings getReplyStrings }. 1202 * 1203 * @param command The text representation of the FTP command to send. 1204 * @param args The arguments to the FTP command. If this parameter is set to null, then the command is sent with no argument. 1205 * @return The integer value of the FTP reply code returned by the server in response to the command. 1206 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1207 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1208 * independently as itself. 1209 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1210 */ 1211 public int sendCommand(final String command, final String args) throws IOException { 1212 if (_controlOutput_ == null) { 1213 throw new IOException("Connection is not open"); 1214 } 1215 1216 final String message = buildMessage(command, args); 1217 1218 send(message); 1219 1220 fireCommandSent(command, message); 1221 1222 return getReply(); 1223 } 1224 1225 /** 1226 * Saves the character encoding to be used by the FTP control connection. Some FTP servers require that commands be issued in a non-ASCII encoding like 1227 * UTF-8 so that file names with multi-byte character representations (e.g, Big 8) can be specified. 1228 * <p> 1229 * Please note that this has to be set before the connection is established. 1230 * 1231 * @param encoding The new character encoding for the control connection. 1232 */ 1233 public void setControlEncoding(final String encoding) { 1234 _controlEncoding = encoding; 1235 } 1236 1237 /** 1238 * Set strict multiline parsing. 1239 * 1240 * @param strictMultilineParsing the setting 1241 * @since 2.0 1242 */ 1243 public void setStrictMultilineParsing(final boolean strictMultilineParsing) { 1244 this.strictMultilineParsing = strictMultilineParsing; 1245 } 1246 1247 /** 1248 * Set strict non-multiline parsing. 1249 * <p> 1250 * If true, it requires the 3-digit code be followed by space and some text. <br> 1251 * If false, only the 3-digit code is required (as was the case for versions up to 3.5) 1252 * <p> 1253 * <b>This should not be required by a well-behaved FTP server</b> <br> 1254 * 1255 * @param strictReplyParsing the setting 1256 * @since 3.6 1257 */ 1258 public void setStrictReplyParsing(final boolean strictReplyParsing) { 1259 this.strictReplyParsing = strictReplyParsing; 1260 } 1261 1262 /** 1263 * A convenience method to send the FTP SITE command to the server, receive the reply, and return the reply code. 1264 * 1265 * @param parameters The site parameters to send. 1266 * @return The reply code received from the server. 1267 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1268 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1269 * independently as itself. 1270 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1271 */ 1272 public int site(final String parameters) throws IOException { 1273 return sendCommand(FTPCmd.SITE, parameters); 1274 } 1275 1276 /** 1277 * A convenience method to send the FTP SIZE command to the server, receive the reply, and return the reply code. 1278 * 1279 * @param parameters The site parameters to send. 1280 * @return The reply code received from the server. 1281 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1282 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1283 * independently as itself. 1284 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1285 * @since 3.7 1286 */ 1287 public int size(final String parameters) throws IOException { 1288 return sendCommand(FTPCmd.SIZE, parameters); 1289 } 1290 1291 /** 1292 * A convenience method to send the FTP SMNT command to the server, receive the reply, and return the reply code. 1293 * 1294 * @param dir The directory name. 1295 * @return The reply code received from the server. 1296 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1297 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1298 * independently as itself. 1299 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1300 */ 1301 public int smnt(final String dir) throws IOException { 1302 return sendCommand(FTPCmd.SMNT, dir); 1303 } 1304 1305 /** 1306 * A convenience method to send the FTP STAT command to the server, receive the reply, and return the reply code. 1307 * 1308 * @return The reply code received from the server. 1309 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1310 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1311 * independently as itself. 1312 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1313 */ 1314 public int stat() throws IOException { 1315 return sendCommand(FTPCmd.STAT); 1316 } 1317 1318 /** 1319 * A convenience method to send the FTP STAT command to the server, receive the reply, and return the reply code. 1320 * 1321 * @param pathname A pathname to list. 1322 * @return The reply code received from the server. 1323 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1324 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1325 * independently as itself. 1326 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1327 */ 1328 public int stat(final String pathname) throws IOException { 1329 return sendCommand(FTPCmd.STAT, pathname); 1330 } 1331 1332 /** 1333 * A convenience method to send the FTP STOR command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 1334 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 1335 * for you. 1336 * 1337 * @param pathname The pathname to use for the file when stored at the remote end of the transfer. 1338 * @return The reply code received from the server. 1339 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1340 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1341 * independently as itself. 1342 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1343 */ 1344 public int stor(final String pathname) throws IOException { 1345 return sendCommand(FTPCmd.STOR, pathname); 1346 } 1347 1348 /** 1349 * A convenience method to send the FTP STOU command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 1350 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 1351 * for you. 1352 * 1353 * @return The reply code received from the server. 1354 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1355 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1356 * independently as itself. 1357 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1358 */ 1359 public int stou() throws IOException { 1360 return sendCommand(FTPCmd.STOU); 1361 } 1362 1363 /** 1364 * A convenience method to send the FTP STOU command to the server, receive the reply, and return the reply code. Remember, it is up to you to manage the 1365 * data connection. If you don't need this low level of access, use {@link org.apache.commons.net.ftp.FTPClient} , which will handle all low level details 1366 * for you. 1367 * 1368 * @param pathname The base pathname to use for the file when stored at the remote end of the transfer. Some FTP servers require this. 1369 * @return The reply code received from the server. 1370 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1371 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1372 * independently as itself. 1373 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1374 */ 1375 public int stou(final String pathname) throws IOException { 1376 return sendCommand(FTPCmd.STOU, pathname); 1377 } 1378 1379 // The RFC-compliant multiline termination check 1380 private boolean strictCheck(final String line, final String code) { 1381 return !(line.startsWith(code) && line.charAt(REPLY_CODE_LEN) == ' '); 1382 } 1383 1384 /** 1385 * A convenience method to send the FTP STRU command to the server, receive the reply, and return the reply code. 1386 * 1387 * @param structure The structure of the file (one of the <code>_STRUCTURE</code> constants). 1388 * @return The reply code received from the server. 1389 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1390 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1391 * independently as itself. 1392 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1393 */ 1394 public int stru(final int structure) throws IOException { 1395 return sendCommand(FTPCmd.STRU, modes.substring(structure, structure + 1)); 1396 } 1397 1398 /** 1399 * A convenience method to send the FTP SYST command to the server, receive the reply, and return the reply code. 1400 * 1401 * @return The reply code received from the server. 1402 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1403 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1404 * independently as itself. 1405 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1406 */ 1407 public int syst() throws IOException { 1408 return sendCommand(FTPCmd.SYST); 1409 } 1410 1411 /** 1412 * A convenience method to send the FTP TYPE command to the server, receive the reply, and return the reply code. 1413 * 1414 * @param fileType The type of the file (one of the <code>FILE_TYPE</code> constants). 1415 * @return The reply code received from the server. 1416 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1417 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1418 * independently as itself. 1419 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1420 */ 1421 public int type(final int fileType) throws IOException { 1422 return sendCommand(FTPCmd.TYPE, modes.substring(fileType, fileType + 1)); 1423 } 1424 1425 /** 1426 * A convenience method to send the FTP TYPE command for text files to the server, receive the reply, and return the reply code. 1427 * 1428 * @param fileType The type of the file (one of the <code>FILE_TYPE</code> constants). 1429 * @param formatOrByteSize The format of the file (one of the <code>_FORMAT</code> constants). In the case of <code>LOCAL_FILE_TYPE</code>, the byte size. 1430 * @return The reply code received from the server. 1431 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1432 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1433 * independently as itself. 1434 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1435 */ 1436 public int type(final int fileType, final int formatOrByteSize) throws IOException { 1437 final StringBuilder arg = new StringBuilder(); 1438 1439 arg.append(modes.charAt(fileType)); 1440 arg.append(' '); 1441 if (fileType == LOCAL_FILE_TYPE) { 1442 arg.append(formatOrByteSize); 1443 } else { 1444 arg.append(modes.charAt(formatOrByteSize)); 1445 } 1446 1447 return sendCommand(FTPCmd.TYPE, arg.toString()); 1448 } 1449 1450 /** 1451 * A convenience method to send the FTP USER command to the server, receive the reply, and return the reply code. 1452 * 1453 * @param user The user to login under. 1454 * @return The reply code received from the server. 1455 * @throws FTPConnectionClosedException If the FTP server prematurely closes the connection as a result of the client being idle or some other reason 1456 * causing the server to send FTP reply code 421. This exception may be caught either as an IOException or 1457 * independently as itself. 1458 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 1459 */ 1460 public int user(final String user) throws IOException { 1461 return sendCommand(FTPCmd.USER, user); 1462 } 1463}