增加ftp服务器标志

pull/617/head
laoyuyu 7 years ago
parent 685f6b5525
commit bfc2cff5b0
  1. 274
      Aria/src/main/java/com/arialyy/aria/core/common/FtpOption.java
  2. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  4. 1
      AriaFtpPlug/.gitignore
  5. 11
      AriaFtpPlug/bintray-release.gradle
  6. 14
      AriaFtpPlug/build.gradle
  7. 25
      AriaFtpPlug/proguard-rules.pro
  8. 287
      AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketClient.java
  9. 67
      AriaFtpPlug/src/main/java/aria/apache/commons/net/DatagramSocketFactory.java
  10. 72
      AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultDatagramSocketFactory.java
  11. 204
      AriaFtpPlug/src/main/java/aria/apache/commons/net/DefaultSocketFactory.java
  12. 52
      AriaFtpPlug/src/main/java/aria/apache/commons/net/MalformedServerReplyException.java
  13. 190
      AriaFtpPlug/src/main/java/aria/apache/commons/net/PrintCommandListener.java
  14. 139
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandEvent.java
  15. 58
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandListener.java
  16. 123
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ProtocolCommandSupport.java
  17. 869
      AriaFtpPlug/src/main/java/aria/apache/commons/net/SocketClient.java
  18. 34
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/Configurable.java
  19. 1777
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTP.java
  20. 3787
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClient.java
  21. 713
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPClientConfig.java
  22. 75
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCmd.java
  23. 170
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPCommand.java
  24. 52
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPConnectionClosedException.java
  25. 493
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFile.java
  26. 129
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParser.java
  27. 72
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileEntryParserImpl.java
  28. 34
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilter.java
  29. 54
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPFileFilters.java
  30. 194
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPHTTPClient.java
  31. 311
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPListParseEngine.java
  32. 193
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPReply.java
  33. 931
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSClient.java
  34. 52
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSCommand.java
  35. 72
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSServerSocketFactory.java
  36. 116
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSSocketFactory.java
  37. 54
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/FTPSTrustManager.java
  38. 33
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/OnFtpInputStreamListener.java
  39. 21
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/package-info.java
  40. 59
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
  41. 123
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
  42. 254
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
  43. 159
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
  44. 63
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
  45. 53
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParser.java
  46. 403
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
  47. 260
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MLSxEntryParser.java
  48. 537
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
  49. 245
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/MacOsPeterFTPEntryParser.java
  50. 142
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NTFTPEntryParser.java
  51. 175
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
  52. 127
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
  53. 399
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
  54. 60
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/ParserInitializationException.java
  55. 199
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
  56. 335
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
  57. 251
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
  58. 153
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
  59. 21
      AriaFtpPlug/src/main/java/aria/apache/commons/net/ftp/parser/package-info.java
  60. 75
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CRLFLineReader.java
  61. 111
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamAdapter.java
  62. 113
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamEvent.java
  63. 69
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamException.java
  64. 68
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/CopyStreamListener.java
  65. 238
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageReader.java
  66. 189
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/DotTerminatedMessageWriter.java
  67. 196
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIInputStream.java
  68. 150
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/FromNetASCIIOutputStream.java
  69. 64
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketInputStream.java
  70. 80
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/SocketOutputStream.java
  71. 165
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIInputStream.java
  72. 105
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/ToNetASCIIOutputStream.java
  73. 351
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/Util.java
  74. 21
      AriaFtpPlug/src/main/java/aria/apache/commons/net/io/package-info.java
  75. 1056
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Base64.java
  76. 53
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/Charsets.java
  77. 236
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/KeyManagerUtils.java
  78. 59
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/ListenerList.java
  79. 77
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLContextUtils.java
  80. 68
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SSLSocketUtils.java
  81. 395
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/SubnetUtils.java
  82. 113
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/TrustManagerUtils.java
  83. 21
      AriaFtpPlug/src/main/java/aria/apache/commons/net/util/package-info.java
  84. 1
      DEV_LOG.md
  85. 2
      FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java
  86. 27
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpTaskOption.java
  87. 2
      HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java
  88. 15
      PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
  89. 31
      PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
  90. 5
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java
  91. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/DBConfig.java
  92. 79
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  93. 66
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlUtil.java
  94. 5
      app/src/main/java/com/arialyy/simple/core/download/FtpDownloadActivity.java
  95. 3
      app/src/main/java/com/arialyy/simple/core/download/FtpDownloadModule.java
  96. 4
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  97. 2
      build.gradle
  98. 2
      settings.gradle

@ -21,6 +21,12 @@ import com.arialyy.aria.core.ProtocolType;
import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import java.text.DateFormatSymbols;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
/**
* Created by laoyuyu on 2018/3/9.
@ -37,6 +43,15 @@ public class FtpOption extends BaseOption {
private int minPort, maxPort;
private String activeExternalIPAddress;
//---------------- ftp client 配置信息 start
private String defaultDateFormatStr = null;
private String recentDateFormatStr = null;
private String serverLanguageCode = null;
private String shortMonthNames = null;
private String serverTimeZoneId = null;
private String systemKey = FTPServerIdentifier.SYST_UNIX;
//---------------- ftp client 配置信息 end
public FtpOption() {
super();
}
@ -203,6 +218,78 @@ public class FtpOption extends BaseOption {
return this;
}
/**
* 设置ftp服务器所在的操作系统的标志如果出现文件获取失败请设置该标志为
* 默认使用{@link FTPServerIdentifier#SYST_UNIX}
*
* @param identifier {@link FTPServerIdentifier}
*/
public FtpOption setServerIdentifier(String identifier) {
this.systemKey = identifier;
return this;
}
/**
* 解析ftp信息时默认的文件日期格式setDefaultDateFormatStr("d MMM yyyy")
*
* @param defaultDateFormatStr 日期格式
*/
public FtpOption setDefaultDateFormatStr(String defaultDateFormatStr) {
this.defaultDateFormatStr = defaultDateFormatStr;
return this;
}
/**
* 解析ftp信息时默认的文件修改日期格式setRecentDateFormatStr("d MMM HH:mm")
*
* @param recentDateFormatStr 日期格式
*/
public FtpOption setRecentDateFormatStr(String recentDateFormatStr) {
this.recentDateFormatStr = recentDateFormatStr;
return this;
}
/**
* 设置服务器使用的时区java.util.TimeZoneAmerica/Chicago or Asia/Rangoon.
*
* @param serverTimeZoneId 时区
*/
public void setServerTimeZoneId(String serverTimeZoneId) {
this.serverTimeZoneId = serverTimeZoneId;
}
/**
* <p>
* setter for the shortMonthNames property.
* This property allows the user to specify a set of month names
* used by the server that is different from those that may be
* specified using the {@link #setServerLanguageCode(String) serverLanguageCode}
* property.
* </p><p>
* This should be a string containing twelve strings each composed of
* three characters, delimited by pipe (|) characters. Currently,
* only 8-bit ASCII characters are known to be supported. For example,
* a set of month names used by a hypothetical Icelandic FTP server might
* conceivably be specified as
* <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
* </p>
*
* @param shortMonthNames The value to set to the shortMonthNames property.
*/
public void setShortMonthNames(String shortMonthNames) {
this.shortMonthNames = shortMonthNames;
}
/**
* 设置服务器语言代码
*
* @param serverLanguageCode {@link #LANGUAGE_CODE_MAP}
*/
public FtpOption setServerLanguageCode(String serverLanguageCode) {
this.serverLanguageCode = serverLanguageCode;
return this;
}
public void setUrlEntity(FtpUrlEntity urlEntity) {
this.urlEntity = urlEntity;
urlEntity.needLogin = isNeedLogin;
@ -218,4 +305,191 @@ public class FtpOption extends BaseOption {
urlEntity.isImplicit = isImplicit;
}
}
/**
* ftp 服务器所在的操作系统标志
*/
public interface FTPServerIdentifier {
/**
* Identifier by which a unix-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_UNIX = "UNIX";
/**
* Identifier for alternate UNIX parser; same as {@link #SYST_UNIX} but leading spaces are
* trimmed from file names. This is to maintain backwards compatibility with
* the original behaviour of the parser which ignored multiple spaces between the date
* and the start of the file name.
*
* @since 3.4
*/
String SYST_UNIX_TRIM_LEADING = "UNIX_LTRIM";
/**
* Identifier by which a vms-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_VMS = "VMS";
/**
* Identifier by which a WindowsNT-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_NT = "WINDOWS";
/**
* Identifier by which an OS/2-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_OS2 = "OS/2";
/**
* Identifier by which an OS/400-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_OS400 = "OS/400";
/**
* Identifier by which an AS/400-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_AS400 = "AS/400";
/**
* Identifier by which an MVS-based ftp server is known throughout
* the commons-net ftp system.
*/
String SYST_MVS = "MVS";
/**
* Some servers return an "UNKNOWN Type: L8" message
* in response to the SYST command. We set these to be a Unix-type system.
* This may happen if the ftpd in question was compiled without system
* information.
*
* NET-230 - Updated to be UPPERCASE so that the check done in
* createFileEntryParser will succeed.
*
* @since 1.5
*/
String SYST_L8 = "TYPE: L8";
/**
* Identifier by which an Netware-based ftp server is known throughout
* the commons-net ftp system.
*
* @since 1.5
*/
String SYST_NETWARE = "NETWARE";
/**
* Identifier by which a Mac pre OS-X -based ftp server is known throughout
* the commons-net ftp system.
*
* @since 3.1
*/
// Full string is "MACOS Peter's Server"; the substring below should be enough
String SYST_MACOS_PETER = "MACOS PETER"; // NET-436
}
/**
* 支持的语言代码
*/
private static final Map<String, Object> LANGUAGE_CODE_MAP = new TreeMap<>();
static {
// if there are other commonly used month name encodings which
// correspond to particular locales, please add them here.
// many locales code short names for months as all three letters
// these we handle simply.
LANGUAGE_CODE_MAP.put("en", Locale.ENGLISH);
LANGUAGE_CODE_MAP.put("de", Locale.GERMAN);
LANGUAGE_CODE_MAP.put("it", Locale.ITALIAN);
LANGUAGE_CODE_MAP.put("es", new Locale("es", "", "")); // spanish
LANGUAGE_CODE_MAP.put("pt", new Locale("pt", "", "")); // portuguese
LANGUAGE_CODE_MAP.put("da", new Locale("da", "", "")); // danish
LANGUAGE_CODE_MAP.put("sv", new Locale("sv", "", "")); // swedish
LANGUAGE_CODE_MAP.put("no", new Locale("no", "", "")); // norwegian
LANGUAGE_CODE_MAP.put("nl", new Locale("nl", "", "")); // dutch
LANGUAGE_CODE_MAP.put("ro", new Locale("ro", "", "")); // romanian
LANGUAGE_CODE_MAP.put("sq", new Locale("sq", "", "")); // albanian
LANGUAGE_CODE_MAP.put("sh", new Locale("sh", "", "")); // serbo-croatian
LANGUAGE_CODE_MAP.put("sk", new Locale("sk", "", "")); // slovak
LANGUAGE_CODE_MAP.put("sl", new Locale("sl", "", "")); // slovenian
// some don't
LANGUAGE_CODE_MAP.put("fr",
"jan|f\u00e9v|mar|avr|mai|jun|jui|ao\u00fb|sep|oct|nov|d\u00e9c"); //french
}
/**
* Looks up the supplied language code in the internally maintained table of
* language codes. Returns a DateFormatSymbols object configured with
* short month names corresponding to the code. If there is no corresponding
* entry in the table, the object returned will be that for
* <code>Locale.US</code>
*
* @param languageCode See {@link #setServerLanguageCode(String) serverLanguageCode}
* @return a DateFormatSymbols object configured with short month names
* corresponding to the supplied code, or with month names for
* <code>Locale.US</code> if there is no corresponding entry in the internal
* table.
*/
public static DateFormatSymbols lookupDateFormatSymbols(String languageCode) {
Object lang = LANGUAGE_CODE_MAP.get(languageCode);
if (lang != null) {
if (lang instanceof Locale) {
return new DateFormatSymbols((Locale) lang);
} else if (lang instanceof String) {
return getDateFormatSymbols((String) lang);
}
}
return new DateFormatSymbols(Locale.US);
}
/**
* Returns a DateFormatSymbols object configured with short month names
* as in the supplied string
*
* @param shortmonths This should be as described in
* {@link #setShortMonthNames(String) shortMonthNames}
* @return a DateFormatSymbols object configured with short month names
* as in the supplied string
*/
public static DateFormatSymbols getDateFormatSymbols(String shortmonths) {
String[] months = splitShortMonthString(shortmonths);
DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
dfs.setShortMonths(months);
return dfs;
}
private static String[] splitShortMonthString(String shortmonths) {
StringTokenizer st = new StringTokenizer(shortmonths, "|");
int monthcnt = st.countTokens();
if (12 != monthcnt) {
throw new IllegalArgumentException("expecting a pipe-delimited string containing 12 tokens");
}
String[] months = new String[13];
int pos = 0;
while (st.hasMoreTokens()) {
months[pos++] = st.nextToken();
}
months[pos] = "";
return months;
}
/**
* Returns a Collection of all the language codes currently supported
* by this class. See {@link #setServerLanguageCode(String) serverLanguageCode}
* for a functional descrption of language codes within this system.
*
* @return a Collection of all the language codes currently supported
* by this class
*/
public static Collection<String> getSupportedLanguageCodes() {
return LANGUAGE_CODE_MAP.keySet();
}
}

@ -181,7 +181,7 @@ public class DownloadReceiver extends AbsReceiver {
}
}
} else {
ALog.e(TAG, "没有Aria的注解方法");
ALog.e(TAG, "没有Aria的注解方法,详情见:https://aria.laoyuyu.me/aria_doc/other/annotaion_invalid.html");
}
}

@ -267,7 +267,7 @@ public class UploadReceiver extends AbsReceiver {
}
}
} else {
ALog.e(TAG, "没有Aria的注解方法");
ALog.e(TAG, "没有Aria的注解方法,详情见:https://aria.laoyuyu.me/aria_doc/other/annotaion_invalid.html");
}
}

@ -1 +0,0 @@
/build

@ -1,11 +0,0 @@
apply plugin: 'com.novoda.bintray-release'
publish {
artifactId = 'aria-ftp-plug'
userOrg = rootProject.ext.userOrg
groupId = rootProject.ext.groupId
uploadName = 'FtpPlug'
publishVersion = rootProject.ext.publishVersion
desc = rootProject.ext.desc
website = rootProject.ext.website
licences = rootProject.ext.licences
}

@ -1,14 +0,0 @@
apply plugin: 'java'
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
//apply from: 'bintray-release.gradle'

@ -1,25 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in E:\sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -1,287 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.Charset;
/***
* The DatagramSocketClient provides the basic operations that are required
* of client objects accessing datagram sockets. It is meant to be
* subclassed to avoid having to rewrite the same code over and over again
* to open a socket, close a socket, set timeouts, etc. Of special note
* is the {@link #setDatagramSocketFactory setDatagramSocketFactory }
* method, which allows you to control the type of DatagramSocket the
* DatagramSocketClient creates for network communications. This is
* especially useful for adding things like proxy support as well as better
* support for applets. For
* example, you could create a
* {@link DatagramSocketFactory}
* that
* requests browser security capabilities before creating a socket.
* All classes derived from DatagramSocketClient should use the
* {@link #_socketFactory_ _socketFactory_ } member variable to
* create DatagramSocket instances rather than instantiating
* them by directly invoking a constructor. By honoring this contract
* you guarantee that a user will always be able to provide his own
* Socket implementations by substituting his own SocketFactory.
*
*
* @see DatagramSocketFactory
***/
public abstract class DatagramSocketClient {
/***
* The default DatagramSocketFactory shared by all DatagramSocketClient
* instances.
***/
private static final DatagramSocketFactory __DEFAULT_SOCKET_FACTORY =
new DefaultDatagramSocketFactory();
/**
* Charset to use for byte IO.
*/
private Charset charset = Charset.defaultCharset();
/*** The timeout to use after opening a socket. ***/
protected int _timeout_;
/*** The datagram socket used for the connection. ***/
protected DatagramSocket _socket_;
/***
* A status variable indicating if the client's socket is currently open.
***/
protected boolean _isOpen_;
/*** The datagram socket's DatagramSocketFactory. ***/
protected DatagramSocketFactory _socketFactory_;
/***
* Default constructor for DatagramSocketClient. Initializes
* _socket_ to null, _timeout_ to 0, and _isOpen_ to false.
***/
public DatagramSocketClient() {
_socket_ = null;
_timeout_ = 0;
_isOpen_ = false;
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
}
/***
* Opens a DatagramSocket on the local host at the first available port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
* <p>
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open() throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket();
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket on the local host at a specified port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
* <p>
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @param port The port to use for the socket.
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port) throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket(port);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket at the specified address on the local host
* at a specified port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
* <p>
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @throws SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port, InetAddress laddr) throws SocketException {
_socket_ = _socketFactory_.createDatagramSocket(port, laddr);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Closes the DatagramSocket used for the connection.
* You should call this method after you've finished using the class
* instance and also before you call {@link #open open() }
* again. _isOpen_ is set to false and _socket_ is set to null.
***/
public void close() {
if (_socket_ != null) {
_socket_.close();
}
_socket_ = null;
_isOpen_ = false;
}
/***
* Returns true if the client has a currently open socket.
*
* @return True if the client has a currently open socket, false otherwise.
***/
public boolean isOpen() {
return _isOpen_;
}
/***
* Set the default timeout in milliseconds to use when opening a socket.
* After a call to open, the timeout for the socket is set using this value.
* This method should be used prior to a call to {@link #open open()}
* and should not be confused with {@link #setSoTimeout setSoTimeout()}
* which operates on the currently open socket. _timeout_ contains
* the new timeout value.
*
* @param timeout The timeout in milliseconds to use for the datagram socket
* connection.
***/
public void setDefaultTimeout(int timeout) {
_timeout_ = timeout;
}
/***
* Returns the default timeout in milliseconds that is used when
* opening a socket.
*
* @return The default timeout in milliseconds that is used when
* opening a socket.
***/
public int getDefaultTimeout() {
return _timeout_;
}
/***
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
* by {@link #open open()}.
*
* @param timeout The timeout in milliseconds to use for the currently
* open datagram socket connection.
* @throws SocketException if an error setting the timeout
***/
public void setSoTimeout(int timeout) throws SocketException {
_socket_.setSoTimeout(timeout);
}
/***
* Returns the timeout in milliseconds of the currently opened socket.
* If you call this method when the client socket is not open,
* a NullPointerException is thrown.
*
* @return The timeout in milliseconds of the currently opened socket.
* @throws SocketException if an error getting the timeout
***/
public int getSoTimeout() throws SocketException {
return _socket_.getSoTimeout();
}
/***
* Returns the port number of the open socket on the local host used
* for the connection. If you call this method when the client socket
* is not open, a NullPointerException is thrown.
*
* @return The port number of the open socket on the local host used
* for the connection.
***/
public int getLocalPort() {
return _socket_.getLocalPort();
}
/***
* Returns the local address to which the client's socket is bound.
* If you call this method when the client socket is not open, a
* NullPointerException is thrown.
*
* @return The local address to which the client's socket is bound.
***/
public InetAddress getLocalAddress() {
return _socket_.getLocalAddress();
}
/***
* Sets the DatagramSocketFactory used by the DatagramSocketClient
* to open DatagramSockets. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
*
* @param factory The new DatagramSocketFactory the DatagramSocketClient
* should use.
***/
public void setDatagramSocketFactory(DatagramSocketFactory factory) {
if (factory == null) {
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
} else {
_socketFactory_ = factory;
}
}
/**
* Gets the charset name.
*
* @return the charset name.
* @since 3.3
* TODO Will be deprecated once the code requires Java 1.6 as a mininmum
*/
public String getCharsetName() {
return charset.name();
}
/**
* Gets the charset.
*
* @return the charset.
* @since 3.3
*/
public Charset getCharset() {
return charset;
}
/**
* Sets the charset.
*
* @param charset the charset.
* @since 3.3
*/
public void setCharset(Charset charset) {
this.charset = charset;
}
}

