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