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 package org.apache.commons.net.ftp;
018 import java.io.BufferedInputStream;
019 import java.io.BufferedOutputStream;
020 import java.io.BufferedReader;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.InputStreamReader;
024 import java.io.OutputStream;
025 import java.net.Inet6Address;
026 import java.net.InetAddress;
027 import java.net.ServerSocket;
028 import java.net.Socket;
029 import java.net.UnknownHostException;
030 import java.util.ArrayList;
031 import java.util.Random;
032
033 import org.apache.commons.net.MalformedServerReplyException;
034 import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
035 import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
036 import org.apache.commons.net.ftp.parser.ParserInitializationException;
037 import org.apache.commons.net.io.CopyStreamEvent;
038 import org.apache.commons.net.io.CopyStreamException;
039 import org.apache.commons.net.io.FromNetASCIIInputStream;
040 import org.apache.commons.net.io.ToNetASCIIOutputStream;
041 import org.apache.commons.net.io.Util;
042
043 /***
044 * FTPClient encapsulates all the functionality necessary to store and
045 * retrieve files from an FTP server. This class takes care of all
046 * low level details of interacting with an FTP server and provides
047 * a convenient higher level interface. As with all classes derived
048 * from {@link org.apache.commons.net.SocketClient},
049 * you must first connect to the server with
050 * {@link org.apache.commons.net.SocketClient#connect connect }
051 * before doing anything, and finally
052 * {@link org.apache.commons.net.SocketClient#disconnect disconnect }
053 * after you're completely finished interacting with the server.
054 * Then you need to check the FTP reply code to see if the connection
055 * was successful. For example:
056 * <pre>
057 * boolean error = false;
058 * try {
059 * int reply;
060 * ftp.connect("ftp.foobar.com");
061 * System.out.println("Connected to " + server + ".");
062 * System.out.print(ftp.getReplyString());
063 *
064 * // After connection attempt, you should check the reply code to verify
065 * // success.
066 * reply = ftp.getReplyCode();
067 *
068 * if(!FTPReply.isPositiveCompletion(reply)) {
069 * ftp.disconnect();
070 * System.err.println("FTP server refused connection.");
071 * System.exit(1);
072 * }
073 * ... // transfer files
074 * ftp.logout();
075 * } catch(IOException e) {
076 * error = true;
077 * e.printStackTrace();
078 * } finally {
079 * if(ftp.isConnected()) {
080 * try {
081 * ftp.disconnect();
082 * } catch(IOException ioe) {
083 * // do nothing
084 * }
085 * }
086 * System.exit(error ? 1 : 0);
087 * }
088 * </pre>
089 * <p>
090 * Immediately after connecting is the only real time you need to check the
091 * reply code (because connect is of type void). The convention for all the
092 * FTP command methods in FTPClient is such that they either return a
093 * boolean value or some other value.
094 * The boolean methods return true on a successful completion reply from
095 * the FTP server and false on a reply resulting in an error condition or
096 * failure. The methods returning a value other than boolean return a value
097 * containing the higher level data produced by the FTP command, or null if a
098 * reply resulted in an error condition or failure. If you want to access
099 * the exact FTP reply code causing a success or failure, you must call
100 * {@link org.apache.commons.net.ftp.FTP#getReplyCode getReplyCode } after
101 * a success or failure.
102 * <p>
103 * The default settings for FTPClient are for it to use
104 * <code> FTP.ASCII_FILE_TYPE </code>,
105 * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
106 * <code> FTP.STREAM_TRANSFER_MODE </code>, and
107 * <code> FTP.FILE_STRUCTURE </code>. The only file types directly supported
108 * are <code> FTP.ASCII_FILE_TYPE </code> and
109 * <code> FTP.BINARY_FILE_TYPE </code>. Because there are at least 4
110 * different EBCDIC encodings, we have opted not to provide direct support
111 * for EBCDIC. To transfer EBCDIC and other unsupported file types you
112 * must create your own filter InputStreams and OutputStreams and wrap
113 * them around the streams returned or required by the FTPClient methods.
114 * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}
115 * filter streams to provide transparent handling of ASCII files. We will
116 * consider incorporating EBCDIC support if there is enough demand.
117 * <p>
118 * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
119 * <code> FTP.STREAM_TRANSFER_MODE </code>, and
120 * <code> FTP.FILE_STRUCTURE </code> are the only supported formats,
121 * transfer modes, and file structures.
122 * <p>
123 * Because the handling of sockets on different platforms can differ
124 * significantly, the FTPClient automatically issues a new PORT (or EPRT) command
125 * prior to every transfer requiring that the server connect to the client's
126 * data port. This ensures identical problem-free behavior on Windows, Unix,
127 * and Macintosh platforms. Additionally, it relieves programmers from
128 * having to issue the PORT (or EPRT) command themselves and dealing with platform
129 * dependent issues.
130 * <p>
131 * Additionally, for security purposes, all data connections to the
132 * client are verified to ensure that they originated from the intended
133 * party (host and port). If a data connection is initiated by an unexpected
134 * party, the command will close the socket and throw an IOException. You
135 * may disable this behavior with
136 * {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}.
137 * <p>
138 * You should keep in mind that the FTP server may choose to prematurely
139 * close a connection if the client has been idle for longer than a
140 * given time period (usually 900 seconds). The FTPClient class will detect a
141 * premature FTP server connection closing when it receives a
142 * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
143 * response to a command.
144 * When that occurs, the FTP class method encountering that reply will throw
145 * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
146 * .
147 * <code>FTPConnectionClosedException</code>
148 * is a subclass of <code> IOException </code> and therefore need not be
149 * caught separately, but if you are going to catch it separately, its
150 * catch block must appear before the more general <code> IOException </code>
151 * catch block. When you encounter an
152 * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
153 * , you must disconnect the connection with
154 * {@link #disconnect disconnect() } to properly clean up the
155 * system resources used by FTPClient. Before disconnecting, you may check the
156 * last reply code and text with
157 * {@link org.apache.commons.net.ftp.FTP#getReplyCode getReplyCode },
158 * {@link org.apache.commons.net.ftp.FTP#getReplyString getReplyString },
159 * and
160 * {@link org.apache.commons.net.ftp.FTP#getReplyStrings getReplyStrings}.
161 * You may avoid server disconnections while the client is idle by
162 * periodically sending NOOP commands to the server.
163 * <p>
164 * Rather than list it separately for each method, we mention here that
165 * every method communicating with the server and throwing an IOException
166 * can also throw a
167 * {@link org.apache.commons.net.MalformedServerReplyException}
168 * , which is a subclass
169 * of IOException. A MalformedServerReplyException will be thrown when
170 * the reply received from the server deviates enough from the protocol
171 * specification that it cannot be interpreted in a useful manner despite
172 * attempts to be as lenient as possible.
173 * <p>
174 * Listing API Examples
175 * Both paged and unpaged examples of directory listings are available,
176 * as follows:
177 * <p>
178 * Unpaged (whole list) access, using a parser accessible by auto-detect:
179 * <pre>
180 * FTPClient f = new FTPClient();
181 * f.connect(server);
182 * f.login(username, password);
183 * FTPFile[] files = listFiles(directory);
184 * </pre>
185 * <p>
186 * Paged access, using a parser not accessible by auto-detect. The class
187 * defined in the first parameter of initateListParsing should be derived
188 * from org.apache.commons.net.FTPFileEntryParser:
189 * <pre>
190 * FTPClient f = new FTPClient();
191 * f.connect(server);
192 * f.login(username, password);
193 * FTPListParseEngine engine =
194 * f.initiateListParsing("com.whatever.YourOwnParser", directory);
195 *
196 * while (engine.hasNext()) {
197 * FTPFile[] files = engine.getNext(25); // "page size" you want
198 * //do whatever you want with these files, display them, etc.
199 * //expensive FTPFile objects not created until needed.
200 * }
201 * </pre>
202 * <p>
203 * Paged access, using a parser accessible by auto-detect:
204 * <pre>
205 * FTPClient f = new FTPClient();
206 * f.connect(server);
207 * f.login(username, password);
208 * FTPListParseEngine engine = f.initiateListParsing(directory);
209 *
210 * while (engine.hasNext()) {
211 * FTPFile[] files = engine.getNext(25); // "page size" you want
212 * //do whatever you want with these files, display them, etc.
213 * //expensive FTPFile objects not created until needed.
214 * }
215 * </pre>
216 * <p>
217 * For examples of using FTPClient on servers whose directory listings
218 * <ul>
219 * <li>use languages other than English</li>
220 * <li>use date formats other than the American English "standard" <code>MM d yyyy</code></li>
221 * <li>are in different timezones and you need accurate timestamps for dependency checking
222 * as in Ant</li>
223 * </ul>see {@link FTPClientConfig FTPClientConfig}.
224 * <p>
225 * @author Daniel F. Savarese
226 * @author Rory Winston
227 * @see FTP
228 * @see FTPConnectionClosedException
229 * @see FTPFileEntryParser
230 * @see FTPFileEntryParserFactory
231 * @see DefaultFTPFileEntryParserFactory
232 * @see FTPClientConfig
233 *
234 * @see org.apache.commons.net.MalformedServerReplyException
235 **/
236 public class FTPClient extends FTP
237 implements Configurable
238 {
239 /***
240 * A constant indicating the FTP session is expecting all transfers
241 * to occur between the client (local) and server and that the server
242 * should connect to the client's data port to initiate a data transfer.
243 * This is the default data connection mode when and FTPClient instance
244 * is created.
245 ***/
246 public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
247 /***
248 * A constant indicating the FTP session is expecting all transfers
249 * to occur between two remote servers and that the server
250 * the client is connected to should connect to the other server's
251 * data port to initiate a data transfer.
252 ***/
253 public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
254 /***
255 * A constant indicating the FTP session is expecting all transfers
256 * to occur between the client (local) and server and that the server
257 * is in passive mode, requiring the client to connect to the
258 * server's data port to initiate a transfer.
259 ***/
260 public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
261 /***
262 * A constant indicating the FTP session is expecting all transfers
263 * to occur between two remote servers and that the server
264 * the client is connected to is in passive mode, requiring the other
265 * server to connect to the first server's data port to initiate a data
266 * transfer.
267 ***/
268 public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
269
270 private int __dataConnectionMode, __dataTimeout;
271 private int __passivePort;
272 private String __passiveHost;
273 private final Random __random;
274 private int __activeMinPort, __activeMaxPort;
275 private InetAddress __activeExternalHost;
276 private int __fileType;
277 @SuppressWarnings("unused") // fields are written, but currently not read
278 private int __fileFormat, __fileStructure, __fileTransferMode;
279 private boolean __remoteVerificationEnabled;
280 private long __restartOffset;
281 private FTPFileEntryParserFactory __parserFactory;
282 private int __bufferSize;
283 private boolean __listHiddenFiles;
284 private boolean __useEPSVwithIPv4; // whether to attempt EPSV with an IPv4 connection
285
286 // __systemName is a cached value that should not be referenced directly
287 // except when assigned in getSystemName and __initDefaults.
288 private String __systemName;
289
290 // __entryParser is a cached value that should not be referenced directly
291 // except when assigned in listFiles(String, String) and __initDefaults.
292 private FTPFileEntryParser __entryParser;
293
294 // Key used to create the parser; necessary to ensure that the parser type is not ignored
295 private String __entryParserKey;
296
297 private FTPClientConfig __configuration;
298
299 /** Pattern for PASV mode responses */
300 private static final String __parms = "\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
301 private static final java.util.regex.Pattern __parms_pat;
302 static {
303 __parms_pat = java.util.regex.Pattern.compile(__parms);
304 }
305
306 /***
307 * Default FTPClient constructor. Creates a new FTPClient instance
308 * with the data connection mode set to
309 * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
310 * set to <code> FTP.ASCII_FILE_TYPE </code>, the
311 * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
312 * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
313 * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
314 ***/
315 public FTPClient()
316 {
317 __initDefaults();
318 __dataTimeout = -1;
319 __remoteVerificationEnabled = true;
320 __parserFactory = new DefaultFTPFileEntryParserFactory();
321 __configuration = null;
322 __listHiddenFiles = false;
323 __useEPSVwithIPv4 = false;
324 __random = new Random();
325 }
326
327
328 private void __initDefaults()
329 {
330 __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
331 __passiveHost = null;
332 __passivePort = -1;
333 __activeExternalHost = null;
334 __activeMinPort = 0;
335 __activeMaxPort = 0;
336 __fileType = FTP.ASCII_FILE_TYPE;
337 __fileStructure = FTP.FILE_STRUCTURE;
338 __fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
339 __fileTransferMode = FTP.STREAM_TRANSFER_MODE;
340 __restartOffset = 0;
341 __systemName = null;
342 __entryParser = null;
343 __entryParserKey = "";
344 __bufferSize = Util.DEFAULT_COPY_BUFFER_SIZE;
345 }
346
347 private String __parsePathname(String reply)
348 {
349 int begin, end;
350
351 begin = reply.indexOf('"') + 1;
352 end = reply.indexOf('"', begin);
353
354 return reply.substring(begin, end);
355 }
356
357
358 private void __parsePassiveModeReply(String reply)
359 throws MalformedServerReplyException
360 {
361 java.util.regex.Matcher m = __parms_pat.matcher(reply);
362 if (!m.find()) {
363 throw new MalformedServerReplyException(
364 "Could not parse passive host information.\nServer Reply: " + reply);
365 }
366 reply = m.group();
367 String parts[] = m.group().split(",");
368
369 __passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' + parts[3];
370
371 try
372 {
373 int oct1 = Integer.parseInt(parts[4]);
374 int oct2 = Integer.parseInt(parts[5]);
375 __passivePort = (oct1 << 8) | oct2;
376 }
377 catch (NumberFormatException e)
378 {
379 throw new MalformedServerReplyException(
380 "Could not parse passive host information.\nServer Reply: " + reply);
381 }
382
383 }
384
385 private void __parseExtendedPassiveModeReply(String reply)
386 throws MalformedServerReplyException
387 {
388 int port;
389
390 reply = reply.substring(reply.indexOf('(') + 1,
391 reply.indexOf(')')).trim();
392
393 char delim1, delim2, delim3, delim4;
394 delim1 = reply.charAt(0);
395 delim2 = reply.charAt(1);
396 delim3 = reply.charAt(2);
397 delim4 = reply.charAt(reply.length()-1);
398
399 if (!(delim1 == delim2) || !(delim2 == delim3)
400 || !(delim3 == delim4))
401 throw new MalformedServerReplyException(
402 "Could not parse extended passive host information.\nServer Reply: " + reply);
403 try
404 {
405 port = Integer.parseInt(reply.substring(3, reply.length()-1));
406 }
407 catch (NumberFormatException e)
408 {
409 throw new MalformedServerReplyException(
410 "Could not parse extended passive host information.\nServer Reply: " + reply);
411 }
412
413
414 // in EPSV mode, the passive host address is implicit
415 __passiveHost = getRemoteAddress().getHostAddress();
416 __passivePort = port;
417 }
418
419 private boolean __storeFile(int command, String remote, InputStream local)
420 throws IOException
421 {
422 OutputStream output;
423 Socket socket;
424
425 if ((socket = _openDataConnection_(command, remote)) == null)
426 return false;
427
428 output = new BufferedOutputStream(socket.getOutputStream(),
429 getBufferSize()
430 );
431 if (__fileType == ASCII_FILE_TYPE)
432 output = new ToNetASCIIOutputStream(output);
433 // Treat everything else as binary for now
434 try
435 {
436 Util.copyStream(local, output, getBufferSize(),
437 CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
438 false);
439 }
440 catch (IOException e)
441 {
442 try
443 {
444 socket.close();
445 }
446 catch (IOException f)
447 {}
448 throw e;
449 }
450 output.close();
451 socket.close();
452 return completePendingCommand();
453 }
454
455 private OutputStream __storeFileStream(int command, String remote)
456 throws IOException
457 {
458 OutputStream output;
459 Socket socket;
460
461 if ((socket = _openDataConnection_(command, remote)) == null)
462 return null;
463
464 output = socket.getOutputStream();
465 if (__fileType == ASCII_FILE_TYPE) {
466 // We buffer ascii transfers because the buffering has to
467 // be interposed between ToNetASCIIOutputSream and the underlying
468 // socket output stream. We don't buffer binary transfers
469 // because we don't want to impose a buffering policy on the
470 // programmer if possible. Programmers can decide on their
471 // own if they want to wrap the SocketOutputStream we return
472 // for file types other than ASCII.
473 output = new BufferedOutputStream(output,
474 getBufferSize());
475 output = new ToNetASCIIOutputStream(output);
476
477 }
478 return new org.apache.commons.net.io.SocketOutputStream(socket, output);
479 }
480
481
482 /**
483 * Establishes a data connection with the FTP server, returning
484 * a Socket for the connection if successful. If a restart
485 * offset has been set with {@link #setRestartOffset(long)},
486 * a REST command is issued to the server with the offset as
487 * an argument before establishing the data connection. Active
488 * mode connections also cause a local PORT command to be issued.
489 * <p>
490 * @param command The text representation of the FTP command to send.
491 * @param arg The arguments to the FTP command. If this parameter is
492 * set to null, then the command is sent with no argument.
493 * @return A Socket corresponding to the established data connection.
494 * Null is returned if an FTP protocol error is reported at
495 * any point during the establishment and initialization of
496 * the connection.
497 * @exception IOException If an I/O error occurs while either sending a
498 * command to the server or receiving a reply from the server.
499 */
500 protected Socket _openDataConnection_(int command, String arg)
501 throws IOException
502 {
503 Socket socket;
504
505 if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
506 __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
507 return null;
508
509 final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;
510
511 if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
512 {
513 // if no activePortRange was set (correctly) -> getActivePort() = 0
514 // -> new ServerSocket(0) -> bind to any free local port
515 ServerSocket server = _serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());
516
517 // Try EPRT only if remote server is over IPv6, if not use PORT,
518 // because EPRT has no advantage over PORT on IPv4.
519 // It could even have the disadvantage,
520 // that EPRT will make the data connection fail, because
521 // today's intelligent NAT Firewalls are able to
522 // substitute IP addresses in the PORT command,
523 // but might not be able to recognize the EPRT command.
524 if (isInet6Address)
525 {
526 if (!FTPReply.isPositiveCompletion(eprt(getHostAddress(), server.getLocalPort())))
527 {
528 server.close();
529 return null;
530 }
531 }
532 else
533 {
534 if (!FTPReply.isPositiveCompletion(port(getHostAddress(), server.getLocalPort())))
535 {
536 server.close();
537 return null;
538 }
539 }
540
541 if ((__restartOffset > 0) && !restart(__restartOffset))
542 {
543 server.close();
544 return null;
545 }
546
547 if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
548 {
549 server.close();
550 return null;
551 }
552
553 // For now, let's just use the data timeout value for waiting for
554 // the data connection. It may be desirable to let this be a
555 // separately configurable value. In any case, we really want
556 // to allow preventing the accept from blocking indefinitely.
557 if (__dataTimeout >= 0)
558 server.setSoTimeout(__dataTimeout);
559 try {
560 socket = server.accept();
561 } finally {
562 server.close();
563 }
564 }
565 else
566 { // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
567
568 // Try EPSV command first on IPv6 - and IPv4 if enabled.
569 // When using IPv4 with NAT it has the advantage
570 // to work with more rare configurations.
571 // E.g. if FTP server has a static PASV address (external network)
572 // and the client is coming from another internal network.
573 // In that case the data connection after PASV command would fail,
574 // while EPSV would make the client succeed by taking just the port.
575 boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
576 if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE)
577 {
578 __parseExtendedPassiveModeReply(_replyLines.get(0));
579 }
580 else
581 {
582 if (isInet6Address) {
583 return null; // Must use EPSV for IPV6
584 }
585 // If EPSV failed on IPV4, revert to PASV
586 if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
587 return null;
588 }
589 __parsePassiveModeReply(_replyLines.get(0));
590 }
591
592 socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
593 if ((__restartOffset > 0) && !restart(__restartOffset))
594 {
595 socket.close();
596 return null;
597 }
598
599 if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
600 {
601 socket.close();
602 return null;
603 }
604 }
605
606 if (__remoteVerificationEnabled && !verifyRemote(socket))
607 {
608 InetAddress host1, host2;
609
610 host1 = socket.getInetAddress();
611 host2 = getRemoteAddress();
612
613 socket.close();
614
615 throw new IOException(
616 "Host attempting data connection " + host1.getHostAddress() +
617 " is not same as server " + host2.getHostAddress());
618 }
619
620 if (__dataTimeout >= 0)
621 socket.setSoTimeout(__dataTimeout);
622
623 return socket;
624 }
625
626
627 @Override
628 protected void _connectAction_() throws IOException
629 {
630 super._connectAction_();
631 __initDefaults();
632 }
633
634
635 /***
636 * Sets the timeout in milliseconds to use when reading from the
637 * data connection. This timeout will be set immediately after
638 * opening the data connection.
639 * <p>
640 * @param timeout The default timeout in milliseconds that is used when
641 * opening a data connection socket.
642 ***/
643 public void setDataTimeout(int timeout)
644 {
645 __dataTimeout = timeout;
646 }
647
648 /**
649 * set the factory used for parser creation to the supplied factory object.
650 *
651 * @param parserFactory
652 * factory object used to create FTPFileEntryParsers
653 *
654 * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
655 * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
656 */
657 public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
658 __parserFactory = parserFactory;
659 }
660
661
662 /***
663 * Closes the connection to the FTP server and restores
664 * connection parameters to the default values.
665 * <p>
666 * @exception IOException If an error occurs while disconnecting.
667 ***/
668 @Override
669 public void disconnect() throws IOException
670 {
671 super.disconnect();
672 __initDefaults();
673 }
674
675
676 /***
677 * Enable or disable verification that the remote host taking part
678 * of a data connection is the same as the host to which the control
679 * connection is attached. The default is for verification to be
680 * enabled. You may set this value at any time, whether the
681 * FTPClient is currently connected or not.
682 * <p>
683 * @param enable True to enable verification, false to disable verification.
684 ***/
685 public void setRemoteVerificationEnabled(boolean enable)
686 {
687 __remoteVerificationEnabled = enable;
688 }
689
690 /***
691 * Return whether or not verification of the remote host participating
692 * in data connections is enabled. The default behavior is for
693 * verification to be enabled.
694 * <p>
695 * @return True if verification is enabled, false if not.
696 ***/
697 public boolean isRemoteVerificationEnabled()
698 {
699 return __remoteVerificationEnabled;
700 }
701
702 /***
703 * Login to the FTP server using the provided username and password.
704 * <p>
705 * @param username The username to login under.
706 * @param password The password to use.
707 * @return True if successfully completed, false if not.
708 * @exception FTPConnectionClosedException
709 * If the FTP server prematurely closes the connection as a result
710 * of the client being idle or some other reason causing the server
711 * to send FTP reply code 421. This exception may be caught either
712 * as an IOException or independently as itself.
713 * @exception IOException If an I/O error occurs while either sending a
714 * command to the server or receiving a reply from the server.
715 ***/
716 public boolean login(String username, String password) throws IOException
717 {
718
719 user(username);
720
721 if (FTPReply.isPositiveCompletion(_replyCode))
722 return true;
723
724 // If we get here, we either have an error code, or an intermmediate
725 // reply requesting password.
726 if (!FTPReply.isPositiveIntermediate(_replyCode))
727 return false;
728
729 return FTPReply.isPositiveCompletion(pass(password));
730 }
731
732
733 /***
734 * Login to the FTP server using the provided username, password,
735 * and account. If no account is required by the server, only
736 * the username and password, the account information is not used.
737 * <p>
738 * @param username The username to login under.
739 * @param password The password to use.
740 * @param account The account to use.
741 * @return True if successfully completed, false if not.
742 * @exception FTPConnectionClosedException
743 * If the FTP server prematurely closes the connection as a result
744 * of the client being idle or some other reason causing the server
745 * to send FTP reply code 421. This exception may be caught either
746 * as an IOException or independently as itself.
747 * @exception IOException If an I/O error occurs while either sending a
748 * command to the server or receiving a reply from the server.
749 ***/
750 public boolean login(String username, String password, String account)
751 throws IOException
752 {
753 user(username);
754
755 if (FTPReply.isPositiveCompletion(_replyCode))
756 return true;
757
758 // If we get here, we either have an error code, or an intermmediate
759 // reply requesting password.
760 if (!FTPReply.isPositiveIntermediate(_replyCode))
761 return false;
762
763 pass(password);
764
765 if (FTPReply.isPositiveCompletion(_replyCode))
766 return true;
767
768 if (!FTPReply.isPositiveIntermediate(_replyCode))
769 return false;
770
771 return FTPReply.isPositiveCompletion(acct(account));
772 }
773
774 /***
775 * Logout of the FTP server by sending the QUIT command.
776 * <p>
777 * @return True if successfully completed, false if not.
778 * @exception FTPConnectionClosedException
779 * If the FTP server prematurely closes the connection as a result
780 * of the client being idle or some other reason causing the server
781 * to send FTP reply code 421. This exception may be caught either
782 * as an IOException or independently as itself.
783 * @exception IOException If an I/O error occurs while either sending a
784 * command to the server or receiving a reply from the server.
785 ***/
786 public boolean logout() throws IOException
787 {
788 return FTPReply.isPositiveCompletion(quit());
789 }
790
791
792 /***
793 * Change the current working directory of the FTP session.
794 * <p>
795 * @param pathname The new current working directory.
796 * @return True if successfully completed, false if not.
797 * @exception FTPConnectionClosedException
798 * If the FTP server prematurely closes the connection as a result
799 * of the client being idle or some other reason causing the server
800 * to send FTP reply code 421. This exception may be caught either
801 * as an IOException or independently as itself.
802 * @exception IOException If an I/O error occurs while either sending a
803 * command to the server or receiving a reply from the server.
804 ***/
805 public boolean changeWorkingDirectory(String pathname) throws IOException
806 {
807 return FTPReply.isPositiveCompletion(cwd(pathname));
808 }
809
810
811 /***
812 * Change to the parent directory of the current working directory.
813 * <p>
814 * @return True if successfully completed, false if not.
815 * @exception FTPConnectionClosedException
816 * If the FTP server prematurely closes the connection as a result
817 * of the client being idle or some other reason causing the server
818 * to send FTP reply code 421. This exception may be caught either
819 * as an IOException or independently as itself.
820 * @exception IOException If an I/O error occurs while either sending a
821 * command to the server or receiving a reply from the server.
822 ***/
823 public boolean changeToParentDirectory() throws IOException
824 {
825 return FTPReply.isPositiveCompletion(cdup());
826 }
827
828
829 /***
830 * Issue the FTP SMNT command.
831 * <p>
832 * @param pathname The pathname to mount.
833 * @return True if successfully completed, false if not.
834 * @exception FTPConnectionClosedException
835 * If the FTP server prematurely closes the connection as a result
836 * of the client being idle or some other reason causing the server
837 * to send FTP reply code 421. This exception may be caught either
838 * as an IOException or independently as itself.
839 * @exception IOException If an I/O error occurs while either sending a
840 * command to the server or receiving a reply from the server.
841 ***/
842 public boolean structureMount(String pathname) throws IOException
843 {
844 return FTPReply.isPositiveCompletion(smnt(pathname));
845 }
846
847 /***
848 * Reinitialize the FTP session. Not all FTP servers support this
849 * command, which issues the FTP REIN command.
850 * <p>
851 * @return True if successfully completed, false if not.
852 * @exception FTPConnectionClosedException
853 * If the FTP server prematurely closes the connection as a result
854 * of the client being idle or some other reason causing the server
855 * to send FTP reply code 421. This exception may be caught either
856 * as an IOException or independently as itself.
857 * @exception IOException If an I/O error occurs while either sending a
858 * command to the server or receiving a reply from the server.
859 ***/
860 boolean reinitialize() throws IOException
861 {
862 rein();
863
864 if (FTPReply.isPositiveCompletion(_replyCode) ||
865 (FTPReply.isPositivePreliminary(_replyCode) &&
866 FTPReply.isPositiveCompletion(getReply())))
867 {
868
869 __initDefaults();
870
871 return true;
872 }
873
874 return false;
875 }
876
877
878 /***
879 * Set the current data connection mode to
880 * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>. No communication
881 * with the FTP server is conducted, but this causes all future data
882 * transfers to require the FTP server to connect to the client's
883 * data port. Additionally, to accommodate differences between socket
884 * implementations on different platforms, this method causes the
885 * client to issue a PORT command before every data transfer.
886 ***/
887 public void enterLocalActiveMode()
888 {
889 __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
890 __passiveHost = null;
891 __passivePort = -1;
892 }
893
894
895 /***
896 * Set the current data connection mode to
897 * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>. Use this
898 * method only for data transfers between the client and server.
899 * This method causes a PASV (or EPSV) command to be issued to the server
900 * before the opening of every data connection, telling the server to
901 * open a data port to which the client will connect to conduct
902 * data transfers. The FTPClient will stay in
903 * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
904 * mode is changed by calling some other method such as
905 * {@link #enterLocalActiveMode enterLocalActiveMode() }
906 * <p>
907 * <b>N.B.</b> currently calling any connect method will reset the mode to
908 * ACTIVE_LOCAL_DATA_CONNECTION_MODE.
909 ***/
910 public void enterLocalPassiveMode()
911 {
912 __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
913 // These will be set when just before a data connection is opened
914 // in _openDataConnection_()
915 __passiveHost = null;
916 __passivePort = -1;
917 }
918
919
920 /***
921 * Set the current data connection mode to
922 * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>. Use this method only
923 * for server to server data transfers. This method issues a PORT
924 * command to the server, indicating the other server and port to which
925 * it should connect for data transfers. You must call this method
926 * before EVERY server to server transfer attempt. The FTPClient will
927 * NOT automatically continue to issue PORT commands. You also
928 * must remember to call
929 * {@link #enterLocalActiveMode enterLocalActiveMode() } if you
930 * wish to return to the normal data connection mode.
931 * <p>
932 * @param host The passive mode server accepting connections for data
933 * transfers.
934 * @param port The passive mode server's data port.
935 * @return True if successfully completed, false if not.
936 * @exception FTPConnectionClosedException
937 * If the FTP server prematurely closes the connection as a result
938 * of the client being idle or some other reason causing the server
939 * to send FTP reply code 421. This exception may be caught either
940 * as an IOException or independently as itself.
941 * @exception IOException If an I/O error occurs while either sending a
942 * command to the server or receiving a reply from the server.
943 ***/
944 public boolean enterRemoteActiveMode(InetAddress host, int port)
945 throws IOException
946 {
947 if (FTPReply.isPositiveCompletion(port(host, port)))
948 {
949 __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
950 __passiveHost = null;
951 __passivePort = -1;
952 return true;
953 }
954 return false;
955 }
956
957 /***
958 * Set the current data connection mode to
959 * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>. Use this
960 * method only for server to server data transfers.
961 * This method issues a PASV command to the server, telling it to
962 * open a data port to which the active server will connect to conduct
963 * data transfers. You must call this method
964 * before EVERY server to server transfer attempt. The FTPClient will
965 * NOT automatically continue to issue PASV commands. You also
966 * must remember to call
967 * {@link #enterLocalActiveMode enterLocalActiveMode() } if you
968 * wish to return to the normal data connection mode.
969 * <p>
970 * @return True if successfully completed, false if not.
971 * @exception FTPConnectionClosedException
972 * If the FTP server prematurely closes the connection as a result
973 * of the client being idle or some other reason causing the server
974 * to send FTP reply code 421. This exception may be caught either
975 * as an IOException or independently as itself.
976 * @exception IOException If an I/O error occurs while either sending a
977 * command to the server or receiving a reply from the server.
978 ***/
979 public boolean enterRemotePassiveMode() throws IOException
980 {
981 if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
982 return false;
983
984 __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
985 __parsePassiveModeReply(_replyLines.get(0));
986
987 return true;
988 }
989
990 /***
991 * Returns the hostname or IP address (in the form of a string) returned
992 * by the server when entering passive mode. If not in passive mode,
993 * returns null. This method only returns a valid value AFTER a
994 * data connection has been opened after a call to
995 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
996 * This is because FTPClient sends a PASV command to the server only
997 * just before opening a data connection, and not when you call
998 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
999 * <p>
1000 * @return The passive host name if in passive mode, otherwise null.
1001 ***/
1002 public String getPassiveHost()
1003 {
1004 return __passiveHost;
1005 }
1006
1007 /***
1008 * If in passive mode, returns the data port of the passive host.
1009 * This method only returns a valid value AFTER a
1010 * data connection has been opened after a call to
1011 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
1012 * This is because FTPClient sends a PASV command to the server only
1013 * just before opening a data connection, and not when you call
1014 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
1015 * <p>
1016 * @return The data port of the passive server. If not in passive
1017 * mode, undefined.
1018 ***/
1019 public int getPassivePort()
1020 {
1021 return __passivePort;
1022 }
1023
1024
1025 /***
1026 * Returns the current data connection mode (one of the
1027 * <code> _DATA_CONNECTION_MODE </code> constants.
1028 * <p>
1029 * @return The current data connection mode (one of the
1030 * <code> _DATA_CONNECTION_MODE </code> constants.
1031 ***/
1032 public int getDataConnectionMode()
1033 {
1034 return __dataConnectionMode;
1035 }
1036
1037 /**
1038 * Get the client port for active mode.
1039 * <p>
1040 * @return The client port for active mode.
1041 */
1042 private int getActivePort()
1043 {
1044 if (__activeMinPort > 0 && __activeMaxPort >= __activeMinPort)
1045 {
1046 if (__activeMaxPort == __activeMinPort)
1047 return __activeMaxPort;
1048 // Get a random port between the min and max port range
1049 return __random.nextInt(__activeMaxPort - __activeMinPort + 1) + __activeMinPort;
1050 }
1051 else
1052 {
1053 // default port
1054 return 0;
1055 }
1056 }
1057
1058 /**
1059 * Get the host address for active mode.
1060 * <p>
1061 * @return The host address for active mode.
1062 */
1063 private InetAddress getHostAddress()
1064 {
1065 if (__activeExternalHost != null)
1066 {
1067 return __activeExternalHost;
1068 }
1069 else
1070 {
1071 // default local address
1072 return getLocalAddress();
1073 }
1074 }
1075
1076 /***
1077 * Set the client side port range in active mode.
1078 * <p>
1079 * @param minPort The lowest available port (inclusive).
1080 * @param maxPort The highest available port (inclusive).
1081 * @since 2.2
1082 ***/
1083 public void setActivePortRange(int minPort, int maxPort)
1084 {
1085 this.__activeMinPort = minPort;
1086 this.__activeMaxPort = maxPort;
1087 }
1088
1089 /***
1090 * Set the external IP address in active mode.
1091 * Useful when there are multiple network cards.
1092 * <p>
1093 * @param ipAddress The external IP address of this machine.
1094 * @throws UnknownHostException
1095 * @since 2.2
1096 ***/
1097 public void setActiveExternalIPAddress(String ipAddress) throws UnknownHostException
1098 {
1099 this.__activeExternalHost = InetAddress.getByName(ipAddress);
1100 }
1101
1102
1103 /***
1104 * Sets the file type to be transferred. This should be one of
1105 * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.BINARY_FILE_TYPE</code>,
1106 * etc. The file type only needs to be set when you want to change the
1107 * type. After changing it, the new type stays in effect until you change
1108 * it again. The default file type is <code> FTP.ASCII_FILE_TYPE </code>
1109 * if this method is never called.
1110 * <p>
1111 * <b>N.B.</b> currently calling any connect method will reset the mode to
1112 * ACTIVE_LOCAL_DATA_CONNECTION_MODE.
1113 * @param fileType The <code> _FILE_TYPE </code> constant indcating the
1114 * type of file.
1115 * @return True if successfully completed, false if not.
1116 * @exception FTPConnectionClosedException
1117 * If the FTP server prematurely closes the connection as a result
1118 * of the client being idle or some other reason causing the server
1119 * to send FTP reply code 421. This exception may be caught either
1120 * as an IOException or independently as itself.
1121 * @exception IOException If an I/O error occurs while either sending a
1122 * command to the server or receiving a reply from the server.
1123 ***/
1124 public boolean setFileType(int fileType) throws IOException
1125 {
1126 if (FTPReply.isPositiveCompletion(type(fileType)))
1127 {
1128 __fileType = fileType;
1129 __fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
1130 return true;
1131 }
1132 return false;
1133 }
1134
1135
1136 /***
1137 * Sets the file type to be transferred and the format. The type should be
1138 * one of <code> FTP.ASCII_FILE_TYPE </code>,
1139 * <code> FTP.BINARY_FILE_TYPE </code>, etc. The file type only needs to
1140 * be set when you want to change the type. After changing it, the new
1141 * type stays in effect until you change it again. The default file type
1142 * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
1143 * The format should be one of the FTP class <code> TEXT_FORMAT </code>
1144 * constants, or if the type is <code> FTP.LOCAL_FILE_TYPE </code>, the
1145 * format should be the byte size for that type. The default format
1146 * is <code> FTP.NON_PRINT_TEXT_FORMAT </code> if this method is never
1147 * called.
1148 * <p>
1149 * <b>N.B.</b> currently calling any connect method will reset the mode to
1150 * ACTIVE_LOCAL_DATA_CONNECTION_MODE.
1151 * <p>
1152 * @param fileType The <code> _FILE_TYPE </code> constant indcating the
1153 * type of file.
1154 * @param formatOrByteSize The format of the file (one of the
1155 * <code>_FORMAT</code> constants. In the case of
1156 * <code>LOCAL_FILE_TYPE</code>, the byte size.
1157 * <p>
1158 * @return True if successfully completed, false if not.
1159 * @exception FTPConnectionClosedException
1160 * If the FTP server prematurely closes the connection as a result
1161 * of the client being idle or some other reason causing the server
1162 * to send FTP reply code 421. This exception may be caught either
1163 * as an IOException or independently as itself.
1164 * @exception IOException If an I/O error occurs while either sending a
1165 * command to the server or receiving a reply from the server.
1166 ***/
1167 public boolean setFileType(int fileType, int formatOrByteSize)
1168 throws IOException
1169 {
1170 if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
1171 {
1172 __fileType = fileType;
1173 __fileFormat = formatOrByteSize;
1174 return true;
1175 }
1176 return false;
1177 }
1178
1179
1180 /***
1181 * Sets the file structure. The default structure is
1182 * <code> FTP.FILE_STRUCTURE </code> if this method is never called.
1183 * <p>
1184 * @param structure The structure of the file (one of the FTP class
1185 * <code>_STRUCTURE</code> constants).
1186 * @return True if successfully completed, false if not.
1187 * @exception FTPConnectionClosedException
1188 * If the FTP server prematurely closes the connection as a result
1189 * of the client being idle or some other reason causing the server
1190 * to send FTP reply code 421. This exception may be caught either
1191 * as an IOException or independently as itself.
1192 * @exception IOException If an I/O error occurs while either sending a
1193 * command to the server or receiving a reply from the server.
1194 ***/
1195 public boolean setFileStructure(int structure) throws IOException
1196 {
1197 if (FTPReply.isPositiveCompletion(stru(structure)))
1198 {
1199 __fileStructure = structure;
1200 return true;
1201 }
1202 return false;
1203 }
1204
1205
1206 /***
1207 * Sets the transfer mode. The default transfer mode
1208 * <code> FTP.STREAM_TRANSFER_MODE </code> if this method is never called.
1209 * <p>
1210 * @param mode The new transfer mode to use (one of the FTP class
1211 * <code>_TRANSFER_MODE</code> constants).
1212 * @return True if successfully completed, false if not.
1213 * @exception FTPConnectionClosedException
1214 * If the FTP server prematurely closes the connection as a result
1215 * of the client being idle or some other reason causing the server
1216 * to send FTP reply code 421. This exception may be caught either
1217 * as an IOException or independently as itself.
1218 * @exception IOException If an I/O error occurs while either sending a
1219 * command to the server or receiving a reply from the server.
1220 ***/
1221 public boolean setFileTransferMode(int mode) throws IOException
1222 {
1223 if (FTPReply.isPositiveCompletion(mode(mode)))
1224 {
1225 __fileTransferMode = mode;
1226 return true;
1227 }
1228 return false;
1229 }
1230
1231
1232 /***
1233 * Initiate a server to server file transfer. This method tells the
1234 * server to which the client is connected to retrieve a given file from
1235 * the other server.
1236 * <p>
1237 * @param filename The name of the file to retrieve.
1238 * @return True if successfully completed, false if not.
1239 * @exception FTPConnectionClosedException
1240 * If the FTP server prematurely closes the connection as a result
1241 * of the client being idle or some other reason causing the server
1242 * to send FTP reply code 421. This exception may be caught either
1243 * as an IOException or independently as itself.
1244 * @exception IOException If an I/O error occurs while either sending a
1245 * command to the server or receiving a reply from the server.
1246 ***/
1247 public boolean remoteRetrieve(String filename) throws IOException
1248 {
1249 if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1250 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1251 return FTPReply.isPositivePreliminary(retr(filename));
1252 return false;
1253 }
1254
1255
1256 /***
1257 * Initiate a server to server file transfer. This method tells the
1258 * server to which the client is connected to store a file on
1259 * the other server using the given filename. The other server must
1260 * have had a <code> remoteRetrieve </code> issued to it by another
1261 * FTPClient.
1262 * <p>
1263 * @param filename The name to call the file that is to be stored.
1264 * @return True if successfully completed, false if not.
1265 * @exception FTPConnectionClosedException
1266 * If the FTP server prematurely closes the connection as a result
1267 * of the client being idle or some other reason causing the server
1268 * to send FTP reply code 421. This exception may be caught either
1269 * as an IOException or independently as itself.
1270 * @exception IOException If an I/O error occurs while either sending a
1271 * command to the server or receiving a reply from the server.
1272 ***/
1273 public boolean remoteStore(String filename) throws IOException
1274 {
1275 if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1276 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1277 return FTPReply.isPositivePreliminary(stor(filename));
1278 return false;
1279 }
1280
1281
1282 /***
1283 * Initiate a server to server file transfer. This method tells the
1284 * server to which the client is connected to store a file on
1285 * the other server using a unique filename based on the given filename.
1286 * The other server must have had a <code> remoteRetrieve </code> issued
1287 * to it by another FTPClient.
1288 * <p>
1289 * @param filename The name on which to base the filename of the file
1290 * that is to be stored.
1291 * @return True if successfully completed, false if not.
1292 * @exception FTPConnectionClosedException
1293 * If the FTP server prematurely closes the connection as a result
1294 * of the client being idle or some other reason causing the server
1295 * to send FTP reply code 421. This exception may be caught either
1296 * as an IOException or independently as itself.
1297 * @exception IOException If an I/O error occurs while either sending a
1298 * command to the server or receiving a reply from the server.
1299 ***/
1300 public boolean remoteStoreUnique(String filename) throws IOException
1301 {
1302 if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1303 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1304 return FTPReply.isPositivePreliminary(stou(filename));
1305 return false;
1306 }
1307
1308
1309 /***
1310 * Initiate a server to server file transfer. This method tells the
1311 * server to which the client is connected to store a file on
1312 * the other server using a unique filename.
1313 * The other server must have had a <code> remoteRetrieve </code> issued
1314 * to it by another FTPClient. Many FTP servers require that a base
1315 * filename be given from which the unique filename can be derived. For
1316 * those servers use the other version of <code> remoteStoreUnique</code>
1317 * <p>
1318 * @return True if successfully completed, false if not.
1319 * @exception FTPConnectionClosedException
1320 * If the FTP server prematurely closes the connection as a result
1321 * of the client being idle or some other reason causing the server
1322 * to send FTP reply code 421. This exception may be caught either
1323 * as an IOException or independently as itself.
1324 * @exception IOException If an I/O error occurs while either sending a
1325 * command to the server or receiving a reply from the server.
1326 ***/
1327 public boolean remoteStoreUnique() throws IOException
1328 {
1329 if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1330 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1331 return FTPReply.isPositivePreliminary(stou());
1332 return false;
1333 }
1334
1335 // For server to server transfers
1336 /***
1337 * Initiate a server to server file transfer. This method tells the
1338 * server to which the client is connected to append to a given file on
1339 * the other server. The other server must have had a
1340 * <code> remoteRetrieve </code> issued to it by another FTPClient.
1341 * <p>
1342 * @param filename The name of the file to be appended to, or if the
1343 * file does not exist, the name to call the file being stored.
1344 * <p>
1345 * @return True if successfully completed, false if not.
1346 * @exception FTPConnectionClosedException
1347 * If the FTP server prematurely closes the connection as a result
1348 * of the client being idle or some other reason causing the server
1349 * to send FTP reply code 421. This exception may be caught either
1350 * as an IOException or independently as itself.
1351 * @exception IOException If an I/O error occurs while either sending a
1352 * command to the server or receiving a reply from the server.
1353 ***/
1354 public boolean remoteAppend(String filename) throws IOException
1355 {
1356 if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1357 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1358 return FTPReply.isPositivePreliminary(appe(filename));
1359 return false;
1360 }
1361
1362 /***
1363 * There are a few FTPClient methods that do not complete the
1364 * entire sequence of FTP commands to complete a transaction. These
1365 * commands require some action by the programmer after the reception
1366 * of a positive intermediate command. After the programmer's code
1367 * completes its actions, it must call this method to receive
1368 * the completion reply from the server and verify the success of the
1369 * entire transaction.
1370 * <p>
1371 * For example,
1372 * <pre>
1373 * InputStream input;
1374 * OutputStream output;
1375 * input = new FileInputStream("foobaz.txt");
1376 * output = ftp.storeFileStream("foobar.txt")
1377 * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
1378 * input.close();
1379 * output.close();
1380 * ftp.logout();
1381 * ftp.disconnect();
1382 * System.err.println("File transfer failed.");
1383 * System.exit(1);
1384 * }
1385 * Util.copyStream(input, output);
1386 * input.close();
1387 * output.close();
1388 * // Must call completePendingCommand() to finish command.
1389 * if(!ftp.completePendingCommand()) {
1390 * ftp.logout();
1391 * ftp.disconnect();
1392 * System.err.println("File transfer failed.");
1393 * System.exit(1);
1394 * }
1395 * </pre>
1396 * <p>
1397 * @return True if successfully completed, false if not.
1398 * @exception FTPConnectionClosedException
1399 * If the FTP server prematurely closes the connection as a result
1400 * of the client being idle or some other reason causing the server
1401 * to send FTP reply code 421. This exception may be caught either
1402 * as an IOException or independently as itself.
1403 * @exception IOException If an I/O error occurs while either sending a
1404 * command to the server or receiving a reply from the server.
1405 ***/
1406 public boolean completePendingCommand() throws IOException
1407 {
1408 return FTPReply.isPositiveCompletion(getReply());
1409 }
1410
1411
1412 /***
1413 * Retrieves a named file from the server and writes it to the given
1414 * OutputStream. This method does NOT close the given OutputStream.
1415 * If the current file type is ASCII, line separators in the file are
1416 * converted to the local representation.
1417 * <p>
1418 * Note: if you have used {@link #setRestartOffset(long)},
1419 * the file data will start from the selected offset.
1420 * @param remote The name of the remote file.
1421 * @param local The local OutputStream to which to write the file.
1422 * @return True if successfully completed, false if not.
1423 * @exception FTPConnectionClosedException
1424 * If the FTP server prematurely closes the connection as a result
1425 * of the client being idle or some other reason causing the server
1426 * to send FTP reply code 421. This exception may be caught either
1427 * as an IOException or independently as itself.
1428 * @exception CopyStreamException If an I/O error occurs while actually
1429 * transferring the file. The CopyStreamException allows you to
1430 * determine the number of bytes transferred and the IOException
1431 * causing the error. This exception may be caught either
1432 * as an IOException or independently as itself.
1433 * @exception IOException If an I/O error occurs while either sending a
1434 * command to the server or receiving a reply from the server.
1435 ***/
1436 public boolean retrieveFile(String remote, OutputStream local)
1437 throws IOException
1438 {
1439 InputStream input;
1440 Socket socket;
1441
1442 if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
1443 return false;
1444
1445 input = new BufferedInputStream(socket.getInputStream(),
1446 getBufferSize());
1447 if (__fileType == ASCII_FILE_TYPE)
1448 input = new FromNetASCIIInputStream(input);
1449 // Treat everything else as binary for now
1450 try
1451 {
1452 Util.copyStream(input, local, getBufferSize(),
1453 CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
1454 false);
1455 }
1456 catch (IOException e)
1457 {
1458 try
1459 {
1460 socket.close();
1461 }
1462 catch (IOException f)
1463 {}
1464 throw e;
1465 }
1466 socket.close();
1467 return completePendingCommand();
1468 }
1469
1470 /***
1471 * Returns an InputStream from which a named file from the server
1472 * can be read. If the current file type is ASCII, the returned
1473 * InputStream will convert line separators in the file to
1474 * the local representation. You must close the InputStream when you
1475 * finish reading from it. The InputStream itself will take care of
1476 * closing the parent data connection socket upon being closed. To
1477 * finalize the file transfer you must call
1478 * {@link #completePendingCommand completePendingCommand } and
1479 * check its return value to verify success.
1480 * <p>
1481 * Note: if you have used {@link #setRestartOffset(long)},
1482 * the file data will start from the selected offset.
1483 *
1484 * @param remote The name of the remote file.
1485 * @return An InputStream from which the remote file can be read. If
1486 * the data connection cannot be opened (e.g., the file does not
1487 * exist), null is returned (in which case you may check the reply
1488 * code to determine the exact reason for failure).
1489 * @exception FTPConnectionClosedException
1490 * If the FTP server prematurely closes the connection as a result
1491 * of the client being idle or some other reason causing the server
1492 * to send FTP reply code 421. This exception may be caught either
1493 * as an IOException or independently as itself.
1494 * @exception IOException If an I/O error occurs while either sending a
1495 * command to the server or receiving a reply from the server.
1496 ***/
1497 public InputStream retrieveFileStream(String remote) throws IOException
1498 {
1499 InputStream input;
1500 Socket socket;
1501
1502 if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
1503 return null;
1504
1505 input = socket.getInputStream();
1506 if (__fileType == ASCII_FILE_TYPE) {
1507 // We buffer ascii transfers because the buffering has to
1508 // be interposed between FromNetASCIIOutputSream and the underlying
1509 // socket input stream. We don't buffer binary transfers
1510 // because we don't want to impose a buffering policy on the
1511 // programmer if possible. Programmers can decide on their
1512 // own if they want to wrap the SocketInputStream we return
1513 // for file types other than ASCII.
1514 input = new BufferedInputStream(input,
1515 getBufferSize());
1516 input = new FromNetASCIIInputStream(input);
1517 }
1518 return new org.apache.commons.net.io.SocketInputStream(socket, input);
1519 }
1520
1521
1522 /***
1523 * Stores a file on the server using the given name and taking input
1524 * from the given InputStream. This method does NOT close the given
1525 * InputStream. If the current file type is ASCII, line separators in
1526 * the file are transparently converted to the NETASCII format (i.e.,
1527 * you should not attempt to create a special InputStream to do this).
1528 * <p>
1529 * @param remote The name to give the remote file.
1530 * @param local The local InputStream from which to read the file.
1531 * @return True if successfully completed, false if not.
1532 * @exception FTPConnectionClosedException
1533 * If the FTP server prematurely closes the connection as a result
1534 * of the client being idle or some other reason causing the server
1535 * to send FTP reply code 421. This exception may be caught either
1536 * as an IOException or independently as itself.
1537 * @exception CopyStreamException If an I/O error occurs while actually
1538 * transferring the file. The CopyStreamException allows you to
1539 * determine the number of bytes transferred and the IOException
1540 * causing the error. This exception may be caught either
1541 * as an IOException or independently as itself.
1542 * @exception IOException If an I/O error occurs while either sending a
1543 * command to the server or receiving a reply from the server.
1544 ***/
1545 public boolean storeFile(String remote, InputStream local)
1546 throws IOException
1547 {
1548 return __storeFile(FTPCommand.STOR, remote, local);
1549 }
1550
1551
1552 /***
1553 * Returns an OutputStream through which data can be written to store
1554 * a file on the server using the given name. If the current file type
1555 * is ASCII, the returned OutputStream will convert line separators in
1556 * the file to the NETASCII format (i.e., you should not attempt to
1557 * create a special OutputStream to do this). You must close the
1558 * OutputStream when you finish writing to it. The OutputStream itself
1559 * will take care of closing the parent data connection socket upon being
1560 * closed. To finalize the file transfer you must call
1561 * {@link #completePendingCommand completePendingCommand } and
1562 * check its return value to verify success.
1563 * <p>
1564 * @param remote The name to give the remote file.
1565 * @return An OutputStream through which the remote file can be written. If
1566 * the data connection cannot be opened (e.g., the file does not
1567 * exist), null is returned (in which case you may check the reply
1568 * code to determine the exact reason for failure).
1569 * @exception FTPConnectionClosedException
1570 * If the FTP server prematurely closes the connection as a result
1571 * of the client being idle or some other reason causing the server
1572 * to send FTP reply code 421. This exception may be caught either
1573 * as an IOException or independently as itself.
1574 * @exception IOException If an I/O error occurs while either sending a
1575 * command to the server or receiving a reply from the server.
1576 ***/
1577 public OutputStream storeFileStream(String remote) throws IOException
1578 {
1579 return __storeFileStream(FTPCommand.STOR, remote);
1580 }
1581
1582 /***
1583 * Appends to a file on the server with the given name, taking input
1584 * from the given InputStream. This method does NOT close the given
1585 * InputStream. If the current file type is ASCII, line separators in
1586 * the file are transparently converted to the NETASCII format (i.e.,
1587 * you should not attempt to create a special InputStream to do this).
1588 * <p>
1589 * @param remote The name of the remote file.
1590 * @param local The local InputStream from which to read the data to
1591 * be appended to the remote file.
1592 * @return True if successfully completed, false if not.
1593 * @exception FTPConnectionClosedException
1594 * If the FTP server prematurely closes the connection as a result
1595 * of the client being idle or some other reason causing the server
1596 * to send FTP reply code 421. This exception may be caught either
1597 * as an IOException or independently as itself.
1598 * @exception CopyStreamException If an I/O error occurs while actually
1599 * transferring the file. The CopyStreamException allows you to
1600 * determine the number of bytes transferred and the IOException
1601 * causing the error. This exception may be caught either
1602 * as an IOException or independently as itself.
1603 * @exception IOException If an I/O error occurs while either sending a
1604 * command to the server or receiving a reply from the server.
1605 ***/
1606 public boolean appendFile(String remote, InputStream local)
1607 throws IOException
1608 {
1609 return __storeFile(FTPCommand.APPE, remote, local);
1610 }
1611
1612 /***
1613 * Returns an OutputStream through which data can be written to append
1614 * to a file on the server with the given name. If the current file type
1615 * is ASCII, the returned OutputStream will convert line separators in
1616 * the file to the NETASCII format (i.e., you should not attempt to
1617 * create a special OutputStream to do this). You must close the
1618 * OutputStream when you finish writing to it. The OutputStream itself
1619 * will take care of closing the parent data connection socket upon being
1620 * closed. To finalize the file transfer you must call
1621 * {@link #completePendingCommand completePendingCommand } and
1622 * check its return value to verify success.
1623 * <p>
1624 * @param remote The name of the remote file.
1625 * @return An OutputStream through which the remote file can be appended.
1626 * If the data connection cannot be opened (e.g., the file does not
1627 * exist), null is returned (in which case you may check the reply
1628 * code to determine the exact reason for failure).
1629 * @exception FTPConnectionClosedException
1630 * If the FTP server prematurely closes the connection as a result
1631 * of the client being idle or some other reason causing the server
1632 * to send FTP reply code 421. This exception may be caught either
1633 * as an IOException or independently as itself.
1634 * @exception IOException If an I/O error occurs while either sending a
1635 * command to the server or receiving a reply from the server.
1636 ***/
1637 public OutputStream appendFileStream(String remote) throws IOException
1638 {
1639 return __storeFileStream(FTPCommand.APPE, remote);
1640 }
1641
1642 /***
1643 * Stores a file on the server using a unique name derived from the
1644 * given name and taking input
1645 * from the given InputStream. This method does NOT close the given
1646 * InputStream. If the current file type is ASCII, line separators in
1647 * the file are transparently converted to the NETASCII format (i.e.,
1648 * you should not attempt to create a special InputStream to do this).
1649 * <p>
1650 * @param remote The name on which to base the unique name given to
1651 * the remote file.
1652 * @param local The local InputStream from which to read the file.
1653 * @return True if successfully completed, false if not.
1654 * @exception FTPConnectionClosedException
1655 * If the FTP server prematurely closes the connection as a result
1656 * of the client being idle or some other reason causing the server
1657 * to send FTP reply code 421. This exception may be caught either
1658 * as an IOException or independently as itself.
1659 * @exception CopyStreamException If an I/O error occurs while actually
1660 * transferring the file. The CopyStreamException allows you to
1661 * determine the number of bytes transferred and the IOException
1662 * causing the error. This exception may be caught either
1663 * as an IOException or independently as itself.
1664 * @exception IOException If an I/O error occurs while either sending a
1665 * command to the server or receiving a reply from the server.
1666 ***/
1667 public boolean storeUniqueFile(String remote, InputStream local)
1668 throws IOException
1669 {
1670 return __storeFile(FTPCommand.STOU, remote, local);
1671 }
1672
1673
1674 /***
1675 * Returns an OutputStream through which data can be written to store
1676 * a file on the server using a unique name derived from the given name.
1677 * If the current file type
1678 * is ASCII, the returned OutputStream will convert line separators in
1679 * the file to the NETASCII format (i.e., you should not attempt to
1680 * create a special OutputStream to do this). You must close the
1681 * OutputStream when you finish writing to it. The OutputStream itself
1682 * will take care of closing the parent data connection socket upon being
1683 * closed. To finalize the file transfer you must call
1684 * {@link #completePendingCommand completePendingCommand } and
1685 * check its return value to verify success.
1686 * <p>
1687 * @param remote The name on which to base the unique name given to
1688 * the remote file.
1689 * @return An OutputStream through which the remote file can be written. If
1690 * the data connection cannot be opened (e.g., the file does not
1691 * exist), null is returned (in which case you may check the reply
1692 * code to determine the exact reason for failure).
1693 * @exception FTPConnectionClosedException
1694 * If the FTP server prematurely closes the connection as a result
1695 * of the client being idle or some other reason causing the server
1696 * to send FTP reply code 421. This exception may be caught either
1697 * as an IOException or independently as itself.
1698 * @exception IOException If an I/O error occurs while either sending a
1699 * command to the server or receiving a reply from the server.
1700 ***/
1701 public OutputStream storeUniqueFileStream(String remote) throws IOException
1702 {
1703 return __storeFileStream(FTPCommand.STOU, remote);
1704 }
1705
1706 /**
1707 * Stores a file on the server using a unique name assigned by the
1708 * server and taking input from the given InputStream. This method does
1709 * NOT close the given
1710 * InputStream. If the current file type is ASCII, line separators in
1711 * the file are transparently converted to the NETASCII format (i.e.,
1712 * you should not attempt to create a special InputStream to do this).
1713 * <p>
1714 * @param local The local InputStream from which to read the file.
1715 * @return True if successfully completed, false if not.
1716 * @exception FTPConnectionClosedException
1717 * If the FTP server prematurely closes the connection as a result
1718 * of the client being idle or some other reason causing the server
1719 * to send FTP reply code 421. This exception may be caught either
1720 * as an IOException or independently as itself.
1721 * @exception CopyStreamException If an I/O error occurs while actually
1722 * transferring the file. The CopyStreamException allows you to
1723 * determine the number of bytes transferred and the IOException
1724 * causing the error. This exception may be caught either
1725 * as an IOException or independently as itself.
1726 * @exception IOException If an I/O error occurs while either sending a
1727 * command to the server or receiving a reply from the server.
1728 */
1729 public boolean storeUniqueFile(InputStream local) throws IOException
1730 {
1731 return __storeFile(FTPCommand.STOU, null, local);
1732 }
1733
1734 /**
1735 * Returns an OutputStream through which data can be written to store
1736 * a file on the server using a unique name assigned by the server.
1737 * If the current file type
1738 * is ASCII, the returned OutputStream will convert line separators in
1739 * the file to the NETASCII format (i.e., you should not attempt to
1740 * create a special OutputStream to do this). You must close the
1741 * OutputStream when you finish writing to it. The OutputStream itself
1742 * will take care of closing the parent data connection socket upon being
1743 * closed. To finalize the file transfer you must call
1744 * {@link #completePendingCommand completePendingCommand } and
1745 * check its return value to verify success.
1746 * <p>
1747 * @return An OutputStream through which the remote file can be written. If
1748 * the data connection cannot be opened (e.g., the file does not
1749 * exist), null is returned (in which case you may check the reply
1750 * code to determine the exact reason for failure).
1751 * @exception FTPConnectionClosedException
1752 * If the FTP server prematurely closes the connection as a result
1753 * of the client being idle or some other reason causing the server
1754 * to send FTP reply code 421. This exception may be caught either
1755 * as an IOException or independently as itself.
1756 * @exception IOException If an I/O error occurs while either sending a
1757 * command to the server or receiving a reply from the server.
1758 */
1759 public OutputStream storeUniqueFileStream() throws IOException
1760 {
1761 return __storeFileStream(FTPCommand.STOU, null);
1762 }
1763
1764 /***
1765 * Reserve a number of bytes on the server for the next file transfer.
1766 * <p>
1767 * @param bytes The number of bytes which the server should allocate.
1768 * @return True if successfully completed, false if not.
1769 * @exception FTPConnectionClosedException
1770 * If the FTP server prematurely closes the connection as a result
1771 * of the client being idle or some other reason causing the server
1772 * to send FTP reply code 421. This exception may be caught either
1773 * as an IOException or independently as itself.
1774 * @exception IOException If an I/O error occurs while either sending a
1775 * command to the server or receiving a reply from the server.
1776 ***/
1777 public boolean allocate(int bytes) throws IOException
1778 {
1779 return FTPReply.isPositiveCompletion(allo(bytes));
1780 }
1781
1782 /**
1783 * Query the server for supported features. The server may reply with a list of server-supported exensions.
1784 * For example, a typical client-server interaction might be (from RFC 2289):
1785 * <pre>
1786 C> feat
1787 S> 211-Extensions supported:
1788 S> MLST size*;create;modify*;perm;media-type
1789 S> SIZE
1790 S> COMPRESSION
1791 S> MDTM
1792 S> 211 END
1793 * </pre>
1794 * @see <a href="http://www.faqs.org/rfcs/rfc2389.html">http://www.faqs.org/rfcs/rfc2389.html</a>
1795 * @return True if successfully completed, false if not.
1796 * @throws IOException
1797 * @since 2.2
1798 */
1799 public boolean features() throws IOException {
1800 return FTPReply.isPositiveCompletion(feat());
1801 }
1802
1803
1804 /**
1805 * Reserve space on the server for the next file transfer.
1806 * <p>
1807 * @param bytes The number of bytes which the server should allocate.
1808 * @param recordSize The size of a file record.
1809 * @return True if successfully completed, false if not.
1810 * @exception FTPConnectionClosedException
1811 * If the FTP server prematurely closes the connection as a result
1812 * of the client being idle or some other reason causing the server
1813 * to send FTP reply code 421. This exception may be caught either
1814 * as an IOException or independently as itself.
1815 * @exception IOException If an I/O error occurs while either sending a
1816 * command to the server or receiving a reply from the server.
1817 */
1818 public boolean allocate(int bytes, int recordSize) throws IOException
1819 {
1820 return FTPReply.isPositiveCompletion(allo(bytes, recordSize));
1821 }
1822
1823
1824 /***
1825 * Restart a <code>STREAM_TRANSFER_MODE</code> file transfer starting
1826 * from the given offset. This will only work on FTP servers supporting
1827 * the REST comand for the stream transfer mode. However, most FTP
1828 * servers support this. Any subsequent file transfer will start
1829 * reading or writing the remote file from the indicated offset.
1830 * <p>
1831 * @param offset The offset into the remote file at which to start the
1832 * next file transfer.
1833 * @return True if successfully completed, false if not.
1834 * @exception FTPConnectionClosedException
1835 * If the FTP server prematurely closes the connection as a result
1836 * of the client being idle or some other reason causing the server
1837 * to send FTP reply code 421. This exception may be caught either
1838 * as an IOException or independently as itself.
1839 * @exception IOException If an I/O error occurs while either sending a
1840 * command to the server or receiving a reply from the server.
1841 ***/
1842 private boolean restart(long offset) throws IOException
1843 {
1844 __restartOffset = 0;
1845 return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));
1846 }
1847
1848 /***
1849 * Sets the restart offset. The restart command is sent to the server
1850 * only before sending the file transfer command. When this is done,
1851 * the restart marker is reset to zero.
1852 * <p>
1853 * @param offset The offset into the remote file at which to start the
1854 * next file transfer. This must be a value greater than or
1855 * equal to zero.
1856 ***/
1857 public void setRestartOffset(long offset)
1858 {
1859 if (offset >= 0)
1860 __restartOffset = offset;
1861 }
1862
1863 /***
1864 * Fetches the restart offset.
1865 * <p>
1866 * @return offset The offset into the remote file at which to start the
1867 * next file transfer.
1868 ***/
1869 public long getRestartOffset()
1870 {
1871 return __restartOffset;
1872 }
1873
1874
1875
1876 /***
1877 * Renames a remote file.
1878 * <p>
1879 * @param from The name of the remote file to rename.
1880 * @param to The new name of the remote file.
1881 * @return True if successfully completed, false if not.
1882 * @exception FTPConnectionClosedException
1883 * If the FTP server prematurely closes the connection as a result
1884 * of the client being idle or some other reason causing the server
1885 * to send FTP reply code 421. This exception may be caught either
1886 * as an IOException or independently as itself.
1887 * @exception IOException If an I/O error occurs while either sending a
1888 * command to the server or receiving a reply from the server.
1889 ***/
1890 public boolean rename(String from, String to) throws IOException
1891 {
1892 if (!FTPReply.isPositiveIntermediate(rnfr(from)))
1893 return false;
1894
1895 return FTPReply.isPositiveCompletion(rnto(to));
1896 }
1897
1898
1899 /***
1900 * Abort a transfer in progress.
1901 * <p>
1902 * @return True if successfully completed, false if not.
1903 * @exception FTPConnectionClosedException
1904 * If the FTP server prematurely closes the connection as a result
1905 * of the client being idle or some other reason causing the server
1906 * to send FTP reply code 421. This exception may be caught either
1907 * as an IOException or independently as itself.
1908 * @exception IOException If an I/O error occurs while either sending a
1909 * command to the server or receiving a reply from the server.
1910 ***/
1911 public boolean abort() throws IOException
1912 {
1913 return FTPReply.isPositiveCompletion(abor());
1914 }
1915
1916 /***
1917 * Deletes a file on the FTP server.
1918 * <p>
1919 * @param pathname The pathname of the file to be deleted.
1920 * @return True if successfully completed, false if not.
1921 * @exception FTPConnectionClosedException
1922 * If the FTP server prematurely closes the connection as a result
1923 * of the client being idle or some other reason causing the server
1924 * to send FTP reply code 421. This exception may be caught either
1925 * as an IOException or independently as itself.
1926 * @exception IOException If an I/O error occurs while either sending a
1927 * command to the server or receiving a reply from the server.
1928 ***/
1929 public boolean deleteFile(String pathname) throws IOException
1930 {
1931 return FTPReply.isPositiveCompletion(dele(pathname));
1932 }
1933
1934
1935 /***
1936 * Removes a directory on the FTP server (if empty).
1937 * <p>
1938 * @param pathname The pathname of the directory to remove.
1939 * @return True if successfully completed, false if not.
1940 * @exception FTPConnectionClosedException
1941 * If the FTP server prematurely closes the connection as a result
1942 * of the client being idle or some other reason causing the server
1943 * to send FTP reply code 421. This exception may be caught either
1944 * as an IOException or independently as itself.
1945 * @exception IOException If an I/O error occurs while either sending a
1946 * command to the server or receiving a reply from the server.
1947 ***/
1948 public boolean removeDirectory(String pathname) throws IOException
1949 {
1950 return FTPReply.isPositiveCompletion(rmd(pathname));
1951 }
1952
1953
1954 /***
1955 * Creates a new subdirectory on the FTP server in the current directory
1956 * (if a relative pathname is given) or where specified (if an absolute
1957 * pathname is given).
1958 * <p>
1959 * @param pathname The pathname of the directory to create.
1960 * @return True if successfully completed, false if not.
1961 * @exception FTPConnectionClosedException
1962 * If the FTP server prematurely closes the connection as a result
1963 * of the client being idle or some other reason causing the server
1964 * to send FTP reply code 421. This exception may be caught either
1965 * as an IOException or independently as itself.
1966 * @exception IOException If an I/O error occurs while either sending a
1967 * command to the server or receiving a reply from the server.
1968 ***/
1969 public boolean makeDirectory(String pathname) throws IOException
1970 {
1971 return FTPReply.isPositiveCompletion(mkd(pathname));
1972 }
1973
1974
1975 /***
1976 * Returns the pathname of the current working directory.
1977 * <p>
1978 * @return The pathname of the current working directory. If it cannot
1979 * be obtained, returns null.
1980 * @exception FTPConnectionClosedException
1981 * If the FTP server prematurely closes the connection as a result
1982 * of the client being idle or some other reason causing the server
1983 * to send FTP reply code 421. This exception may be caught either
1984 * as an IOException or independently as itself.
1985 * @exception IOException If an I/O error occurs while either sending a
1986 * command to the server or receiving a reply from the server.
1987 ***/
1988 public String printWorkingDirectory() throws IOException
1989 {
1990 if (pwd() != FTPReply.PATHNAME_CREATED)
1991 return null;
1992
1993 return __parsePathname(_replyLines.get( _replyLines.size() - 1));
1994 }
1995
1996
1997 /**
1998 * Send a site specific command.
1999 * @param arguments The site specific command and arguments.
2000 * @return True if successfully completed, false if not.
2001 * @exception FTPConnectionClosedException
2002 * If the FTP server prematurely closes the connection as a result
2003 * of the client being idle or some other reason causing the server
2004 * to send FTP reply code 421. This exception may be caught either
2005 * as an IOException or independently as itself.
2006 * @exception IOException If an I/O error occurs while either sending a
2007 * command to the server or receiving a reply from the server.
2008 */
2009 public boolean sendSiteCommand(String arguments) throws IOException
2010 {
2011 return FTPReply.isPositiveCompletion(site(arguments));
2012 }
2013
2014
2015 /***
2016 * Fetches the system type name from the server and returns the string.
2017 * This value is cached for the duration of the connection after the
2018 * first call to this method. In other words, only the first time
2019 * that you invoke this method will it issue a SYST command to the
2020 * FTP server. FTPClient will remember the value and return the
2021 * cached value until a call to disconnect.
2022 * <p>
2023 * @return The system type name obtained from the server. null if the
2024 * information could not be obtained.
2025 * @exception FTPConnectionClosedException
2026 * If the FTP server prematurely closes the connection as a result
2027 * of the client being idle or some other reason causing the server
2028 * to send FTP reply code 421. This exception may be caught either
2029 * as an IOException or independently as itself.
2030 * @exception IOException If an I/O error occurs while either sending a
2031 * command to the server or receiving a reply from the server.
2032 * @deprecated Use {@link #getSystemType()} - which does not return null.
2033 * Will be deleted in version 3.0
2034 ***/
2035 @Deprecated
2036 public String getSystemName() throws IOException
2037 {
2038 //if (syst() == FTPReply.NAME_SYSTEM_TYPE)
2039 // Technically, we should expect a NAME_SYSTEM_TYPE response, but
2040 // in practice FTP servers deviate, so we soften the condition to
2041 // a positive completion.
2042 if (__systemName == null && FTPReply.isPositiveCompletion(syst()))
2043 __systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
2044
2045 return __systemName;
2046 }
2047
2048
2049 /***
2050 * Fetches the system type from the server and returns the string.
2051 * This value is cached for the duration of the connection after the
2052 * first call to this method. In other words, only the first time
2053 * that you invoke this method will it issue a SYST command to the
2054 * FTP server. FTPClient will remember the value and return the
2055 * cached value until a call to disconnect.
2056 * <p>
2057 * @return The system type obtained from the server. Never null.
2058 * @exception FTPConnectionClosedException
2059 * If the FTP server prematurely closes the connection as a result
2060 * of the client being idle or some other reason causing the server
2061 * to send FTP reply code 421. This exception may be caught either
2062 * as an IOException or independently as itself.
2063 * @exception IOException If an I/O error occurs while either sending a
2064 * command to the server or receiving a reply from the server.
2065 * @since 2.2
2066 ***/
2067 public String getSystemType() throws IOException
2068 {
2069 //if (syst() == FTPReply.NAME_SYSTEM_TYPE)
2070 // Technically, we should expect a NAME_SYSTEM_TYPE response, but
2071 // in practice FTP servers deviate, so we soften the condition to
2072 // a positive completion.
2073 if (__systemName == null){
2074 if (FTPReply.isPositiveCompletion(syst())) {
2075 // Assume that response is not empty here (cannot be null)
2076 __systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
2077 } else {
2078 throw new IOException("Unable to determine system type - response: " + getReplyString());
2079 }
2080 }
2081 return __systemName;
2082 }
2083
2084
2085 /***
2086 * Fetches the system help information from the server and returns the
2087 * full string.
2088 * <p>
2089 * @return The system help string obtained from the server. null if the
2090 * information could not be obtained.
2091 * @exception FTPConnectionClosedException
2092 * If the FTP server prematurely closes the connection as a result
2093 * of the client being idle or some other reason causing the server
2094 * to send FTP reply code 421. This exception may be caught either
2095 * as an IOException or independently as itself.
2096 * @exception IOException If an I/O error occurs while either sending a
2097 * command to the server or receiving a reply from the server.
2098 ***/
2099 public String listHelp() throws IOException
2100 {
2101 if (FTPReply.isPositiveCompletion(help()))
2102 return getReplyString();
2103 return null;
2104 }
2105
2106
2107 /**
2108 * Fetches the help information for a given command from the server and
2109 * returns the full string.
2110 * @param command The command on which to ask for help.
2111 * @return The command help string obtained from the server. null if the
2112 * information could not be obtained.
2113 * @exception FTPConnectionClosedException
2114 * If the FTP server prematurely closes the connection as a result
2115 * of the client being idle or some other reason causing the server
2116 * to send FTP reply code 421. This exception may be caught either
2117 * as an IOException or independently as itself.
2118 * @exception IOException If an I/O error occurs while either sending a
2119 * command to the server or receiving a reply from the server.
2120 */
2121 public String listHelp(String command) throws IOException
2122 {
2123 if (FTPReply.isPositiveCompletion(help(command)))
2124 return getReplyString();
2125 return null;
2126 }
2127
2128
2129 /***
2130 * Sends a NOOP command to the FTP server. This is useful for preventing
2131 * server timeouts.
2132 * <p>
2133 * @return True if successfully completed, false if not.
2134 * @exception FTPConnectionClosedException
2135 * If the FTP server prematurely closes the connection as a result
2136 * of the client being idle or some other reason causing the server
2137 * to send FTP reply code 421. This exception may be caught either
2138 * as an IOException or independently as itself.
2139 * @exception IOException If an I/O error occurs while either sending a
2140 * command to the server or receiving a reply from the server.
2141 ***/
2142 public boolean sendNoOp() throws IOException
2143 {
2144 return FTPReply.isPositiveCompletion(noop());
2145 }
2146
2147
2148 /***
2149 * Obtain a list of filenames in a directory (or just the name of a given
2150 * file, which is not particularly useful). This information is obtained
2151 * through the NLST command. If the given pathname is a directory and
2152 * contains no files, a zero length array is returned only
2153 * if the FTP server returned a positive completion code, otherwise
2154 * null is returned (the FTP server returned a 550 error No files found.).
2155 * If the directory is not empty, an array of filenames in the directory is
2156 * returned. If the pathname corresponds
2157 * to a file, only that file will be listed. The server may or may not
2158 * expand glob expressions.
2159 * <p>
2160 * @param pathname The file or directory to list.
2161 * @return The list of filenames contained in the given path. null if
2162 * the list could not be obtained. If there are no filenames in
2163 * the directory, a zero-length array is returned.
2164 * @exception FTPConnectionClosedException
2165 * If the FTP server prematurely closes the connection as a result
2166 * of the client being idle or some other reason causing the server
2167 * to send FTP reply code 421. This exception may be caught either
2168 * as an IOException or independently as itself.
2169 * @exception IOException If an I/O error occurs while either sending a
2170 * command to the server or receiving a reply from the server.
2171 ***/
2172 public String[] listNames(String pathname) throws IOException
2173 {
2174 String line;
2175 Socket socket;
2176 BufferedReader reader;
2177 ArrayList<String> results;
2178
2179 if ((socket = _openDataConnection_(FTPCommand.NLST, pathname)) == null)
2180 return null;
2181
2182 reader =
2183 new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
2184
2185 results = new ArrayList<String>();
2186 while ((line = reader.readLine()) != null)
2187 results.add(line);
2188
2189 reader.close();
2190 socket.close();
2191
2192 if (completePendingCommand())
2193 {
2194 String[] names = new String[ results.size() ];
2195 return results.toArray(names);
2196 }
2197
2198 return null;
2199 }
2200
2201
2202 /***
2203 * Obtain a list of filenames in the current working directory
2204 * This information is obtained through the NLST command. If the current
2205 * directory contains no files, a zero length array is returned only
2206 * if the FTP server returned a positive completion code, otherwise,
2207 * null is returned (the FTP server returned a 550 error No files found.).
2208 * If the directory is not empty, an array of filenames in the directory is
2209 * returned.
2210 * <p>
2211 * @return The list of filenames contained in the current working
2212 * directory. null if the list could not be obtained.
2213 * If there are no filenames in the directory, a zero-length array
2214 * is returned.
2215 * @exception FTPConnectionClosedException
2216 * If the FTP server prematurely closes the connection as a result
2217 * of the client being idle or some other reason causing the server
2218 * to send FTP reply code 421. This exception may be caught either
2219 * as an IOException or independently as itself.
2220 * @exception IOException If an I/O error occurs while either sending a
2221 * command to the server or receiving a reply from the server.
2222 ***/
2223 public String[] listNames() throws IOException
2224 {
2225 return listNames(null);
2226 }
2227
2228
2229
2230 /**
2231 * Using the default system autodetect mechanism, obtain a
2232 * list of file information for the current working directory
2233 * or for just a single file.
2234 * <p>
2235 * This information is obtained through the LIST command. The contents of
2236 * the returned array is determined by the<code> FTPFileEntryParser </code>
2237 * used.
2238 * <p>
2239 * @param pathname The file or directory to list. Since the server may
2240 * or may not expand glob expressions, using them here
2241 * is not recommended and may well cause this method to
2242 * fail.
2243 *
2244 * @return The list of file information contained in the given path in
2245 * the format determined by the autodetection mechanism
2246 * @exception FTPConnectionClosedException
2247 * If the FTP server prematurely closes the connection
2248 * as a result of the client being idle or some other
2249 * reason causing the server to send FTP reply code 421.
2250 * This exception may be caught either as an IOException
2251 * or independently as itself.
2252 * @exception IOException
2253 * If an I/O error occurs while either sending a
2254 * command to the server or receiving a reply
2255 * from the server.
2256 * @exception ParserInitializationException
2257 * Thrown if the parserKey parameter cannot be
2258 * resolved by the selected parser factory.
2259 * In the DefaultFTPEntryParserFactory, this will
2260 * happen when parserKey is neither
2261 * the fully qualified class name of a class
2262 * implementing the interface
2263 * org.apache.commons.net.ftp.FTPFileEntryParser
2264 * nor a string containing one of the recognized keys
2265 * mapping to such a parser or if class loader
2266 * security issues prevent its being loaded.
2267 * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
2268 * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
2269 * @see org.apache.commons.net.ftp.FTPFileEntryParser
2270 */
2271 public FTPFile[] listFiles(String pathname)
2272 throws IOException
2273 {
2274 String key = null;
2275 FTPListParseEngine engine =
2276 initiateListParsing(key, pathname);
2277 return engine.getFiles();
2278
2279 }
2280 /**
2281 * Using the default system autodetect mechanism, obtain a
2282 * list of file information for the current working directory.
2283 * <p>
2284 * This information is obtained through the LIST command. The contents of
2285 * the returned array is determined by the<code> FTPFileEntryParser </code>
2286 * used.
2287 * <p>
2288 * @return The list of file information contained in the current directory
2289 * in the format determined by the autodetection mechanism.
2290 * <p><b>
2291 * NOTE:</b> This array may contain null members if any of the
2292 * individual file listings failed to parse. The caller should
2293 * check each entry for null before referencing it.
2294 * @exception FTPConnectionClosedException
2295 * If the FTP server prematurely closes the connection
2296 * as a result of the client being idle or some other
2297 * reason causing the server to send FTP reply code 421.
2298 * This exception may be caught either as an IOException
2299 * or independently as itself.
2300 * @exception IOException
2301 * If an I/O error occurs while either sending a
2302 * command to the server or receiving a reply
2303 * from the server.
2304 * @exception ParserInitializationException
2305 * Thrown if the parserKey parameter cannot be
2306 * resolved by the selected parser factory.
2307 * In the DefaultFTPEntryParserFactory, this will
2308 * happen when parserKey is neither
2309 * the fully qualified class name of a class
2310 * implementing the interface
2311 * org.apache.commons.net.ftp.FTPFileEntryParser
2312 * nor a string containing one of the recognized keys
2313 * mapping to such a parser or if class loader
2314 * security issues prevent its being loaded.
2315 * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
2316 * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
2317 * @see org.apache.commons.net.ftp.FTPFileEntryParser
2318 */
2319 public FTPFile[] listFiles()
2320 throws IOException
2321 {
2322 return listFiles((String) null);
2323 }
2324
2325 /**
2326 * Version of {@link #listFiles(String)} which allows a filter to be provided.
2327 * For example: <code>listFiles("site", FTPFileFilters.DIRECTORY);</code>
2328 * @param pathname the initial path, may be null
2329 * @param filter the filter, non-null
2330 * @return the list of FTPFile entries.
2331 * @throws IOException
2332 * @since 2.2
2333 */
2334 public FTPFile[] listFiles(String pathname, FTPFileFilter filter)
2335 throws IOException
2336 {
2337 FTPListParseEngine engine = initiateListParsing((String) null, pathname);
2338 return engine.getFiles(filter);
2339
2340 }
2341
2342 /**
2343 * Using the default autodetect mechanism, initialize an FTPListParseEngine
2344 * object containing a raw file information for the current working
2345 * directory on the server
2346 * This information is obtained through the LIST command. This object
2347 * is then capable of being iterated to return a sequence of FTPFile
2348 * objects with information filled in by the
2349 * <code> FTPFileEntryParser </code> used.
2350 * <p>
2351 * This method differs from using the listFiles() methods in that
2352 * expensive FTPFile objects are not created until needed which may be
2353 * an advantage on large lists.
2354 *
2355 * @return A FTPListParseEngine object that holds the raw information and
2356 * is capable of providing parsed FTPFile objects, one for each file
2357 * containing information contained in the given path in the format
2358 * determined by the <code> parser </code> parameter. Null will be
2359 * returned if a data connection cannot be opened. If the current working
2360 * directory contains no files, an empty array will be the return.
2361 *
2362 * @exception FTPConnectionClosedException
2363 * If the FTP server prematurely closes the connection as a result
2364 * of the client being idle or some other reason causing the server
2365 * to send FTP reply code 421. This exception may be caught either
2366 * as an IOException or independently as itself.
2367 * @exception IOException
2368 * If an I/O error occurs while either sending a
2369 * command to the server or receiving a reply from the server.
2370 * @exception ParserInitializationException
2371 * Thrown if the autodetect mechanism cannot
2372 * resolve the type of system we are connected with.
2373 * @see FTPListParseEngine
2374 */
2375 public FTPListParseEngine initiateListParsing()
2376 throws IOException
2377 {
2378 return initiateListParsing((String) null);
2379 }
2380
2381 /**
2382 * Using the default autodetect mechanism, initialize an FTPListParseEngine
2383 * object containing a raw file information for the supplied directory.
2384 * This information is obtained through the LIST command. This object
2385 * is then capable of being iterated to return a sequence of FTPFile
2386 * objects with information filled in by the
2387 * <code> FTPFileEntryParser </code> used.
2388 * <p>
2389 * The server may or may not expand glob expressions. You should avoid
2390 * using glob expressions because the return format for glob listings
2391 * differs from server to server and will likely cause this method to fail.
2392 * <p>
2393 * This method differs from using the listFiles() methods in that
2394 * expensive FTPFile objects are not created until needed which may be
2395 * an advantage on large lists.
2396 * <p>
2397 * <pre>
2398 * FTPClient f=FTPClient();
2399 * f.connect(server);
2400 * f.login(username, password);
2401 * FTPListParseEngine engine = f.initiateListParsing(directory);
2402 *
2403 * while (engine.hasNext()) {
2404 * FTPFile[] files = engine.getNext(25); // "page size" you want
2405 * //do whatever you want with these files, display them, etc.
2406 * //expensive FTPFile objects not created until needed.
2407 * }
2408 * </pre>
2409 *
2410 * @return A FTPListParseEngine object that holds the raw information and
2411 * is capable of providing parsed FTPFile objects, one for each file
2412 * containing information contained in the given path in the format
2413 * determined by the <code> parser </code> parameter. Null will be
2414 * returned if a data connection cannot be opened. If the current working
2415 * directory contains no files, an empty array will be the return.
2416 *
2417 * @exception FTPConnectionClosedException
2418 * If the FTP server prematurely closes the connection as a result
2419 * of the client being idle or some other reason causing the server
2420 * to send FTP reply code 421. This exception may be caught either
2421 * as an IOException or independently as itself.
2422 * @exception IOException
2423 * If an I/O error occurs while either sending a
2424 * command to the server or receiving a reply from the server.
2425 * @exception ParserInitializationException
2426 * Thrown if the autodetect mechanism cannot
2427 * resolve the type of system we are connected with.
2428 * @see FTPListParseEngine
2429 */
2430 public FTPListParseEngine initiateListParsing(
2431 String pathname)
2432 throws IOException
2433 {
2434 String key = null;
2435 return initiateListParsing(key, pathname);
2436 }
2437
2438 /**
2439 * Using the supplied parser key, initialize an FTPListParseEngine
2440 * object containing a raw file information for the supplied directory.
2441 * This information is obtained through the LIST command. This object
2442 * is then capable of being iterated to return a sequence of FTPFile
2443 * objects with information filled in by the
2444 * <code> FTPFileEntryParser </code> used.
2445 * <p>
2446 * The server may or may not expand glob expressions. You should avoid
2447 * using glob expressions because the return format for glob listings
2448 * differs from server to server and will likely cause this method to fail.
2449 * <p>
2450 * This method differs from using the listFiles() methods in that
2451 * expensive FTPFile objects are not created until needed which may be
2452 * an advantage on large lists.
2453 *
2454 * @param parserKey A string representing a designated code or fully-qualified
2455 * class name of an <code> FTPFileEntryParser </code> that should be
2456 * used to parse each server file listing.
2457 *
2458 * @return A FTPListParseEngine object that holds the raw information and
2459 * is capable of providing parsed FTPFile objects, one for each file
2460 * containing information contained in the given path in the format
2461 * determined by the <code> parser </code> parameter. Null will be
2462 * returned if a data connection cannot be opened. If the current working
2463 * directory contains no files, an empty array will be the return.
2464 *
2465 * @exception FTPConnectionClosedException
2466 * If the FTP server prematurely closes the connection as a result
2467 * of the client being idle or some other reason causing the server
2468 * to send FTP reply code 421. This exception may be caught either
2469 * as an IOException or independently as itself.
2470 * @exception IOException
2471 * If an I/O error occurs while either sending a
2472 * command to the server or receiving a reply from the server.
2473 * @exception ParserInitializationException
2474 * Thrown if the parserKey parameter cannot be
2475 * resolved by the selected parser factory.
2476 * In the DefaultFTPEntryParserFactory, this will
2477 * happen when parserKey is neither
2478 * the fully qualified class name of a class
2479 * implementing the interface
2480 * org.apache.commons.net.ftp.FTPFileEntryParser
2481 * nor a string containing one of the recognized keys
2482 * mapping to such a parser or if class loader
2483 * security issues prevent its being loaded.
2484 * @see FTPListParseEngine
2485 */
2486 public FTPListParseEngine initiateListParsing(
2487 String parserKey, String pathname)
2488 throws IOException
2489 {
2490 // We cache the value to avoid creation of a new object every
2491 // time a file listing is generated.
2492 if(__entryParser == null || ! __entryParserKey.equals(parserKey)) {
2493 if (null != parserKey) {
2494 // if a parser key was supplied in the parameters,
2495 // use that to create the parser
2496 __entryParser =
2497 __parserFactory.createFileEntryParser(parserKey);
2498 __entryParserKey = parserKey;
2499
2500 } else {
2501 // if no parserKey was supplied, check for a configuration
2502 // in the params, and if non-null, use that.
2503 if (null != __configuration) {
2504 __entryParser =
2505 __parserFactory.createFileEntryParser(__configuration);
2506 __entryParserKey = __configuration.getServerSystemKey();
2507 } else {
2508 // if a parserKey hasn't been supplied, and a configuration
2509 // hasn't been supplied, then autodetect by calling
2510 // the SYST command and use that to choose the parser.
2511 final String systemType = getSystemType(); // cannot be null
2512 __entryParser =
2513 __parserFactory.createFileEntryParser(systemType);
2514 __entryParserKey = systemType;
2515 }
2516 }
2517 }
2518
2519 return initiateListParsing(__entryParser, pathname);
2520
2521 }
2522
2523
2524 /**
2525 * private method through which all listFiles() and
2526 * initiateListParsing methods pass once a parser is determined.
2527 *
2528 * @exception FTPConnectionClosedException
2529 * If the FTP server prematurely closes the connection as a result
2530 * of the client being idle or some other reason causing the server
2531 * to send FTP reply code 421. This exception may be caught either
2532 * as an IOException or independently as itself.
2533 * @exception IOException
2534 * If an I/O error occurs while either sending a
2535 * command to the server or receiving a reply from the server.
2536 * @see FTPListParseEngine
2537 */
2538 private FTPListParseEngine initiateListParsing(
2539 FTPFileEntryParser parser, String pathname)
2540 throws IOException
2541 {
2542 Socket socket;
2543
2544 FTPListParseEngine engine = new FTPListParseEngine(parser);
2545 if ((socket = _openDataConnection_(FTPCommand.LIST, getListArguments(pathname))) == null)
2546 {
2547 return engine;
2548 }
2549
2550 try {
2551 engine.readServerList(socket.getInputStream(), getControlEncoding());
2552 }
2553 finally {
2554 socket.close();
2555 }
2556
2557 completePendingCommand();
2558 return engine;
2559 }
2560
2561 /**
2562 * @since 2.0
2563 */
2564 protected String getListArguments(String pathname) {
2565 if (getListHiddenFiles())
2566 {
2567 if (pathname != null)
2568 {
2569 StringBuilder sb = new StringBuilder(pathname.length() + 3);
2570 sb.append("-a ");
2571 sb.append(pathname);
2572 return sb.toString();
2573 }
2574 else
2575 {
2576 return "-a";
2577 }
2578 }
2579
2580 return pathname;
2581 }
2582
2583
2584 /***
2585 * Issue the FTP STAT command to the server.
2586 * <p>
2587 * @return The status information returned by the server.
2588 * @exception FTPConnectionClosedException
2589 * If the FTP server prematurely closes the connection as a result
2590 * of the client being idle or some other reason causing the server
2591 * to send FTP reply code 421. This exception may be caught either
2592 * as an IOException or independently as itself.
2593 * @exception IOException If an I/O error occurs while either sending a
2594 * command to the server or receiving a reply from the server.
2595 ***/
2596 public String getStatus() throws IOException
2597 {
2598 if (FTPReply.isPositiveCompletion(stat()))
2599 return getReplyString();
2600 return null;
2601 }
2602
2603
2604 /***
2605 * Issue the FTP STAT command to the server for a given pathname. This
2606 * should produce a listing of the file or directory.
2607 * <p>
2608 * @return The status information returned by the server.
2609 * @exception FTPConnectionClosedException
2610 * If the FTP server prematurely closes the connection as a result
2611 * of the client being idle or some other reason causing the server
2612 * to send FTP reply code 421. This exception may be caught either
2613 * as an IOException or independently as itself.
2614 * @exception IOException If an I/O error occurs while either sending a
2615 * command to the server or receiving a reply from the server.
2616 ***/
2617 public String getStatus(String pathname) throws IOException
2618 {
2619 if (FTPReply.isPositiveCompletion(stat(pathname)))
2620 return getReplyString();
2621 return null;
2622 }
2623
2624
2625 /**
2626 * Issue the FTP MDTM command (not supported by all servers to retrieve the last
2627 * modification time of a file. The modification string should be in the
2628 * ISO 3077 form "YYYYMMDDhhmmss(.xxx)?". The timestamp represented should also be in
2629 * GMT, but not all FTP servers honour this.
2630 *
2631 * @param pathname The file path to query.
2632 * @return A string representing the last file modification time in <code>YYYYMMDDhhmmss</code> format.
2633 * @throws IOException if an I/O error occurs.
2634 * @since 2.0
2635 */
2636 public String getModificationTime(String pathname) throws IOException {
2637 if (FTPReply.isPositiveCompletion(mdtm(pathname)))
2638 return getReplyString();
2639 return null;
2640 }
2641
2642
2643 /**
2644 * Issue the FTP MFMT command (not supported by all servers) which sets the last
2645 * modified time of a file.
2646 *
2647 * The timestamp should be in the form <code>YYYYMMDDhhmmss</code>. It should also
2648 * be in GMT, but not all servers honour this.
2649 *
2650 * An FTP server would indicate its support of this feature by including "MFMT"
2651 * in its response to the FEAT command, which may be retrieved by FTPClient.features()
2652 *
2653 * @param pathname The file path for which last modified time is to be changed.
2654 * @param timeval The timestamp to set to, in <code>YYYYMMDDhhmmss</code> format.
2655 * @return true if successfully set, false if not
2656 * @throws IOException if an I/O error occurs.
2657 * @since 2.2
2658 * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
2659 */
2660 public boolean setModificationTime(String pathname, String timeval) throws IOException {
2661 return (FTPReply.isPositiveCompletion(mfmt(pathname, timeval)));
2662 }
2663
2664
2665 /**
2666 * Set the internal buffer size.
2667 *
2668 * @param bufSize The size of the buffer
2669 */
2670 public void setBufferSize(int bufSize) {
2671 __bufferSize = bufSize;
2672 }
2673
2674 /**
2675 * Retrieve the current internal buffer size.
2676 * @return The current buffer size.
2677 */
2678 public int getBufferSize() {
2679 return __bufferSize;
2680 }
2681
2682
2683 /**
2684 * Implementation of the {@link Configurable Configurable} interface.
2685 * In the case of this class, configuring merely makes the config object available for the
2686 * factory methods that construct parsers.
2687 * @param config {@link FTPClientConfig FTPClientConfig} object used to
2688 * provide non-standard configurations to the parser.
2689 * @since 1.4
2690 */
2691 public void configure(FTPClientConfig config) {
2692 this.__configuration = config;
2693 }
2694
2695 /**
2696 * You can set this to true if you would like to get hidden files when {@link #listFiles} too.
2697 * A <code>LIST -a</code> will be issued to the ftp server.
2698 * It depends on your ftp server if you need to call this method, also dont expect to get rid
2699 * of hidden files if you call this method with "false".
2700 *
2701 * @param listHiddenFiles true if hidden files should be listed
2702 * @since 2.0
2703 */
2704 public void setListHiddenFiles(boolean listHiddenFiles) {
2705 this.__listHiddenFiles = listHiddenFiles;
2706 }
2707
2708 /**
2709 * @see #setListHiddenFiles(boolean)
2710 * @return the current state
2711 * @since 2.0
2712 */
2713 public boolean getListHiddenFiles() {
2714 return this.__listHiddenFiles;
2715 }
2716
2717 /**
2718 * Whether should attempt to use EPSV with IPv4.
2719 * Default (if not set) is <code>false</code>
2720 * @return true if should attempt EPS
2721 * @since 2.2
2722 */
2723 public boolean isUseEPSVwithIPv4() {
2724 return __useEPSVwithIPv4;
2725 }
2726
2727
2728 /**
2729 * Set whether to use EPSV with IPv4.
2730 * Might be worth enabling in some circumstances.
2731 *
2732 * For example, when using IPv4 with NAT it
2733 * may work with some rare configurations.
2734 * E.g. if FTP server has a static PASV address (external network)
2735 * and the client is coming from another internal network.
2736 * In that case the data connection after PASV command would fail,
2737 * while EPSV would make the client succeed by taking just the port.
2738 *
2739 * @param selected value to set.
2740 * @since 2.2
2741 */
2742 public void setUseEPSVwithIPv4(boolean selected) {
2743 this.__useEPSVwithIPv4 = selected;
2744 }
2745
2746 }
2747
2748 /* Emacs configuration
2749 * Local variables: **
2750 * mode: java **
2751 * c-basic-offset: 4 **
2752 * indent-tabs-mode: nil **
2753 * End: **
2754 */