@ -1,67 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/***
* The DatagramSocketFactory interface provides a means for the
* programmer to control the creation of datagram sockets and
* provide his own DatagramSocket implementations for use by all
* classes derived from
* {@link DatagramSocketClient}
* .
* This allows you to provide your own DatagramSocket implementations and
* to perform security checks or browser capability requests before
* creating a DatagramSocket.
*
*
***/
public interface DatagramSocketFactory {
/***
* Creates a DatagramSocket on the local host at the first available port.
* @return the socket
*
* @throws SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket() throws SocketException;
/***
* Creates a DatagramSocket on the local host at a specified port.
*
* @param port The port to use for the socket.
* @return the socket
* @throws SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port) throws SocketException;
/***
* Creates a DatagramSocket at the specified address on the local host
* at a specified port.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @return the socket
* @throws SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port, InetAddress laddr) throws SocketException;
}

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/***
* DefaultDatagramSocketFactory implements the DatagramSocketFactory
* interface by simply wrapping the java.net.DatagramSocket
* constructors. It is the default DatagramSocketFactory used by
* {@link DatagramSocketClient}
* implementations.
*
*
* @see DatagramSocketFactory
* @see DatagramSocketClient
* @see DatagramSocketClient#setDatagramSocketFactory
***/
public class DefaultDatagramSocketFactory implements DatagramSocketFactory {
/***
* Creates a DatagramSocket on the local host at the first available port.
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override public DatagramSocket createDatagramSocket() throws SocketException {
return new DatagramSocket();
}
/***
* Creates a DatagramSocket on the local host at a specified port.
*
* @param port The port to use for the socket.
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override public DatagramSocket createDatagramSocket(int port) throws SocketException {
return new DatagramSocket(port);
}
/***
* Creates a DatagramSocket at the specified address on the local host
* at a specified port.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @return a new DatagramSocket
* @throws SocketException If the socket could not be created.
***/
@Override public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException {
return new DatagramSocket(port, laddr);
}
}

@ -1,204 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
/***
* DefaultSocketFactory implements the SocketFactory interface by
* simply wrapping the java.net.Socket and java.net.ServerSocket
* constructors. It is the default SocketFactory used by
* {@link SocketClient}
* implementations.
*
*
* @see SocketFactory
* @see SocketClient
* @see SocketClient#setSocketFactory
***/
public class DefaultSocketFactory extends SocketFactory {
/** The proxy to use when creating new sockets. */
private final Proxy connProxy;
/**
* The default constructor.
*/
public DefaultSocketFactory() {
this(null);
}
/**
* A constructor for sockets with proxy support.
*
* @param proxy The Proxy to use when creating new Sockets.
* @since 3.2
*/
public DefaultSocketFactory(Proxy proxy) {
connProxy = proxy;
}
/**
* Creates an unconnected Socket.
*
* @return A new unconnected Socket.
* @throws IOException If an I/O error occurs while creating the Socket.
* @since 3.2
*/
@Override public Socket createSocket() throws IOException {
if (connProxy != null) {
return new Socket(connProxy);
}
return new Socket();
}
/***
* Creates a Socket connected to the given host and port.
*
* @param host The hostname to connect to.
* @param port The port to connect to.
* @return A Socket connected to the given host and port.
* @throws UnknownHostException If the hostname cannot be resolved.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override public Socket createSocket(String host, int port)
throws UnknownHostException, IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.connect(new InetSocketAddress(host, port));
return s;
}
return new Socket(host, port);
}
/***
* Creates a Socket connected to the given host and port.
*
* @param address The address of the host to connect to.
* @param port The port to connect to.
* @return A Socket connected to the given host and port.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override public Socket createSocket(InetAddress address, int port) throws IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.connect(new InetSocketAddress(address, port));
return s;
}
return new Socket(address, port);
}
/***
* Creates a Socket connected to the given host and port and
* originating from the specified local address and port.
*
* @param host The hostname to connect to.
* @param port The port to connect to.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @return A Socket connected to the given host and port.
* @throws UnknownHostException If the hostname cannot be resolved.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override public Socket createSocket(String host, int port, InetAddress localAddr, int localPort)
throws UnknownHostException, IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.bind(new InetSocketAddress(localAddr, localPort));
s.connect(new InetSocketAddress(host, port));
return s;
}
return new Socket(host, port, localAddr, localPort);
}
/***
* Creates a Socket connected to the given host and port and
* originating from the specified local address and port.
*
* @param address The address of the host to connect to.
* @param port The port to connect to.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @return A Socket connected to the given host and port.
* @throws IOException If an I/O error occurs while creating the Socket.
***/
@Override public Socket createSocket(InetAddress address, int port, InetAddress localAddr,
int localPort) throws IOException {
if (connProxy != null) {
Socket s = new Socket(connProxy);
s.bind(new InetSocketAddress(localAddr, localPort));
s.connect(new InetSocketAddress(address, port));
return s;
}
return new Socket(address, port, localAddr, localPort);
}
/***
* Creates a ServerSocket bound to a specified port. A port
* of 0 will create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @return A ServerSocket that will listen on a specified port.
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port) throws IOException {
return new ServerSocket(port);
}
/***
* Creates a ServerSocket bound to a specified port with a given
* maximum queue length for incoming connections. A port of 0 will
* create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @param backlog The maximum length of the queue for incoming connections.
* @return A ServerSocket that will listen on a specified port.
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return new ServerSocket(port, backlog);
}
/***
* Creates a ServerSocket bound to a specified port on a given local
* address with a given maximum queue length for incoming connections.
* A port of 0 will
* create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @param backlog The maximum length of the queue for incoming connections.
* @param bindAddr The local address to which the ServerSocket should bind.
* @return A ServerSocket that will listen on a specified port.
* @throws IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException {
return new ServerSocket(port, backlog, bindAddr);
}
}

@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.io.IOException;
/***
* This exception is used to indicate that the reply from a server
* could not be interpreted. Most of the NetComponents classes attempt
* to be as lenient as possible when receiving server replies. Many
* server implementations deviate from IETF protocol specifications, making
* it necessary to be as flexible as possible. However, there will be
* certain situations where it is not possible to continue an operation
* because the server reply could not be interpreted in a meaningful manner.
* In these cases, a MalformedServerReplyException should be thrown.
*
*
***/
public class MalformedServerReplyException extends IOException {
private static final long serialVersionUID = 6006765264250543945L;
/*** Constructs a MalformedServerReplyException with no message ***/
public MalformedServerReplyException() {
super();
}
/***
* Constructs a MalformedServerReplyException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public MalformedServerReplyException(String message) {
super(message);
}
}

@ -1,190 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.io.PrintStream;
import java.io.PrintWriter;
/***
* This is a support class for some of the example programs. It is
* a sample implementation of the ProtocolCommandListener interface
* which just prints out to a specified stream all command/reply traffic.
*
* @since 2.0
***/
public class PrintCommandListener implements ProtocolCommandListener {
private final PrintWriter __writer;
private final boolean __nologin;
private final char __eolMarker;
private final boolean __directionMarker;
/**
* Create the default instance which prints everything.
*
* @param stream where to write the commands and responses
* e.g. System.out
* @since 3.0
*/
public PrintCommandListener(PrintStream stream) {
this(new PrintWriter(stream));
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin) {
this(new PrintWriter(stream), suppressLogin);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker) {
this(new PrintWriter(stream), suppressLogin, eolMarker);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the
* output
* @since 3.0
*/
public PrintCommandListener(PrintStream stream, boolean suppressLogin, char eolMarker,
boolean showDirection) {
this(new PrintWriter(stream), suppressLogin, eolMarker, showDirection);
}
/**
* Create the default instance which prints everything.
*
* @param writer where to write the commands and responses
*/
public PrintCommandListener(PrintWriter writer) {
this(writer, false);
}
/**
* Create an instance which optionally suppresses login command text.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin) {
this(writer, suppressLogin, (char) 0);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker) {
this(writer, suppressLogin, eolMarker, false);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the
* output
* @since 3.0
*/
public PrintCommandListener(PrintWriter writer, boolean suppressLogin, char eolMarker,
boolean showDirection) {
__writer = writer;
__nologin = suppressLogin;
__eolMarker = eolMarker;
__directionMarker = showDirection;
}
@Override public void protocolCommandSent(ProtocolCommandEvent event) {
if (__directionMarker) {
__writer.print("> ");
}
if (__nologin) {
String cmd = event.getCommand();
if ("PASS".equalsIgnoreCase(cmd) || "USER".equalsIgnoreCase(cmd)) {
__writer.print(cmd);
__writer.println(" *******"); // Don't bother with EOL marker for this!
} else {
final String IMAP_LOGIN = "LOGIN";
if (IMAP_LOGIN.equalsIgnoreCase(cmd)) { // IMAP
String msg = event.getMessage();
msg = msg.substring(0, msg.indexOf(IMAP_LOGIN) + IMAP_LOGIN.length());
__writer.print(msg);
__writer.println(" *******"); // Don't bother with EOL marker for this!
} else {
__writer.print(getPrintableString(event.getMessage()));
}
}
} else {
__writer.print(getPrintableString(event.getMessage()));
}
__writer.flush();
}
private String getPrintableString(String msg) {
if (__eolMarker == 0) {
return msg;
}
int pos = msg.indexOf(SocketClient.NETASCII_EOL);
if (pos > 0) {
StringBuilder sb = new StringBuilder();
sb.append(msg.substring(0, pos));
sb.append(__eolMarker);
sb.append(msg.substring(pos));
return sb.toString();
}
return msg;
}
@Override public void protocolReplyReceived(ProtocolCommandEvent event) {
if (__directionMarker) {
__writer.print("< ");
}
__writer.print(event.getMessage());
__writer.flush();
}
}

@ -1,139 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.util.EventObject;
/***
* There exists a large class of IETF protocols that work by sending an
* ASCII text command and arguments to a server, and then receiving an
* ASCII text reply. For debugging and other purposes, it is extremely
* useful to log or keep track of the contents of the protocol messages.
* The ProtocolCommandEvent class coupled with the
* {@link ProtocolCommandListener}
* interface facilitate this process.
*
*
* @see ProtocolCommandListener
* @see ProtocolCommandSupport
***/
public class ProtocolCommandEvent extends EventObject {
private static final long serialVersionUID = 403743538418947240L;
private final int __replyCode;
private final boolean __isCommand;
private final String __message, __command;
/***
* Creates a ProtocolCommandEvent signalling a command was sent to
* the server. ProtocolCommandEvents created with this constructor
* should only be sent after a command has been sent, but before the
* reply has been received.
*
* @param source The source of the event.
* @param command The string representation of the command type sent, not
* including the arguments (e.g., "STAT" or "GET").
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public ProtocolCommandEvent(Object source, String command, String message) {
super(source);
__replyCode = 0;
__message = message;
__isCommand = true;
__command = command;
}
/***
* Creates a ProtocolCommandEvent signalling a reply to a command was
* received. ProtocolCommandEvents created with this constructor
* should only be sent after a complete command reply has been received
* fromt a server.
*
* @param source The source of the event.
* @param replyCode The integer code indicating the natureof the reply.
* This will be the protocol integer value for protocols
* that use integer reply codes, or the reply class constant
* corresponding to the reply for protocols like POP3 that use
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public ProtocolCommandEvent(Object source, int replyCode, String message) {
super(source);
__replyCode = replyCode;
__message = message;
__isCommand = false;
__command = null;
}
/***
* Returns the string representation of the command type sent (e.g., "STAT"
* or "GET"). If the ProtocolCommandEvent is a reply event, then null
* is returned.
*
* @return The string representation of the command type sent, or null
* if this is a reply event.
***/
public String getCommand() {
return __command;
}
/***
* Returns the reply code of the received server reply. Undefined if
* this is not a reply event.
*
* @return The reply code of the received server reply. Undefined if
* not a reply event.
***/
public int getReplyCode() {
return __replyCode;
}
/***
* Returns true if the ProtocolCommandEvent was generated as a result
* of sending a command.
*
* @return true If the ProtocolCommandEvent was generated as a result
* of sending a command. False otherwise.
***/
public boolean isCommand() {
return __isCommand;
}
/***
* Returns true if the ProtocolCommandEvent was generated as a result
* of receiving a reply.
*
* @return true If the ProtocolCommandEvent was generated as a result
* of receiving a reply. False otherwise.
***/
public boolean isReply() {
return !isCommand();
}
/***
* Returns the entire message sent to or received from the server.
* Includes the line terminator.
*
* @return The entire message sent to or received from the server.
***/
public String getMessage() {
return __message;
}
}

@ -1,58 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import aria.apache.commons.net.ftp.FTPClient;
import java.util.EventListener;
/***
* There exists a large class of IETF protocols that work by sending an
* ASCII text command and arguments to a server, and then receiving an
* ASCII text reply. For debugging and other purposes, it is extremely
* useful to log or keep track of the contents of the protocol messages.
* The ProtocolCommandListener interface coupled with the
* {@link ProtocolCommandEvent} class facilitate this process.
* <p>
* To receive ProtocolCommandEvents, you merely implement the
* ProtocolCommandListener interface and register the class as a listener
* with a ProtocolCommandEvent source such as
* {@link FTPClient}.
*
*
* @see ProtocolCommandEvent
* @see ProtocolCommandSupport
***/
public interface ProtocolCommandListener extends EventListener {
/***
* This method is invoked by a ProtocolCommandEvent source after
* sending a protocol command to a server.
*
* @param event The ProtocolCommandEvent fired.
***/
public void protocolCommandSent(ProtocolCommandEvent event);
/***
* This method is invoked by a ProtocolCommandEvent source after
* receiving a reply from a server.
*
* @param event The ProtocolCommandEvent fired.
***/
public void protocolReplyReceived(ProtocolCommandEvent event);
}

@ -1,123 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.io.Serializable;
import java.util.EventListener;
import aria.apache.commons.net.util.ListenerList;
/***
* ProtocolCommandSupport is a convenience class for managing a list of
* ProtocolCommandListeners and firing ProtocolCommandEvents. You can
* simply delegate ProtocolCommandEvent firing and listener
* registering/unregistering tasks to this class.
*
*
* @see ProtocolCommandEvent
* @see ProtocolCommandListener
***/
public class ProtocolCommandSupport implements Serializable {
private static final long serialVersionUID = -8017692739988399978L;
private final Object __source;
private final ListenerList __listeners;
/***
* Creates a ProtocolCommandSupport instance using the indicated source
* as the source of ProtocolCommandEvents.
*
* @param source The source to use for all generated ProtocolCommandEvents.
***/
public ProtocolCommandSupport(Object source) {
__listeners = new ListenerList();
__source = source;
}
/***
* Fires a ProtocolCommandEvent signalling the sending of a command to all
* registered listeners, invoking their
* {@link ProtocolCommandListener#protocolCommandSent protocolCommandSent() }
* methods.
*
* @param command The string representation of the command type sent, not
* including the arguments (e.g., "STAT" or "GET").
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public void fireCommandSent(String command, String message) {
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, command, message);
for (EventListener listener : __listeners) {
((ProtocolCommandListener) listener).protocolCommandSent(event);
}
}
/***
* Fires a ProtocolCommandEvent signalling the reception of a command reply
* to all registered listeners, invoking their
* {@link ProtocolCommandListener#protocolReplyReceived protocolReplyReceived() }
* methods.
*
* @param replyCode The integer code indicating the natureof the reply.
* This will be the protocol integer value for protocols
* that use integer reply codes, or the reply class constant
* corresponding to the reply for protocols like POP3 that use
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public void fireReplyReceived(int replyCode, String message) {
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, replyCode, message);
for (EventListener listener : __listeners) {
((ProtocolCommandListener) listener).protocolReplyReceived(event);
}
}
/***
* Adds a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener) {
__listeners.addListener(listener);
}
/***
* Removes a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandListener(ProtocolCommandListener listener) {
__listeners.removeListener(listener);
}
/***
* Returns the number of ProtocolCommandListeners currently registered.
*
* @return The number of ProtocolCommandListeners currently registered.
***/
public int getListenerCount() {
return __listeners.getListenerCount();
}
}

@ -1,869 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketException;
import java.nio.charset.Charset;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
/**
* The SocketClient provides the basic operations that are required of
* client objects accessing sockets. It is meant to be
* subclassed to avoid having to rewrite the same code over and over again
* to open a socket, close a socket, set timeouts, etc. Of special note
* is the {@link #setSocketFactory setSocketFactory }
* method, which allows you to control the type of Socket the SocketClient
* creates for initiating network connections. This is especially useful
* for adding SSL or proxy support as well as better support for applets. For
* example, you could create a
* {@link SocketFactory} that
* requests browser security capabilities before creating a socket.
* All classes derived from SocketClient should use the
* {@link #_socketFactory_ _socketFactory_ } member variable to
* create Socket and ServerSocket instances rather than instantiating
* them by directly invoking a constructor. By honoring this contract
* you guarantee that a user will always be able to provide his own
* Socket implementations by substituting his own SocketFactory.
*
* @see SocketFactory
*/
public abstract class SocketClient {
/**
* The end of line character sequence used by most IETF protocols. That
* is a carriage return followed by a newline: "\r\n"
*/
public static final String NETASCII_EOL = "\r\n";
/** The default SocketFactory shared by all SocketClient instances. */
private static final SocketFactory __DEFAULT_SOCKET_FACTORY = SocketFactory.getDefault();
/** The default {@link ServerSocketFactory} */
private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY =
ServerSocketFactory.getDefault();
/**
* A ProtocolCommandSupport object used to manage the registering of
* ProtocolCommandListeners and the firing of ProtocolCommandEvents.
*/
private ProtocolCommandSupport __commandSupport;
/** The timeout to use after opening a socket. */
protected int _timeout_;
/** The socket used for the connection. */
protected Socket _socket_;
/** The hostname used for the connection (null = no hostname supplied). */
protected String _hostname_;
/** The default port the client should connect to. */
protected int _defaultPort_;
/** The socket's InputStream. */
protected InputStream _input_;
/** The socket's OutputStream. */
protected OutputStream _output_;
/** The socket's SocketFactory. */
protected SocketFactory _socketFactory_;
/** The socket's ServerSocket Factory. */
protected ServerSocketFactory _serverSocketFactory_;
/** The socket's connect timeout (0 = infinite timeout) */
private static final int DEFAULT_CONNECT_TIMEOUT = 0;
protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
/** Hint for SO_RCVBUF size */
private int receiveBufferSize = -1;
/** Hint for SO_SNDBUF size */
private int sendBufferSize = -1;
/** The proxy to use when connecting. */
private Proxy connProxy;
/**
* Charset to use for byte IO.
*/
private Charset charset = Charset.defaultCharset();
/**
* Default constructor for SocketClient. Initializes
* _socket_ to null, _timeout_ to 0, _defaultPort to 0,
* _isConnected_ to false, charset to {@code Charset.defaultCharset()}
* and _socketFactory_ to a shared instance of
* {@link DefaultSocketFactory}.
*/
public SocketClient() {
_socket_ = null;
_hostname_ = null;
_input_ = null;
_output_ = null;
_timeout_ = 0;
_defaultPort_ = 0;
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
_serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
}
/**
* Because there are so many connect() methods, the _connectAction_()
* method is provided as a means of performing some action immediately
* after establishing a connection, rather than reimplementing all
* of the connect() methods. The last action performed by every
* connect() method after opening a socket is to call this method.
* <p>
* This method sets the timeout on the just opened socket to the default
* timeout set by {@link #setDefaultTimeout setDefaultTimeout() },
* sets _input_ and _output_ to the socket's InputStream and OutputStream
* respectively, and sets _isConnected_ to true.
* <p>
* Subclasses overriding this method should start by calling
* <code> super._connectAction_() </code> first to ensure the
* initialization of the aforementioned protected variables.
*
* @throws IOException (SocketException) if a problem occurs with the socket
*/
protected void _connectAction_() throws IOException {
_socket_.setSoTimeout(_timeout_);
_input_ = _socket_.getInputStream();
_output_ = _socket_.getOutputStream();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port) throws SocketException, IOException {
_hostname_ = null;
_connect(host, port, null, -1);
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port) throws SocketException, IOException {
_hostname_ = hostname;
_connect(InetAddress.getByName(hostname), port, null, -1);
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
_hostname_ = null;
_connect(host, port, localAddr, localPort);
}
// helper method to allow code to be shared with connect(String,...) methods
private void _connect(InetAddress host, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
_socket_ = _socketFactory_.createSocket();
if (receiveBufferSize != -1) {
_socket_.setReceiveBufferSize(receiveBufferSize);
}
if (sendBufferSize != -1) {
_socket_.setSendBufferSize(sendBufferSize);
}
if (localAddr != null) {
_socket_.bind(new InetSocketAddress(localAddr, localPort));
}
_socket_.connect(new InetSocketAddress(host, port), connectTimeout);
_connectAction_();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port, InetAddress localAddr, int localPort)
throws SocketException, IOException {
_hostname_ = hostname;
_connect(InetAddress.getByName(hostname), port, localAddr, localPort);
}
/**
* Opens a Socket connected to a remote host at the current default port
* and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param host The remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host) throws SocketException, IOException {
_hostname_ = null;
connect(host, _defaultPort_);
}
/**
* Opens a Socket connected to a remote host at the current default
* port and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* <p>
*
* @param hostname The name of the remote host.
* @throws SocketException If the socket timeout could not be set.
* @throws IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @throws java.net.UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname) throws SocketException, IOException {
connect(hostname, _defaultPort_);
}
/**
* Disconnects the socket connection.
* You should call this method after you've finished using the class
* instance and also before you call
* {@link #connect connect() }
* again. _isConnected_ is set to false, _socket_ is set to null,
* _input_ is set to null, and _output_ is set to null.
* <p>
*
* @throws IOException If there is an error closing the socket.
*/
public void disconnect() throws IOException {
closeQuietly(_socket_);
closeQuietly(_input_);
closeQuietly(_output_);
_socket_ = null;
_hostname_ = null;
_input_ = null;
_output_ = null;
}
private void closeQuietly(Socket socket) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// Ignored
}
}
}
private void closeQuietly(Closeable close) {
if (close != null) {
try {
close.close();
} catch (IOException e) {
// Ignored
}
}
}
/**
* Returns true if the client is currently connected to a server.
* <p>
* Delegates to {@link Socket#isConnected()}
*
* @return True if the client is currently connected to a server,
* false otherwise.
*/
public boolean isConnected() {
if (_socket_ == null) {
return false;
}
return _socket_.isConnected();
}
/**
* Make various checks on the socket to test if it is available for use.
* Note that the only sure test is to use it, but these checks may help
* in some cases.
*
* @return {@code true} if the socket appears to be available for use
* @see <a href="https://issues.apache.org/jira/browse/NET-350">NET-350</a>
* @since 3.0
*/
public boolean isAvailable() {
if (isConnected()) {
try {
if (_socket_.getInetAddress() == null) {
return false;
}
if (_socket_.getPort() == 0) {
return false;
}
if (_socket_.getRemoteSocketAddress() == null) {
return false;
}
if (_socket_.isClosed()) {
return false;
}
/* these aren't exact checks (a Socket can be half-open),
but since we usually require two-way data transfer,
we check these here too: */
if (_socket_.isInputShutdown()) {
return false;
}
if (_socket_.isOutputShutdown()) {
return false;
}
/* ignore the result, catch exceptions: */
_socket_.getInputStream();
_socket_.getOutputStream();
} catch (IOException ioex) {
return false;
}
return true;
} else {
return false;
}
}
/**
* Sets the default port the SocketClient should connect to when a port
* is not specified. The {@link #_defaultPort_ _defaultPort_ }
* variable stores this value. If never set, the default port is equal
* to zero.
* <p>
*
* @param port The default port to set.
*/
public void setDefaultPort(int port) {
_defaultPort_ = port;
}
/**
* Returns the current value of the default port (stored in
* {@link #_defaultPort_ _defaultPort_ }).
* <p>
*
* @return The current value of the default port.
*/
public int getDefaultPort() {
return _defaultPort_;
}
/**
* Set the default timeout in milliseconds to use when opening a socket.
* This value is only used previous to a call to
* {@link #connect connect()}
* and should not be confused with {@link #setSoTimeout setSoTimeout()}
* which operates on an the currently opened socket. _timeout_ contains
* the new timeout value.
* <p>
*
* @param timeout The timeout in milliseconds to use for the socket
* connection.
*/
public void setDefaultTimeout(int timeout) {
_timeout_ = timeout;
}
/**
* Returns the default timeout in milliseconds that is used when
* opening a socket.
* <p>
*
* @return The default timeout in milliseconds that is used when
* opening a socket.
*/
public int getDefaultTimeout() {
return _timeout_;
}
/**
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
* by {@link #connect connect()}.
* <p>
* To set the initial timeout, use {@link #setDefaultTimeout(int)} instead.
*
* @param timeout The timeout in milliseconds to use for the currently
* open socket connection.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setSoTimeout(int timeout) throws SocketException {
_socket_.setSoTimeout(timeout);
}
/**
* Set the underlying socket send buffer size.
* <p>
*
* @param size The size of the buffer in bytes.
* @throws SocketException never thrown, but subclasses might want to do so
* @since 2.0
*/
public void setSendBufferSize(int size) throws SocketException {
sendBufferSize = size;
}
/**
* Get the current sendBuffer size
*
* @return the size, or -1 if not initialised
* @since 3.0
*/
protected int getSendBufferSize() {
return sendBufferSize;
}
/**
* Sets the underlying socket receive buffer size.
* <p>
*
* @param size The size of the buffer in bytes.
* @throws SocketException never (but subclasses may wish to do so)
* @since 2.0
*/
public void setReceiveBufferSize(int size) throws SocketException {
receiveBufferSize = size;
}
/**
* Get the current receivedBuffer size
*
* @return the size, or -1 if not initialised
* @since 3.0
*/
protected int getReceiveBufferSize() {
return receiveBufferSize;
}
/**
* Returns the timeout in milliseconds of the currently opened socket.
* <p>
*
* @return The timeout in milliseconds of the currently opened socket.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public int getSoTimeout() throws SocketException {
return _socket_.getSoTimeout();
}
/**
* Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
* currently opened socket.
* <p>
*
* @param on True if Nagle's algorithm is to be enabled, false if not.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setTcpNoDelay(boolean on) throws SocketException {
_socket_.setTcpNoDelay(on);
}
/**
* Returns true if Nagle's algorithm is enabled on the currently opened
* socket.
* <p>
*
* @return True if Nagle's algorithm is enabled on the currently opened
* socket, false otherwise.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public boolean getTcpNoDelay() throws SocketException {
return _socket_.getTcpNoDelay();
}
/**
* Sets the SO_KEEPALIVE flag on the currently opened socket.
*
* From the Javadocs, the default keepalive time is 2 hours (although this is
* implementation dependent). It looks as though the Windows WSA sockets implementation
* allows a specific keepalive value to be set, although this seems not to be the case on
* other systems.
*
* @param keepAlive If true, keepAlive is turned on
* @throws SocketException if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
* @since 2.2
*/
public void setKeepAlive(boolean keepAlive) throws SocketException {
_socket_.setKeepAlive(keepAlive);
}
/**
* Returns the current value of the SO_KEEPALIVE flag on the currently opened socket.
* Delegates to {@link Socket#getKeepAlive()}
*
* @return True if SO_KEEPALIVE is enabled.
* @throws SocketException if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
* @since 2.2
*/
public boolean getKeepAlive() throws SocketException {
return _socket_.getKeepAlive();
}
/**
* Sets the SO_LINGER timeout on the currently opened socket.
* <p>
*
* @param on True if linger is to be enabled, false if not.
* @param val The linger timeout (in hundredths of a second?)
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public void setSoLinger(boolean on, int val) throws SocketException {
_socket_.setSoLinger(on, val);
}
/**
* Returns the current SO_LINGER timeout of the currently opened socket.
* <p>
*
* @return The current SO_LINGER timeout. If SO_LINGER is disabled returns
* -1.
* @throws SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public int getSoLinger() throws SocketException {
return _socket_.getSoLinger();
}
/**
* Returns the port number of the open socket on the local host used
* for the connection.
* Delegates to {@link Socket#getLocalPort()}
* <p>
*
* @return The port number of the open socket on the local host used
* for the connection.
* @throws NullPointerException if the socket is not currently open
*/
public int getLocalPort() {
return _socket_.getLocalPort();
}
/**
* Returns the local address to which the client's socket is bound.
* Delegates to {@link Socket#getLocalAddress()}
* <p>
*
* @return The local address to which the client's socket is bound.
* @throws NullPointerException if the socket is not currently open
*/
public InetAddress getLocalAddress() {
return _socket_.getLocalAddress();
}
/**
* Returns the port number of the remote host to which the client is
* connected.
* Delegates to {@link Socket#getPort()}
* <p>
*
* @return The port number of the remote host to which the client is
* connected.
* @throws NullPointerException if the socket is not currently open
*/
public int getRemotePort() {
return _socket_.getPort();
}
/**
* @return The remote address to which the client is connected.
* Delegates to {@link Socket#getInetAddress()}
* @throws NullPointerException if the socket is not currently open
*/
public InetAddress getRemoteAddress() {
return _socket_.getInetAddress();
}
/**
* Verifies that the remote end of the given socket is connected to the
* the same host that the SocketClient is currently connected to. This
* is useful for doing a quick security check when a client needs to
* accept a connection from a server, such as an FTP data connection or
* a BSD R command standard error stream.
* <p>
*
* @param socket the item to check against
* @return True if the remote hosts are the same, false if not.
*/
public boolean verifyRemote(Socket socket) {
InetAddress host1, host2;
host1 = socket.getInetAddress();
host2 = getRemoteAddress();
return host1.equals(host2);
}
/**
* Sets the SocketFactory used by the SocketClient to open socket
* connections. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
* Any proxy setting is discarded.
* <p>
*
* @param factory The new SocketFactory the SocketClient should use.
*/
public void setSocketFactory(SocketFactory factory) {
if (factory == null) {
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
} else {
_socketFactory_ = factory;
}
// re-setting the socket factory makes the proxy setting useless,
// so set the field to null so that getProxy() doesn't return a
// Proxy that we're actually not using.
connProxy = null;
}
/**
* Sets the ServerSocketFactory used by the SocketClient to open ServerSocket
* connections. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
* <p>
*
* @param factory The new ServerSocketFactory the SocketClient should use.
* @since 2.0
*/
public void setServerSocketFactory(ServerSocketFactory factory) {
if (factory == null) {
_serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
} else {
_serverSocketFactory_ = factory;
}
}
/**
* Sets the connection timeout in milliseconds, which will be passed to the {@link Socket}
* object's
* connect() method.
*
* @param connectTimeout The connection timeout to use (in ms)
* @since 2.0
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* Get the underlying socket connection timeout.
*
* @return timeout (in ms)
* @since 2.0
*/
public int getConnectTimeout() {
return connectTimeout;
}
/**
* Get the underlying {@link ServerSocketFactory}
*
* @return The server socket factory
* @since 2.2
*/
public ServerSocketFactory getServerSocketFactory() {
return _serverSocketFactory_;
}
/**
* Adds a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to add.
* @since 3.0
*/
public void addProtocolCommandListener(ProtocolCommandListener listener) {
getCommandSupport().addProtocolCommandListener(listener);
}
/**
* Removes a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to remove.
* @since 3.0
*/
public void removeProtocolCommandListener(ProtocolCommandListener listener) {
getCommandSupport().removeProtocolCommandListener(listener);
}
/**
* If there are any listeners, send them the reply details.
*
* @param replyCode the code extracted from the reply
* @param reply the full reply text
* @since 3.0
*/
protected void fireReplyReceived(int replyCode, String reply) {
if (getCommandSupport().getListenerCount() > 0) {
getCommandSupport().fireReplyReceived(replyCode, reply);
}
}
/**
* If there are any listeners, send them the command details.
*
* @param command the command name
* @param message the complete message, including command name
* @since 3.0
*/
protected void fireCommandSent(String command, String message) {
if (getCommandSupport().getListenerCount() > 0) {
getCommandSupport().fireCommandSent(command, message);
}
}
/**
* Create the CommandSupport instance if required
*/
protected void createCommandSupport() {
__commandSupport = new ProtocolCommandSupport(this);
}
/**
* Subclasses can override this if they need to provide their own
* instance field for backwards compatibilty.
*
* @return the CommandSupport instance, may be {@code null}
* @since 3.0
*/
protected ProtocolCommandSupport getCommandSupport() {
return __commandSupport;
}
/**
* Sets the proxy for use with all the connections.
* The proxy is used for connections established after the
* call to this method.
*
* @param proxy the new proxy for connections.
* @since 3.2
*/
public void setProxy(Proxy proxy) {
setSocketFactory(new DefaultSocketFactory(proxy));
connProxy = proxy;
}
/**
* Gets the proxy for use with all the connections.
*
* @return the current proxy for connections.
*/
public Proxy getProxy() {
return connProxy;
}
/**
* Gets the charset name.
*
* @return the charset.
* @since 3.3
* @deprecated Since the code now requires Java 1.6 as a mininmum
*/
@Deprecated public String getCharsetName() {
return charset.name();
}
/**
* Gets the charset.
*
* @return the charset.
* @since 3.3
*/
public Charset getCharset() {
return charset;
}
/**
* Sets the charset.
*
* @param charset the charset.
* @since 3.3
*/
public void setCharset(Charset charset) {
this.charset = charset;
}
/*
* N.B. Fields cannot be pulled up into a super-class without breaking binary compatibility,
* so the abstract method is needed to pass the instance to the methods which were moved here.
*/
}

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
/**
* This interface adds the aspect of configurability by means of
* a supplied FTPClientConfig object to other classes in the
* system, especially listing parsers.
*/
public interface Configurable {
/**
* @param config the object containing the configuration data
* @throws IllegalArgumentException if the elements of the
* <code>config</code> are somehow inadequate to configure the
* Configurable object.
*/
public void configure(FTPClientConfig config);
}

@ -1,713 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import aria.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl;
import aria.apache.commons.net.ftp.parser.FTPTimestampParserImpl;
import java.text.DateFormatSymbols;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
/**
* <p>
* This class implements an alternate means of configuring the
* {@link FTPClient FTPClient} object and
* also subordinate objects which it uses. Any class implementing the
* {@link Configurable Configurable }
* interface can be configured by this object.
* </p><p>
* In particular this class was designed primarily to support configuration
* of FTP servers which express file timestamps in formats and languages
* other than those for the US locale, which although it is the most common
* is not universal. Unfortunately, nothing in the FTP spec allows this to
* be determined in an automated way, so manual configuration such as this
* is necessary.
* </p><p>
* This functionality was designed to allow existing clients to work exactly
* as before without requiring use of this component. This component should
* only need to be explicitly invoked by the user of this package for problem
* cases that previous implementations could not solve.
* </p>
* <h3>Examples of use of FTPClientConfig</h3>
* Use cases:
* You are trying to access a server that
* <ul>
* <li>lists files with timestamps that use month names in languages other
* than English</li>
* <li>lists files with timestamps that use date formats other
* than the American English "standard" <code>MM dd yyyy</code></li>
* <li>is in different timezone and you need accurate timestamps for
* dependency checking as in Ant</li>
* </ul>
* <p>
* Unpaged (whole list) access on a UNIX server that uses French month names
* but uses the "standard" <code>MMM d yyyy</code> date formatting
* <pre>
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setServerLanguageCode("fr");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
* </pre>
* <p>
* Paged access on a UNIX server that uses Danish month names
* and "European" date formatting in Denmark's time zone, when you
* are in some other time zone.
* <pre>
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setServerLanguageCode("da");
* conf.setDefaultDateFormat("d MMM yyyy");
* conf.setRecentDateFormat("d MMM HH:mm");
* conf.setTimeZoneId("Europe/Copenhagen");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine =
* f.initiateListParsing("com.whatever.YourOwnParser", directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
* </pre>
* <p>
* Unpaged (whole list) access on a VMS server that uses month names
* in a language not {@link #getSupportedLanguageCodes() supported} by the system.
* but uses the "standard" <code>MMM d yyyy</code> date formatting
* <pre>
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_VMS);
* conf.setShortMonthNames(
* "jan|feb|mar|apr|ma\u00ED|j\u00FAn|j\u00FAl|\u00e1g\u00FA|sep|okt|n\u00F3v|des");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
* </pre>
* <p>
* Unpaged (whole list) access on a Windows-NT server in a different time zone.
* (Note, since the NT Format uses numeric date formatting, language issues
* are irrelevant here).
* <pre>
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
* conf.setTimeZoneId("America/Denver");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
* </pre>
* Unpaged (whole list) access on a Windows-NT server in a different time zone
* but which has been configured to use a unix-style listing format.
* <pre>
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setTimeZoneId("America/Denver");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
* </pre>
*
* @see Configurable
* @see FTPClient
* @see FTPTimestampParserImpl#configure(FTPClientConfig)
* @see ConfigurableFTPFileEntryParserImpl
* @since 1.4
*/
public class FTPClientConfig {
/**
* Identifier by which a unix-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_UNIX = "UNIX";
/**
* Identifier for alternate UNIX parser; same as {@link #SYST_UNIX} but leading spaces are
* trimmed from file names. This is to maintain backwards compatibility with
* the original behaviour of the parser which ignored multiple spaces between the date
* and the start of the file name.
*
* @since 3.4
*/
public static final String SYST_UNIX_TRIM_LEADING = "UNIX_LTRIM";
/**
* Identifier by which a vms-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_VMS = "VMS";
/**
* Identifier by which a WindowsNT-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_NT = "WINDOWS";
/**
* Identifier by which an OS/2-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_OS2 = "OS/2";
/**
* Identifier by which an OS/400-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_OS400 = "OS/400";
/**
* Identifier by which an AS/400-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_AS400 = "AS/400";
/**
* Identifier by which an MVS-based ftp server is known throughout
* the commons-net ftp system.
*/
public static final String SYST_MVS = "MVS";
/**
* Some servers return an "UNKNOWN Type: L8" message
* in response to the SYST command. We set these to be a Unix-type system.
* This may happen if the ftpd in question was compiled without system
* information.
*
* NET-230 - Updated to be UPPERCASE so that the check done in
* createFileEntryParser will succeed.
*
* @since 1.5
*/
public static final String SYST_L8 = "TYPE: L8";
/**
* Identifier by which an Netware-based ftp server is known throughout
* the commons-net ftp system.
*
* @since 1.5
*/
public static final String SYST_NETWARE = "NETWARE";
/**
* Identifier by which a Mac pre OS-X -based ftp server is known throughout
* the commons-net ftp system.
*
* @since 3.1
*/
// Full string is "MACOS Peter's Server"; the substring below should be enough
public static final String SYST_MACOS_PETER = "MACOS PETER"; // NET-436
private final String serverSystemKey;
private String defaultDateFormatStr = null;
private String recentDateFormatStr = null;
private boolean lenientFutureDates = true; // NET-407
private String serverLanguageCode = null;
private String shortMonthNames = null;
private String serverTimeZoneId = null;
private boolean saveUnparseableEntries = false;
/**
* The main constructor for an FTPClientConfig object
*
* @param systemKey key representing system type of the server being
* connected to. See {@link #getServerSystemKey() serverSystemKey}
* If set to the empty string, then FTPClient uses the system type returned by the server.
* However this is not recommended for general use;
* the correct system type should be set if it is known.
*/
public FTPClientConfig(String systemKey) {
this.serverSystemKey = systemKey;
}
/**
* Convenience constructor mainly for use in testing.
* Constructs a UNIX configuration.
*/
public FTPClientConfig() {
this(SYST_UNIX);
}
/**
* Constructor which allows setting of the format string member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
* @param defaultDateFormatStr See
* {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* @param recentDateFormatStr See
* {@link #setRecentDateFormatStr(String) recentDateFormatStr}
* @since 3.6
*/
public FTPClientConfig(String systemKey, String defaultDateFormatStr,
String recentDateFormatStr) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.recentDateFormatStr = recentDateFormatStr;
}
/**
* Constructor which allows setting of most member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
* @param defaultDateFormatStr See
* {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* @param recentDateFormatStr See
* {@link #setRecentDateFormatStr(String) recentDateFormatStr}
* @param serverLanguageCode See
* {@link #setServerLanguageCode(String) serverLanguageCode}
* @param shortMonthNames See
* {@link #setShortMonthNames(String) shortMonthNames}
* @param serverTimeZoneId See
* {@link #setServerTimeZoneId(String) serverTimeZoneId}
*/
public FTPClientConfig(String systemKey, String defaultDateFormatStr, String recentDateFormatStr,
String serverLanguageCode, String shortMonthNames, String serverTimeZoneId) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.recentDateFormatStr = recentDateFormatStr;
this.serverLanguageCode = serverLanguageCode;
this.shortMonthNames = shortMonthNames;
this.serverTimeZoneId = serverTimeZoneId;
}
/**
* Constructor which allows setting of all member fields
*
* @param systemKey key representing system type of the server being
* connected to. See
* {@link #getServerSystemKey() serverSystemKey}
* @param defaultDateFormatStr See
* {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* @param recentDateFormatStr See
* {@link #setRecentDateFormatStr(String) recentDateFormatStr}
* @param serverLanguageCode See
* {@link #setServerLanguageCode(String) serverLanguageCode}
* @param shortMonthNames See
* {@link #setShortMonthNames(String) shortMonthNames}
* @param serverTimeZoneId See
* {@link #setServerTimeZoneId(String) serverTimeZoneId}
* @param lenientFutureDates See
* {@link #setLenientFutureDates(boolean) lenientFutureDates}
* @param saveUnparseableEntries See
* {@link #setUnparseableEntries(boolean) saveUnparseableEntries}
*/
public FTPClientConfig(String systemKey, String defaultDateFormatStr, String recentDateFormatStr,
String serverLanguageCode, String shortMonthNames, String serverTimeZoneId,
boolean lenientFutureDates, boolean saveUnparseableEntries) {
this(systemKey);
this.defaultDateFormatStr = defaultDateFormatStr;
this.lenientFutureDates = lenientFutureDates;
this.recentDateFormatStr = recentDateFormatStr;
this.saveUnparseableEntries = saveUnparseableEntries;
this.serverLanguageCode = serverLanguageCode;
this.shortMonthNames = shortMonthNames;
this.serverTimeZoneId = serverTimeZoneId;
}
// Copy constructor, intended for use by FTPClient only
FTPClientConfig(String systemKey, FTPClientConfig config) {
this.serverSystemKey = systemKey;
this.defaultDateFormatStr = config.defaultDateFormatStr;
this.lenientFutureDates = config.lenientFutureDates;
this.recentDateFormatStr = config.recentDateFormatStr;
this.saveUnparseableEntries = config.saveUnparseableEntries;
this.serverLanguageCode = config.serverLanguageCode;
this.serverTimeZoneId = config.serverTimeZoneId;
this.shortMonthNames = config.shortMonthNames;
}
/**
* Copy constructor
*
* @param config source
* @since 3.6
*/
public FTPClientConfig(FTPClientConfig config) {
this.serverSystemKey = config.serverSystemKey;
this.defaultDateFormatStr = config.defaultDateFormatStr;
this.lenientFutureDates = config.lenientFutureDates;
this.recentDateFormatStr = config.recentDateFormatStr;
this.saveUnparseableEntries = config.saveUnparseableEntries;
this.serverLanguageCode = config.serverLanguageCode;
this.serverTimeZoneId = config.serverTimeZoneId;
this.shortMonthNames = config.shortMonthNames;
}
private static final Map<String, Object> LANGUAGE_CODE_MAP = new TreeMap<String, Object>();
static {
// if there are other commonly used month name encodings which
// correspond to particular locales, please add them here.
// many locales code short names for months as all three letters
// these we handle simply.
LANGUAGE_CODE_MAP.put("en", Locale.ENGLISH);
LANGUAGE_CODE_MAP.put("de", Locale.GERMAN);
LANGUAGE_CODE_MAP.put("it", Locale.ITALIAN);
LANGUAGE_CODE_MAP.put("es", new Locale("es", "", "")); // spanish
LANGUAGE_CODE_MAP.put("pt", new Locale("pt", "", "")); // portuguese
LANGUAGE_CODE_MAP.put("da", new Locale("da", "", "")); // danish
LANGUAGE_CODE_MAP.put("sv", new Locale("sv", "", "")); // swedish
LANGUAGE_CODE_MAP.put("no", new Locale("no", "", "")); // norwegian
LANGUAGE_CODE_MAP.put("nl", new Locale("nl", "", "")); // dutch
LANGUAGE_CODE_MAP.put("ro", new Locale("ro", "", "")); // romanian
LANGUAGE_CODE_MAP.put("sq", new Locale("sq", "", "")); // albanian
LANGUAGE_CODE_MAP.put("sh", new Locale("sh", "", "")); // serbo-croatian
LANGUAGE_CODE_MAP.put("sk", new Locale("sk", "", "")); // slovak
LANGUAGE_CODE_MAP.put("sl", new Locale("sl", "", "")); // slovenian
// some don't
LANGUAGE_CODE_MAP.put("fr",
"jan|f\u00e9v|mar|avr|mai|jun|jui|ao\u00fb|sep|oct|nov|d\u00e9c"); //french
}
/**
* Getter for the serverSystemKey property. This property
* specifies the general type of server to which the client connects.
* Should be either one of the <code>FTPClientConfig.SYST_*</code> codes
* or else the fully qualified class name of a parser implementing both
* the <code>FTPFileEntryParser</code> and <code>Configurable</code>
* interfaces.
*
* @return Returns the serverSystemKey property.
*/
public String getServerSystemKey() {
return serverSystemKey;
}
/**
* getter for the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* property.
*
* @return Returns the defaultDateFormatStr property.
*/
public String getDefaultDateFormatStr() {
return defaultDateFormatStr;
}
/**
* getter for the {@link #setRecentDateFormatStr(String) recentDateFormatStr} property.
*
* @return Returns the recentDateFormatStr property.
*/
public String getRecentDateFormatStr() {
return recentDateFormatStr;
}
/**
* getter for the {@link #setServerTimeZoneId(String) serverTimeZoneId} property.
*
* @return Returns the serverTimeZoneId property.
*/
public String getServerTimeZoneId() {
return serverTimeZoneId;
}
/**
* <p>
* getter for the {@link #setShortMonthNames(String) shortMonthNames}
* property.
* </p>
*
* @return Returns the shortMonthNames.
*/
public String getShortMonthNames() {
return shortMonthNames;
}
/**
* <p>
* getter for the {@link #setServerLanguageCode(String) serverLanguageCode} property.
* </p>
*
* @return Returns the serverLanguageCode property.
*/
public String getServerLanguageCode() {
return serverLanguageCode;
}
/**
* <p>
* getter for the {@link #setLenientFutureDates(boolean) lenientFutureDates} property.
* </p>
*
* @return Returns the lenientFutureDates.
* @since 1.5
*/
public boolean isLenientFutureDates() {
return lenientFutureDates;
}
/**
* <p>
* setter for the defaultDateFormatStr property. This property
* specifies the main date format that will be used by a parser configured
* by this configuration to parse file timestamps. If this is not
* specified, such a parser will use as a default value, the most commonly
* used format which will be in as used in <code>en_US</code> locales.
* </p><p>
* This should be in the format described for
* <code>java.text.SimpleDateFormat</code>.
* property.
* </p>
*
* @param defaultDateFormatStr The defaultDateFormatStr to set.
*/
public void setDefaultDateFormatStr(String defaultDateFormatStr) {
this.defaultDateFormatStr = defaultDateFormatStr;
}
/**
* <p>
* setter for the recentDateFormatStr property. This property
* specifies a secondary date format that will be used by a parser
* configured by this configuration to parse file timestamps, typically
* those less than a year old. If this is not specified, such a parser
* will not attempt to parse using an alternate format.
* </p>
* <p>
* This is used primarily in unix-based systems.
* </p>
* <p>
* This should be in the format described for
* <code>java.text.SimpleDateFormat</code>.
* </p>
*
* @param recentDateFormatStr The recentDateFormatStr to set.
*/
public void setRecentDateFormatStr(String recentDateFormatStr) {
this.recentDateFormatStr = recentDateFormatStr;
}
/**
* <p>
* setter for the lenientFutureDates property. This boolean property
* (default: false) only has meaning when a
* {@link #setRecentDateFormatStr(String) recentDateFormatStr} property
* has been set. In that case, if this property is set true, then the
* parser, when it encounters a listing parseable with the recent date
* format, will only consider a date to belong to the previous year if
* it is more than one day in the future. This will allow all
* out-of-synch situations (whether based on "slop" - i.e. servers simply
* out of synch with one another or because of time zone differences -
* but in the latter case it is highly recommended to use the
* {@link #setServerTimeZoneId(String) serverTimeZoneId} property
* instead) to resolve correctly.
* </p><p>
* This is used primarily in unix-based systems.
* </p>
*
* @param lenientFutureDates set true to compensate for out-of-synch
* conditions.
*/
public void setLenientFutureDates(boolean lenientFutureDates) {
this.lenientFutureDates = lenientFutureDates;
}
/**
* <p>
* setter for the serverTimeZoneId property. This property
* allows a time zone to be specified corresponding to that known to be
* used by an FTP server in file listings. This might be particularly
* useful to clients such as Ant that try to use these timestamps for
* dependency checking.
* </p><p>
* This should be one of the identifiers used by
* <code>java.util.TimeZone</code> to refer to time zones, for example,
* <code>America/Chicago</code> or <code>Asia/Rangoon</code>.
* </p>
*
* @param serverTimeZoneId The serverTimeZoneId to set.
*/
public void setServerTimeZoneId(String serverTimeZoneId) {
this.serverTimeZoneId = serverTimeZoneId;
}
/**
* <p>
* setter for the shortMonthNames property.
* This property allows the user to specify a set of month names
* used by the server that is different from those that may be
* specified using the {@link #setServerLanguageCode(String) serverLanguageCode}
* property.
* </p><p>
* This should be a string containing twelve strings each composed of
* three characters, delimited by pipe (|) characters. Currently,
* only 8-bit ASCII characters are known to be supported. For example,
* a set of month names used by a hypothetical Icelandic FTP server might
* conceivably be specified as
* <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
* </p>
*
* @param shortMonthNames The value to set to the shortMonthNames property.
*/
public void setShortMonthNames(String shortMonthNames) {
this.shortMonthNames = shortMonthNames;
}
/**
* <p>
* setter for the serverLanguageCode property. This property allows
* user to specify a
* <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
* two-letter ISO-639 language code</a> that will be used to
* configure the set of month names used by the file timestamp parser.
* If neither this nor the {@link #setShortMonthNames(String) shortMonthNames}
* is specified, parsing will assume English month names, which may or
* may not be significant, depending on whether the date format(s)
* specified via {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* and/or {@link #setRecentDateFormatStr(String) recentDateFormatStr} are using
* numeric or alphabetic month names.
* </p>
* <p>If the code supplied is not supported here, <code>en_US</code>
* month names will be used. We are supporting here those language
* codes which, when a <code> java.util.Locale</code> is constucted
* using it, and a <code>java.text.SimpleDateFormat</code> is
* constructed using that Locale, the array returned by the
* SimpleDateFormat's <code>getShortMonths()</code> method consists
* solely of three 8-bit ASCII character strings. Additionally,
* languages which do not meet this requirement are included if a
* common alternative set of short month names is known to be used.
* This means that users who can tell us of additional such encodings
* may get them added to the list of supported languages by contacting
* the Apache Commons Net team.
* </p>
* <p><strong>
* Please note that this attribute will NOT be used to determine a
* locale-based date format for the language. </strong>
* Experience has shown that many if not most FTP servers outside the
* United States employ the standard <code>en_US</code> date format
* orderings of <code>MMM d yyyy</code> and <code>MMM d HH:mm</code>
* and attempting to deduce this automatically here would cause more
* problems than it would solve. The date format must be changed
* via the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr} and/or
* {@link #setRecentDateFormatStr(String) recentDateFormatStr} parameters.
* </p>
*
* @param serverLanguageCode The value to set to the serverLanguageCode property.
*/
public void setServerLanguageCode(String serverLanguageCode) {
this.serverLanguageCode = serverLanguageCode;
}
/**
* Looks up the supplied language code in the internally maintained table of
* language codes. Returns a DateFormatSymbols object configured with
* short month names corresponding to the code. If there is no corresponding
* entry in the table, the object returned will be that for
* <code>Locale.US</code>
*
* @param languageCode See {@link #setServerLanguageCode(String) serverLanguageCode}
* @return a DateFormatSymbols object configured with short month names
* corresponding to the supplied code, or with month names for
* <code>Locale.US</code> if there is no corresponding entry in the internal
* table.
*/
public static DateFormatSymbols lookupDateFormatSymbols(String languageCode) {
Object lang = LANGUAGE_CODE_MAP.get(languageCode);
if (lang != null) {
if (lang instanceof Locale) {
return new DateFormatSymbols((Locale) lang);
} else if (lang instanceof String) {
return getDateFormatSymbols((String) lang);
}
}
return new DateFormatSymbols(Locale.US);
}
/**
* Returns a DateFormatSymbols object configured with short month names
* as in the supplied string
*
* @param shortmonths This should be as described in
* {@link #setShortMonthNames(String) shortMonthNames}
* @return a DateFormatSymbols object configured with short month names
* as in the supplied string
*/
public static DateFormatSymbols getDateFormatSymbols(String shortmonths) {
String[] months = splitShortMonthString(shortmonths);
DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
dfs.setShortMonths(months);
return dfs;
}
private static String[] splitShortMonthString(String shortmonths) {
StringTokenizer st = new StringTokenizer(shortmonths, "|");
int monthcnt = st.countTokens();
if (12 != monthcnt) {
throw new IllegalArgumentException("expecting a pipe-delimited string containing 12 tokens");
}
String[] months = new String[13];
int pos = 0;
while (st.hasMoreTokens()) {
months[pos++] = st.nextToken();
}
months[pos] = "";
return months;
}
/**
* Returns a Collection of all the language codes currently supported
* by this class. See {@link #setServerLanguageCode(String) serverLanguageCode}
* for a functional descrption of language codes within this system.
*
* @return a Collection of all the language codes currently supported
* by this class
*/
public static Collection<String> getSupportedLanguageCodes() {
return LANGUAGE_CODE_MAP.keySet();
}
/**
* Allow list parsing methods to create basic FTPFile entries if parsing fails.
* <p>
* In this case, the FTPFile will contain only the unparsed entry {@link FTPFile#getRawListing()}
* and {@link FTPFile#isValid()} will return {@code false}
*
* @param saveUnparseable if true, then create FTPFile entries if parsing fails
* @since 3.4
*/
public void setUnparseableEntries(boolean saveUnparseable) {
this.saveUnparseableEntries = saveUnparseable;
}
/**
* @return true if list parsing should return FTPFile entries even for unparseable response lines
* <p>
* If true, the FTPFile for any unparseable entries will contain only the unparsed entry
* {@link FTPFile#getRawListing()} and {@link FTPFile#isValid()} will return {@code false}
* @since 3.4
*/
public boolean getUnparseableEntries() {
return this.saveUnparseableEntries;
}
}

