+ * @param host The inet address of the host to use or null to + * disable overriding. + ***/ + public void overrideHostForPassiveConnections(InetAddress host) + { + __overrideHostForPassiveConnections = host; + } + /*** * Login to the FTP server using the provided username and password. *
@@ -647,7 +664,16 @@ public boolean login(String username, String password) throws IOException
if (!FTPReply.isPositiveIntermediate(_replyCode))
return false;
- return FTPReply.isPositiveCompletion(pass(password));
+ int replyCode = pass(password);
+ boolean replyOk = FTPReply.isPositiveCompletion(replyCode);
+
+ // Work around stupid servers that send a 451 here
+ if (!replyOk && (replyCode == FTPReply.ACTION_ABORTED)) {
+ replyCode = getReply();
+ replyOk = FTPReply.isPositiveCompletion(replyCode);
+ }
+
+ return replyOk;
}
@@ -2414,7 +2440,7 @@ public void configure(FTPClientConfig config) {
public void setListHiddenFiles(boolean listHiddenFiles) {
this.__listHiddenFiles = listHiddenFiles;
}
-
+
/**
* @see #setListHiddenFiles(boolean)
* @return the current state
@@ -2422,6 +2448,27 @@ public void setListHiddenFiles(boolean listHiddenFiles) {
public boolean getListHiddenFiles() {
return this.__listHiddenFiles;
}
+
+ /**
+ *
+ * @return
+ */
+ public boolean isDateRollbackPermitted() {
+ return __configuration.isDateRollbackPermitted();
+ }
+
+ /**
+ * Set a boolean flag that specifies whether short date timestamps on the server
+ * (i.e. those with no year component) can be "rolled back" by a year if the server
+ * timestamp is greater than the local timestamp. This is true by default.
+ *
+ * @param dateRollbackPermitted false to explicitly prevent date rollback
+ */
+ public void setDateRollbackPermitted(boolean dateRollbackPermitted) {
+ __configuration.setDateRollbackPermitted(dateRollbackPermitted);
+ }
+
+
}
/* Emacs configuration
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java b/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
index 89754f012..360642ae8 100644
--- a/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
@@ -192,6 +192,8 @@ public class FTPClientConfig
private String shortMonthNames = null;
private String serverTimeZoneId = null;
+ private boolean dateRollbackPermitted = true;
+
/**
* The main constructor for an FTPClientConfig object
@@ -554,5 +556,22 @@ public static Collection getSupportedLanguageCodes() {
return LANGUAGE_CODE_MAP.keySet();
}
+
+ /**
+ * getter for the {@link #dateRollbackPermitted} property
+ * @return
+ */
+ public boolean isDateRollbackPermitted() {
+ return dateRollbackPermitted;
+ }
+
+ /**
+ * @see FTPClient#setDateRollbackPermitted(boolean)
+ *
+ * @param dateRollbackPermitted true/false
+ */
+ public void setDateRollbackPermitted(boolean dateRollbackPermitted) {
+ this.dateRollbackPermitted = dateRollbackPermitted;
+ }
}
diff --git a/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
index 497a1516c..53eca9108 100644
--- a/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
@@ -26,6 +26,7 @@
import java.util.TimeZone;
import org.apache.commons.net.ftp.Configurable;
+import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
/**
@@ -44,6 +45,7 @@ public class FTPTimestampParserImpl implements
private SimpleDateFormat defaultDateFormat;
private SimpleDateFormat recentDateFormat;
private boolean lenientFutureDates = false;
+ private boolean dateRollbackPermitted = true;
/**
@@ -91,7 +93,7 @@ public Calendar parseTimestamp(String timestampStr) throws ParseException {
// slightly in the future to roll back a full year. (Bug 35181)
now.add(Calendar.DATE, 1);
}
- if (working.after(now)) {
+ if (working.after(now) && isDateRollbackPermitted()) {
working.add(Calendar.YEAR, -1);
}
} else {
@@ -244,6 +246,8 @@ public void configure(FTPClientConfig config) {
setServerTimeZone(config.getServerTimeZoneId());
this.lenientFutureDates = config.isLenientFutureDates();
+
+ this.dateRollbackPermitted = config.isDateRollbackPermitted();
}
/**
* @return Returns the lenientFutureDates.
@@ -257,4 +261,19 @@ boolean isLenientFutureDates() {
void setLenientFutureDates(boolean lenientFutureDates) {
this.lenientFutureDates = lenientFutureDates;
}
+
+ /**
+ * @returns the {@link #dateRollbackPermitted} property
+ */
+ boolean isDateRollbackPermitted() {
+ return dateRollbackPermitted;
+ }
+
+ /**
+ * @see FTPClient#setDateRollbackPermitted(boolean)
+ * @param dateRollbackPermitted
+ */
+ void setDateRollbackPermitted(boolean dateRollbackPermitted) {
+ this.dateRollbackPermitted = dateRollbackPermitted;
+ }
}
diff --git a/src/main/java/org/apache/commons/net/io/CopyStreamException.java b/src/main/java/org/apache/commons/net/io/CopyStreamException.java
index 49ef6c32f..974365bbf 100644
--- a/src/main/java/org/apache/commons/net/io/CopyStreamException.java
+++ b/src/main/java/org/apache/commons/net/io/CopyStreamException.java
@@ -68,4 +68,12 @@ public IOException getIOException()
{
return ioException;
}
+
+ /**
+ * Returns the original {@link IOException}
+ */
+ @Override
+ public Throwable getCause() {
+ return getIOException();
+ }
}
diff --git a/src/main/java/org/apache/commons/net/nntp/NNTPClient.java b/src/main/java/org/apache/commons/net/nntp/NNTPClient.java
index 96ec72539..79848250f 100644
--- a/src/main/java/org/apache/commons/net/nntp/NNTPClient.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTPClient.java
@@ -54,7 +54,7 @@
* When that occurs, the NNTP class method encountering that reply will throw
* an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
* .
- * NNTPConectionClosedException
+ * NNTPConnectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
@@ -176,7 +176,7 @@ private NewsgroupInfo __parseNewsgroupListEntry(String entry)
{
NewsgroupInfo result;
StringTokenizer tokenizer;
- int lastNum, firstNum;
+ long lastNum, firstNum;
String last, first, permission;
result = new NewsgroupInfo();
@@ -192,8 +192,8 @@ private NewsgroupInfo __parseNewsgroupListEntry(String entry)
try
{
- lastNum = Integer.parseInt(last);
- firstNum = Integer.parseInt(first);
+ lastNum = Long.valueOf(last);
+ firstNum = Long.valueOf(first);
result._setFirstArticle(firstNum);
result._setLastArticle(lastNum);
@@ -1212,8 +1212,8 @@ public Reader retrieveArticleInfo(int articleNumber) throws IOException
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException
*/
- public Reader retrieveArticleInfo(int lowArticleNumber,
- int highArticleNumber)
+ public Reader retrieveArticleInfo(long lowArticleNumber,
+ long highArticleNumber)
throws IOException
{
return
diff --git a/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java b/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
index dea53287e..538e11f61 100644
--- a/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
+++ b/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
@@ -32,124 +32,118 @@
* @see NNTPClient
***/
-public final class NewsgroupInfo
-{
- /***
- * A constant indicating that the posting permission of a newsgroup is
- * unknown. For example, the NNTP GROUP command does not return posting
- * information, so NewsgroupInfo instances obtained from that command
- * willhave an UNKNOWN_POSTING_PERMISSION.
- ***/
- public static final int UNKNOWN_POSTING_PERMISSION = 0;
-
- /*** A constant indicating that a newsgroup is moderated. ***/
- public static final int MODERATED_POSTING_PERMISSION = 1;
-
- /*** A constant indicating that a newsgroup is public and unmoderated. ***/
- public static final int PERMITTED_POSTING_PERMISSION = 2;
-
- /***
- * A constant indicating that a newsgroup is closed for general posting.
- ***/
- public static final int PROHIBITED_POSTING_PERMISSION = 3;
-
- private String __newsgroup;
- private int __estimatedArticleCount;
- private int __firstArticle, __lastArticle;
- private int __postingPermission;
-
- void _setNewsgroup(String newsgroup)
- {
- __newsgroup = newsgroup;
- }
-
- void _setArticleCount(int count)
- {
- __estimatedArticleCount = count;
- }
-
- void _setFirstArticle(int first)
- {
- __firstArticle = first;
- }
-
- void _setLastArticle(int last)
- {
- __lastArticle = last;
- }
-
- void _setPostingPermission(int permission)
- {
- __postingPermission = permission;
- }
-
- /***
- * Get the newsgroup name.
- *
- * @return The name of the newsgroup. - ***/ - public String getNewsgroup() - { - return __newsgroup; - } - - /*** - * Get the estimated number of articles in the newsgroup. The - * accuracy of this value will depend on the server implementation. - *
- * @return The estimated number of articles in the newsgroup. - ***/ - public int getArticleCount() - { - return __estimatedArticleCount; - } - - /*** - * Get the number of the first article in the newsgroup. - *
- * @return The number of the first article in the newsgroup. - ***/ - public int getFirstArticle() - { - return __firstArticle; - } - - /*** - * Get the number of the last article in the newsgroup. - *
- * @return The number of the last article in the newsgroup.
- ***/
- public int getLastArticle()
- {
- return __lastArticle;
- }
-
- /***
- * Get the posting permission of the newsgroup. This will be one of
- * the POSTING_PERMISSION
constants.
- *
- * @return The posting permission status of the newsgroup. - ***/ - public int getPostingPermission() - { - return __postingPermission; - } - - /* - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(__newsgroup); - buffer.append(' '); - buffer.append(__lastArticle); - buffer.append(' '); - buffer.append(__firstArticle); - buffer.append(' '); - switch(__postingPermission) { - case 1: buffer.append('m'); break; - case 2: buffer.append('y'); break; - case 3: buffer.append('n'); break; - } - return buffer.toString(); -} - */ +public final class NewsgroupInfo { + /*** + * A constant indicating that the posting permission of a newsgroup is + * unknown. For example, the NNTP GROUP command does not return posting + * information, so NewsgroupInfo instances obtained from that command + * willhave an UNKNOWN_POSTING_PERMISSION. + ***/ + public static final int UNKNOWN_POSTING_PERMISSION = 0; + + /*** A constant indicating that a newsgroup is moderated. ***/ + public static final int MODERATED_POSTING_PERMISSION = 1; + + /*** A constant indicating that a newsgroup is public and unmoderated. ***/ + public static final int PERMITTED_POSTING_PERMISSION = 2; + + /*** + * A constant indicating that a newsgroup is closed for general posting. + ***/ + public static final int PROHIBITED_POSTING_PERMISSION = 3; + + private String __newsgroup; + private long __estimatedArticleCount; + private long __firstArticle, __lastArticle; + private int __postingPermission; + + void _setNewsgroup(String newsgroup) { + __newsgroup = newsgroup; + } + + void _setArticleCount(long count) { + __estimatedArticleCount = count; + } + + void _setFirstArticle(long first) { + __firstArticle = first; + } + + void _setLastArticle(long last) { + __lastArticle = last; + } + + void _setPostingPermission(int permission) { + __postingPermission = permission; + } + + /*** + * Get the newsgroup name. + *
+ * @return The name of the newsgroup. + ***/ + public String getNewsgroup() { + return __newsgroup; + } + + /*** + * Get the estimated number of articles in the newsgroup. The + * accuracy of this value will depend on the server implementation. + *
+ * @return The estimated number of articles in the newsgroup. + ***/ + public long getArticleCount() { + return __estimatedArticleCount; + } + + /*** + * Get the number of the first article in the newsgroup. + *
+ * @return The number of the first article in the newsgroup. + ***/ + public long getFirstArticle() { + return __firstArticle; + } + + /*** + * Get the number of the last article in the newsgroup. + *
+ * @return The number of the last article in the newsgroup.
+ ***/
+ public long getLastArticle() {
+ return __lastArticle;
+ }
+
+ /***
+ * Get the posting permission of the newsgroup. This will be one of
+ * the POSTING_PERMISSION
constants.
+ *
+ * @return The posting permission status of the newsgroup. + ***/ + public int getPostingPermission() { + return __postingPermission; + } + + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(__newsgroup); + buffer.append(' '); + buffer.append(__lastArticle); + buffer.append(' '); + buffer.append(__firstArticle); + buffer.append(' '); + switch (__postingPermission) { + case 1: + buffer.append('m'); + break; + case 2: + buffer.append('y'); + break; + case 3: + buffer.append('n'); + break; + } + return buffer.toString(); + } + } diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index c23dc3396..52f86ecbe 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -23,6 +23,23 @@ limitations under the License.