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