@ -1,75 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.ftp;
/**
* @since 3.3
*/
public enum FTPCmd {
ABOR, ACCT, ALLO, APPE, CDUP, CWD, DELE, EPRT, EPSV, FEAT, HELP, LIST, MDTM, MFMT, MKD, MLSD, MLST, MODE, NLST, NOOP, PASS, PASV, PORT, PWD, QUIT, REIN, REST, RETR, RMD, RNFR, RNTO, SITE, SMNT, STAT, STOR, STOU, STRU, SYST, TYPE, USER,;
// Aliases
public static final FTPCmd ABORT = ABOR;
public static final FTPCmd ACCOUNT = ACCT;
public static final FTPCmd ALLOCATE = ALLO;
public static final FTPCmd APPEND = APPE;
public static final FTPCmd CHANGE_TO_PARENT_DIRECTORY = CDUP;
public static final FTPCmd CHANGE_WORKING_DIRECTORY = CWD;
public static final FTPCmd DATA_PORT = PORT;
public static final FTPCmd DELETE = DELE;
public static final FTPCmd FEATURES = FEAT;
public static final FTPCmd FILE_STRUCTURE = STRU;
public static final FTPCmd GET_MOD_TIME = MDTM;
public static final FTPCmd LOGOUT = QUIT;
public static final FTPCmd MAKE_DIRECTORY = MKD;
public static final FTPCmd MOD_TIME = MDTM;
public static final FTPCmd NAME_LIST = NLST;
public static final FTPCmd PASSIVE = PASV;
public static final FTPCmd PASSWORD = PASS;
public static final FTPCmd PRINT_WORKING_DIRECTORY = PWD;
public static final FTPCmd REINITIALIZE = REIN;
public static final FTPCmd REMOVE_DIRECTORY = RMD;
public static final FTPCmd RENAME_FROM = RNFR;
public static final FTPCmd RENAME_TO = RNTO;
public static final FTPCmd REPRESENTATION_TYPE = TYPE;
public static final FTPCmd RESTART = REST;
public static final FTPCmd RETRIEVE = RETR;
public static final FTPCmd SET_MOD_TIME = MFMT;
public static final FTPCmd SITE_PARAMETERS = SITE;
public static final FTPCmd STATUS = STAT;
public static final FTPCmd STORE = STOR;
public static final FTPCmd STORE_UNIQUE = STOU;
public static final FTPCmd STRUCTURE_MOUNT = SMNT;
public static final FTPCmd SYSTEM = SYST;
public static final FTPCmd TRANSFER_MODE = MODE;
public static final FTPCmd USERNAME = USER;
/**
* Retrieve the FTP protocol command string corresponding to a specified
* command code.
*
* @return The FTP protcol command string corresponding to a specified
* command code.
*/
public final String getCommand() {
return this.name();
}
}

