Search code examples
antftpapache-commons-net

ant ftp doesn't download files in subdirectories


I'm trying to download files in subdirectories from an ftp server with ant. The exact set of files is known. Some of them are in subdirectories. Ant only seems to download the ones in the root directory. It does work if I download all files without listing them.

The first ftp action should do the exact same thing as the second. Instead I get "Hidden file \\a\a.txt assumed to not be a symlink."

Does anyone know what's wrong here? Is this a bug in the ant FTP task?

<?xml version="1.0" encoding="utf-8"?>
<project name="example" default="example" basedir=".">
    <taskdef name="ftp" 
    classname="org.apache.tools.ant.taskdefs.optional.net.FTP" />

    <target name="example">

        <!-- doesn't work -->
        <ftp action="get" verbose="true"
        server="localhost" userid="example" password="example" 
        remotedir="">
            <fileset dir="downloads" casesensitive="false" 
            includes="a/a.txt,a/b/ab.txt,c/c.txt" />
        </ftp>

        <!-- works (but requires multiple ftp tasks) -->
        <ftp action="get" verbose="true"
        server="localhost" userid="example" password="example"
        remotedir="a">
            <fileset dir="downloads" casesensitive="false" 
            includes="a.txt,b/ab.txt" />
        </ftp>
        <ftp action="get" verbose="true"
        server="localhost" userid="example" password="example"
        remotedir="c">
            <fileset dir="downloads" casesensitive="false" 
            includes="c.txt" />
        </ftp>

    </target>

</project>

Update: I posted a bug about this to Commons Net jira https://issues.apache.org/jira/browse/NET-324

Update: I added a bugreport to the ant bugreport system https://issues.apache.org/bugzilla/show_bug.cgi?id=49296


Solution

  • I believe to have found and fixed the problem. Also see my the bugreport in jira: https://issues.apache.org/jira/browse/NET-324

    and I have added a bugreport to the ant bugreport system https://issues.apache.org/bugzilla/show_bug.cgi?id=49296

    diff --git a/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java b/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
    --- a/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
    +++ b/libs/apache-ant-1.8.1/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
    @@ -834,8 +834,7 @@
                             } else if (!result) {
                                 return;
                             }
    -                        this.curpwd = this.curpwd + remoteFileSep
    -                            + currentPathElement;
    +                        this.curpwd = getCurpwdPlusFileSep() + currentPathElement;
                         } catch (IOException ioe) {
                             throw new BuildException("could not change working dir to "
                                                      + (String) pathElements.elementAt(fcount)
    @@ -895,7 +894,7 @@
                  * @return absolute path as string
                  */
                 public String getAbsolutePath() {
    -                return curpwd + remoteFileSep + ftpFile.getName();
    +                return getCurpwdPlusFileSep() + ftpFile.getName();
                 }
                 /**
                  * find out the relative path assuming that the path used to construct
    @@ -1036,6 +1035,17 @@
                 public String getCurpwd() {
                     return curpwd;
                 }
    +
    +            /**
    +             * @return parent directory of the AntFTPFile with a remoteFileSep appended
    +             */
    +            private String getCurpwdPlusFileSep() {
    +                if (this.curpwd.endsWith(remoteFileSep)) {
    +                    return this.curpwd;
    +                }
    +                return this.curpwd + remoteFileSep;
    +            }
    +            
                 /**
                  * find out if a symbolic link is encountered in the relative path of this file
                  * from rootPath.