001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.examples.ftp;
019
020import java.io.IOException;
021import java.io.PrintWriter;
022import java.net.InetAddress;
023
024import org.apache.commons.net.PrintCommandListener;
025import org.apache.commons.net.ProtocolCommandListener;
026import org.apache.commons.net.ftp.FTPClient;
027import org.apache.commons.net.ftp.FTPReply;
028
029/**
030 * This is an example program demonstrating how to use the FTPClient class. This program arranges a server to server file transfer that transfers a file from
031 * host1 to host2. Keep in mind, this program might only work if host2 is the same as the host you run it on (for security reasons, some ftp servers only allow
032 * PORT commands to be issued with a host argument equal to the client host).
033 * <p>
034 * Usage: ftp <host1> <user1> <pass1> <file1> <host2> <user2> <pass2> <file2>
035 */
036public final class ServerToServerFTP {
037
038    public static void main(final String[] args) {
039        String server1;
040        final String username1;
041        final String password1;
042        final String file1;
043        String server2;
044        final String username2;
045        final String password2;
046        final String file2;
047        String[] parts;
048        int port1 = 0, port2 = 0;
049        final FTPClient ftp1;
050        final FTPClient ftp2;
051        final ProtocolCommandListener listener;
052
053        if (args.length < 8) {
054            System.err.println("Usage: ftp <host1> <user1> <pass1> <file1> <host2> <user2> <pass2> <file2>");
055            System.exit(1);
056        }
057
058        server1 = args[0];
059        parts = server1.split(":");
060        if (parts.length == 2) {
061            server1 = parts[0];
062            port1 = Integer.parseInt(parts[1]);
063        }
064        username1 = args[1];
065        password1 = args[2];
066        file1 = args[3];
067        server2 = args[4];
068        parts = server2.split(":");
069        if (parts.length == 2) {
070            server2 = parts[0];
071            port2 = Integer.parseInt(parts[1]);
072        }
073        username2 = args[5];
074        password2 = args[6];
075        file2 = args[7];
076
077        listener = new PrintCommandListener(new PrintWriter(System.out), true);
078        ftp1 = new FTPClient();
079        ftp1.addProtocolCommandListener(listener);
080        ftp2 = new FTPClient();
081        ftp2.addProtocolCommandListener(listener);
082
083        try {
084            final int reply;
085            if (port1 > 0) {
086                ftp1.connect(server1, port1);
087            } else {
088                ftp1.connect(server1);
089            }
090            System.out.println("Connected to " + server1 + ".");
091
092            reply = ftp1.getReplyCode();
093
094            if (!FTPReply.isPositiveCompletion(reply)) {
095                ftp1.disconnect();
096                System.err.println("FTP server1 refused connection.");
097                System.exit(1);
098            }
099        } catch (final IOException e) {
100            if (ftp1.isConnected()) {
101                try {
102                    ftp1.disconnect();
103                } catch (final IOException f) {
104                    // do nothing
105                }
106            }
107            System.err.println("Could not connect to server1.");
108            e.printStackTrace();
109            System.exit(1);
110        }
111
112        try {
113            final int reply;
114            if (port2 > 0) {
115                ftp2.connect(server2, port2);
116            } else {
117                ftp2.connect(server2);
118            }
119            System.out.println("Connected to " + server2 + ".");
120
121            reply = ftp2.getReplyCode();
122
123            if (!FTPReply.isPositiveCompletion(reply)) {
124                ftp2.disconnect();
125                System.err.println("FTP server2 refused connection.");
126                System.exit(1);
127            }
128        } catch (final IOException e) {
129            if (ftp2.isConnected()) {
130                try {
131                    ftp2.disconnect();
132                } catch (final IOException f) {
133                    // do nothing
134                }
135            }
136            System.err.println("Could not connect to server2.");
137            e.printStackTrace();
138            System.exit(1);
139        }
140
141        __main: try {
142            if (!ftp1.login(username1, password1)) {
143                System.err.println("Could not login to " + server1);
144                break __main;
145            }
146
147            if (!ftp2.login(username2, password2)) {
148                System.err.println("Could not login to " + server2);
149                break __main;
150            }
151
152            // Let's just assume success for now.
153            ftp2.enterRemotePassiveMode();
154
155            ftp1.enterRemoteActiveMode(InetAddress.getByName(ftp2.getPassiveHost()), ftp2.getPassivePort());
156
157            // Although you would think the store command should be sent to server2
158            // first, in reality, ftp servers like wu-ftpd start accepting data
159            // connections right after entering passive mode. Additionally, they
160            // don't even send the positive preliminary reply until after the
161            // transfer is completed (in the case of passive mode transfers).
162            // Therefore, calling store first would hang waiting for a preliminary
163            // reply.
164            if (!ftp1.remoteRetrieve(file1) || !ftp2.remoteStoreUnique(file2)) {
165                System.err.println("Couldn't initiate transfer. Check that file names are valid.");
166                break __main;
167            }
168            // if(ftp1.remoteRetrieve(file1) && ftp2.remoteStore(file2)) {
169            // We have to fetch the positive completion reply.
170            ftp1.completePendingCommand();
171            ftp2.completePendingCommand();
172
173        } catch (final IOException e) {
174            e.printStackTrace();
175            System.exit(1);
176        } finally {
177            try {
178                if (ftp1.isConnected()) {
179                    ftp1.logout();
180                    ftp1.disconnect();
181                }
182            } catch (final IOException e) {
183                // do nothing
184            }
185
186            try {
187                if (ftp2.isConnected()) {
188                    ftp2.logout();
189                    ftp2.disconnect();
190                }
191            } catch (final IOException e) {
192                // do nothing
193            }
194        }
195    }
196}