@ -1,170 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
/**
* FTPCommand stores a set of constants for FTP command codes. To interpret
* the meaning of the codes, familiarity with RFC 959 is assumed.
* The mnemonic constant names are transcriptions from the code descriptions
* of RFC 959. For those who think in terms of the actual FTP commands,
* a set of constants such as {@link #USER USER } are provided
* where the constant name is the same as the FTP command.
*
* @deprecated use {@link FTPCmd} instead
*/
@Deprecated public final class FTPCommand {
public static final int USER = 0;
public static final int PASS = 1;
public static final int ACCT = 2;
public static final int CWD = 3;
public static final int CDUP = 4;
public static final int SMNT = 5;
public static final int REIN = 6;
public static final int QUIT = 7;
public static final int PORT = 8;
public static final int PASV = 9;
public static final int TYPE = 10;
public static final int STRU = 11;
public static final int MODE = 12;
public static final int RETR = 13;
public static final int STOR = 14;
public static final int STOU = 15;
public static final int APPE = 16;
public static final int ALLO = 17;
public static final int REST = 18;
public static final int RNFR = 19;
public static final int RNTO = 20;
public static final int ABOR = 21;
public static final int DELE = 22;
public static final int RMD = 23;
public static final int MKD = 24;
public static final int PWD = 25;
public static final int LIST = 26;
public static final int NLST = 27;
public static final int SITE = 28;
public static final int SYST = 29;
public static final int STAT = 30;
public static final int HELP = 31;
public static final int NOOP = 32;
/** @since 2.0 */
public static final int MDTM = 33;
/** @since 2.2 */
public static final int FEAT = 34;
/** @since 2.2 */
public static final int MFMT = 35;
/** @since 2.2 */
public static final int EPSV = 36;
/** @since 2.2 */
public static final int EPRT = 37;
/**
* Machine parseable list for a directory
*
* @since 3.0
*/
public static final int MLSD = 38;
/**
* Machine parseable list for a single file
*
* @since 3.0
*/
public static final int MLST = 39;
// Must agree with final entry above; used to check array size
private static final int LAST = MLST;
public static final int USERNAME = USER;
public static final int PASSWORD = PASS;
public static final int ACCOUNT = ACCT;
public static final int CHANGE_WORKING_DIRECTORY = CWD;
public static final int CHANGE_TO_PARENT_DIRECTORY = CDUP;
public static final int STRUCTURE_MOUNT = SMNT;
public static final int REINITIALIZE = REIN;
public static final int LOGOUT = QUIT;
public static final int DATA_PORT = PORT;
public static final int PASSIVE = PASV;
public static final int REPRESENTATION_TYPE = TYPE;
public static final int FILE_STRUCTURE = STRU;
public static final int TRANSFER_MODE = MODE;
public static final int RETRIEVE = RETR;
public static final int STORE = STOR;
public static final int STORE_UNIQUE = STOU;
public static final int APPEND = APPE;
public static final int ALLOCATE = ALLO;
public static final int RESTART = REST;
public static final int RENAME_FROM = RNFR;
public static final int RENAME_TO = RNTO;
public static final int ABORT = ABOR;
public static final int DELETE = DELE;
public static final int REMOVE_DIRECTORY = RMD;
public static final int MAKE_DIRECTORY = MKD;
public static final int PRINT_WORKING_DIRECTORY = PWD;
// public static final int LIST = LIST;
public static final int NAME_LIST = NLST;
public static final int SITE_PARAMETERS = SITE;
public static final int SYSTEM = SYST;
public static final int STATUS = STAT;
//public static final int HELP = HELP;
//public static final int NOOP = NOOP;
/** @since 2.0 */
public static final int MOD_TIME = MDTM;
/** @since 2.2 */
public static final int FEATURES = FEAT;
/** @since 2.2 */
public static final int GET_MOD_TIME = MDTM;
/** @since 2.2 */
public static final int SET_MOD_TIME = MFMT;
// Cannot be instantiated
private FTPCommand() {
}
private static final String[] _commands = {
"USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT", "PASV", "TYPE", "STRU",
"MODE", "RETR", "STOR", "STOU", "APPE", "ALLO", "REST", "RNFR", "RNTO", "ABOR", "DELE", "RMD",
"MKD", "PWD", "LIST", "NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "FEAT", "MFMT",
"EPSV", "EPRT", "MLSD", "MLST"
};
// default access needed for Unit test
static void checkArray() {
int expectedLength = LAST + 1;
if (_commands.length != expectedLength) {
throw new RuntimeException("Incorrect _commands array. Should have length "
+ expectedLength
+ " found "
+ _commands.length);
}
}
/**
* Retrieve the FTP protocol command string corresponding to a specified
* command code.
*
* @param command The command code.
* @return The FTP protcol command string corresponding to a specified
* command code.
*/
public static final String getCommand(int command) {
return _commands[command];
}
}

