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.Closeable; 021import java.io.File; 022import java.io.FileInputStream; 023import java.io.FileOutputStream; 024import java.io.IOException; 025import java.net.SocketException; 026import java.net.UnknownHostException; 027 028import org.apache.commons.net.tftp.TFTP; 029import org.apache.commons.net.tftp.TFTPClient; 030import org.apache.commons.net.tftp.TFTPPacket; 031 032/** 033 * This is an example of a simple Java tftp client. Notice how all of the code is really just argument processing and error handling. 034 * <p> 035 * Usage: tftp [options] hostname localfile remotefile hostname - The name of the remote host, with optional :port localfile - The name of the local file to 036 * send or the name to use for the received file remotefile - The name of the remote file to receive or the name for the remote server to use to name the local 037 * file being sent. options: (The default is to assume -r -b) -s Send a local file -r Receive a remote file -a Use ASCII transfer mode -b Use binary transfer 038 * mode 039 */ 040public final class TFTPExample { 041 static final String USAGE = "Usage: tftp [options] hostname localfile remotefile\n\n" + "hostname - The name of the remote host [:port]\n" 042 + "localfile - The name of the local file to send or the name to use for\n" + "\tthe received file\n" 043 + "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" 044 + "options: (The default is to assume -r -b)\n" + "\t-t timeout in seconds (default 60s)\n" + "\t-s Send a local file\n" 045 + "\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"; 046 047 private static boolean close(final TFTPClient tftp, final Closeable output) { 048 boolean closed; 049 tftp.close(); 050 try { 051 if (output != null) { 052 output.close(); 053 } 054 closed = true; 055 } catch (final IOException e) { 056 closed = false; 057 System.err.println("Error: error closing file."); 058 System.err.println(e.getMessage()); 059 } 060 return closed; 061 } 062 063 public static void main(final String[] args) { 064 boolean receiveFile = true, closed; 065 int transferMode = TFTP.BINARY_MODE, argc; 066 String arg; 067 final String hostname; 068 final String localFilename; 069 final String remoteFilename; 070 final TFTPClient tftp; 071 int timeout = 60000; 072 boolean verbose = false; 073 074 // Parse options 075 for (argc = 0; argc < args.length; argc++) { 076 arg = args[argc]; 077 if (!arg.startsWith("-")) { 078 break; 079 } 080 if (arg.equals("-r")) { 081 receiveFile = true; 082 } else if (arg.equals("-s")) { 083 receiveFile = false; 084 } else if (arg.equals("-a")) { 085 transferMode = TFTP.ASCII_MODE; 086 } else if (arg.equals("-b")) { 087 transferMode = TFTP.BINARY_MODE; 088 } else if (arg.equals("-t")) { 089 timeout = 1000 * Integer.parseInt(args[++argc]); 090 } else if (arg.equals("-v")) { 091 verbose = true; 092 } else { 093 System.err.println("Error: unrecognized option."); 094 System.err.print(USAGE); 095 System.exit(1); 096 } 097 } 098 099 // Make sure there are enough arguments 100 if (args.length - argc != 3) { 101 System.err.println("Error: invalid number of arguments."); 102 System.err.print(USAGE); 103 System.exit(1); 104 } 105 106 // Get host and file arguments 107 hostname = args[argc]; 108 localFilename = args[argc + 1]; 109 remoteFilename = args[argc + 2]; 110 111 // Create our TFTP instance to handle the file transfer. 112 if (verbose) { 113 tftp = new TFTPClient() { 114 @Override 115 protected void trace(final String direction, final TFTPPacket packet) { 116 System.out.println(direction + " " + packet); 117 } 118 }; 119 } else { 120 tftp = new TFTPClient(); 121 } 122 123 // We want to timeout if a response takes longer than 60 seconds 124 tftp.setDefaultTimeout(timeout); 125 126 // We haven't closed the local file yet. 127 closed = false; 128 129 // If we're receiving a file, receive, otherwise send. 130 if (receiveFile) { 131 closed = receive(transferMode, hostname, localFilename, remoteFilename, tftp); 132 } else { 133 // We're sending a file 134 closed = send(transferMode, hostname, localFilename, remoteFilename, tftp); 135 } 136 137 System.out.println("Recd: " + tftp.getTotalBytesReceived() + " Sent: " + tftp.getTotalBytesSent()); 138 139 if (!closed) { 140 System.out.println("Failed"); 141 System.exit(1); 142 } 143 144 System.out.println("OK"); 145 } 146 147 private static void open(final TFTPClient tftp) { 148 try { 149 tftp.open(); 150 } catch (final SocketException e) { 151 throw new RuntimeException("Error: could not open local UDP socket.", e); 152 } 153 } 154 155 private static boolean receive(final int transferMode, final String hostname, final String localFilename, final String remoteFilename, 156 final TFTPClient tftp) { 157 final boolean closed; 158 FileOutputStream output = null; 159 final File file; 160 161 file = new File(localFilename); 162 163 // If file exists, don't overwrite it. 164 if (file.exists()) { 165 System.err.println("Error: " + localFilename + " already exists."); 166 return false; 167 } 168 169 // Try to open local file for writing 170 try { 171 output = new FileOutputStream(file); 172 } catch (final IOException e) { 173 tftp.close(); 174 throw new RuntimeException("Error: could not open local file for writing.", e); 175 } 176 177 open(tftp); 178 179 // Try to receive remote file via TFTP 180 try { 181 final String[] parts = hostname.split(":"); 182 if (parts.length == 2) { 183 tftp.receiveFile(remoteFilename, transferMode, output, parts[0], Integer.parseInt(parts[1])); 184 } else { 185 tftp.receiveFile(remoteFilename, transferMode, output, hostname); 186 } 187 } catch (final UnknownHostException e) { 188 System.err.println("Error: could not resolve hostname."); 189 System.err.println(e.getMessage()); 190 System.exit(1); 191 } catch (final IOException e) { 192 System.err.println("Error: I/O exception occurred while receiving file."); 193 System.err.println(e.getMessage()); 194 System.exit(1); 195 } finally { 196 // Close local socket and output file 197 closed = close(tftp, output); 198 } 199 200 return closed; 201 } 202 203 private static boolean send(final int transferMode, final String hostname, final String localFilename, final String remoteFilename, final TFTPClient tftp) { 204 final boolean closed; 205 FileInputStream input = null; 206 207 // Try to open local file for reading 208 try { 209 input = new FileInputStream(localFilename); 210 } catch (final IOException e) { 211 tftp.close(); 212 throw new RuntimeException("Error: could not open local file for reading.", e); 213 } 214 215 open(tftp); 216 217 // Try to send local file via TFTP 218 try { 219 final String[] parts = hostname.split(":"); 220 if (parts.length == 2) { 221 tftp.sendFile(remoteFilename, transferMode, input, parts[0], Integer.parseInt(parts[1])); 222 } else { 223 tftp.sendFile(remoteFilename, transferMode, input, hostname); 224 } 225 } catch (final UnknownHostException e) { 226 System.err.println("Error: could not resolve hostname."); 227 System.err.println(e.getMessage()); 228 System.exit(1); 229 } catch (final IOException e) { 230 System.err.println("Error: I/O exception occurred while sending file."); 231 System.err.println(e.getMessage()); 232 System.exit(1); 233 } finally { 234 // Close local socket and input file 235 closed = close(tftp, input); 236 } 237 238 return closed; 239 } 240 241}