--- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java +++ a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java @@ -89,6 +89,7 @@ public class FTP extends Task implements FTPTaskConfig { protected static final int CHMOD = 5; protected static final int RM_DIR = 6; protected static final int SITE_CMD = 7; + protected static final int FEAT = 8; /** return code of ftp */ private static final int CODE_521 = 521; private static final int CODE_550 = 550; @@ -2176,6 +2177,30 @@ public class FTP extends Task implements FTPTaskConfig { } /** + * Sends the feat command to the ftp server + * @param ftp ftp client + * @throws IOException in unknown circumstances + * @throws BuildException in unknown circumstances + */ + protected void doFeatCommand(FTPClient ftp) + throws IOException, BuildException { + + log("Doing Feat Command: ", Project.MSG_VERBOSE); + + // use commons-net 1.4 compatible syntax although there + // are alternatives for newer versions + if (ftp.sendCommand("FEAT") != 211) { + log("Failed to issue Feat Command: ", Project.MSG_WARN); + } else { + for (String reply : ftp.getReplyStrings()) { + if (reply != null && !reply.contains("211")) { + log(reply, Project.MSG_WARN); + } + } + } + } + + /** * Sends a single file to the remote host. filename may * contain a relative path specification. When this is the case, sendFile * will attempt to create any necessary parent directories before sending @@ -2590,6 +2615,11 @@ public class FTP extends Task implements FTPTaskConfig { executeRetryable(new RetryHandler(this.retriesAllowed, this), () -> doSiteCommand(lftp, FTP.this.siteCommand), "Site Command: " + this.siteCommand); + } else if (action == FEAT) { + final FTPClient lftp = ftp; + executeRetryable(new RetryHandler(this.retriesAllowed, this), + () -> doFeatCommand(lftp), + "Feat Command"); } else { if (remotedir != null) { log("changing the remote directory to " + remotedir, @@ -2644,13 +2674,13 @@ public class FTP extends Task implements FTPTaskConfig { /** * an action to perform, one of * "send", "put", "recv", "get", "del", "delete", "list", "mkdir", "chmod", - * "rmdir" + * "rmdir", "feat" */ public static class Action extends EnumeratedAttribute { private static final String[] VALID_ACTIONS = { "send", "put", "recv", "get", "del", "delete", "list", "mkdir", - "chmod", "rmdir", "site" + "chmod", "rmdir", "site", "feat" }; /** @@ -2689,6 +2719,8 @@ public class FTP extends Task implements FTPTaskConfig { return RM_DIR; case "site": return SITE_CMD; + case "feat": + return FEAT; default: return SEND_FILES; }