@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.IOException;
/***
* FTPConnectionClosedException is used to indicate the premature or
* unexpected closing of an FTP connection resulting from a
* {@link FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
* response (FTP reply code 421) to a
* failed FTP command. This exception is derived from IOException and
* therefore may be caught either as an IOException or specifically as an
* FTPConnectionClosedException.
*
* @see FTP
* @see FTPClient
***/
public class FTPConnectionClosedException extends IOException {
private static final long serialVersionUID = 3500547241659379952L;
/*** Constructs a FTPConnectionClosedException with no message ***/
public FTPConnectionClosedException() {
super();
}
/***
* Constructs a FTPConnectionClosedException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public FTPConnectionClosedException(String message) {
super(message);
}
}

@ -1,493 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.Formatter;
import java.util.TimeZone;
/***
* The FTPFile class is used to represent information about files stored
* on an FTP server.
*
* @see FTPFileEntryParser
* @see FTPClient#listFiles
***/
public class FTPFile implements Serializable {
private static final long serialVersionUID = 9010790363003271996L;
/** A constant indicating an FTPFile is a file. ***/
public static final int FILE_TYPE = 0;
/** A constant indicating an FTPFile is a directory. ***/
public static final int DIRECTORY_TYPE = 1;
/** A constant indicating an FTPFile is a symbolic link. ***/
public static final int SYMBOLIC_LINK_TYPE = 2;
/** A constant indicating an FTPFile is of unknown type. ***/
public static final int UNKNOWN_TYPE = 3;
/** A constant indicating user access permissions. ***/
public static final int USER_ACCESS = 0;
/** A constant indicating group access permissions. ***/
public static final int GROUP_ACCESS = 1;
/** A constant indicating world access permissions. ***/
public static final int WORLD_ACCESS = 2;
/** A constant indicating file/directory read permission. ***/
public static final int READ_PERMISSION = 0;
/** A constant indicating file/directory write permission. ***/
public static final int WRITE_PERMISSION = 1;
/**
* A constant indicating file execute permission or directory listing
* permission.
***/
public static final int EXECUTE_PERMISSION = 2;
private int _type, _hardLinkCount;
private long _size;
private String _rawListing, _user, _group, _name, _link;
private Calendar _date;
// If this is null, then list entry parsing failed
private final boolean[] _permissions[]; // e.g. _permissions[USER_ACCESS][READ_PERMISSION]
/*** Creates an empty FTPFile. ***/
public FTPFile() {
_permissions = new boolean[3][3];
_type = UNKNOWN_TYPE;
// init these to values that do not occur in listings
// so can distinguish which fields are unset
_hardLinkCount = 0; // 0 is invalid as a link count
_size = -1; // 0 is valid, so use -1
_user = "";
_group = "";
_date = null;
_name = null;
}
/**
* Constructor for use by {@link FTPListParseEngine} only.
* Used to create FTPFile entries for failed parses
*
* @param rawListing line that could not be parsed.
* @since 3.4
*/
FTPFile(String rawListing) {
_permissions = null; // flag that entry is invalid
_rawListing = rawListing;
_type = UNKNOWN_TYPE;
// init these to values that do not occur in listings
// so can distinguish which fields are unset
_hardLinkCount = 0; // 0 is invalid as a link count
_size = -1; // 0 is valid, so use -1
_user = "";
_group = "";
_date = null;
_name = null;
}
/***
* Set the original FTP server raw listing from which the FTPFile was
* created.
*
* @param rawListing The raw FTP server listing.
***/
public void setRawListing(String rawListing) {
_rawListing = rawListing;
}
/***
* Get the original FTP server raw listing used to initialize the FTPFile.
*
* @return The original FTP server raw listing used to initialize the
* FTPFile.
***/
public String getRawListing() {
return _rawListing;
}
/***
* Determine if the file is a directory.
*
* @return True if the file is of type <code>DIRECTORY_TYPE</code>, false if
* not.
***/
public boolean isDirectory() {
return (_type == DIRECTORY_TYPE);
}
/***
* Determine if the file is a regular file.
*
* @return True if the file is of type <code>FILE_TYPE</code>, false if
* not.
***/
public boolean isFile() {
return (_type == FILE_TYPE);
}
/***
* Determine if the file is a symbolic link.
*
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isSymbolicLink() {
return (_type == SYMBOLIC_LINK_TYPE);
}
/***
* Determine if the type of the file is unknown.
*
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isUnknown() {
return (_type == UNKNOWN_TYPE);
}
/**
* Used to indicate whether an entry is valid or not.
* If the entry is invalid, only the {@link #getRawListing()} method will be useful.
* Other methods may fail.
*
* Used in conjunction with list parsing that preseverves entries that failed to parse.
*
* @return true if the entry is valid
* @see FTPClientConfig#setUnparseableEntries(boolean)
* @since 3.4
*/
public boolean isValid() {
return (_permissions != null);
}
/***
* Set the type of the file (<code>DIRECTORY_TYPE</code>,
* <code>FILE_TYPE</code>, etc.).
*
* @param type The integer code representing the type of the file.
***/
public void setType(int type) {
_type = type;
}
/***
* Return the type of the file (one of the <code>_TYPE</code> constants),
* e.g., if it is a directory, a regular file, or a symbolic link.
*
* @return The type of the file.
***/
public int getType() {
return _type;
}
/***
* Set the name of the file.
*
* @param name The name of the file.
***/
public void setName(String name) {
_name = name;
}
/***
* Return the name of the file.
*
* @return The name of the file.
***/
public String getName() {
return _name;
}
/**
* Set the file size in bytes.
*
* @param size The file size in bytes.
*/
public void setSize(long size) {
_size = size;
}
/***
* Return the file size in bytes.
*
* @return The file size in bytes.
***/
public long getSize() {
return _size;
}
/***
* Set the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @param links The number of hard links to this file.
***/
public void setHardLinkCount(int links) {
_hardLinkCount = links;
}
/***
* Return the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @return The number of hard links to this file.
***/
public int getHardLinkCount() {
return _hardLinkCount;
}
/***
* Set the name of the group owning the file. This may be
* a string representation of the group number.
*
* @param group The name of the group owning the file.
***/
public void setGroup(String group) {
_group = group;
}
/***
* Returns the name of the group owning the file. Sometimes this will be
* a string representation of the group number.
*
* @return The name of the group owning the file.
***/
public String getGroup() {
return _group;
}
/***
* Set the name of the user owning the file. This may be
* a string representation of the user number;
*
* @param user The name of the user owning the file.
***/
public void setUser(String user) {
_user = user;
}
/***
* Returns the name of the user owning the file. Sometimes this will be
* a string representation of the user number.
*
* @return The name of the user owning the file.
***/
public String getUser() {
return _user;
}
/***
* If the FTPFile is a symbolic link, use this method to set the name of the
* file being pointed to by the symbolic link.
*
* @param link The file pointed to by the symbolic link.
***/
public void setLink(String link) {
_link = link;
}
/***
* If the FTPFile is a symbolic link, this method returns the name of the
* file being pointed to by the symbolic link. Otherwise it returns null.
*
* @return The file pointed to by the symbolic link (null if the FTPFile
* is not a symbolic link).
***/
public String getLink() {
return _link;
}
/***
* Set the file timestamp. This usually the last modification time.
* The parameter is not cloned, so do not alter its value after calling
* this method.
*
* @param date A Calendar instance representing the file timestamp.
***/
public void setTimestamp(Calendar date) {
_date = date;
}
/***
* Returns the file timestamp. This usually the last modification time.
*
* @return A Calendar instance representing the file timestamp.
***/
public Calendar getTimestamp() {
return _date;
}
/***
* Set if the given access group (one of the <code> _ACCESS </code>
* constants) has the given access permission (one of the
* <code> _PERMISSION </code> constants) to the file.
*
* @param access The access group (one of the <code> _ACCESS </code>
* constants)
* @param permission The access permission (one of the
* <code> _PERMISSION </code> constants)
* @param value True if permission is allowed, false if not.
* @throws ArrayIndexOutOfBoundsException if either of the parameters is out of range
***/
public void setPermission(int access, int permission, boolean value) {
_permissions[access][permission] = value;
}
/***
* Determines if the given access group (one of the <code> _ACCESS </code>
* constants) has the given access permission (one of the
* <code> _PERMISSION </code> constants) to the file.
*
* @param access The access group (one of the <code> _ACCESS </code>
* constants)
* @param permission The access permission (one of the
* <code> _PERMISSION </code> constants)
* @throws ArrayIndexOutOfBoundsException if either of the parameters is out of range
* @return true if {@link #isValid()} is {@code true &&} the associated permission is set;
* {@code false} otherwise.
***/
public boolean hasPermission(int access, int permission) {
if (_permissions == null) {
return false;
}
return _permissions[access][permission];
}
/***
* Returns a string representation of the FTPFile information.
*
* @return A string representation of the FTPFile information.
*/
@Override public String toString() {
return getRawListing();
}
/***
* Returns a string representation of the FTPFile information.
* This currently mimics the Unix listing format.
* This method uses the timezone of the Calendar entry, which is
* the server time zone (if one was provided) otherwise it is
* the local time zone.
* <p>
* Note: if the instance is not valid {@link #isValid()}, no useful
* information can be returned. In this case, use {@link #getRawListing()}
* instead.
*
* @return A string representation of the FTPFile information.
* @since 3.0
*/
public String toFormattedString() {
return toFormattedString(null);
}
/**
* Returns a string representation of the FTPFile information.
* This currently mimics the Unix listing format.
* This method allows the Calendar time zone to be overridden.
* <p>
* Note: if the instance is not valid {@link #isValid()}, no useful
* information can be returned. In this case, use {@link #getRawListing()}
* instead.
*
* @param timezone the timezone to use for displaying the time stamp
* If {@code null}, then use the Calendar entry timezone
* @return A string representation of the FTPFile information.
* @since 3.4
*/
public String toFormattedString(final String timezone) {
if (!isValid()) {
return "[Invalid: could not parse file entry]";
}
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
sb.append(formatType());
sb.append(permissionToString(USER_ACCESS));
sb.append(permissionToString(GROUP_ACCESS));
sb.append(permissionToString(WORLD_ACCESS));
fmt.format(" %4d", Integer.valueOf(getHardLinkCount()));
fmt.format(" %-8s %-8s", getUser(), getGroup());
fmt.format(" %8d", Long.valueOf(getSize()));
Calendar timestamp = getTimestamp();
if (timestamp != null) {
if (timezone != null) {
TimeZone newZone = TimeZone.getTimeZone(timezone);
if (!newZone.equals(timestamp.getTimeZone())) {
Date original = timestamp.getTime();
Calendar newStamp = Calendar.getInstance(newZone);
newStamp.setTime(original);
timestamp = newStamp;
}
}
fmt.format(" %1$tY-%1$tm-%1$td", timestamp);
// Only display time units if they are present
if (timestamp.isSet(Calendar.HOUR_OF_DAY)) {
fmt.format(" %1$tH", timestamp);
if (timestamp.isSet(Calendar.MINUTE)) {
fmt.format(":%1$tM", timestamp);
if (timestamp.isSet(Calendar.SECOND)) {
fmt.format(":%1$tS", timestamp);
if (timestamp.isSet(Calendar.MILLISECOND)) {
fmt.format(".%1$tL", timestamp);
}
}
}
fmt.format(" %1$tZ", timestamp);
}
}
sb.append(' ');
sb.append(getName());
fmt.close();
return sb.toString();
}
private char formatType() {
switch (_type) {
case FILE_TYPE:
return '-';
case DIRECTORY_TYPE:
return 'd';
case SYMBOLIC_LINK_TYPE:
return 'l';
default:
return '?';
}
}
private String permissionToString(int access) {
StringBuilder sb = new StringBuilder();
if (hasPermission(access, READ_PERMISSION)) {
sb.append('r');
} else {
sb.append('-');
}
if (hasPermission(access, WRITE_PERMISSION)) {
sb.append('w');
} else {
sb.append('-');
}
if (hasPermission(access, EXECUTE_PERMISSION)) {
sb.append('x');
} else {
sb.append('-');
}
return sb.toString();
}
}

@ -1,129 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
/**
* FTPFileEntryParser defines the interface for parsing a single FTP file
* listing and converting that information into an
* {@link FTPFile} instance.
* Sometimes you will want to parse unusual listing formats, in which
* case you would create your own implementation of FTPFileEntryParser and
* if necessary, subclass FTPFile.
* <p>
* Here are some examples showing how to use one of the classes that
* implement this interface.
* <p>
*
* The first example uses the <code>FTPClient.listFiles()</code>
* API to pull the whole list from the subfolder <code>subfolder</code> in
* one call, attempting to automatically detect the parser type. This
* method, without a parserKey parameter, indicates that autodection should
* be used.
*
* <pre>
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles("subfolder");
* </pre>
*
* The second example uses the <code>FTPClient.listFiles()</code>
* API to pull the whole list from the current working directory in one call,
* but specifying by classname the parser to be used. For this particular
* parser class, this approach is necessary since there is no way to
* autodetect this server type.
*
* <pre>
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles(
* "org.apache.commons.net.ftp.parser.EnterpriseUnixFTPFileEntryParser",
* ".");
* </pre>
*
* The third example uses the <code>FTPClient.listFiles()</code>
* API to pull a single file listing in an arbitrary directory in one call,
* specifying by KEY the parser to be used, in this case, VMS.
*
* <pre>
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles("VMS", "subfolder/foo.java");
* </pre>
*
* For an alternative approach, see the {@link FTPListParseEngine} class
* which provides iterative access.
*
* @version $Id: FTPFileEntryParser.java 1747119 2016-06-07 02:22:24Z ggregory $
* @see FTPFile
* @see FTPClient#listFiles()
*/
public interface FTPFileEntryParser {
/**
* Parses a line of an FTP server file listing and converts it into a usable
* format in the form of an <code> FTPFile </code> instance. If the
* file listing line doesn't describe a file, <code> null </code> should be
* returned, otherwise a <code> FTPFile </code> instance representing the
* files in the directory is returned.
*
* @param listEntry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
FTPFile parseFTPEntry(String listEntry);
/**
* Reads the next entry using the supplied BufferedReader object up to
* whatever delemits one entry from the next. Implementors must define
* this for the particular ftp system being parsed. In many but not all
* cases, this can be defined simply by calling BufferedReader.readLine().
*
* @param reader The BufferedReader object from which entries are to be
* read.
* @return A string representing the next ftp entry or null if none found.
* @throws IOException thrown on any IO Error reading from the reader.
*/
String readNextEntry(BufferedReader reader) throws IOException;
/**
* This method is a hook for those implementors (such as
* VMSVersioningFTPEntryParser, and possibly others) which need to
* perform some action upon the FTPFileList after it has been created
* from the server stream, but before any clients see the list.
*
* The default implementation can be a no-op.
*
* @param original Original list after it has been created from the server stream
* @return Original list as processed by this method.
*/
List<String> preParse(List<String> original);
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
/**
* This abstract class implements both the older FTPFileListParser and
* newer FTPFileEntryParser interfaces with default functionality.
* All the classes in the parser subpackage inherit from this.
*/
public abstract class FTPFileEntryParserImpl implements FTPFileEntryParser {
/**
* The constructor for a FTPFileEntryParserImpl object.
*/
public FTPFileEntryParserImpl() {
}
/**
* Reads the next entry using the supplied BufferedReader object up to
* whatever delimits one entry from the next. This default implementation
* simply calls BufferedReader.readLine().
*
* @param reader The BufferedReader object from which entries are to be
* read.
* @return A string representing the next ftp entry or null if none found.
* @throws IOException thrown on any IO Error reading from the reader.
*/
@Override public String readNextEntry(BufferedReader reader) throws IOException {
return reader.readLine();
}
/**
* This method is a hook for those implementors (such as
* VMSVersioningFTPEntryParser, and possibly others) which need to
* perform some action upon the FTPFileList after it has been created
* from the server stream, but before any clients see the list.
*
* This default implementation does nothing.
*
* @param original Original list after it has been created from the server stream
* @return <code>original</code> unmodified.
*/
@Override public List<String> preParse(List<String> original) {
return original;
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.ftp;
/**
* Perform filtering on FTPFile entries.
*
* @since 2.2
*/
public interface FTPFileFilter {
/**
* Checks if an FTPFile entry should be included or not.
*
* @param file entry to be checked for inclusion. May be <code>null</code>.
* @return <code>true</code> if the file is to be included, <code>false</code> otherwise
*/
public boolean accept(FTPFile file);
}

@ -1,54 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package aria.apache.commons.net.ftp;
/**
* Implements some simple FTPFileFilter classes.
*
* @since 2.2
*/
public class FTPFileFilters {
/**
* Accepts all FTPFile entries, including null.
*/
public static final FTPFileFilter ALL = new FTPFileFilter() {
@Override public boolean accept(FTPFile file) {
return true;
}
};
/**
* Accepts all non-null FTPFile entries.
*/
public static final FTPFileFilter NON_NULL = new FTPFileFilter() {
@Override public boolean accept(FTPFile file) {
return file != null;
}
};
/**
* Accepts all (non-null) FTPFile directory entries.
*/
public static final FTPFileFilter DIRECTORIES = new FTPFileFilter() {
@Override public boolean accept(FTPFile file) {
return file != null && file.isDirectory();
}
};
}

@ -1,194 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.Inet6Address;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import aria.apache.commons.net.util.Base64;
/**
* Experimental attempt at FTP client that tunnels over an HTTP proxy connection.
*
* @since 2.2
*/
public class FTPHTTPClient extends FTPClient {
private final String proxyHost;
private final int proxyPort;
private final String proxyUsername;
private final String proxyPassword;
private static final byte[] CRLF = { '\r', '\n' };
private final Base64 base64 = new Base64();
private String tunnelHost; // Save the host when setting up a tunnel (needed for EPSV)
public FTPHTTPClient(String proxyHost, int proxyPort, String proxyUser, String proxyPass) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
this.proxyUsername = proxyUser;
this.proxyPassword = proxyPass;
this.tunnelHost = null;
}
public FTPHTTPClient(String proxyHost, int proxyPort) {
this(proxyHost, proxyPort, null, null);
}
/**
* {@inheritDoc}
*
* @throws IllegalStateException if connection mode is not passive
* @deprecated (3.3) Use {@link FTPClient#_openDataConnection_(FTPCmd, String)} instead
*/
// Kept to maintain binary compatibility
// Not strictly necessary, but Clirr complains even though there is a super-impl
@Override @Deprecated protected Socket _openDataConnection_(int command, String arg)
throws IOException {
return super._openDataConnection_(command, arg);
}
/**
* {@inheritDoc}
*
* @throws IllegalStateException if connection mode is not passive
* @since 3.1
*/
@Override protected Socket _openDataConnection_(String command, String arg) throws IOException {
//Force local passive mode, active mode not supported by through proxy
if (getDataConnectionMode() != PASSIVE_LOCAL_DATA_CONNECTION_MODE) {
throw new IllegalStateException("Only passive connection mode supported");
}
final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;
String passiveHost = null;
boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE) {
_parseExtendedPassiveModeReply(_replyLines.get(0));
passiveHost = this.tunnelHost;
} else {
if (isInet6Address) {
return null; // Must use EPSV for IPV6
}
// If EPSV failed on IPV4, revert to PASV
if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
return null;
}
_parsePassiveModeReply(_replyLines.get(0));
passiveHost = this.getPassiveHost();
}
Socket socket = _socketFactory_.createSocket(proxyHost, proxyPort);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
tunnelHandshake(passiveHost, this.getPassivePort(), is, os);
if ((getRestartOffset() > 0) && !restart(getRestartOffset())) {
socket.close();
return null;
}
if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) {
socket.close();
return null;
}
return socket;
}
@Override public void connect(String host, int port) throws SocketException, IOException {
_socket_ = _socketFactory_.createSocket(proxyHost, proxyPort);
_input_ = _socket_.getInputStream();
_output_ = _socket_.getOutputStream();
Reader socketIsReader;
try {
socketIsReader = tunnelHandshake(host, port, _input_, _output_);
} catch (Exception e) {
IOException ioe = new IOException("Could not connect to " + host + " using port " + port);
ioe.initCause(e);
throw ioe;
}
super._connectAction_(socketIsReader);
}
private BufferedReader tunnelHandshake(String host, int port, InputStream input,
OutputStream output) throws IOException, UnsupportedEncodingException {
final String connectString = "CONNECT " + host + ":" + port + " HTTP/1.1";
final String hostString = "Host: " + host + ":" + port;
this.tunnelHost = host;
output.write(connectString.getBytes("UTF-8")); // TODO what is the correct encoding?
output.write(CRLF);
output.write(hostString.getBytes("UTF-8"));
output.write(CRLF);
if (proxyUsername != null && proxyPassword != null) {
final String auth = proxyUsername + ":" + proxyPassword;
final String header =
"Proxy-Authorization: Basic " + base64.encodeToString(auth.getBytes("UTF-8"));
output.write(header.getBytes("UTF-8"));
}
output.write(CRLF);
List<String> response = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(input, getCharset()));
for (String line = reader.readLine(); line != null && line.length() > 0;
line = reader.readLine()) {
response.add(line);
}
int size = response.size();
if (size == 0) {
throw new IOException("No response from proxy");
}
String code = null;
String resp = response.get(0);
if (resp.startsWith("HTTP/") && resp.length() >= 12) {
code = resp.substring(9, 12);
} else {
throw new IOException("Invalid response from proxy: " + resp);
}
if (!"200".equals(code)) {
StringBuilder msg = new StringBuilder();
msg.append("HTTPTunnelConnector: connection failed\r\n");
msg.append("Response received from the proxy:\r\n");
for (String line : response) {
msg.append(line);
msg.append("\r\n");
}
throw new IOException(msg.toString());
}
return reader;
}
}

