1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.examples.ftp;
19
20 import java.io.Closeable;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.net.SocketException;
26 import java.net.UnknownHostException;
27 import java.time.Duration;
28
29 import org.apache.commons.net.tftp.TFTP;
30 import org.apache.commons.net.tftp.TFTPClient;
31 import org.apache.commons.net.tftp.TFTPPacket;
32
33
34
35
36
37
38
39
40
41
42 public final class TFTPExample {
43 static final String USAGE = "Usage: TFTPExample [options] hostname localfile remotefile\n\n" + "hostname - The name of the remote host [:port]\n"
44 + "localfile - The name of the local file to send or the name to use for\n" + "\tthe received file\n"
45 + "remotefile - The name of the remote file to receive or the name for\n" + "\tthe remote server to use to name the local file being sent.\n\n"
46 + "options: (The default is to assume -r -b)\n" + "\t-t timeout in seconds (default 60s)\n" + "\t-s Send a local file\n"
47 + "\t-r Receive a remote file\n" + "\t-a Use ASCII transfer mode\n" + "\t-b Use binary transfer mode\n" + "\t-v Verbose (trace packets)\n";
48
49 private static boolean close(final TFTPClient tftp, final Closeable output) {
50 boolean closed;
51 tftp.close();
52 try {
53 if (output != null) {
54 output.close();
55 }
56 closed = true;
57 } catch (final IOException e) {
58 closed = false;
59 System.err.println("Error: error closing file.");
60 System.err.println(e.getMessage());
61 }
62 return closed;
63 }
64
65 public static void main(final String[] args) throws IOException {
66 boolean receiveFile = true, closed;
67 int transferMode = TFTP.BINARY_MODE, argc;
68 String arg;
69 final String hostname;
70 final String localFilename;
71 final String remoteFilename;
72 final TFTPClient tftp;
73 int timeout = 60000;
74 boolean verbose = false;
75
76
77 for (argc = 0; argc < args.length; argc++) {
78 arg = args[argc];
79 if (!arg.startsWith("-")) {
80 break;
81 }
82 if (arg.equals("-r")) {
83 receiveFile = true;
84 } else if (arg.equals("-s")) {
85 receiveFile = false;
86 } else if (arg.equals("-a")) {
87 transferMode = TFTP.ASCII_MODE;
88 } else if (arg.equals("-b")) {
89 transferMode = TFTP.BINARY_MODE;
90 } else if (arg.equals("-t")) {
91 timeout = 1000 * Integer.parseInt(args[++argc]);
92 } else if (arg.equals("-v")) {
93 verbose = true;
94 } else {
95 System.err.println("Error: unrecognized option.");
96 System.err.print(USAGE);
97 System.exit(1);
98 }
99 }
100
101
102 if (args.length - argc != 3) {
103 System.err.println("Error: invalid number of arguments.");
104 System.err.print(USAGE);
105 System.exit(1);
106 }
107
108
109 hostname = args[argc];
110 localFilename = args[argc + 1];
111 remoteFilename = args[argc + 2];
112
113
114 if (verbose) {
115 tftp = new TFTPClient() {
116 @Override
117 protected void trace(final String direction, final TFTPPacket packet) {
118 System.out.println(direction + " " + packet);
119 }
120 };
121 } else {
122 tftp = new TFTPClient();
123 }
124
125
126 tftp.setDefaultTimeout(Duration.ofSeconds(timeout));
127
128
129 closed = false;
130
131
132 if (receiveFile) {
133 closed = receive(transferMode, hostname, localFilename, remoteFilename, tftp);
134 } else {
135
136 closed = send(transferMode, hostname, localFilename, remoteFilename, tftp);
137 }
138
139 System.out.println("Recd: " + tftp.getTotalBytesReceived() + " Sent: " + tftp.getTotalBytesSent());
140
141 if (!closed) {
142 System.out.println("Failed");
143 System.exit(1);
144 }
145
146 System.out.println("OK");
147 }
148
149 private static void open(final TFTPClient tftp) throws IOException {
150 try {
151 tftp.open();
152 } catch (final SocketException e) {
153 throw new IOException("Error: could not open local UDP socket.", e);
154 }
155 }
156
157 private static boolean receive(final int transferMode, final String hostname, final String localFilename, final String remoteFilename,
158 final TFTPClient tftp) throws IOException {
159 final File file = new File(localFilename);
160
161 if (file.exists()) {
162 System.err.println("Error: " + localFilename + " already exists.");
163 return false;
164 }
165 FileOutputStream output;
166
167 try {
168 output = new FileOutputStream(file);
169 } catch (final IOException e) {
170 tftp.close();
171 throw new IOException("Error: could not open local file for writing.", e);
172 }
173 open(tftp);
174 final boolean closed;
175
176 try {
177 final String[] parts = hostname.split(":");
178 if (parts.length == 2) {
179 tftp.receiveFile(remoteFilename, transferMode, output, parts[0], Integer.parseInt(parts[1]));
180 } else {
181 tftp.receiveFile(remoteFilename, transferMode, output, hostname);
182 }
183 } catch (final UnknownHostException e) {
184 System.err.println("Error: could not resolve hostname.");
185 System.err.println(e.getMessage());
186 System.exit(1);
187 } catch (final IOException e) {
188 System.err.println("Error: I/O exception occurred while receiving file.");
189 System.err.println(e.getMessage());
190 System.exit(1);
191 } finally {
192
193 closed = close(tftp, output);
194 }
195 return closed;
196 }
197
198 private static boolean send(final int transferMode, final String hostname, final String localFilename, final String remoteFilename, final TFTPClient tftp)
199 throws IOException {
200 FileInputStream input;
201
202 try {
203 input = new FileInputStream(localFilename);
204 } catch (final IOException e) {
205 tftp.close();
206 throw new IOException("Error: could not open local file for reading.", e);
207 }
208 open(tftp);
209 final boolean closed;
210
211 try {
212 final String[] parts = hostname.split(":");
213 if (parts.length == 2) {
214 tftp.sendFile(remoteFilename, transferMode, input, parts[0], Integer.parseInt(parts[1]));
215 } else {
216 tftp.sendFile(remoteFilename, transferMode, input, hostname);
217 }
218 } catch (final UnknownHostException e) {
219 System.err.println("Error: could not resolve hostname.");
220 System.err.println(e.getMessage());
221 System.exit(1);
222 } catch (final IOException e) {
223 System.err.println("Error: I/O exception occurred while sending file.");
224 System.err.println(e.getMessage());
225 System.exit(1);
226 } finally {
227
228 closed = close(tftp, input);
229 }
230 return closed;
231 }
232
233 }