From 3c6661202656fab045e5becd7f0b2e3f4cba293d Mon Sep 17 00:00:00 2001
From: Stefan Bodewig todo.html
are excluded.
Copies files from the local system to a remote ftp server.
+The fileset
syntax must be used for specifying the local
+files to copy. All filesets will be copied into the single remote directory
+specified by remotedir.
The ftp task makes no attempt to determine what file system syntax is +required by the remote server, and defaults to Unix standards. +remotedir must be specified in the exact syntax required by the ftp +server. If the usual Unix conventions are not supported by the server, +separator can be used to set the file separator that should be used +instead.
+See the section on directory based +tasks, on how the inclusion/exclusion of files works, and how to +write patterns.
+Attribute | +Description | +Required | +
server | +the address of the remote ftp server. | +Yes | +
port | +the port number of the remote ftp server. + Defaults to port 21. | +No | +
userid | +the login id to use on the ftp server. | +Yes | +
password | +the login password to use on the ftp server. | +Yes | +
remotedir | +the directory to which to upload files on the + ftp server. | +No | +
action | +the ftp action to perform. + Current only supports"put" | +No | +
binary | +selects binary-mode ("yes") or text-mode + ("no") transfers. + Defaults to "yes" | +No | +
verbose | +displays information on each file transferred if set + to "yes". Defaults to "no". | +No | +
depends | +transfers only new or changed files if set to + "yes". Defaults to "no". | +No | +
newer | +a synonym for depends. | +No | +
separator | +sets the file separator used on the ftp server. + Defaults to "/". | +No | +
<ftp server="ftp.apache.org" + userid="anonymous" + password="me@myorg.com" + > + <fileset dir="htdocs/manual" /> + </ftp>+
Logs in to ftp.apache.org
as anonymous
and
+uploads all files in the htdocs/manual
directory
+to the default directory for that user.
<ftp server="ftp.apache.org" + remotedir="incoming" + userid="anonymous" + password="me@myorg.com" + depends="yes" + > + <fileset dir="htdocs/manual" /> + </ftp>+
Logs in to ftp.apache.org
as anonymous
and
+uploads all new or changed files in the htdocs/manual
directory
+to the incoming
directory relative to the default directory
+for anonymous
.
<ftp server="ftp.apache.org" + port="2121" + remotedir="/pub/incoming" + userid="coder" + password="java1" + depends="yes" + binary="no" + > + <fileset dir="htdocs/manual"> + <include name="**/*.html" /> + </fileset> + </ftp>+
Logs in to ftp.apache.org
at port 2121
as
+coder
with password java1
and uploads all new or
+changed HTML files in the htdocs/manual
directory to the
+/pub/incoming
directory. The files are transferred in text
+mode.
<ftp server="ftp.nt.org" + remotedir="c:\uploads" + userid="coder" + password="java1" + separator="\" + verbose="yes" + > + <fileset dir="htdocs/manual"> + <include name="**/*.html" /> + </fileset> + </ftp>+
Logs in to the Windows-based ftp.nt.org
as
+coder
with password java1
and uploads all
+HTML files in the htdocs/manual
directory to the
+c:\uploads
directory. Progress messages are displayed as each
+file is uploaded.
Compiles a NetRexx
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index 66373b9d9..f838a2d88 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -54,6 +54,7 @@ ejbjar=org.apache.tools.ant.taskdefs.optional.ejb.EjbJar
mparse=org.apache.tools.ant.taskdefs.optional.metamata.MParse
junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
cab=org.apache.tools.ant.taskdefs.optional.Cab
+ftp=org.apache.tools.ant.taskdefs.optional.FTP
# deprecated ant tasks (kept for back compatibility)
javadoc2=org.apache.tools.ant.taskdefs.Javadoc
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/FTP.java b/src/main/org/apache/tools/ant/taskdefs/optional/FTP.java
new file mode 100644
index 000000000..17c44e982
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/FTP.java
@@ -0,0 +1,535 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * separator
task parameter. No
+ * attempt is made to determine what syntax is appropriate for the
+ * remote host.
+ */
+ protected String resolveFile(String file)
+ {
+ return file.replace(System.getProperty("file.separator").charAt(0),
+ remoteFileSep.charAt(0));
+ }
+
+ /**
+ * Creates all parent directories specified in a complete relative
+ * pathname. Attempts to create existing directories will not cause
+ * errors.
+ */
+ protected void createParents(FTPClient ftp, String filename)
+ throws IOException, BuildException
+ {
+ Vector parents = new Vector();
+ File dir = new File(filename);
+ String dirname;
+
+ while ((dirname = dir.getParent()) != null)
+ {
+ dir = new File(dirname);
+ parents.addElement(dir);
+ }
+
+ for (int i = parents.size() - 1; i >= 0; i--)
+ {
+ dir = (File)parents.elementAt(i);
+ if (!dirCache.contains(dir))
+ {
+ log("creating remote directory " + resolveFile(dir.getPath()),
+ Project.MSG_VERBOSE);
+ ftp.makeDirectory(resolveFile(dir.getPath()));
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()) &&
+ (ftp.getReplyCode() != 550))
+ {
+ throw new BuildException(
+ "could not create directory: " +
+ ftp.getReplyString());
+ }
+ dirCache.addElement(dir);
+ }
+ }
+ }
+
+ /**
+ * Checks to see if the remote file is current as compared with the
+ * local file. Returns true if the remote file is up to date.
+ */
+ protected boolean isUpToDate(FTPClient ftp, File localFile, String remoteFile)
+ throws IOException, BuildException
+ {
+ log("checking date for " + remoteFile, Project.MSG_VERBOSE);
+
+ FTPFile[] files = ftp.listFiles(remoteFile);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
+ {
+ throw new BuildException(
+ "could not date test remote file: " +
+ ftp.getReplyString());
+ }
+
+ if (files == null)
+ {
+ return false;
+ }
+
+ return files[0].getTimestamp().getTime().getTime() >
+ localFile.lastModified();
+ }
+
+ /**
+ * 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 the file. The file
+ * will then be sent using the entire relative path spec - no attempt
+ * is made to change directories. It is anticipated that this may
+ * eventually cause problems with some FTP servers, but it simplifies
+ * the coding.
+ */
+ protected void sendFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException
+ {
+ InputStream instream = null;
+ try
+ {
+ File file = project.resolveFile(new File(dir, filename).getPath());
+
+ if (newerOnly && isUpToDate(ftp, file, resolveFile(filename)))
+ return;
+
+ if (verbose)
+ {
+ log("transferring " + file.getAbsolutePath());
+ }
+
+ instream = new BufferedInputStream(new FileInputStream(file));
+
+ createParents(ftp, filename);
+
+ ftp.storeFile(resolveFile(filename), instream);
+
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
+ {
+ throw new BuildException(
+ "could not transfer file: " +
+ ftp.getReplyString());
+ }
+
+ log("File " + file.getAbsolutePath() + " copied to " + server,
+ Project.MSG_VERBOSE);
+
+ transferred++;
+ }
+ finally
+ {
+ if (instream != null)
+ {
+ try
+ {
+ instream.close();
+ }
+ catch(IOException ex)
+ {
+ // ignore it
+ }
+ }
+ }
+ }
+
+ /**
+ * Runs the task.
+ */
+ public void execute()
+ throws BuildException
+ {
+ checkConfiguration();
+
+ FTPClient ftp = null;
+
+ try
+ {
+ log("Opening FTP connection to " + server, Project.MSG_VERBOSE);
+
+ ftp = new FTPClient();
+
+ ftp.connect(server, port);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
+ {
+ throw new BuildException("FTP connection failed: " + ftp.getReplyString());
+ }
+
+ log("connected", Project.MSG_VERBOSE);
+ log("logging in to FTP server", Project.MSG_VERBOSE);
+
+ if (!ftp.login(userid, password))
+ {
+ throw new BuildException("Could not login to FTP server");
+ }
+
+ log("login succeeded", Project.MSG_VERBOSE);
+
+ if (binary)
+ {
+ ftp.setFileType(com.oroinc.net.ftp.FTP.IMAGE_FILE_TYPE);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
+ {
+ throw new BuildException(
+ "could not set transfer type: " +
+ ftp.getReplyString());
+ }
+ }
+
+ if (remotedir != null)
+ {
+ log("changing the remote directory", Project.MSG_VERBOSE);
+ ftp.changeWorkingDirectory(remotedir);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode()))
+ {
+ throw new BuildException(
+ "could not change remote directory: " +
+ ftp.getReplyString());
+ }
+ }
+
+ log("transferring files");
+
+ if (action == SEND_FILES)
+ {
+ sendFiles(ftp);
+ }
+ else
+ {
+ throw new BuildException("getting files is not yet supported");
+ }
+ }
+ catch(IOException ex)
+ {
+ throw new BuildException("error during FTP transfer: " + ex);
+ }
+ finally
+ {
+ /*
+ if (ftp != null && ftp.isConnected())
+ {
+ try
+ {
+ // this hangs - I don't know why.
+ ftp.disconnect();
+ }
+ catch(IOException ex)
+ {
+ // ignore it
+ }
+ }
+ */
+ }
+ }
+}