@ -1,311 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import aria.apache.commons.net.util.Charsets;
/**
* This class handles the entire process of parsing a listing of
* file entries from the server.
* <p>
* This object defines a two-part parsing mechanism.
* <p>
* The first part is comprised of reading the raw input into an internal
* list of strings. Every item in this list corresponds to an actual
* file. All extraneous matter emitted by the server will have been
* removed by the end of this phase. This is accomplished in conjunction
* with the FTPFileEntryParser associated with this engine, by calling
* its methods <code>readNextEntry()</code> - which handles the issue of
* what delimits one entry from another, usually but not always a line
* feed and <code>preParse()</code> - which handles removal of
* extraneous matter such as the preliminary lines of a listing, removal
* of duplicates on versioning systems, etc.
* <p>
* The second part is composed of the actual parsing, again in conjunction
* with the particular parser used by this engine. This is controlled
* by an iterator over the internal list of strings. This may be done
* either in block mode, by calling the <code>getNext()</code> and
* <code>getPrevious()</code> methods to provide "paged" output of less
* than the whole list at one time, or by calling the
* <code>getFiles()</code> method to return the entire list.
* <p>
* Examples:
* <p>
* Paged access:
* <pre>
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine = f.initiateListParsing(directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
* </pre>
* <p>
* For unpaged access, simply use FTPClient.listFiles(). That method
* uses this class transparently.
*
* @version $Id: FTPListParseEngine.java 1747119 2016-06-07 02:22:24Z ggregory $
*/
public class FTPListParseEngine {
private List<String> entries = new LinkedList<String>();
private ListIterator<String> _internalIterator = entries.listIterator();
private final FTPFileEntryParser parser;
// Should invalid files (parse failures) be allowed?
private final boolean saveUnparseableEntries;
public FTPListParseEngine(FTPFileEntryParser parser) {
this(parser, null);
}
/**
* Intended for use by FTPClient only
*
* @since 3.4
*/
FTPListParseEngine(FTPFileEntryParser parser, FTPClientConfig configuration) {
this.parser = parser;
if (configuration != null) {
this.saveUnparseableEntries = configuration.getUnparseableEntries();
} else {
this.saveUnparseableEntries = false;
}
}
/**
* handle the initial reading and preparsing of the list returned by
* the server. After this method has completed, this object will contain
* a list of unparsed entries (Strings) each referring to a unique file
* on the server.
*
* @param stream input stream provided by the server socket.
* @param encoding the encoding to be used for reading the stream
* @throws IOException thrown on any failure to read from the sever.
*/
public void readServerList(InputStream stream, String encoding) throws IOException {
this.entries = new LinkedList<String>();
readStream(stream, encoding);
this.parser.preParse(this.entries);
resetIterator();
}
/**
* Internal method for reading the input into the <code>entries</code> list.
* After this method has completed, <code>entries</code> will contain a
* collection of entries (as defined by
* <code>FTPFileEntryParser.readNextEntry()</code>), but this may contain
* various non-entry preliminary lines from the server output, duplicates,
* and other data that will not be part of the final listing.
*
* @param stream The socket stream on which the input will be read.
* @param encoding The encoding to use.
* @throws IOException thrown on any failure to read the stream
*/
private void readStream(InputStream stream, String encoding) throws IOException {
BufferedReader reader =
new BufferedReader(new InputStreamReader(stream, Charsets.toCharset(encoding)));
String line = this.parser.readNextEntry(reader);
while (line != null) {
this.entries.add(line);
line = this.parser.readNextEntry(reader);
}
reader.close();
}
/**
* Returns an array of at most <code>quantityRequested</code> FTPFile
* objects starting at this object's internal iterator's current position.
* If fewer than <code>quantityRequested</code> such
* elements are available, the returned array will have a length equal
* to the number of entries at and after after the current position.
* If no such entries are found, this array will have a length of 0.
*
* After this method is called this object's internal iterator is advanced
* by a number of positions equal to the size of the array returned.
*
* @param quantityRequested the maximum number of entries we want to get.
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
* and after its current position.
* <p><b>
* NOTE:</b> This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
*/
public FTPFile[] getNext(int quantityRequested) {
List<FTPFile> tmpResults = new LinkedList<FTPFile>();
int count = quantityRequested;
while (count > 0 && this._internalIterator.hasNext()) {
String entry = this._internalIterator.next();
FTPFile temp = this.parser.parseFTPEntry(entry);
if (temp == null && saveUnparseableEntries) {
temp = new FTPFile(entry);
}
tmpResults.add(temp);
count--;
}
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
}
/**
* Returns an array of at most <code>quantityRequested</code> FTPFile
* objects starting at this object's internal iterator's current position,
* and working back toward the beginning.
*
* If fewer than <code>quantityRequested</code> such
* elements are available, the returned array will have a length equal
* to the number of entries at and after after the current position.
* If no such entries are found, this array will have a length of 0.
*
* After this method is called this object's internal iterator is moved
* back by a number of positions equal to the size of the array returned.
*
* @param quantityRequested the maximum number of entries we want to get.
* @return an array of at most <code>quantityRequested</code> FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
* and after its current position. This array will be in the same order
* as the underlying list (not reversed).
* <p><b>
* NOTE:</b> This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
*/
public FTPFile[] getPrevious(int quantityRequested) {
List<FTPFile> tmpResults = new LinkedList<FTPFile>();
int count = quantityRequested;
while (count > 0 && this._internalIterator.hasPrevious()) {
String entry = this._internalIterator.previous();
FTPFile temp = this.parser.parseFTPEntry(entry);
if (temp == null && saveUnparseableEntries) {
temp = new FTPFile(entry);
}
tmpResults.add(0, temp);
count--;
}
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
}
/**
* Returns an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
*
* @return an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* None of the entries will be null
* @throws IOException - not ever thrown, may be removed in a later release
*/
public FTPFile[] getFiles() throws IOException // TODO remove; not actually thrown
{
return getFiles(FTPFileFilters.NON_NULL);
}
/**
* Returns an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* The files are filtered before being added to the array.
*
* @param filter FTPFileFilter, must not be <code>null</code>.
* @return an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* <p><b>
* NOTE:</b> This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it, or use the
* a filter such as {@link FTPFileFilters#NON_NULL} which does not
* allow null entries.
* @throws IOException - not ever thrown, may be removed in a later release
* @since 2.2
*/
public FTPFile[] getFiles(FTPFileFilter filter)
throws IOException // TODO remove; not actually thrown
{
List<FTPFile> tmpResults = new ArrayList<FTPFile>();
Iterator<String> iter = this.entries.iterator();
while (iter.hasNext()) {
String entry = iter.next();
FTPFile temp = this.parser.parseFTPEntry(entry);
if (temp == null && saveUnparseableEntries) {
temp = new FTPFile(entry);
}
if (filter.accept(temp)) {
tmpResults.add(temp);
}
}
return tmpResults.toArray(new FTPFile[tmpResults.size()]);
}
/**
* convenience method to allow clients to know whether this object's
* internal iterator's current position is at the end of the list.
*
* @return true if internal iterator is not at end of list, false
* otherwise.
*/
public boolean hasNext() {
return _internalIterator.hasNext();
}
/**
* convenience method to allow clients to know whether this object's
* internal iterator's current position is at the beginning of the list.
*
* @return true if internal iterator is not at beginning of list, false
* otherwise.
*/
public boolean hasPrevious() {
return _internalIterator.hasPrevious();
}
/**
* resets this object's internal iterator to the beginning of the list.
*/
public void resetIterator() {
this._internalIterator = this.entries.listIterator();
}
// DEPRECATED METHODS - for API compatibility only - DO NOT USE
/**
* Do not use.
*
* @param stream the stream from which to read
* @throws IOException on error
* @deprecated use {@link #readServerList(InputStream, String)} instead
*/
@Deprecated public void readServerList(InputStream stream) throws IOException {
readServerList(stream, null);
}
}

@ -1,193 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
/***
* FTPReply stores a set of constants for FTP reply codes. To interpret
* the meaning of the codes, familiarity with RFC 959 is assumed.
* The mnemonic constant names are transcriptions from the code descriptions
* of RFC 959.
* <p>
* TODO replace with an enum
***/
public final class FTPReply {
public static final int RESTART_MARKER = 110;
public static final int SERVICE_NOT_READY = 120;
public static final int DATA_CONNECTION_ALREADY_OPEN = 125;
public static final int FILE_STATUS_OK = 150;
public static final int COMMAND_OK = 200;
public static final int COMMAND_IS_SUPERFLUOUS = 202;
public static final int SYSTEM_STATUS = 211;
public static final int DIRECTORY_STATUS = 212;
public static final int FILE_STATUS = 213;
public static final int HELP_MESSAGE = 214;
public static final int NAME_SYSTEM_TYPE = 215;
public static final int SERVICE_READY = 220;
public static final int SERVICE_CLOSING_CONTROL_CONNECTION = 221;
public static final int DATA_CONNECTION_OPEN = 225;
public static final int CLOSING_DATA_CONNECTION = 226;
public static final int ENTERING_PASSIVE_MODE = 227;
/** @since 2.2 */
public static final int ENTERING_EPSV_MODE = 229;
public static final int USER_LOGGED_IN = 230;
public static final int FILE_ACTION_OK = 250;
public static final int PATHNAME_CREATED = 257;
public static final int NEED_PASSWORD = 331;
public static final int NEED_ACCOUNT = 332;
public static final int FILE_ACTION_PENDING = 350;
public static final int SERVICE_NOT_AVAILABLE = 421;
public static final int CANNOT_OPEN_DATA_CONNECTION = 425;
public static final int TRANSFER_ABORTED = 426;
public static final int FILE_ACTION_NOT_TAKEN = 450;
public static final int ACTION_ABORTED = 451;
public static final int INSUFFICIENT_STORAGE = 452;
public static final int UNRECOGNIZED_COMMAND = 500;
public static final int SYNTAX_ERROR_IN_ARGUMENTS = 501;
public static final int COMMAND_NOT_IMPLEMENTED = 502;
public static final int BAD_COMMAND_SEQUENCE = 503;
public static final int COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER = 504;
public static final int NOT_LOGGED_IN = 530;
public static final int NEED_ACCOUNT_FOR_STORING_FILES = 532;
public static final int FILE_UNAVAILABLE = 550;
public static final int PAGE_TYPE_UNKNOWN = 551;
public static final int STORAGE_ALLOCATION_EXCEEDED = 552;
public static final int FILE_NAME_NOT_ALLOWED = 553;
// FTPS Reply Codes
/** @since 2.0 */
public static final int SECURITY_DATA_EXCHANGE_COMPLETE = 234;
/** @since 2.0 */
public static final int SECURITY_DATA_EXCHANGE_SUCCESSFULLY = 235;
/** @since 2.0 */
public static final int SECURITY_MECHANISM_IS_OK = 334;
/** @since 2.0 */
public static final int SECURITY_DATA_IS_ACCEPTABLE = 335;
/** @since 2.0 */
public static final int UNAVAILABLE_RESOURCE = 431;
/** @since 2.2 */
public static final int BAD_TLS_NEGOTIATION_OR_DATA_ENCRYPTION_REQUIRED = 522;
/** @since 2.0 */
public static final int DENIED_FOR_POLICY_REASONS = 533;
/** @since 2.0 */
public static final int REQUEST_DENIED = 534;
/** @since 2.0 */
public static final int FAILED_SECURITY_CHECK = 535;
/** @since 2.0 */
public static final int REQUESTED_PROT_LEVEL_NOT_SUPPORTED = 536;
// IPv6 error codes
// Note this is also used as an FTPS error code reply
/** @since 2.2 */
public static final int EXTENDED_PORT_FAILURE = 522;
// Cannot be instantiated
private FTPReply() {
}
/***
* Determine if a reply code is a positive preliminary response. All
* codes beginning with a 1 are positive preliminary responses.
* Postitive preliminary responses are used to indicate tentative success.
* No further commands can be issued to the FTP server after a positive
* preliminary response until a follow up response is received from the
* server.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive preliminary response, false
* if not.
***/
public static boolean isPositivePreliminary(int reply) {
return (reply >= 100 && reply < 200);
}
/***
* Determine if a reply code is a positive completion response. All
* codes beginning with a 2 are positive completion responses.
* The FTP server will send a positive completion response on the final
* successful completion of a command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive completion response, false
* if not.
***/
public static boolean isPositiveCompletion(int reply) {
return (reply >= 200 && reply < 300);
}
/***
* Determine if a reply code is a positive intermediate response. All
* codes beginning with a 3 are positive intermediate responses.
* The FTP server will send a positive intermediate response on the
* successful completion of one part of a multi-part sequence of
* commands. For example, after a successful USER command, a positive
* intermediate response will be sent to indicate that the server is
* ready for the PASS command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive intermediate response, false
* if not.
***/
public static boolean isPositiveIntermediate(int reply) {
return (reply >= 300 && reply < 400);
}
/***
* Determine if a reply code is a negative transient response. All
* codes beginning with a 4 are negative transient responses.
* The FTP server will send a negative transient response on the
* failure of a command that can be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative transient response, false
* if not.
***/
public static boolean isNegativeTransient(int reply) {
return (reply >= 400 && reply < 500);
}
/***
* Determine if a reply code is a negative permanent response. All
* codes beginning with a 5 are negative permanent responses.
* The FTP server will send a negative permanent response on the
* failure of a command that cannot be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative permanent response, false
* if not.
***/
public static boolean isNegativePermanent(int reply) {
return (reply >= 500 && reply < 600);
}
/**
* Determine if a reply code is a protected response.
*
* @param reply The reply code to test.
* @return True if a reply code is a protected response, false
* if not.
* @since 3.0
*/
public static boolean isProtectedReplyCode(int reply) {
// actually, only 3 protected reply codes are
// defined in RFC 2228: 631, 632 and 633.
return (reply >= 600 && reply < 700);
}
}

@ -1,931 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import aria.apache.commons.net.SocketClient;
import aria.apache.commons.net.util.KeyManagerUtils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import aria.apache.commons.net.util.Base64;
import aria.apache.commons.net.util.SSLContextUtils;
import aria.apache.commons.net.util.SSLSocketUtils;
import aria.apache.commons.net.util.TrustManagerUtils;
/**
* FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all can be used to
* see wire-level SSL details.
*
* Warning: the hostname is not verified against the certificate by default, use
* {@link #setHostnameVerifier(HostnameVerifier)} or {@link #setEndpointCheckingEnabled(boolean)}
* (on Java 1.7+) to enable verification. Verification is only performed on client mode connections.
*
* @version $Id: FTPSClient.java 1747829 2016-06-11 00:57:57Z sebb $
* @since 2.0
*/
public class FTPSClient extends FTPClient {
// From http://www.iana.org/assignments/port-numbers
// ftps-data 989/tcp ftp protocol, data, over TLS/SSL
// ftps-data 989/udp ftp protocol, data, over TLS/SSL
// ftps 990/tcp ftp protocol, control, over TLS/SSL
// ftps 990/udp ftp protocol, control, over TLS/SSL
public static final int DEFAULT_FTPS_DATA_PORT = 989;
public static final int DEFAULT_FTPS_PORT = 990;
/** The value that I can set in PROT command (C = Clear, P = Protected) */
private static final String[] PROT_COMMAND_VALUE = { "C", "E", "S", "P" };
/** Default PROT Command */
private static final String DEFAULT_PROT = "C";
/** Default secure socket protocol name, i.e. TLS */
private static final String DEFAULT_PROTOCOL = "TLS";
/** The AUTH (Authentication/Security Mechanism) command. */
private static final String CMD_AUTH = "AUTH";
/** The ADAT (Authentication/Security Data) command. */
private static final String CMD_ADAT = "ADAT";
/** The PROT (Data Channel Protection Level) command. */
private static final String CMD_PROT = "PROT";
/** The PBSZ (Protection Buffer Size) command. */
private static final String CMD_PBSZ = "PBSZ";
/** The MIC (Integrity Protected Command) command. */
private static final String CMD_MIC = "MIC";
/** The CONF (Confidentiality Protected Command) command. */
private static final String CMD_CONF = "CONF";
/** The ENC (Privacy Protected Command) command. */
private static final String CMD_ENC = "ENC";
/** The CCC (Clear Command Channel) command. */
private static final String CMD_CCC = "CCC";
/** The security mode. (True - Implicit Mode / False - Explicit Mode) */
private final boolean isImplicit;
/** The secure socket protocol to be used, e.g. SSL/TLS. */
private final String protocol;
/** The AUTH Command value */
private String auth = DEFAULT_PROTOCOL;
/** The context object. */
private SSLContext context;
/** The socket object. */
private Socket plainSocket;
/** Controls whether a new SSL session may be established by this socket. Default true. */
private boolean isCreation = true;
/** The use client mode flag. */
private boolean isClientMode = true;
/** The need client auth flag. */
private boolean isNeedClientAuth = false;
/** The want client auth flag. */
private boolean isWantClientAuth = false;
/** The cipher suites */
private String[] suites = null;
/** The protocol versions */
private String[] protocols = null;
/**
* The FTPS {@link TrustManager} implementation, default validate only
* {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}.
*/
private TrustManager trustManager = TrustManagerUtils.getValidateServerCertificateTrustManager();
/** The {@link KeyManager}, default null (i.e. use system default). */
private KeyManager keyManager = null;
/** The {@link HostnameVerifier} to use post-TLS, default null (i.e. no verification). */
private HostnameVerifier hostnameVerifier = null;
/** Use Java 1.7+ HTTPS Endpoint Identification Algorithim. */
private boolean tlsEndpointChecking;
/**
* Constructor for FTPSClient, calls {@link #FTPSClient(String, boolean)}.
*
* Sets protocol to {@link #DEFAULT_PROTOCOL} - i.e. TLS - and security mode to explicit
* (isImplicit = false)
*/
public FTPSClient() {
this(DEFAULT_PROTOCOL, false);
}
/**
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* Calls {@link #FTPSClient(String, boolean)}
*
* @param isImplicit The security mode (Implicit/Explicit).
*/
public FTPSClient(boolean isImplicit) {
this(DEFAULT_PROTOCOL, isImplicit);
}
/**
* Constructor for FTPSClient, using explict mode, calls {@link #FTPSClient(String, boolean)}.
*
* @param protocol the protocol to use
*/
public FTPSClient(String protocol) {
this(protocol, false);
}
/**
* Constructor for FTPSClient allowing specification of protocol
* and security mode. If isImplicit is true, the port is set to
* {@link #DEFAULT_FTPS_PORT} i.e. 990.
* The default TrustManager is set from {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}
*
* @param protocol the protocol
* @param isImplicit The security mode(Implicit/Explicit).
*/
public FTPSClient(String protocol, boolean isImplicit) {
super();
this.protocol = protocol;
this.isImplicit = isImplicit;
if (isImplicit) {
setDefaultPort(DEFAULT_FTPS_PORT);
}
}
/**
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* The default TrustManager is set from {@link TrustManagerUtils#getValidateServerCertificateTrustManager()}
*
* @param isImplicit The security mode(Implicit/Explicit).
* @param context A pre-configured SSL Context
*/
public FTPSClient(boolean isImplicit, SSLContext context) {
this(DEFAULT_PROTOCOL, isImplicit);
this.context = context;
}
/**
* Constructor for FTPSClient, using {@link #DEFAULT_PROTOCOL} - i.e. TLS
* and isImplicit {@code false}
* Calls {@link #FTPSClient(boolean, SSLContext)}
*
* @param context A pre-configured SSL Context
*/
public FTPSClient(SSLContext context) {
this(false, context);
}
/**
* Set AUTH command use value.
* This processing is done before connected processing.
*
* @param auth AUTH command use value.
*/
public void setAuthValue(String auth) {
this.auth = auth;
}
/**
* Return AUTH command use value.
*
* @return AUTH command use value.
*/
public String getAuthValue() {
return this.auth;
}
/**
* Because there are so many connect() methods,
* the _connectAction_() method is provided as a means of performing
* some action immediately after establishing a connection,
* rather than reimplementing all of the connect() methods.
*
* @throws IOException If it throw by _connectAction_.
* @see SocketClient#_connectAction_()
*/
@Override protected void _connectAction_() throws IOException {
// Implicit mode.
if (isImplicit) {
sslNegotiation();
}
super._connectAction_();
// Explicit mode.
if (!isImplicit) {
execAUTH();
sslNegotiation();
}
}
/**
* AUTH command.
*
* @throws SSLException If it server reply code not equal "234" and "334".
* @throws IOException If an I/O error occurs while either sending
* the command.
*/
protected void execAUTH() throws SSLException, IOException {
int replyCode = sendCommand(CMD_AUTH, auth);
if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
// replyCode = 334
// I carry out an ADAT command.
} else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
throw new SSLException(getReplyString());
}
}
/**
* Performs a lazy init of the SSL context
*
* @throws IOException
*/
private void initSslContext() throws IOException {
if (context == null) {
context = SSLContextUtils.createSSLContext(protocol, getKeyManager(), getTrustManager());
}
}
/**
* SSL/TLS negotiation. Acquires an SSL socket of a control
* connection and carries out handshake processing.
*
* @throws IOException If server negotiation fails
*/
protected void sslNegotiation() throws IOException {
plainSocket = _socket_;
initSslContext();
SSLSocketFactory ssf = context.getSocketFactory();
String host = (_hostname_ != null) ? _hostname_ : getRemoteAddress().getHostAddress();
int port = _socket_.getPort();
SSLSocket socket = (SSLSocket) ssf.createSocket(_socket_, host, port, false);
socket.setEnableSessionCreation(isCreation);
socket.setUseClientMode(isClientMode);
// client mode
if (isClientMode) {
if (tlsEndpointChecking) {
SSLSocketUtils.enableEndpointNameVerification(socket);
}
} else { // server mode
socket.setNeedClientAuth(isNeedClientAuth);
socket.setWantClientAuth(isWantClientAuth);
}
if (protocols != null) {
socket.setEnabledProtocols(protocols);
}
if (suites != null) {
socket.setEnabledCipherSuites(suites);
}
socket.startHandshake();
// TODO the following setup appears to duplicate that in the super class methods
_socket_ = socket;
_controlInput_ =
new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
_controlOutput_ =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), getControlEncoding()));
if (isClientMode) {
if (hostnameVerifier != null && !hostnameVerifier.verify(host, socket.getSession())) {
throw new SSLHandshakeException("Hostname doesn't match certificate");
}
}
}
/**
* Get the {@link KeyManager} instance.
*
* @return The {@link KeyManager} instance
*/
private KeyManager getKeyManager() {
return keyManager;
}
/**
* Set a {@link KeyManager} to use
*
* @param keyManager The KeyManager implementation to set.
* @see KeyManagerUtils
*/
public void setKeyManager(KeyManager keyManager) {
this.keyManager = keyManager;
}
/**
* Controls whether a new SSL session may be established by this socket.
*
* @param isCreation The established socket flag.
*/
public void setEnabledSessionCreation(boolean isCreation) {
this.isCreation = isCreation;
}
/**
* Returns true if new SSL sessions may be established by this socket.
* When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
* instance of {@link SSLSocket} with {@link SSLSocket}{@link #getEnableSessionCreation()})
* enabled,
* this returns False.
*
* @return true - Indicates that sessions may be created;
* this is the default.
* false - indicates that an existing session must be resumed.
*/
public boolean getEnableSessionCreation() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getEnableSessionCreation();
}
return false;
}
/**
* Configures the socket to require client authentication.
*
* @param isNeedClientAuth The need client auth flag.
*/
public void setNeedClientAuth(boolean isNeedClientAuth) {
this.isNeedClientAuth = isNeedClientAuth;
}
/**
* Returns true if the socket will require client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
public boolean getNeedClientAuth() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getNeedClientAuth();
}
return false;
}
/**
* Configures the socket to request client authentication,
* but only if such a request is appropriate to the cipher
* suite negotiated.
*
* @param isWantClientAuth The want client auth flag.
*/
public void setWantClientAuth(boolean isWantClientAuth) {
this.isWantClientAuth = isWantClientAuth;
}
/**
* Returns true if the socket will request client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
public boolean getWantClientAuth() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getWantClientAuth();
}
return false;
}
/**
* Configures the socket to use client (or server) mode in its first
* handshake.
*
* @param isClientMode The use client mode flag.
*/
public void setUseClientMode(boolean isClientMode) {
this.isClientMode = isClientMode;
}
/**
* Returns true if the socket is set to use client mode
* in its first handshake.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
*
* @return true - If the socket should start its first handshake
* in "client" mode.
*/
public boolean getUseClientMode() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getUseClientMode();
}
return false;
}
/**
* Controls which particular cipher suites are enabled for use on this
* connection. Called before server negotiation.
*
* @param cipherSuites The cipher suites.
*/
public void setEnabledCipherSuites(String[] cipherSuites) {
suites = new String[cipherSuites.length];
System.arraycopy(cipherSuites, 0, suites, 0, cipherSuites.length);
}
/**
* Returns the names of the cipher suites which could be enabled
* for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
*
* @return An array of cipher suite names, or <code>null</code>
*/
public String[] getEnabledCipherSuites() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getEnabledCipherSuites();
}
return null;
}
/**
* Controls which particular protocol versions are enabled for use on this
* connection. I perform setting before a server negotiation.
*
* @param protocolVersions The protocol versions.
*/
public void setEnabledProtocols(String[] protocolVersions) {
protocols = new String[protocolVersions.length];
System.arraycopy(protocolVersions, 0, protocols, 0, protocolVersions.length);
}
/**
* Returns the names of the protocol versions which are currently
* enabled for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
*
* @return An array of protocols, or <code>null</code>
*/
public String[] getEnabledProtocols() {
if (_socket_ instanceof SSLSocket) {
return ((SSLSocket) _socket_).getEnabledProtocols();
}
return null;
}
/**
* PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
*
* @param pbsz Protection Buffer Size.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
* the command.
* @see #parsePBSZ(long)
*/
public void execPBSZ(long pbsz) throws SSLException, IOException {
if (pbsz < 0 || 4294967295L < pbsz) { // 32-bit unsigned number
throw new IllegalArgumentException();
}
int status = sendCommand(CMD_PBSZ, String.valueOf(pbsz));
if (FTPReply.COMMAND_OK != status) {
throw new SSLException(getReplyString());
}
}
/**
* PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
* Issues the command and parses the response to return the negotiated value.
*
* @param pbsz Protection Buffer Size.
* @return the negotiated value.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
* the command.
* @see #execPBSZ(long)
* @since 3.0
*/
public long parsePBSZ(long pbsz) throws SSLException, IOException {
execPBSZ(pbsz);
long minvalue = pbsz;
String remainder = extractPrefixedData("PBSZ=", getReplyString());
if (remainder != null) {
long replysz = Long.parseLong(remainder);
if (replysz < minvalue) {
minvalue = replysz;
}
}
return minvalue;
}
/**
* PROT command.
* <ul>
* <li>C - Clear</li>
* <li>S - Safe(SSL protocol only)</li>
* <li>E - Confidential(SSL protocol only)</li>
* <li>P - Private</li>
* </ul>
* <b>N.B.</b> the method calls
* {@link #setSocketFactory(javax.net.SocketFactory)} and
* {@link #setServerSocketFactory(javax.net.ServerSocketFactory)}
*
* @param prot Data Channel Protection Level, if {@code null}, use {@link #DEFAULT_PROT}.
* @throws SSLException If the server reply code does not equal {@code 200}.
* @throws IOException If an I/O error occurs while sending
* the command.
*/
public void execPROT(String prot) throws SSLException, IOException {
if (prot == null) {
prot = DEFAULT_PROT;
}
if (!checkPROTValue(prot)) {
throw new IllegalArgumentException();
}
if (FTPReply.COMMAND_OK != sendCommand(CMD_PROT, prot)) {
throw new SSLException(getReplyString());
}
if (DEFAULT_PROT.equals(prot)) {
setSocketFactory(null);
setServerSocketFactory(null);
} else {
setSocketFactory(new FTPSSocketFactory(context));
setServerSocketFactory(new FTPSServerSocketFactory(context));
initSslContext();
}
}
/**
* Check the value that can be set in PROT Command value.
*
* @param prot Data Channel Protection Level.
* @return True - A set point is right / False - A set point is not right
*/
private boolean checkPROTValue(String prot) {
for (String element : PROT_COMMAND_VALUE) {
if (element.equals(prot)) {
return true;
}
}
return false;
}
/**
* Send an FTP command.
* A successful CCC (Clear Command Channel) command causes the underlying {@link SSLSocket}
* instance to be assigned to a plain {@link Socket}
*
* @param command The FTP command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending the command.
* @throws SSLException if a CCC command fails
* @see FTP#sendCommand(String)
*/
// Would like to remove this method, but that will break any existing clients that are using CCC
@Override public int sendCommand(String command, String args) throws IOException {
int repCode = super.sendCommand(command, args);
/* If CCC is issued, restore socket i/o streams to unsecured versions */
if (CMD_CCC.equals(command)) {
if (FTPReply.COMMAND_OK == repCode) {
_socket_.close();
_socket_ = plainSocket;
_controlInput_ = new BufferedReader(
new InputStreamReader(_socket_.getInputStream(), getControlEncoding()));
_controlOutput_ = new BufferedWriter(
new OutputStreamWriter(_socket_.getOutputStream(), getControlEncoding()));
} else {
throw new SSLException(getReplyString());
}
}
return repCode;
}
/**
* Returns a socket of the data connection.
* Wrapped as an {@link SSLSocket}, which carries out handshake processing.
*
* @param command The int representation of the FTP command to send.
* @param arg The arguments to the FTP command.
* If this parameter is set to null, then the command is sent with
* no arguments.
* @return corresponding to the established data connection.
* Null is returned if an FTP protocol error is reported at any point
* during the establishment and initialization of the connection.
* @throws IOException If there is any problem with the connection.
* @see FTPClient#_openDataConnection_(int, String)
* @deprecated (3.3) Use {@link FTPClient#_openDataConnection_(FTPCmd, String)} instead
*/
@Override
// Strictly speaking this is not needed, but it works round a Clirr bug
// So rather than invoke the parent code, we do it here
@Deprecated protected Socket _openDataConnection_(int command, String arg) throws IOException {
return _openDataConnection_(FTPCommand.getCommand(command), arg);
}
/**
* Returns a socket of the data connection.
* Wrapped as an {@link SSLSocket}, which carries out handshake processing.
*
* @param command The textual representation of the FTP command to send.
* @param arg The arguments to the FTP command.
* If this parameter is set to null, then the command is sent with
* no arguments.
* @return corresponding to the established data connection.
* Null is returned if an FTP protocol error is reported at any point
* during the establishment and initialization of the connection.
* @throws IOException If there is any problem with the connection.
* @see FTPClient#_openDataConnection_(int, String)
* @since 3.2
*/
@Override protected Socket _openDataConnection_(String command, String arg) throws IOException {
Socket socket = super._openDataConnection_(command, arg);
_prepareDataSocket_(socket);
if (socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket) socket;
sslSocket.setUseClientMode(isClientMode);
sslSocket.setEnableSessionCreation(isCreation);
// server mode
if (!isClientMode) {
sslSocket.setNeedClientAuth(isNeedClientAuth);
sslSocket.setWantClientAuth(isWantClientAuth);
}
if (suites != null) {
sslSocket.setEnabledCipherSuites(suites);
}
if (protocols != null) {
sslSocket.setEnabledProtocols(protocols);
}
sslSocket.startHandshake();
}
return socket;
}
/**
* Performs any custom initialization for a newly created SSLSocket (before
* the SSL handshake happens).
* Called by {@link #_openDataConnection_(int, String)} immediately
* after creating the socket.
* The default implementation is a no-op
*
* @param socket the socket to set up
* @throws IOException on error
* @since 3.1
*/
protected void _prepareDataSocket_(Socket socket) throws IOException {
}
/**
* Get the currently configured {@link TrustManager}.
*
* @return A TrustManager instance.
*/
public TrustManager getTrustManager() {
return trustManager;
}
/**
* Override the default {@link TrustManager} to use; if set to {@code null},
* the default TrustManager from the JVM will be used.
*
* @param trustManager The TrustManager implementation to set, may be {@code null}
* @see TrustManagerUtils
*/
public void setTrustManager(TrustManager trustManager) {
this.trustManager = trustManager;
}
/**
* Get the currently configured {@link HostnameVerifier}.
* The verifier is only used on client mode connections.
*
* @return A HostnameVerifier instance.
* @since 3.4
*/
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
/**
* Override the default {@link HostnameVerifier} to use.
* The verifier is only used on client mode connections.
*
* @param newHostnameVerifier The HostnameVerifier implementation to set or <code>null</code> to
* disable.
* @since 3.4
*/
public void setHostnameVerifier(HostnameVerifier newHostnameVerifier) {
hostnameVerifier = newHostnameVerifier;
}
/**
* Return whether or not endpoint identification using the HTTPS algorithm
* on Java 1.7+ is enabled. The default behaviour is for this to be disabled.
*
* This check is only performed on client mode connections.
*
* @return True if enabled, false if not.
* @since 3.4
*/
public boolean isEndpointCheckingEnabled() {
return tlsEndpointChecking;
}
/**
* Automatic endpoint identification checking using the HTTPS algorithm
* is supported on Java 1.7+. The default behaviour is for this to be disabled.
*
* This check is only performed on client mode connections.
*
* @param enable Enable automatic endpoint identification checking using the HTTPS algorithm on
* Java 1.7+.
* @since 3.4
*/
public void setEndpointCheckingEnabled(boolean enable) {
tlsEndpointChecking = enable;
}
/**
* Closes the connection to the FTP server and restores
* connection parameters to the default values.
* <p>
* Calls {@code setSocketFactory(null)} and {@code setServerSocketFactory(null)}
* to reset the factories that may have been changed during the session,
* e.g. by {@link #execPROT(String)}
*
* @throws IOException If an error occurs while disconnecting.
* @since 3.0
*/
@Override public void disconnect() throws IOException {
super.disconnect();
if (plainSocket != null) {
plainSocket.close();
}
setSocketFactory(null);
setServerSocketFactory(null);
}
/**
* Send the AUTH command with the specified mechanism.
*
* @param mechanism The mechanism name to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execAUTH(String mechanism) throws IOException {
return sendCommand(CMD_AUTH, mechanism);
}
/**
* Send the ADAT command with the specified authentication data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execADAT(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_ADAT, Base64.encodeBase64StringUnChunked(data));
} else {
return sendCommand(CMD_ADAT);
}
}
/**
* Send the CCC command to the server.
* The CCC (Clear Command Channel) command causes the underlying {@link SSLSocket} instance to be
* assigned
* to a plain {@link Socket} instances
*
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execCCC() throws IOException {
int repCode = sendCommand(CMD_CCC);
// This will be performed by sendCommand(String, String)
// if (FTPReply.isPositiveCompletion(repCode)) {
// _socket_.close();
// _socket_ = plainSocket;
// _controlInput_ = new BufferedReader(
// new InputStreamReader(
// _socket_.getInputStream(), getControlEncoding()));
// _controlOutput_ = new BufferedWriter(
// new OutputStreamWriter(
// _socket_.getOutputStream(), getControlEncoding()));
// }
return repCode;
}
/**
* Send the MIC command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execMIC(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_MIC, Base64.encodeBase64StringUnChunked(data));
} else {
return sendCommand(CMD_MIC, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Send the CONF command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execCONF(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_CONF, Base64.encodeBase64StringUnChunked(data));
} else {
return sendCommand(CMD_CONF, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Send the ENC command with the specified data.
*
* @param data The data to send with the command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @since 3.0
*/
public int execENC(byte[] data) throws IOException {
if (data != null) {
return sendCommand(CMD_ENC, Base64.encodeBase64StringUnChunked(data));
} else {
return sendCommand(CMD_ENC, ""); // perhaps "=" or just sendCommand(String)?
}
}
/**
* Parses the given ADAT response line and base64-decodes the data.
*
* @param reply The ADAT reply to parse.
* @return the data in the reply, base64-decoded.
* @since 3.0
*/
public byte[] parseADATReply(String reply) {
if (reply == null) {
return null;
} else {
return Base64.decodeBase64(extractPrefixedData("ADAT=", reply));
}
}
/**
* Extract the data from a reply with a prefix, e.g. PBSZ=1234 => 1234
*
* @param prefix the prefix to find
* @param reply where to find the prefix
* @return the remainder of the string after the prefix, or null if the prefix was not present.
*/
private String extractPrefixedData(String prefix, String reply) {
int idx = reply.indexOf(prefix);
if (idx == -1) {
return null;
}
// N.B. Cannot use trim before substring as leading space would affect the offset.
return reply.substring(idx + prefix.length()).trim();
}
// DEPRECATED - for API compatibility only - DO NOT USE
/** @deprecated - not used - may be removed in a future release */
@Deprecated public static String KEYSTORE_ALGORITHM;
/** @deprecated - not used - may be removed in a future release */
@Deprecated public static String TRUSTSTORE_ALGORITHM;
/** @deprecated - not used - may be removed in a future release */
@Deprecated public static String PROVIDER;
/** @deprecated - not used - may be removed in a future release */
@Deprecated public static String STORE_TYPE;
}
/* kate: indent-width 4; replace-tabs on; */

@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
/**
* FTPS-specific commands.
*
* @since 2.0
* @deprecated 3.0 DO NOT USE
*/
@Deprecated public final class FTPSCommand {
public static final int AUTH = 0;
public static final int ADAT = 1;
public static final int PBSZ = 2;
public static final int PROT = 3;
public static final int CCC = 4;
public static final int AUTHENTICATION_SECURITY_MECHANISM = AUTH;
public static final int AUTHENTICATION_SECURITY_DATA = ADAT;
public static final int PROTECTION_BUFFER_SIZE = PBSZ;
public static final int DATA_CHANNEL_PROTECTION_LEVEL = PROT;
public static final int CLEAR_COMMAND_CHANNEL = CCC;
private static final String[] _commands = { "AUTH", "ADAT", "PBSZ", "PROT", "CCC" };
/**
* Retrieve the FTPS command string corresponding to a specified
* command code.
*
* @param command The command code.
* @return The FTPS command string corresponding to a specified
* command code.
*/
public static final String getCommand(int command) {
return _commands[command];
}
}

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
/**
* Server socket factory for FTPS connections.
*
* @since 2.2
*/
public class FTPSServerSocketFactory extends ServerSocketFactory {
/** Factory for secure socket factories */
private final SSLContext context;
public FTPSServerSocketFactory(SSLContext context) {
this.context = context;
}
// Override the default superclass method
@Override public ServerSocket createServerSocket() throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket());
}
@Override public ServerSocket createServerSocket(int port) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port));
}
@Override public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
}
@Override public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
}
/**
* Sets the socket so newly accepted connections will use SSL client mode.
*
* @param socket the SSLServerSocket to initialise
* @return the socket
* @throws ClassCastException if socket is not an instance of SSLServerSocket
*/
public ServerSocket init(ServerSocket socket) {
((SSLServerSocket) socket).setUseClientMode(true);
return socket;
}
}

@ -1,116 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
/**
* Implementation of org.apache.commons.net.SocketFactory
*
* @since 2.0
*/
public class FTPSSocketFactory extends SocketFactory {
private final SSLContext context;
public FTPSSocketFactory(SSLContext context) {
this.context = context;
}
// Override the default implementation
@Override public Socket createSocket() throws IOException {
return this.context.getSocketFactory().createSocket();
}
@Override public Socket createSocket(String address, int port)
throws UnknownHostException, IOException {
return this.context.getSocketFactory().createSocket(address, port);
}
@Override public Socket createSocket(InetAddress address, int port) throws IOException {
return this.context.getSocketFactory().createSocket(address, port);
}
@Override
public Socket createSocket(String address, int port, InetAddress localAddress, int localPort)
throws UnknownHostException, IOException {
return this.context.getSocketFactory().createSocket(address, port, localAddress, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return this.context.getSocketFactory().createSocket(address, port, localAddress, localPort);
}
// DEPRECATED METHODS - for API compatibility only - DO NOT USE
/**
* @param port the port
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int) instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port) throws IOException {
return this.init(this.context.getServerSocketFactory().createServerSocket(port));
}
/**
* @param port the port
* @param backlog the backlog
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int) instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port, int backlog)
throws IOException {
return this.init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
}
/**
* @param port the port
* @param backlog the backlog
* @param ifAddress the interface
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#createServerSocket(int, int, InetAddress)
* instead}
*/
@Deprecated public java.net.ServerSocket createServerSocket(int port, int backlog,
InetAddress ifAddress) throws IOException {
return this.init(
this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
}
/**
* @param socket the socket
* @return the socket
* @throws IOException on error
* @deprecated (2.2) use {@link FTPSServerSocketFactory#init(java.net.ServerSocket)}
*/
@Deprecated public java.net.ServerSocket init(java.net.ServerSocket socket) throws IOException {
((javax.net.ssl.SSLServerSocket) socket).setUseClientMode(true);
return socket;
}
}

@ -1,54 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import aria.apache.commons.net.util.TrustManagerUtils;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/**
* Do not use.
*
* @since 2.0
* @deprecated 3.0 use
* {@link TrustManagerUtils#getValidateServerCertificateTrustManager()
* TrustManagerUtils#getValidateServerCertificateTrustManager()} instead
*/
@Deprecated public class FTPSTrustManager implements X509TrustManager {
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[] {};
/**
* No-op
*/
@Override public void checkClientTrusted(X509Certificate[] certificates, String authType) {
return;
}
@Override public void checkServerTrusted(X509Certificate[] certificates, String authType)
throws CertificateException {
for (X509Certificate certificate : certificates) {
certificate.checkValidity();
}
}
@Override public X509Certificate[] getAcceptedIssuers() {
return EMPTY_X509CERTIFICATE_ARRAY;
}
}

@ -1,33 +0,0 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp;
import aria.apache.commons.net.io.CopyStreamListener;
/**
* Created by AriaL on 2017/9/26.
* ftp 上传文件流事件监听
*/
public interface OnFtpInputStreamListener {
/**
* {@link CopyStreamListener#bytesTransferred(long, int, long)}
*
* @param totalBytesTransferred 已经上传的文件长度
* @param bytesTransferred 上传byte长度
*/
void onFtpInputStream(FTPClient client, long totalBytesTransferred, int bytesTransferred,
long streamSize);
}

@ -1,21 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* FTP and FTPS support classes
*/
package aria.apache.commons.net.ftp;

@ -1,59 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp.parser;
import aria.apache.commons.net.ftp.FTPFile;
import aria.apache.commons.net.ftp.FTPFileEntryParser;
import aria.apache.commons.net.ftp.FTPFileEntryParserImpl;
/**
* This implementation allows to pack some FileEntryParsers together
* and handle the case where to returned dirstyle isnt clearly defined.
* The matching parser will be cached.
* If the cached parser wont match due to the server changed the dirstyle,
* a new matching parser will be searched.
*/
public class CompositeFileEntryParser extends FTPFileEntryParserImpl {
private final FTPFileEntryParser[] ftpFileEntryParsers;
private FTPFileEntryParser cachedFtpFileEntryParser;
public CompositeFileEntryParser(FTPFileEntryParser[] ftpFileEntryParsers) {
super();
this.cachedFtpFileEntryParser = null;
this.ftpFileEntryParsers = ftpFileEntryParsers;
}
@Override public FTPFile parseFTPEntry(String listEntry) {
if (cachedFtpFileEntryParser != null) {
FTPFile matched = cachedFtpFileEntryParser.parseFTPEntry(listEntry);
if (matched != null) {
return matched;
}
} else {
for (FTPFileEntryParser ftpFileEntryParser : ftpFileEntryParsers) {
FTPFile matched = ftpFileEntryParser.parseFTPEntry(listEntry);
if (matched != null) {
cachedFtpFileEntryParser = ftpFileEntryParser;
return matched;
}
}
}
return null;
}
}

@ -1,123 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp.parser;
import aria.apache.commons.net.ftp.Configurable;
import aria.apache.commons.net.ftp.FTPClientConfig;
import java.text.ParseException;
import java.util.Calendar;
/**
* <p>
* This abstract class implements the common timestamp parsing
* algorithm for all the concrete parsers. Classes derived from
* this one will parse file listings via a supplied regular expression
* that pulls out the date portion as a separate string which is
* passed to the underlying {@link FTPTimestampParser delegate} to
* handle parsing of the file timestamp.
* <p>
* This class also implements the {@link Configurable Configurable}
* interface to allow the parser to be configured from the outside.
*
* @since 1.4
*/
public abstract class ConfigurableFTPFileEntryParserImpl extends RegexFTPFileEntryParserImpl
implements Configurable {
private final FTPTimestampParser timestampParser;
/**
* constructor for this abstract class.
*
* @param regex Regular expression used main parsing of the
* file listing.
*/
public ConfigurableFTPFileEntryParserImpl(String regex) {
super(regex);
this.timestampParser = new FTPTimestampParserImpl();
}
/**
* constructor for this abstract class.
*
* @param regex Regular expression used main parsing of the
* file listing.
* @param flags the flags to apply, see
* {@link java.util.regex.Pattern#compile(String, int) Pattern#compile(String, int)}. Use 0 for
* none.
* @since 3.4
*/
public ConfigurableFTPFileEntryParserImpl(String regex, int flags) {
super(regex, flags);
this.timestampParser = new FTPTimestampParserImpl();
}
/**
* This method is called by the concrete parsers to delegate
* timestamp parsing to the timestamp parser.
*
* @param timestampStr the timestamp string pulled from the
* file listing by the regular expression parser, to be submitted
* to the <code>timestampParser</code> for extracting the timestamp.
* @return a <code>java.util.Calendar</code> containing results of the
* timestamp parse.
* @throws ParseException on parse error
*/
public Calendar parseTimestamp(String timestampStr) throws ParseException {
return this.timestampParser.parseTimestamp(timestampStr);
}
/**
* Implementation of the {@link Configurable Configurable}
* interface. Configures this parser by delegating to the
* underlying Configurable FTPTimestampParser implementation, '
* passing it the supplied {@link FTPClientConfig FTPClientConfig}
* if that is non-null or a default configuration defined by
* each concrete subclass.
*
* @param config the configuration to be used to configure this parser.
* If it is null, a default configuration defined by
* each concrete subclass is used instead.
*/
@Override public void configure(FTPClientConfig config) {
if (this.timestampParser instanceof Configurable) {
FTPClientConfig defaultCfg = getDefaultConfiguration();
if (config != null) {
if (null == config.getDefaultDateFormatStr()) {
config.setDefaultDateFormatStr(defaultCfg.getDefaultDateFormatStr());
}
if (null == config.getRecentDateFormatStr()) {
config.setRecentDateFormatStr(defaultCfg.getRecentDateFormatStr());
}
((Configurable) this.timestampParser).configure(config);
} else {
((Configurable) this.timestampParser).configure(defaultCfg);
}
}
}
/**
* Each concrete subclass must define this member to create
* a default configuration to be used when that subclass is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
*
* @return the default configuration for the subclass.
*/
protected abstract FTPClientConfig getDefaultConfiguration();
}

@ -1,254 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package aria.apache.commons.net.ftp.parser;
import aria.apache.commons.net.ftp.Configurable;
import aria.apache.commons.net.ftp.FTPClient;
import aria.apache.commons.net.ftp.FTPClientConfig;
import aria.apache.commons.net.ftp.FTPFileEntryParser;
import java.util.regex.Pattern;
/**
* This is the default implementation of the
* FTPFileEntryParserFactory interface. This is the
* implementation that will be used by
* FTPClient.listFiles()
* if no other implementation has been specified.
*
* @see FTPClient#listFiles
* @see FTPClient#setParserFactory
*/
public class DefaultFTPFileEntryParserFactory implements FTPFileEntryParserFactory {
// Match a plain Java Identifier
private static final String JAVA_IDENTIFIER =
"\\p{javaJavaIdentifierStart}(\\p{javaJavaIdentifierPart})*";
// Match a qualified name, e.g. a.b.c.Name - but don't allow the default package as that would allow "VMS"/"UNIX" etc.
private static final String JAVA_QUALIFIED_NAME =
"(" + JAVA_IDENTIFIER + "\\.)+" + JAVA_IDENTIFIER;
// Create the pattern, as it will be reused many times
private static final Pattern JAVA_QUALIFIED_NAME_PATTERN = Pattern.compile(JAVA_QUALIFIED_NAME);
/**
* This default implementation of the FTPFileEntryParserFactory
* interface works according to the following logic:
* First it attempts to interpret the supplied key as a fully
* qualified classname (default package is not allowed) of a class implementing the
* FTPFileEntryParser interface. If that succeeds, a parser
* object of this class is instantiated and is returned;
* otherwise it attempts to interpret the key as an identirier
* commonly used by the FTP SYST command to identify systems.
* <p>
* If <code>key</code> is not recognized as a fully qualified
* classname known to the system, this method will then attempt
* to see whether it <b>contains</b> a string identifying one of
* the known parsers. This comparison is <b>case-insensitive</b>.
* The intent here is where possible, to select as keys strings
* which are returned by the SYST command on the systems which
* the corresponding parser successfully parses. This enables
* this factory to be used in the auto-detection system.
*
* @param key should be a fully qualified classname corresponding to
* a class implementing the FTPFileEntryParser interface<br>
* OR<br>
* a string containing (case-insensitively) one of the
* following keywords:
* <ul>
* <li>{@link FTPClientConfig#SYST_UNIX UNIX}</li>
* <li>{@link FTPClientConfig#SYST_NT WINDOWS}</li>
* <li>{@link FTPClientConfig#SYST_OS2 OS/2}</li>
* <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li>
* <li>{@link FTPClientConfig#SYST_AS400 AS/400}</li>
* <li>{@link FTPClientConfig#SYST_VMS VMS}</li>
* <li>{@link FTPClientConfig#SYST_MVS MVS}</li>
* <li>{@link FTPClientConfig#SYST_NETWARE NETWARE}</li>
* <li>{@link FTPClientConfig#SYST_L8 TYPE:L8}</li>
* </ul>
* @return the FTPFileEntryParser corresponding to the supplied key.
* @throws ParserInitializationException thrown if for any reason the factory cannot resolve
* the supplied key into an FTPFileEntryParser.
* @see FTPFileEntryParser
*/
@Override public FTPFileEntryParser createFileEntryParser(String key) {
if (key == null) {
throw new ParserInitializationException("Parser key cannot be null");
}
return createFileEntryParser(key, null);
}
// Common method to process both key and config parameters.
private FTPFileEntryParser createFileEntryParser(String key, FTPClientConfig config) {
FTPFileEntryParser parser = null;
// Is the key a possible class name?
if (JAVA_QUALIFIED_NAME_PATTERN.matcher(key).matches()) {
try {
Class<?> parserClass = Class.forName(key);
try {
parser = (FTPFileEntryParser) parserClass.newInstance();
} catch (ClassCastException e) {
throw new ParserInitializationException(parserClass.getName()
+ " does not implement the interface "
+ "FTPFileEntryParser.", e);
} catch (Exception e) {
throw new ParserInitializationException("Error initializing parser", e);
} catch (ExceptionInInitializerError e) {
throw new ParserInitializationException("Error initializing parser", e);
}
} catch (ClassNotFoundException e) {
// OK, assume it is an alias
}
}
if (parser == null) { // Now try for aliases
String ukey = key.toUpperCase(java.util.Locale.ENGLISH);
if (ukey.indexOf(FTPClientConfig.SYST_UNIX_TRIM_LEADING) >= 0) {
parser = new UnixFTPEntryParser(config, true);
}
// must check this after SYST_UNIX_TRIM_LEADING as it is a substring of it
else if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) {
parser = new UnixFTPEntryParser(config, false);
} else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0) {
parser = new VMSVersioningFTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0) {
parser = createNTFTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0) {
parser = new OS2FTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0
|| ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0) {
parser = createOS400FTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0) {
parser = new MVSFTPEntryParser(); // Does not currently support config parameter
} else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0) {
parser = new NetwareFTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_MACOS_PETER) >= 0) {
parser = new MacOsPeterFTPEntryParser(config);
} else if (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0) {
// L8 normally means Unix, but move it to the end for some L8 systems that aren't.
// This check should be last!
parser = new UnixFTPEntryParser(config);
} else {
throw new ParserInitializationException("Unknown parser type: " + key);
}
}
if (parser instanceof Configurable) {
((Configurable) parser).configure(config);
}
return parser;
}
/**
* <p>Implementation extracts a key from the supplied
* {@link FTPClientConfig FTPClientConfig}
* parameter and creates an object implementing the
* interface FTPFileEntryParser and uses the supplied configuration
* to configure it.
* </p><p>
* Note that this method will generally not be called in scenarios
* that call for autodetection of parser type but rather, for situations
* where the user knows that the server uses a non-default configuration
* and knows what that configuration is.
* </p>
*
* @param config A {@link FTPClientConfig FTPClientConfig}
* used to configure the parser created
* @return the @link FTPFileEntryParser FTPFileEntryParser} so created.
* @throws ParserInitializationException Thrown on any exception in instantiation
* @throws NullPointerException if {@code config} is {@code null}
* @since 1.4
*/
@Override public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
throws ParserInitializationException {
String key = config.getServerSystemKey();
return createFileEntryParser(key, config);
}
public FTPFileEntryParser createUnixFTPEntryParser() {
return new UnixFTPEntryParser();
}
public FTPFileEntryParser createVMSVersioningFTPEntryParser() {
return new VMSVersioningFTPEntryParser();
}
public FTPFileEntryParser createNetwareFTPEntryParser() {
return new NetwareFTPEntryParser();
}
public FTPFileEntryParser createNTFTPEntryParser() {
return createNTFTPEntryParser(null);
}
/**
* Creates an NT FTP parser: if the config exists, and the system key equals
* {@link FTPClientConfig.SYST_NT} then a plain {@link NTFTPEntryParser} is used,
* otherwise a composite of {@link NTFTPEntryParser} and {@link UnixFTPEntryParser} is used.
*
* @param config the config to use, may be {@code null}
* @return the parser
*/
private FTPFileEntryParser createNTFTPEntryParser(FTPClientConfig config) {
if (config != null && FTPClientConfig.SYST_NT.equals(config.getServerSystemKey())) {
return new NTFTPEntryParser(config);
} else {
// clone the config as it may be changed by the parsers (NET-602)
final FTPClientConfig config2 = (config != null) ? new FTPClientConfig(config) : null;
return new CompositeFileEntryParser(new FTPFileEntryParser[] {
new NTFTPEntryParser(config), new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(
config2.getServerSystemKey()))
});
}
}
public FTPFileEntryParser createOS2FTPEntryParser() {
return new OS2FTPEntryParser();
}
public FTPFileEntryParser createOS400FTPEntryParser() {
return createOS400FTPEntryParser(null);
}
/**
* Creates an OS400 FTP parser: if the config exists, and the system key equals
* {@link FTPClientConfig.SYST_OS400} then a plain {@link OS400FTPEntryParser} is used,
* otherwise a composite of {@link OS400FTPEntryParser} and {@link UnixFTPEntryParser} is used.
*
* @param config the config to use, may be {@code null}
* @return the parser
*/
private FTPFileEntryParser createOS400FTPEntryParser(FTPClientConfig config) {
if (config != null && FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) {
return new OS400FTPEntryParser(config);
} else {
// clone the config as it may be changed by the parsers (NET-602)
final FTPClientConfig config2 = (config != null) ? new FTPClientConfig(config) : null;
return new CompositeFileEntryParser(new FTPFileEntryParser[] {
new OS400FTPEntryParser(config), new UnixFTPEntryParser(config2,
config2 != null && FTPClientConfig.SYST_UNIX_TRIM_LEADING.equals(
config2.getServerSystemKey()))
});
}
}
public FTPFileEntryParser createMVSEntryParser() {
return new MVSFTPEntryParser();
}
}

@ -1,159 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more