***/ public final class ListNewsgroups { public final static void main(String[] args) { NNTPClient client; NewsgroupInfo[] list; if (args.length < 1) { System.err.println("Usage: newsgroups newsserver"); System.exit(1); } client = new NNTPClient(); try { client.connect(args[0]); list = client.listNewsgroups(); if (list != null) { for (int i = 0; i < list.length; i++) System.out.println(list[i].getNewsgroup()); } else { System.err.println("LIST command failed."); System.err.println("Server reply: " + client.getReplyString()); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (client.isConnected()) client.disconnect(); } catch (IOException e) { System.err.println("Error disconnecting from server."); e.printStackTrace(); System.exit(1); } } } } commons-net-2.2/src/main/java/examples/unix/ 0000755 0001750 0001750 00000000000 11617452467 021024 5 ustar twerner twerner commons-net-2.2/src/main/java/examples/unix/rexec.java 0000644 0001750 0001750 00000006031 11165734447 022774 0 ustar twerner twerner /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package examples.unix; import java.io.IOException; import org.apache.commons.net.bsd.RExecClient; import examples.util.IOUtil; /*** * This is an example program demonstrating how to use the RExecClient class. * This program connects to an rexec server and requests that the * given command be executed on the server. It then reads input from stdin * (this will be line buffered on most systems, so don't expect character * at a time interactivity), passing it to the remote process and writes * the process stdout and stderr to local stdout. *
* Example: java rexec myhost myusername mypassword "ps -aux" *
* Usage: rexec
***/
// This class requires the IOUtil support class!
public final class rexec
{
public static final void main(String[] args)
{
String server, username, password, command;
RExecClient client;
if (args.length != 4)
{
System.err.println(
"Usage: rexec
* The -l flag is used to request long output from the server.
*
***/
public final class finger
{
public static final void main(String[] args)
{
boolean longOutput = false;
int arg = 0, index;
String handle, host;
FingerClient finger;
InetAddress address = null;
// Get flags. If an invalid flag is present, exit with usage message.
while (arg < args.length && args[arg].startsWith("-"))
{
if (args[arg].equals("-l"))
longOutput = true;
else
{
System.err.println("usage: finger [-l] [[[handle][@
***/
public final class fwhois
{
public static final void main(String[] args)
{
int index;
String handle, host;
InetAddress address = null;
WhoisClient whois;
if (args.length != 1)
{
System.err.println("usage: fwhois handle[@
* Usage: chargen [-udp]
***/
public final class chargen
{
public static final void chargenTCP(String host) throws IOException
{
int lines = 100;
String line;
CharGenTCPClient client = new CharGenTCPClient();
BufferedReader chargenInput;
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.connect(host);
chargenInput =
new BufferedReader(new InputStreamReader(client.getInputStream()));
// We assume the chargen service outputs lines, but it really doesn't
// have to, so this code might actually not work if no newlines are
// present.
while (lines-- > 0)
{
if ((line = chargenInput.readLine()) == null)
break;
System.out.println(line);
}
client.disconnect();
}
public static final void chargenUDP(String host) throws IOException
{
int packets = 50;
byte[] data;
InetAddress address;
CharGenUDPClient client;
address = InetAddress.getByName(host);
client = new CharGenUDPClient();
client.open();
// If we don't receive a return packet within 5 seconds, assume
// the packet is lost.
client.setSoTimeout(5000);
while (packets-- > 0)
{
client.send(address);
try
{
data = client.receive();
}
// Here we catch both SocketException and InterruptedIOException,
// because even though the JDK 1.1 docs claim that
// InterruptedIOException is thrown on a timeout, it seems
// SocketException is also thrown.
catch (SocketException e)
{
// We timed out and assume the packet is lost.
System.err.println("SocketException: Timed out and dropped packet");
continue;
}
catch (InterruptedIOException e)
{
// We timed out and assume the packet is lost.
System.err.println(
"InterruptedIOException: Timed out and dropped packet");
continue;
}
System.out.write(data);
System.out.flush();
}
client.close();
}
public static final void main(String[] args)
{
if (args.length == 1)
{
try
{
chargenTCP(args[0]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else if (args.length == 2 && args[0].equals("-udp"))
{
try
{
chargenUDP(args[1]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else
{
System.err.println("Usage: chargen [-udp]
* Usage: rdate [-udp]
*
* @author Daniel F. Savarese
***/
public final class rdate
{
public static final void timeTCP(String host) throws IOException
{
TimeTCPClient client = new TimeTCPClient();
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.connect(host);
System.out.println(client.getDate().toString());
client.disconnect();
}
public static final void timeUDP(String host) throws IOException
{
TimeUDPClient client = new TimeUDPClient();
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.open();
System.out.println(client.getDate(InetAddress.getByName(host)).toString());
client.close();
}
public static final void main(String[] args)
{
if (args.length == 1)
{
try
{
timeTCP(args[0]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else if (args.length == 2 && args[0].equals("-udp"))
{
try
{
timeUDP(args[1]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else
{
System.err.println("Usage: rdate [-udp]
* Usage: daytime [-udp]
***/
public final class daytime
{
public static final void daytimeTCP(String host) throws IOException
{
DaytimeTCPClient client = new DaytimeTCPClient();
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.connect(host);
System.out.println(client.getTime().trim());
client.disconnect();
}
public static final void daytimeUDP(String host) throws IOException
{
DaytimeUDPClient client = new DaytimeUDPClient();
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.open();
System.out.println(client.getTime(
InetAddress.getByName(host)).trim());
client.close();
}
public static final void main(String[] args)
{
if (args.length == 1)
{
try
{
daytimeTCP(args[0]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else if (args.length == 2 && args[0].equals("-udp"))
{
try
{
daytimeUDP(args[1]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else
{
System.err.println("Usage: daytime [-udp]
* Usage: echo [-udp]
***/
public final class echo
{
public static final void echoTCP(String host) throws IOException
{
EchoTCPClient client = new EchoTCPClient();
BufferedReader input, echoInput;
PrintWriter echoOutput;
String line;
// We want to timeout if a response takes longer than 60 seconds
client.setDefaultTimeout(60000);
client.connect(host);
System.out.println("Connected to " + host + ".");
input = new BufferedReader(new InputStreamReader(System.in));
echoOutput =
new PrintWriter(new OutputStreamWriter(client.getOutputStream()), true);
echoInput =
new BufferedReader(new InputStreamReader(client.getInputStream()));
while ((line = input.readLine()) != null)
{
echoOutput.println(line);
System.out.println(echoInput.readLine());
}
client.disconnect();
}
public static final void echoUDP(String host) throws IOException
{
int length, count;
byte[] data;
String line;
BufferedReader input;
InetAddress address;
EchoUDPClient client;
input = new BufferedReader(new InputStreamReader(System.in));
address = InetAddress.getByName(host);
client = new EchoUDPClient();
client.open();
// If we don't receive an echo within 5 seconds, assume the packet is lost.
client.setSoTimeout(5000);
System.out.println("Ready to echo to " + host + ".");
// Remember, there are no guarantees about the ordering of returned
// UDP packets, so there is a chance the output may be jumbled.
while ((line = input.readLine()) != null)
{
data = line.getBytes();
client.send(data, address);
count = 0;
do
{
try
{
length = client.receive(data);
}
// Here we catch both SocketException and InterruptedIOException,
// because even though the JDK 1.1 docs claim that
// InterruptedIOException is thrown on a timeout, it seems
// SocketException is also thrown.
catch (SocketException e)
{
// We timed out and assume the packet is lost.
System.err.println(
"SocketException: Timed out and dropped packet");
break;
}
catch (InterruptedIOException e)
{
// We timed out and assume the packet is lost.
System.err.println(
"InterruptedIOException: Timed out and dropped packet");
break;
}
System.out.print(new String(data, 0, length));
count += length;
}
while (count < data.length);
System.out.println();
}
client.close();
}
public static final void main(String[] args)
{
if (args.length == 1)
{
try
{
echoTCP(args[0]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else if (args.length == 2 && args[0].equals("-udp"))
{
try
{
echoUDP(args[1]);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
else
{
System.err.println("Usage: echo [-udp]
* On Unix systems you will not be able to use the rshell capability
* unless the process runs as root since only root can bind port addresses
* lower than 1024.
*
* JVM's using green threads will likely have problems if the rlogin daemon
* requests a password. This program is merely a demonstration and is
* not suitable for use as an application, especially given that it relies
* on line buffered input from System.in. The best way to run this example
* is probably from a Win95 dos box into a Unix host.
*
* Example: java rlogin myhost localusername remoteusername vt100
*
* Usage: rlogin
***/
// This class requires the IOUtil support class!
public final class rlogin
{
public static final void main(String[] args)
{
String server, localuser, remoteuser, terminal;
RLoginClient client;
if (args.length != 4)
{
System.err.println(
"Usage: rlogin
* On Unix systems you will not be able to use the rshell capability
* unless the process runs as root since only root can bind port addresses
* lower than 1024.
*
* Example: java rshell myhost localusername remoteusername "ps -aux"
*
* Usage: rshell
***/
// This class requires the IOUtil support class!
public final class rshell
{
public static final void main(String[] args)
{
String server, localuser, remoteuser, command;
RCommandClient client;
if (args.length != 4)
{
System.err.println(
"Usage: rshell
***/
// This class requires the IOUtil support class!
public final class WeatherTelnet
{
public final static void main(String[] args)
{
TelnetClient telnet;
telnet = new TelnetClient();
try
{
telnet.connect("rainmaker.wunderground.com", 3000);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(),
System.in, System.out);
try
{
telnet.disconnect();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}
commons-net-2.2/src/main/java/examples/telnet/TelnetClientExample.java 0000644 0001750 0001750 00000032065 11165734447 026112 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples.telnet;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.SimpleOptionHandler;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import java.util.StringTokenizer;
/***
* This is a simple example of use of TelnetClient.
* An external option handler (SimpleTelnetOptionHandler) is used.
* Initial configuration requested by TelnetClient will be:
* WILL ECHO, WILL SUPPRESS-GA, DO SUPPRESS-GA.
* VT100 terminal type will be subnegotiated.
*
* Also, use of the sendAYT(), getLocalOptionState(), getRemoteOptionState()
* is demonstrated.
* When connected, type AYT to send an AYT command to the server and see
* the result.
* Type OPT to see a report of the state of the first 25 options.
*
* @author Bruno D'Avanzo
***/
public class TelnetClientExample implements Runnable, TelnetNotificationHandler
{
static TelnetClient tc = null;
/***
* Main for the TelnetClientExample.
***/
public static void main(String[] args) throws IOException
{
FileOutputStream fout = null;
if(args.length < 1)
{
System.err.println("Usage: TelnetClientExample1
* @param negotiation_code - type of negotiation command received
* (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT)
*
* @param option_code - code of the option negotiated
*
***/
public void receivedNegotiation(int negotiation_code, int option_code)
{
String command = null;
if(negotiation_code == TelnetNotificationHandler.RECEIVED_DO)
{
command = "DO";
}
else if(negotiation_code == TelnetNotificationHandler.RECEIVED_DONT)
{
command = "DONT";
}
else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WILL)
{
command = "WILL";
}
else if(negotiation_code == TelnetNotificationHandler.RECEIVED_WONT)
{
command = "WONT";
}
System.out.println("Received " + command + " for option code " + option_code);
}
/***
* Reader thread.
* Reads lines from the TelnetClient and echoes them
* on the screen.
***/
public void run()
{
InputStream instr = tc.getInputStream();
try
{
byte[] buff = new byte[1024];
int ret_read = 0;
do
{
ret_read = instr.read(buff);
if(ret_read > 0)
{
System.out.print(new String(buff, 0, ret_read));
}
}
while (ret_read >= 0);
}
catch (Exception e)
{
System.err.println("Exception while reading socket:" + e.getMessage());
}
try
{
tc.disconnect();
}
catch (Exception e)
{
System.err.println("Exception while closing telnet:" + e.getMessage());
}
}
}
commons-net-2.2/src/main/java/examples/ftp/ 0000755 0001750 0001750 00000000000 11617452467 020632 5 ustar twerner twerner commons-net-2.2/src/main/java/examples/ftp/ServerToServerFTP.java 0000644 0001750 0001750 00000015102 11165730111 024765 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples.ftp;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
/***
* 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 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 PORT commands to be issued with a host
* argument equal to the client host).
*
* Usage: ftp
***/
public final class ServerToServerFTP
{
public static final void main(String[] args)
{
String server1, username1, password1, file1;
String server2, username2, password2, file2;
FTPClient ftp1, ftp2;
ProtocolCommandListener listener;
if (args.length < 8)
{
System.err.println(
"Usage: ftp
* Usage: ftp [-s] [-b]
***/
public final class FTPSExample
{
public static final String USAGE =
"Usage: ftp [-s] [-b]
* Usage: tftp [options] hostname localfile remotefile
* hostname - The name of the remote host
* localfile - The name of the local file to 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 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 mode
*
***/
public final class TFTPExample
{
static final String USAGE =
"Usage: tftp [options] hostname localfile remotefile\n\n" +
"hostname - The name of the remote host\n" +
"localfile - The name of the local file to send or the name to use for\n" +
"\tthe received file\n" +
"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" +
"options: (The default is to assume -r -b)\n" +
"\t-s Send a local file\n" +
"\t-r Receive a remote file\n" +
"\t-a Use ASCII transfer mode\n" +
"\t-b Use binary transfer mode\n";
public final static void main(String[] args)
{
boolean receiveFile = true, closed;
int transferMode = TFTP.BINARY_MODE, argc;
String arg, hostname, localFilename, remoteFilename;
TFTPClient tftp;
// Parse options
for (argc = 0; argc < args.length; argc++)
{
arg = args[argc];
if (arg.startsWith("-"))
{
if (arg.equals("-r"))
receiveFile = true;
else if (arg.equals("-s"))
receiveFile = false;
else if (arg.equals("-a"))
transferMode = TFTP.ASCII_MODE;
else if (arg.equals("-b"))
transferMode = TFTP.BINARY_MODE;
else
{
System.err.println("Error: unrecognized option.");
System.err.print(USAGE);
System.exit(1);
}
}
else
break;
}
// Make sure there are enough arguments
if (args.length - argc != 3)
{
System.err.println("Error: invalid number of arguments.");
System.err.print(USAGE);
System.exit(1);
}
// Get host and file arguments
hostname = args[argc];
localFilename = args[argc + 1];
remoteFilename = args[argc + 2];
// Create our TFTP instance to handle the file transfer.
tftp = new TFTPClient();
// We want to timeout if a response takes longer than 60 seconds
tftp.setDefaultTimeout(60000);
// Open local socket
try
{
tftp.open();
}
catch (SocketException e)
{
System.err.println("Error: could not open local UDP socket.");
System.err.println(e.getMessage());
System.exit(1);
}
// We haven't closed the local file yet.
closed = false;
// If we're receiving a file, receive, otherwise send.
if (receiveFile)
{
FileOutputStream output = null;
File file;
file = new File(localFilename);
// If file exists, don't overwrite it.
if (file.exists())
{
System.err.println("Error: " + localFilename + " already exists.");
System.exit(1);
}
// Try to open local file for writing
try
{
output = new FileOutputStream(file);
}
catch (IOException e)
{
tftp.close();
System.err.println("Error: could not open local file for writing.");
System.err.println(e.getMessage());
System.exit(1);
}
// Try to receive remote file via TFTP
try
{
tftp.receiveFile(remoteFilename, transferMode, output, hostname);
}
catch (UnknownHostException e)
{
System.err.println("Error: could not resolve hostname.");
System.err.println(e.getMessage());
System.exit(1);
}
catch (IOException e)
{
System.err.println(
"Error: I/O exception occurred while receiving file.");
System.err.println(e.getMessage());
System.exit(1);
}
finally
{
// Close local socket and output file
tftp.close();
try
{
output.close();
closed = true;
}
catch (IOException e)
{
closed = false;
System.err.println("Error: error closing file.");
System.err.println(e.getMessage());
}
}
if (!closed)
System.exit(1);
}
else
{
// We're sending a file
FileInputStream input = null;
// Try to open local file for reading
try
{
input = new FileInputStream(localFilename);
}
catch (IOException e)
{
tftp.close();
System.err.println("Error: could not open local file for reading.");
System.err.println(e.getMessage());
System.exit(1);
}
// Try to send local file via TFTP
try
{
tftp.sendFile(remoteFilename, transferMode, input, hostname);
}
catch (UnknownHostException e)
{
System.err.println("Error: could not resolve hostname.");
System.err.println(e.getMessage());
System.exit(1);
}
catch (IOException e)
{
System.err.println(
"Error: I/O exception occurred while sending file.");
System.err.println(e.getMessage());
System.exit(1);
}
finally
{
// Close local socket and input file
tftp.close();
try
{
input.close();
closed = true;
}
catch (IOException e)
{
closed = false;
System.err.println("Error: error closing file.");
System.err.println(e.getMessage());
}
}
if (!closed)
System.exit(1);
}
}
}
commons-net-2.2/src/main/java/examples/ftp/FTPClientExample.java 0000644 0001750 0001750 00000013035 11351143411 024560 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples.ftp;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
/***
* This is an example program demonstrating how to use the FTPClient class.
* This program connects to an FTP server and retrieves the specified
* file. If the -s flag is used, it stores the local file at the FTP server.
* Just so you can see what's happening, all reply strings are printed.
* If the -b flag is used, a binary transfer is assumed (default is ASCII).
*
* Usage: ftp [-s] [-b]
***/
public final class FTPClientExample
{
public static final String USAGE =
"Usage: ftp [-s] [-b]
* Methods exist to convert NTP timestamps to and from the equivalent Java date
* representation, which is the number of milliseconds since the standard base
* time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
*
* @param host The address of the server.
* @param port The port of the service.
* @return The time value retrieved from the server.
* @exception IOException If an error occurs while retrieving the time.
***/
public TimeInfo getTime(InetAddress host, int port) throws IOException
{
// if not connected then open to next available UDP port
if (!isOpen())
{
open();
}
NtpV3Packet message = new NtpV3Impl();
message.setMode(NtpV3Packet.MODE_CLIENT);
message.setVersion(_version);
DatagramPacket sendPacket = message.getDatagramPacket();
sendPacket.setAddress(host);
sendPacket.setPort(port);
NtpV3Packet recMessage = new NtpV3Impl();
DatagramPacket receivePacket = recMessage.getDatagramPacket();
/*
* Must minimize the time between getting the current time,
* timestamping the packet, and sending it out which
* introduces an error in the delay time.
* No extraneous logging and initializations here !!!
*/
TimeStamp now = TimeStamp.getCurrentTime();
// Note that if you do not set the transmit time field then originating time
// in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036".
message.setTransmitTime(now);
_socket_.send(sendPacket);
_socket_.receive(receivePacket);
long returnTime = System.currentTimeMillis();
// create TimeInfo message container but don't pre-compute the details yet
TimeInfo info = new TimeInfo(recMessage, returnTime, false);
return info;
}
/***
* Retrieves the time information from the specified server on the
* default NTP port and returns it. The time is the number of miliiseconds
* since 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
* This method reads the raw NTP packet and constructs a TimeInfo
* object that allows access to all the fields of the NTP message header.
*
* @param host The address of the server.
* @return The time value retrieved from the server.
* @exception IOException If an error occurs while retrieving the time.
***/
public TimeInfo getTime(InetAddress host) throws IOException
{
return getTime(host, NtpV3Packet.NTP_PORT);
}
/***
* Returns the NTP protocol version number that client sets on request packet
* that is sent to remote host (e.g. 3=NTP v3, 4=NTP v4, etc.)
*
* @return the NTP protocol version number that client sets on request packet.
* @see #setVersion(int)
***/
public int getVersion()
{
return _version;
}
/***
* Sets the NTP protocol version number that client sets on request packet
* communicate with remote host.
*
* @param version the NTP protocol version number
***/
public void setVersion(int version)
{
_version = version;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java 0000644 0001750 0001750 00000040076 11354710167 025733 0 ustar twerner twerner package org.apache.commons.net.ntp;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.DatagramPacket;
/***
* Implementation of NtpV3Packet with methods converting Java objects to/from
* the Network Time Protocol (NTP) data message header format described in RFC-1305.
*
* @author Naz Irizarry, MITRE Corp
* @author Jason Mathews, MITRE Corp
*
* @version $Revision: 929649 $ $Date: 2010-03-31 20:12:07 +0200 (Mi, 31. Mär 2010) $
*/
public class NtpV3Impl implements NtpV3Packet
{
private static final int MODE_INDEX = 0;
private static final int MODE_SHIFT = 0;
private static final int VERSION_INDEX = 0;
private static final int VERSION_SHIFT = 3;
private static final int LI_INDEX = 0;
private static final int LI_SHIFT = 6;
private static final int STRATUM_INDEX = 1;
private static final int POLL_INDEX = 2;
private static final int PRECISION_INDEX = 3;
private static final int ROOT_DELAY_INDEX = 4;
private static final int ROOT_DISPERSION_INDEX = 8;
private static final int REFERENCE_ID_INDEX = 12;
private static final int REFERENCE_TIMESTAMP_INDEX = 16;
private static final int ORIGINATE_TIMESTAMP_INDEX = 24;
private static final int RECEIVE_TIMESTAMP_INDEX = 32;
private static final int TRANSMIT_TIMESTAMP_INDEX = 40;
private static final int KEY_IDENTIFIER_INDEX = 48;
private static final int MESSAGE_DIGEST = 54; /* len 16 bytes */
private final byte[] buf = new byte[48];
private volatile DatagramPacket dp;
/** Creates a new instance of NtpV3Impl */
public NtpV3Impl()
{
}
/***
* Returns mode as defined in RFC-1305 which is a 3-bit integer
* whose value is indicated by the MODE_xxx parameters.
*
* @return mode as defined in RFC-1305.
*/
public int getMode()
{
return (ui(buf[MODE_INDEX]) >> MODE_SHIFT) & 0x7;
}
/***
* Return human-readable name of message mode type as described in
* RFC 1305.
* @return mode name as string.
*/
public String getModeName()
{
return NtpUtils.getModeName(getMode());
}
/***
* Set mode as defined in RFC-1305.
* @param mode
*/
public void setMode(int mode)
{
buf[MODE_INDEX] = (byte) (buf[MODE_INDEX] & 0xF8 | mode & 0x7);
}
/***
* Returns leap indicator as defined in RFC-1305 which is a two-bit code:
* 0=no warning
* 1=last minute has 61 seconds
* 2=last minute has 59 seconds
* 3=alarm condition (clock not synchronized)
*
* @return leap indicator as defined in RFC-1305.
*/
public int getLeapIndicator()
{
return (ui(buf[LI_INDEX]) >> LI_SHIFT) & 0x3;
}
/***
* Set leap indicator as defined in RFC-1305.
* @param li leap indicator.
*/
public void setLeapIndicator(int li)
{
buf[LI_INDEX] = (byte) (buf[LI_INDEX] & 0x3F | ((li & 0x3) << LI_SHIFT));
}
/***
* Returns poll interval as defined in RFC-1305, which is an eight-bit
* signed integer indicating the maximum interval between successive
* messages, in seconds to the nearest power of two (e.g. value of six
* indicates an interval of 64 seconds. The values that can appear in
* this field range from NTP_MINPOLL to NTP_MAXPOLL inclusive.
*
* @return poll interval as defined in RFC-1305.
*/
public int getPoll()
{
return buf[POLL_INDEX];
}
/***
* Set poll interval as defined in RFC-1305.
*
* @param poll poll interval.
*/
public void setPoll(int poll)
{
buf[POLL_INDEX] = (byte) (poll & 0xFF);
}
/***
* Returns precision as defined in RFC-1305 encoded as an 8-bit signed
* integer (seconds to nearest power of two).
* Values normally range from -6 to -20.
*
* @return precision as defined in RFC-1305.
*/
public int getPrecision()
{
return buf[PRECISION_INDEX];
}
/***
* Set precision as defined in RFC-1305.
* @param precision
*/
public void setPrecision(int precision)
{
buf[PRECISION_INDEX] = (byte) (precision & 0xFF);
}
/***
* Returns NTP version number as defined in RFC-1305.
*
* @return NTP version number.
*/
public int getVersion()
{
return (ui(buf[VERSION_INDEX]) >> VERSION_SHIFT) & 0x7;
}
/***
* Set NTP version as defined in RFC-1305.
*
* @param version NTP version.
*/
public void setVersion(int version)
{
buf[VERSION_INDEX] = (byte) (buf[VERSION_INDEX] & 0xC7 | ((version & 0x7) << VERSION_SHIFT));
}
/***
* Returns Stratum as defined in RFC-1305, which indicates the stratum level
* of the local clock, with values defined as follows: 0=unspecified,
* 1=primary ref clock, and all others a secondary reference (via NTP).
*
* @return Stratum level as defined in RFC-1305.
*/
public int getStratum()
{
return ui(buf[STRATUM_INDEX]);
}
/***
* Set stratum level as defined in RFC-1305.
*
* @param stratum stratum level.
*/
public void setStratum(int stratum)
{
buf[STRATUM_INDEX] = (byte) (stratum & 0xFF);
}
/***
* Return root delay as defined in RFC-1305, which is the total roundtrip delay
* to the primary reference source, in seconds. Values can take positive and
* negative values, depending on clock precision and skew.
*
* @return root delay as defined in RFC-1305.
*/
public int getRootDelay()
{
return getInt(ROOT_DELAY_INDEX);
}
/***
* Return root delay as defined in RFC-1305 in milliseconds, which is
* the total roundtrip delay to the primary reference source, in
* seconds. Values can take positive and negative values, depending
* on clock precision and skew.
*
* @return root delay in milliseconds
*/
public double getRootDelayInMillisDouble()
{
double l = getRootDelay();
return l / 65.536;
}
/***
* Returns root dispersion as defined in RFC-1305.
* @return root dispersion.
*/
public int getRootDispersion()
{
return getInt(ROOT_DISPERSION_INDEX);
}
/***
* Returns root dispersion (as defined in RFC-1305) in milliseconds.
*
* @return root dispersion in milliseconds
*/
public long getRootDispersionInMillis()
{
long l = getRootDispersion();
return (l * 1000) / 65536L;
}
/***
* Returns root dispersion (as defined in RFC-1305) in milliseconds
* as double precision value.
*
* @return root dispersion in milliseconds
*/
public double getRootDispersionInMillisDouble()
{
double l = getRootDispersion();
return l / 65.536;
}
/***
* Set reference clock identifier field with 32-bit unsigned integer value.
* See RFC-1305 for description.
*
* @param refId reference clock identifier.
*/
public void setReferenceId(int refId)
{
for (int i = 3; i >= 0; i--) {
buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
refId >>>= 8; // shift right one-byte
}
}
/***
* Returns the reference id as defined in RFC-1305, which is
* a 32-bit integer whose value is dependent on several criteria.
*
* @return the reference id as defined in RFC-1305.
*/
public int getReferenceId()
{
return getInt(REFERENCE_ID_INDEX);
}
/***
* Returns the reference id string. String cannot be null but
* value is dependent on the version of the NTP spec supported
* and stratum level. Value can be an empty string, clock type string,
* IP address, or a hex string.
*
* @return the reference id string.
*/
public String getReferenceIdString()
{
int version = getVersion();
int stratum = getStratum();
if (version == VERSION_3 || version == VERSION_4) {
if (stratum == 0 || stratum == 1) {
return idAsString(); // 4-character ASCII string (e.g. GPS, USNO)
}
// in NTPv4 servers this is latest transmit timestamp of ref source
if (version == VERSION_4)
return idAsHex();
}
// Stratum 2 and higher this is a four-octet IPv4 address
// of the primary reference host.
if (stratum >= 2) {
return idAsIPAddress();
}
return idAsHex();
}
/***
* Returns Reference id as dotted IP address.
* @return refId as IP address string.
*/
private String idAsIPAddress()
{
return ui(buf[REFERENCE_ID_INDEX]) + "." +
ui(buf[REFERENCE_ID_INDEX + 1]) + "." +
ui(buf[REFERENCE_ID_INDEX + 2]) + "." +
ui(buf[REFERENCE_ID_INDEX + 3]);
}
private String idAsString()
{
StringBuilder id = new StringBuilder();
for (int i = 0; i <= 3; i++) {
char c = (char) buf[REFERENCE_ID_INDEX + i];
if (c == 0) break; // 0-terminated string
id.append(c);
}
return id.toString();
}
private String idAsHex()
{
return Integer.toHexString(getReferenceId());
}
/***
* Returns the transmit timestamp as defined in RFC-1305.
*
* @return the transmit timestamp as defined in RFC-1305.
* Never returns a null object.
*/
public TimeStamp getTransmitTimeStamp()
{
return getTimestamp(TRANSMIT_TIMESTAMP_INDEX);
}
/***
* Set transmit time with NTP timestamp.
* If
* This class implements section 6.8. Base64 Content-Transfer-Encoding from RFC 2045 Multipurpose
* Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies by Freed and Borenstein.
*
* The class can be parameterized in the following manner with various constructors:
*
* Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode
* character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc).
*
* The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any
* equal signs.
*
* N.B. The next major release may break compatibility and make this field private.
*
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
*
* When decoding all variants are supported.
*
* When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
*
* When decoding all variants are supported.
*
* When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is
* STANDARD_ENCODE_TABLE.
*
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
*
* When decoding all variants are supported.
*
* When encoding the line length and line separator are given in the constructor, and the encoding table is
* STANDARD_ENCODE_TABLE.
*
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
*
* When decoding all variants are supported.
*
* When encoding the line length and line separator are given in the constructor, and the encoding table is
* STANDARD_ENCODE_TABLE.
*
* Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data.
*
* When decoding all variants are supported.
*
* Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with
* the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last
* remaining bytes (if not multiple of 3).
*
* Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*
* Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once
* with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1"
* call is not necessary when decoding, but it doesn't hurt, either.
*
* Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are
* silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in,
* garbage-out philosophy: it will not check the provided data for validity.
*
* Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*
*
* @author Daniel F. Savarese
* @see DiscardUDPClient
***/
public class DiscardTCPClient extends SocketClient
{
/*** The default discard port. It is set to 9 according to RFC 863. ***/
public static final int DEFAULT_PORT = 9;
/***
* The default DiscardTCPClient constructor. It merely sets the default
* port to
* @return An OutputStream through which you can write data to the server.
***/
public OutputStream getOutputStream()
{
return _output_;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/discard/DiscardUDPClient.java 0000644 0001750 0001750 00000006061 10761044665 030030 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.discard;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import org.apache.commons.net.DatagramSocketClient;
/***
* The DiscardUDPClient class is a UDP implementation of a client for the
* Discard protocol described in RFC 863. To use the class,
* just open a local UDP port
* with {@link org.apache.commons.net.DatagramSocketClient#open open }
* and call {@link #send send } to send datagrams to the server
* After you're done sending discard data, call
* {@link org.apache.commons.net.DatagramSocketClient#close close() }
* to clean up properly.
*
*
* @author Daniel F. Savarese
* @see DiscardTCPClient
***/
public class DiscardUDPClient extends DatagramSocketClient
{
/*** The default discard port. It is set to 9 according to RFC 863. ***/
public static final int DEFAULT_PORT = 9;
DatagramPacket _sendPacket;
public DiscardUDPClient()
{
_sendPacket = new DatagramPacket(new byte[0], 0);
}
/***
* Sends the specified data to the specified server at the specified port.
*
* @param data The discard data to send.
* @param length The length of the data to send. Should be less than
* or equal to the length of the data byte array.
* @param host The address of the server.
* @param port The service port.
* @exception IOException If an error occurs during the datagram send
* operation.
***/
public void send(byte[] data, int length, InetAddress host, int port)
throws IOException
{
_sendPacket.setData(data);
_sendPacket.setLength(length);
_sendPacket.setAddress(host);
_sendPacket.setPort(port);
_socket_.send(_sendPacket);
}
/***
* Same as
*
*
* @author Daniel F. Savarese
* @see DatagramSocketFactory
* @see DatagramSocketClient
* @see DatagramSocketClient#setDatagramSocketFactory
***/
public class DefaultDatagramSocketFactory implements DatagramSocketFactory
{
/***
* Creates a DatagramSocket on the local host at the first available port.
*
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket() throws SocketException
{
return new DatagramSocket();
}
/***
* Creates a DatagramSocket on the local host at a specified port.
*
* @param port The port to use for the socket.
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port) throws SocketException
{
return new DatagramSocket(port);
}
/***
* Creates a DatagramSocket at the specified address on the local host
* at a specified port.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException
{
return new DatagramSocket(port, laddr);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/echo/ 0000755 0001750 0001750 00000000000 11617452467 023412 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/echo/EchoUDPClient.java 0000644 0001750 0001750 00000006654 11354710167 026646 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.echo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import org.apache.commons.net.discard.DiscardUDPClient;
/***
* The EchoUDPClient class is a UDP implementation of a client for the
* Echo protocol described in RFC 862. To use the class,
* just open a local UDP port
* with {@link org.apache.commons.net.DatagramSocketClient#open open }
* and call {@link #send send } to send datagrams to the server,
* then call {@link #receive receive } to receive echoes.
* After you're done echoing data, call
* {@link org.apache.commons.net.DatagramSocketClient#close close() }
* to clean up properly.
*
*
* @author Daniel F. Savarese
* @see EchoTCPClient
* @see DiscardUDPClient
***/
public final class EchoUDPClient extends DiscardUDPClient
{
/*** The default echo port. It is set to 7 according to RFC 862. ***/
public static final int DEFAULT_PORT = 7;
private final DatagramPacket __receivePacket = new DatagramPacket(new byte[0], 0);
/***
* Sends the specified data to the specified server at the default echo
* port.
*
* @param data The echo data to send.
* @param length The length of the data to send. Should be less than
* or equal to the length of the data byte array.
* @param host The address of the server.
* @exception IOException If an error occurs during the datagram send
* operation.
***/
@Override
public void send(byte[] data, int length, InetAddress host)
throws IOException
{
send(data, length, host, DEFAULT_PORT);
}
/*** Same as
* @return Length of actual data received.
* @exception IOException If an error occurs while receiving the data.
***/
public int receive(byte[] data, int length) throws IOException
{
__receivePacket.setData(data);
__receivePacket.setLength(length);
_socket_.receive(__receivePacket);
return __receivePacket.getLength();
}
/*** Same as
*
* @author Daniel F. Savarese
* @see EchoUDPClient
* @see DiscardTCPClient
***/
public final class EchoTCPClient extends DiscardTCPClient
{
/*** The default echo port. It is set to 7 according to RFC 862. ***/
public static final int DEFAULT_PORT = 7;
/***
* The default EchoTCPClient constructor. It merely sets the default
* port to
* @return An InputStream from which you can read echoed data from the
* server.
***/
public InputStream getInputStream()
{
return _input_;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java 0000644 0001750 0001750 00000011563 11416072763 027441 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.util.EventObject;
/***
* There exists a large class of IETF protocols that work by sending an
* ASCII text command and arguments to a server, and then receiving an
* ASCII text reply. For debugging and other purposes, it is extremely
* useful to log or keep track of the contents of the protocol messages.
* The ProtocolCommandEvent class coupled with the
* {@link org.apache.commons.net.ProtocolCommandListener}
* interface facilitate this process.
*
*
* @see ProtocolCommandListener
* @see ProtocolCommandSupport
* @author Daniel F. Savarese
***/
public class ProtocolCommandEvent extends EventObject
{
private final int __replyCode;
private final boolean __isCommand;
private final String __message, __command;
/***
* Creates a ProtocolCommandEvent signalling a command was sent to
* the server. ProtocolCommandEvents created with this constructor
* should only be sent after a command has been sent, but before the
* reply has been received.
*
* @param source The source of the event.
* @param command The string representation of the command type sent, not
* including the arguments (e.g., "STAT" or "GET").
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public ProtocolCommandEvent(Object source, String command, String message)
{
super(source);
__replyCode = 0;
__message = message;
__isCommand = true;
__command = command;
}
/***
* Creates a ProtocolCommandEvent signalling a reply to a command was
* received. ProtocolCommandEvents created with this constructor
* should only be sent after a complete command reply has been received
* fromt a server.
*
* @param source The source of the event.
* @param replyCode The integer code indicating the natureof the reply.
* This will be the protocol integer value for protocols
* that use integer reply codes, or the reply class constant
* corresponding to the reply for protocols like POP3 that use
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public ProtocolCommandEvent(Object source, int replyCode, String message)
{
super(source);
__replyCode = replyCode;
__message = message;
__isCommand = false;
__command = null;
}
/***
* Returns the string representation of the command type sent (e.g., "STAT"
* or "GET"). If the ProtocolCommandEvent is a reply event, then null
* is returned.
*
* @return The string representation of the command type sent, or null
* if this is a reply event.
***/
public String getCommand()
{
return __command;
}
/***
* Returns the reply code of the received server reply. Undefined if
* this is not a reply event.
*
* @return The reply code of the received server reply. Undefined if
* not a reply event.
***/
public int getReplyCode()
{
return __replyCode;
}
/***
* Returns true if the ProtocolCommandEvent was generated as a result
* of sending a command.
*
* @return true If the ProtocolCommandEvent was generated as a result
* of sending a command. False otherwise.
***/
public boolean isCommand()
{
return __isCommand;
}
/***
* Returns true if the ProtocolCommandEvent was generated as a result
* of receiving a reply.
*
* @return true If the ProtocolCommandEvent was generated as a result
* of receiving a reply. False otherwise.
***/
public boolean isReply()
{
return !isCommand();
}
/***
* Returns the entire message sent to or received from the server.
*
* @return The entire message sent to or received from the server.
***/
public String getMessage()
{
return __message;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/bsd/ 0000755 0001750 0001750 00000000000 11617452467 023244 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/bsd/RCommandClient.java 0000644 0001750 0001750 00000041416 11445713774 026754 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.bsd;
import java.io.IOException;
import java.io.InputStream;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import org.apache.commons.net.io.SocketInputStream;
/***
* RCommandClient is very similar to
* {@link org.apache.commons.net.bsd.RExecClient},
* from which it is derived, and implements the rcmd() facility that
* first appeared in 4.2BSD Unix. rcmd() is the facility used by the rsh
* (rshell) and other commands to execute a command on another machine
* from a trusted host without issuing a password. The trust relationship
* between two machines is established by the contents of a machine's
* /etc/hosts.equiv file and a user's .rhosts file. These files specify
* from which hosts and accounts on those hosts rcmd() requests will be
* accepted. The only additional measure for establishing trust is that
* all client connections must originate from a port between 512 and 1023.
* Consequently, there is an upper limit to the number of rcmd connections
* that can be running simultaneously. The required ports are reserved
* ports on Unix systems, and can only be bound by a
* process running with root permissions (to accomplish this rsh, rlogin,
* and related commands usualy have the suid bit set). Therefore, on a
* Unix system, you will only be able to successfully use the RCommandClient
* class if the process runs as root. However, there is no such restriction
* on Windows95 and some other systems. The security risks are obvious.
* However, when carefully used, rcmd() can be very useful when used behind
* a firewall.
*
* As with virtually all of the client classes in org.apache.commons.net, this
* class derives from SocketClient. But it overrides most of its connection
* methods so that the local Socket will originate from an acceptable
* rshell port. The way to use RCommandClient is to first connect
* to the server, call the {@link #rcommand rcommand() } method,
* and then
* fetch the connection's input, output, and optionally error streams.
* Interaction with the remote command is controlled entirely through the
* I/O streams. Once you have finished processing the streams, you should
* invoke {@link org.apache.commons.net.bsd.RExecClient#disconnect disconnect() }
* to clean up properly.
*
* By default the standard output and standard error streams of the
* remote process are transmitted over the same connection, readable
* from the input stream returned by
* {@link org.apache.commons.net.bsd.RExecClient#getInputStream getInputStream() }
* . However, it is
* possible to tell the rshd daemon to return the standard error
* stream over a separate connection, readable from the input stream
* returned by {@link org.apache.commons.net.bsd.RExecClient#getErrorStream getErrorStream() }
* . You
* can specify that a separate connection should be created for standard
* error by setting the boolean
*
* @author Daniel F. Savarese
* @see org.apache.commons.net.SocketClient
* @see RExecClient
* @see RLoginClient
***/
public class RCommandClient extends RExecClient
{
/***
* The default rshell port. Set to 514 in BSD Unix.
***/
public static final int DEFAULT_PORT = 514;
/***
* The smallest port number an rcmd client may use. By BSD convention
* this number is 512.
***/
public static final int MIN_CLIENT_PORT = 512;
/***
* The largest port number an rcmd client may use. By BSD convention
* this number is 1023.
***/
public static final int MAX_CLIENT_PORT = 1023;
// Overrides method in RExecClient in order to implement proper
// port number limitations.
@Override
InputStream _createErrorStream() throws IOException
{
int localPort;
ServerSocket server;
Socket socket;
localPort = MAX_CLIENT_PORT;
server = null; // Keep compiler from barfing
for (localPort = MAX_CLIENT_PORT; localPort >= MIN_CLIENT_PORT; --localPort)
{
try
{
server = _serverSocketFactory_.createServerSocket(localPort, 1,
getLocalAddress());
break; // got a socket
}
catch (SocketException e)
{
continue;
}
}
if (server == null) {
throw new BindException("All ports in use.");
}
_output_.write(Integer.toString(server.getLocalPort()).getBytes());
_output_.write('\0');
_output_.flush();
socket = server.accept();
server.close();
if (isRemoteVerificationEnabled() && !verifyRemote(socket))
{
socket.close();
throw new IOException(
"Security violation: unexpected connection attempt by " +
socket.getInetAddress().getHostAddress());
}
return (new SocketInputStream(socket, socket.getInputStream()));
}
/***
* The default RCommandClient constructor. Initializes the
* default port to
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @exception SocketException If the socket timeout could not be set.
* @exception BindException If all acceptable rshell ports are in use.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
***/
public void connect(InetAddress host, int port, InetAddress localAddr)
throws SocketException, BindException, IOException
{
int localPort;
localPort = MAX_CLIENT_PORT;
for (localPort = MAX_CLIENT_PORT; localPort >= MIN_CLIENT_PORT; --localPort)
{
try
{
_socket_ =
_socketFactory_.createSocket(host, port, localAddr, localPort);
}
catch (BindException be) {
continue;
}
catch (SocketException e)
{
continue;
}
break;
}
if (localPort < MIN_CLIENT_PORT)
throw new BindException("All ports in use or insufficient permssion.");
_connectAction_();
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a port in a range acceptable
* to the BSD rshell daemon.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception BindException If all acceptable rshell ports are in use.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
***/
@Override
public void connect(InetAddress host, int port)
throws SocketException, IOException
{
connect(host, port, InetAddress.getLocalHost());
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a port in a range acceptable
* to the BSD rshell daemon.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception BindException If all acceptable rshell ports are in use.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
@Override
public void connect(String hostname, int port)
throws SocketException, IOException, UnknownHostException
{
connect(InetAddress.getByName(hostname), port, InetAddress.getLocalHost());
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address using a port in a range
* acceptable to the BSD rshell daemon.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param hostname The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @exception SocketException If the socket timeout could not be set.
* @exception BindException If all acceptable rshell ports are in use.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
***/
public void connect(String hostname, int port, InetAddress localAddr)
throws SocketException, IOException
{
connect(InetAddress.getByName(hostname), port, localAddr);
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port. The
* local port must lie between
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception IllegalArgumentException If an invalid local port number
* is specified.
***/
@Override
public void connect(InetAddress host, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException, IllegalArgumentException
{
if (localPort < MIN_CLIENT_PORT || localPort > MAX_CLIENT_PORT)
throw new IllegalArgumentException("Invalid port number " + localPort);
super.connect(host, port, localAddr, localPort);
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port. The
* local port must lie between
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception UnknownHostException If the hostname cannot be resolved.
* @exception IllegalArgumentException If an invalid local port number
* is specified.
***/
@Override
public void connect(String hostname, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException, IllegalArgumentException, UnknownHostException
{
if (localPort < MIN_CLIENT_PORT || localPort > MAX_CLIENT_PORT)
throw new IllegalArgumentException("Invalid port number " + localPort);
super.connect(hostname, port, localAddr, localPort);
}
/***
* Remotely executes a command through the rshd daemon on the server
* to which the RCommandClient is connected. After calling this method,
* you may interact with the remote process through its standard input,
* output, and error streams. You will typically be able to detect
* the termination of the remote process after reaching end of file
* on its standard output (accessible through
* {@link #getInputStream getInputStream() }. Disconnecting
* from the server or closing the process streams before reaching
* end of file will not necessarily terminate the remote process.
*
* If a separate error stream is requested, the remote server will
* connect to a local socket opened by RCommandClient, providing an
* independent stream through which standard error will be transmitted.
* The local socket must originate from a secure port (512 - 1023),
* and rcommand() ensures that this will be so.
* RCommandClient will also do a simple security check when it accepts a
* connection for this error stream. If the connection does not originate
* from the remote server, an IOException will be thrown. This serves as
* a simple protection against possible hijacking of the error stream by
* an attacker monitoring the rexec() negotiation. You may disable this
* behavior with
* {@link org.apache.commons.net.bsd.RExecClient#setRemoteVerificationEnabled setRemoteVerificationEnabled()}
* .
*
* @param localUsername The user account on the local machine that is
* requesting the command execution.
* @param remoteUsername The account name on the server through which to
* execute the command.
* @param command The command, including any arguments, to execute.
* @param separateErrorStream True if you would like the standard error
* to be transmitted through a different stream than standard output.
* False if not.
* @exception IOException If the rcommand() attempt fails. The exception
* will contain a message indicating the nature of the failure.
***/
public void rcommand(String localUsername, String remoteUsername,
String command, boolean separateErrorStream)
throws IOException
{
rexec(localUsername, remoteUsername, command, separateErrorStream);
}
/***
* Same as
*
* As with virtually all of the client classes in org.apache.commons.net, this
* class derives from SocketClient, inheriting its connection methods.
* The way to use RExecClient is to first connect
* to the server, call the {@link #rexec rexec() } method, and then
* fetch the connection's input, output, and optionally error streams.
* Interaction with the remote command is controlled entirely through the
* I/O streams. Once you have finished processing the streams, you should
* invoke {@link #disconnect disconnect() } to clean up properly.
*
* By default the standard output and standard error streams of the
* remote process are transmitted over the same connection, readable
* from the input stream returned by
* {@link #getInputStream getInputStream() }. However, it is
* possible to tell the rexecd daemon to return the standard error
* stream over a separate connection, readable from the input stream
* returned by {@link #getErrorStream getErrorStream() }. You
* can specify that a separate connection should be created for standard
* error by setting the boolean
*
* @author Daniel F. Savarese
* @see SocketClient
* @see RCommandClient
* @see RLoginClient
***/
public class RExecClient extends SocketClient
{
/***
* The default rexec port. Set to 512 in BSD Unix.
***/
public static final int DEFAULT_PORT = 512;
private boolean __remoteVerificationEnabled;
/***
* If a separate error stream is requested,
* @return The InputStream from which the standard output of the remote
* process can be read.
***/
public InputStream getInputStream()
{
return _input_;
}
/***
* Returns the OutputStream through which the standard input of the remote
* process can be written. The output stream will only be set after a
* successful rexec() invocation.
*
* @return The OutputStream through which the standard input of the remote
* process can be written.
***/
public OutputStream getOutputStream()
{
return _output_;
}
/***
* Returns the InputStream from which the standard error of the remote
* process can be read if a separate error stream is requested from
* the server. Otherwise, null will be returned. The error stream
* will only be set after a successful rexec() invocation.
*
* @return The InputStream from which the standard error of the remote
* process can be read if a separate error stream is requested from
* the server. Otherwise, null will be returned.
***/
public InputStream getErrorStream()
{
return _errorStream_;
}
/***
* Remotely executes a command through the rexecd daemon on the server
* to which the RExecClient is connected. After calling this method,
* you may interact with the remote process through its standard input,
* output, and error streams. You will typically be able to detect
* the termination of the remote process after reaching end of file
* on its standard output (accessible through
* {@link #getInputStream getInputStream() }. Disconnecting
* from the server or closing the process streams before reaching
* end of file will not necessarily terminate the remote process.
*
* If a separate error stream is requested, the remote server will
* connect to a local socket opened by RExecClient, providing an
* independent stream through which standard error will be transmitted.
* RExecClient will do a simple security check when it accepts a
* connection for this error stream. If the connection does not originate
* from the remote server, an IOException will be thrown. This serves as
* a simple protection against possible hijacking of the error stream by
* an attacker monitoring the rexec() negotiation. You may disable this
* behavior with {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}
* .
*
* @param username The account name on the server through which to execute
* the command.
* @param password The plain text password of the user account.
* @param command The command, including any arguments, to execute.
* @param separateErrorStream True if you would like the standard error
* to be transmitted through a different stream than standard output.
* False if not.
* @exception IOException If the rexec() attempt fails. The exception
* will contain a message indicating the nature of the failure.
***/
public void rexec(String username, String password,
String command, boolean separateErrorStream)
throws IOException
{
int ch;
if (separateErrorStream)
{
_errorStream_ = _createErrorStream();
}
else
{
_output_.write('\0');
}
_output_.write(username.getBytes());
_output_.write('\0');
_output_.write(password.getBytes());
_output_.write('\0');
_output_.write(command.getBytes());
_output_.write('\0');
_output_.flush();
ch = _input_.read();
if (ch > 0)
{
StringBuilder buffer = new StringBuilder();
while ((ch = _input_.read()) != -1 && ch != '\n')
buffer.append((char)ch);
throw new IOException(buffer.toString());
}
else if (ch < 0)
{
throw new IOException("Server closed connection.");
}
}
/***
* Same as
* @exception IOException If there an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
if (_errorStream_ != null)
_errorStream_.close();
_errorStream_ = null;
super.disconnect();
}
/***
* Enable or disable verification that the remote host connecting to
* create a separate error stream is the same as the host to which
* the standard out stream is connected. The default is for verification
* to be enabled. You may set this value at any time, whether the
* client is currently connected or not.
*
* @param enable True to enable verification, false to disable verification.
***/
public final void setRemoteVerificationEnabled(boolean enable)
{
__remoteVerificationEnabled = enable;
}
/***
* Return whether or not verification of the remote host providing a
* separate error stream is enabled. The default behavior is for
* verification to be enabled.
*
* @return True if verification is enabled, false if not.
***/
public final boolean isRemoteVerificationEnabled()
{
return __remoteVerificationEnabled;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/bsd/RLoginClient.java 0000644 0001750 0001750 00000012750 10542533103 026424 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.bsd;
import java.io.IOException;
/***
* RLoginClient is very similar to
* {@link org.apache.commons.net.bsd.RCommandClient},
* from which it is derived, and uses the rcmd() facility implemented
* in RCommandClient to implement the functionality of the rlogin command that
* first appeared in 4.2BSD Unix. rlogin is a command used to login to
* a remote machine from a trusted host, sometimes without issuing a
* password. The trust relationship is the same as described in
* the documentation for
* {@link org.apache.commons.net.bsd.RCommandClient}.
*
* As with virtually all of the client classes in org.apache.commons.net, this
* class derives from SocketClient. But it relies on the connection
* methods defined in RcommandClient which ensure that the local Socket
* will originate from an acceptable rshell port. The way to use
* RLoginClient is to first connect
* to the server, call the {@link #rlogin rlogin() } method,
* and then
* fetch the connection's input and output streams.
* Interaction with the remote command is controlled entirely through the
* I/O streams. Once you have finished processing the streams, you should
* invoke {@link org.apache.commons.net.bsd.RExecClient#disconnect disconnect() }
* to clean up properly.
*
* The standard output and standard error streams of the
* remote process are transmitted over the same connection, readable
* from the input stream returned by
* {@link org.apache.commons.net.bsd.RExecClient#getInputStream getInputStream() }
* . Unlike RExecClient and RCommandClient, it is
* not possible to tell the rlogind daemon to return the standard error
* stream over a separate connection.
* {@link org.apache.commons.net.bsd.RExecClient#getErrorStream getErrorStream() }
* will always return null.
* The standard input of the remote process can be written to through
* the output stream returned by
* {@link org.apache.commons.net.bsd.RExecClient#getOutputStream getOutputSream() }
* .
*
*
* @author Daniel F. Savarese
* @see org.apache.commons.net.SocketClient
* @see RExecClient
* @see RCommandClient
***/
public class RLoginClient extends RCommandClient
{
/***
* The default rlogin port. Set to 513 in BSD Unix and according
* to RFC 1282.
***/
public static final int DEFAULT_PORT = 513;
/***
* The default RLoginClient constructor. Initializes the
* default port to
* If user authentication fails, the rlogind daemon will request that
* a password be entered interactively. You will be able to read the
* prompt from the output stream of the RLoginClient and write the
* password to the input stream of the RLoginClient.
*
* @param localUsername The user account on the local machine that is
* trying to login to the remote host.
* @param remoteUsername The account name on the server that is
* being logged in to.
* @param terminalType The name of the user's terminal (e.g., "vt100",
* "network", etc.)
* @param terminalSpeed The speed of the user's terminal, expressed
* as a baud rate or bps (e.g., 9600 or 38400)
* @exception IOException If the rlogin() attempt fails. The exception
* will contain a message indicating the nature of the failure.
***/
public void rlogin(String localUsername, String remoteUsername,
String terminalType, int terminalSpeed)
throws IOException
{
rexec(localUsername, remoteUsername, terminalType + "/" + terminalSpeed,
false);
}
/***
* Same as the other rlogin method, but no terminal speed is defined.
***/
public void rlogin(String localUsername, String remoteUsername,
String terminalType)
throws IOException
{
rexec(localUsername, remoteUsername, terminalType, false);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/ 0000755 0001750 0001750 00000000000 11617452466 023452 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/nntp/ArticlePointer.java 0000644 0001750 0001750 00000003033 11466122735 027233 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/**
* This class is a structure used to return article number and unique
* id information extracted from an NNTP server reply. You will normally
* want this information when issuing a STAT command, implemented by
* {@link NNTPClient#selectArticle selectArticle}.
* @author Daniel F. Savarese
* @see NNTPClient
*/
public final class ArticlePointer
{
/** The number of the referenced article. */
public int articleNumber;
/**
* The unique id of the referenced article, including the enclosing
* < and > symbols which are technically not part of the
* identifier, but are required by all NNTP commands taking an
* article id as an argument.
*/
public String articleId;
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/Threader.java 0000644 0001750 0001750 00000037112 11466231525 026050 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/**
* This is an implementation of a message threading algorithm, as originally devised by Zamie Zawinski.
* See http://www.jwz.org/doc/threading.html for details.
* For his Java implementation, see http://lxr.mozilla.org/mozilla/source/grendel/sources/grendel/view/Threader.java
*
* @author rwinston
*
* @author Daniel F. Savarese
* @see NNTP
* @see NNTPClient
***/
public final class NNTPConnectionClosedException extends IOException
{
/*** Constructs a NNTPConnectionClosedException with no message ***/
public NNTPConnectionClosedException()
{
super();
}
/***
* Constructs a NNTPConnectionClosedException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public NNTPConnectionClosedException(String message)
{
super(message);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java 0000644 0001750 0001750 00000020333 11354512541 030420 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
import java.util.Calendar;
/***
* The NewGroupsOrNewsQuery class. This is used to issue NNTP NEWGROUPS and
* NEWNEWS queries, implemented by
* {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsGroups }
* and
* {@link org.apache.commons.net.nntp.NNTPClient#listNewNews listNewNews }
* respectively. It prevents you from having to format
* date, time, distribution, and newgroup arguments.
*
* You might use the class as follows:
*
*
* @author Daniel F. Savarese
* @see NNTPClient
***/
public final class NewGroupsOrNewsQuery
{
private String __date, __time;
private StringBuffer __distributions;
private StringBuffer __newsgroups;
private boolean __isGMT;
/***
* Creates a new query using the given time as a reference point.
*
* @param date The date since which new groups or news have arrived.
* @param gmt True if the date should be considered as GMT, false if not.
***/
public NewGroupsOrNewsQuery(Calendar date, boolean gmt)
{
int num;
String str;
StringBuilder buffer;
__distributions = null;
__newsgroups = null;
__isGMT = gmt;
buffer = new StringBuilder();
// Get year
num = date.get(Calendar.YEAR);
str = Integer.toString(num);
num = str.length();
if (num >= 2)
buffer.append(str.substring(num - 2));
else
buffer.append("00");
// Get month
num = date.get(Calendar.MONTH) + 1;
str = Integer.toString(num);
num = str.length();
if (num == 1)
{
buffer.append('0');
buffer.append(str);
}
else if (num == 2)
buffer.append(str);
else
buffer.append("01");
// Get day
num = date.get(Calendar.DAY_OF_MONTH);
str = Integer.toString(num);
num = str.length();
if (num == 1)
{
buffer.append('0');
buffer.append(str);
}
else if (num == 2)
buffer.append(str);
else
buffer.append("01");
__date = buffer.toString();
buffer.setLength(0);
// Get hour
num = date.get(Calendar.HOUR_OF_DAY);
str = Integer.toString(num);
num = str.length();
if (num == 1)
{
buffer.append('0');
buffer.append(str);
}
else if (num == 2)
buffer.append(str);
else
buffer.append("00");
// Get minutes
num = date.get(Calendar.MINUTE);
str = Integer.toString(num);
num = str.length();
if (num == 1)
{
buffer.append('0');
buffer.append(str);
}
else if (num == 2)
buffer.append(str);
else
buffer.append("00");
// Get seconds
num = date.get(Calendar.SECOND);
str = Integer.toString(num);
num = str.length();
if (num == 1)
{
buffer.append('0');
buffer.append(str);
}
else if (num == 2)
buffer.append(str);
else
buffer.append("00");
__time = buffer.toString();
}
/***
* Add a newsgroup to the list of newsgroups being queried. Newsgroups
* added this way are only meaningful to the NEWNEWS command. Newsgroup
* names may include the
* @param newsgroup The newsgroup to add to the list of groups to be
* checked for new news.
***/
public void addNewsgroup(String newsgroup)
{
if (__newsgroups != null)
__newsgroups.append(',');
else
__newsgroups = new StringBuffer();
__newsgroups.append(newsgroup);
}
/***
* Add a newsgroup to the list of newsgroups being queried, but indicate
* that group should not be checked for new news. Newsgroups
* added this way are only meaningful to the NEWNEWS command.
* Newsgroup names may include the
* The following would create a query that searched for new news in
* all comp.lang.java newsgroups except for comp.lang.java.advocacy.
*
* @param newsgroup The newsgroup to add to the list of groups to be
* checked for new news, but which should be omitted from
* the search for new news..
***/
public void omitNewsgroup(String newsgroup)
{
addNewsgroup("!" + newsgroup);
}
/***
* Add a distribution group to the query. The distribution part of a
* newsgroup is the segment of the name preceding the first dot (e.g.,
* comp, alt, rec). Only those newsgroups matching one of the
* distributions or, in the case of NEWNEWS, an article in a newsgroup
* matching one of the distributions, will be reported as a query result.
* Adding distributions is purely optional.
*
* @param distribution A distribution to add to the query.
***/
public void addDistribution(String distribution)
{
if (__distributions != null)
__distributions.append(',');
else
__distributions = new StringBuffer();
__distributions.append(distribution);
}
/***
* Return the NNTP query formatted date (year, month, day in the form
* YYMMDD.
*
* @return The NNTP query formatted date.
***/
public String getDate()
{
return __date;
}
/***
* Return the NNTP query formatted time (hour, minutes, seconds in the form
* HHMMSS.
*
* @return The NNTP query formatted time.
***/
public String getTime()
{
return __time;
}
/***
* Return whether or not the query date should be treated as GMT.
*
* @return True if the query date is to be treated as GMT, false if not.
***/
public boolean isGMT()
{
return __isGMT;
}
/***
* Return the comma separated list of distributions. This may be null
* if there are no distributions.
*
* @return The list of distributions, which may be null if no distributions
* have been specified.
***/
public String getDistributions()
{
return (__distributions == null ? null : __distributions.toString());
}
/***
* Return the comma separated list of newsgroups. This may be null
* if there are no newsgroups
*
* @return The list of newsgroups, which may be null if no newsgroups
* have been specified.
***/
public String getNewsgroups()
{
return (__newsgroups == null ? null : __newsgroups.toString());
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/NNTPClient.java 0000644 0001750 0001750 00000147074 11466122735 026243 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.io.DotTerminatedMessageReader;
import org.apache.commons.net.io.DotTerminatedMessageWriter;
import org.apache.commons.net.io.Util;
/***
* NNTPClient encapsulates all the functionality necessary to post and
* retrieve articles from an NNTP server. As with all classes derived
* from {@link org.apache.commons.net.SocketClient},
* you must first connect to the server with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before doing anything, and finally
* {@link org.apache.commons.net.nntp.NNTP#disconnect disconnect() }
* after you're completely finished interacting with the server.
* Remember that the
* {@link org.apache.commons.net.nntp.NNTP#isAllowedToPost isAllowedToPost()}
* method is defined in
* {@link org.apache.commons.net.nntp.NNTP}.
*
* You should keep in mind that the NNTP server may choose to prematurely
* close a connection if the client has been idle for longer than a
* given time period or if the server is being shutdown by the operator or
* some other reason. The NNTP class will detect a
* premature NNTP server connection closing when it receives a
* {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED }
* response to a command.
* When that occurs, the NNTP class method encountering that reply will throw
* an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
* .
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @author Rory Winston
* @author Ted Wise
* @see NNTP
* @see NNTPConnectionClosedException
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class NNTPClient extends NNTP
{
private void __parseArticlePointer(String reply, ArticlePointer pointer)
throws MalformedServerReplyException
{
StringTokenizer tokenizer;
// Do loop is a kluge to simulate goto
do
{
tokenizer = new StringTokenizer(reply);
if (tokenizer.countTokens() < 3)
break;
// Skip numeric response value
tokenizer.nextToken();
// Get article number
try
{
pointer.articleNumber = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException e)
{
break;
}
// Get article id
pointer.articleId = tokenizer.nextToken();
return ;
}
while (false);
throw new MalformedServerReplyException(
"Could not parse article pointer.\nServer reply: " + reply);
}
private void __parseGroupReply(String reply, NewsgroupInfo info)
throws MalformedServerReplyException
{
String count, first, last;
StringTokenizer tokenizer;
// Do loop is a kluge to simulate goto
do
{
tokenizer = new StringTokenizer(reply);
if (tokenizer.countTokens() < 5)
break;
// Skip numeric response value
tokenizer.nextToken();
// Get estimated article count
count = tokenizer.nextToken();
// Get first article number
first = tokenizer.nextToken();
// Get last article number
last = tokenizer.nextToken();
// Get newsgroup name
info._setNewsgroup(tokenizer.nextToken());
try
{
info._setArticleCount(Integer.parseInt(count));
info._setFirstArticle(Integer.parseInt(first));
info._setLastArticle(Integer.parseInt(last));
}
catch (NumberFormatException e)
{
break;
}
info._setPostingPermission(NewsgroupInfo.UNKNOWN_POSTING_PERMISSION);
return ;
}
while (false);
throw new MalformedServerReplyException(
"Could not parse newsgroup info.\nServer reply: " + reply);
}
private NewsgroupInfo __parseNewsgroupListEntry(String entry)
{
NewsgroupInfo result;
StringTokenizer tokenizer;
int lastNum, firstNum;
String last, first, permission;
result = new NewsgroupInfo();
tokenizer = new StringTokenizer(entry);
if (tokenizer.countTokens() < 4)
return null;
result._setNewsgroup(tokenizer.nextToken());
last = tokenizer.nextToken();
first = tokenizer.nextToken();
permission = tokenizer.nextToken();
try
{
lastNum = Integer.parseInt(last);
firstNum = Integer.parseInt(first);
result._setFirstArticle(firstNum);
result._setLastArticle(lastNum);
if((firstNum == 0) && (lastNum == 0))
result._setArticleCount(0);
else
result._setArticleCount(lastNum - firstNum + 1);
}
catch (NumberFormatException e)
{
return null;
}
switch (permission.charAt(0))
{
case 'y':
case 'Y':
result._setPostingPermission(
NewsgroupInfo.PERMITTED_POSTING_PERMISSION);
break;
case 'n':
case 'N':
result._setPostingPermission(
NewsgroupInfo.PROHIBITED_POSTING_PERMISSION);
break;
case 'm':
case 'M':
result._setPostingPermission(
NewsgroupInfo.MODERATED_POSTING_PERMISSION);
break;
default:
result._setPostingPermission(
NewsgroupInfo.UNKNOWN_POSTING_PERMISSION);
break;
}
return result;
}
private NewsgroupInfo[] __readNewsgroupListing() throws IOException
{
int size;
String line;
Vector
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleId The unique article identifier of the article to
* retrieve. If this parameter is null, the currently selected
* article is retrieved.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticle(String articleId, ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.ARTICLE, articleId, pointer);
}
/*** Same as
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleNumber The number of the the article to
* retrieve.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticle(int articleNumber, ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.ARTICLE, articleNumber, pointer);
}
/*** Same as
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleId The unique article identifier of the article whose
* header is being retrieved. If this parameter is null, the
* header of the currently selected article is retrieved.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* header can be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticleHeader(String articleId, ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.HEAD, articleId, pointer);
}
/*** Same as
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleNumber The number of the the article whose header is
* being retrieved.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* header can be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticleHeader(int articleNumber,
ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.HEAD, articleNumber, pointer);
}
/*** Same as
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleId The unique article identifier of the article whose
* body is being retrieved. If this parameter is null, the
* body of the currently selected article is retrieved.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* body can be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticleBody(String articleId, ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.BODY, articleId, pointer);
}
/*** Same as
* A DotTerminatedMessageReader is returned from which the article can
* be read. If the article does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The NNTP protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the NNTP connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param articleNumber The number of the the article whose body is
* being retrieved.
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return A DotTerminatedMessageReader instance from which the article
* body can be read. null if the article does not exist.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Reader retrieveArticleBody(int articleNumber,
ArticlePointer pointer)
throws IOException
{
return __retrieve(NNTPCommand.BODY, articleNumber, pointer);
}
/*** Same as
* @param newsgroup The newsgroup to select.
* @param info A parameter through which the newsgroup information of
* the selected newsgroup contained in the server reply is returned.
* Set this to null if you do not desire this information.
* @return True if the newsgroup exists and was selected, false otherwise.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean selectNewsgroup(String newsgroup, NewsgroupInfo info)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(group(newsgroup)))
return false;
if (info != null)
__parseGroupReply(getReplyString(), info);
return true;
}
/*** Same as
* @return The sever help information.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String listHelp() throws IOException
{
StringWriter help;
Reader reader;
if (!NNTPReply.isInformational(help()))
return null;
help = new StringWriter();
reader = new DotTerminatedMessageReader(_reader_);
Util.copyReader(reader, help);
reader.close();
help.close();
return help.toString();
}
/***
* Select an article by its unique identifier (including enclosing
* < and >) and return its article number and id through the
* pointer parameter. This is achieved through the STAT command.
* According to RFC 977, this will NOT set the current article pointer
* on the server. To do that, you must reference the article by its
* number.
*
* @param articleId The unique article identifier of the article that
* is being selectedd. If this parameter is null, the
* body of the current article is selected
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return True if successful, false if not.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean selectArticle(String articleId, ArticlePointer pointer)
throws IOException
{
if (articleId != null)
{
if (!NNTPReply.isPositiveCompletion(stat(articleId)))
return false;
}
else
{
if (!NNTPReply.isPositiveCompletion(stat()))
return false;
}
if (pointer != null)
__parseArticlePointer(getReplyString(), pointer);
return true;
}
/**** Same as
* @param articleNumber The number of the article to select from the
* currently selected newsgroup.
* @param pointer A parameter through which to return the article's
* number and unique id. Although the articleId field cannot always
* be trusted because of server deviations from RFC 977 reply formats,
* we haven't found a server that misformats this information in response
* to this particular command. You may set this parameter to null if
* you do not desire to retrieve the returned article information.
* @return True if successful, false if not.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean selectArticle(int articleNumber, ArticlePointer pointer)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(stat(articleNumber)))
return false;
if (pointer != null)
__parseArticlePointer(getReplyString(), pointer);
return true;
}
/*** Same as
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return True if successful, false if not (e.g., there is no previous
* article).
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean selectPreviousArticle(ArticlePointer pointer)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(last()))
return false;
if (pointer != null)
__parseArticlePointer(getReplyString(), pointer);
return true;
}
/*** Same as
* @param pointer A parameter through which to return the article's
* number and unique id. The articleId field cannot always be trusted
* because of server deviations from RFC 977 reply formats. You may
* set this parameter to null if you do not desire to retrieve the
* returned article information.
* @return True if successful, false if not (e.g., there is no following
* article).
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean selectNextArticle(ArticlePointer pointer) throws IOException
{
if (!NNTPReply.isPositiveCompletion(next()))
return false;
if (pointer != null)
__parseArticlePointer(getReplyString(), pointer);
return true;
}
/*** Same as
* @return An array of NewsgroupInfo instances containing the information
* for each newsgroup served by the NNTP server. If no newsgroups
* are served, a zero length array will be returned. If the command
* fails, null will be returned.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public NewsgroupInfo[] listNewsgroups() throws IOException
{
if (!NNTPReply.isPositiveCompletion(list()))
return null;
return __readNewsgroupListing();
}
/**
* An overloaded listNewsgroups() command that allows us to
* specify with a pattern what groups we want to list. Wraps the
* LIST ACTIVE command.
*
* @param wildmat a pseudo-regex pattern (cf. RFC 2980)
* @return An array of NewsgroupInfo instances containing the information
* for each newsgroup served by the NNTP server corresponding to the
* supplied pattern. If no such newsgroups are served, a zero length
* array will be returned. If the command fails, null will be returned.
* @throws IOException
*/
public NewsgroupInfo[] listNewsgroups(String wildmat) throws IOException
{
if(!NNTPReply.isPositiveCompletion(listActive(wildmat)))
return null;
return __readNewsgroupListing();
}
/***
* List all new newsgroups added to the NNTP server since a particular
* date subject to the conditions of the specified query. If no new
* newsgroups were added, a zero length array will be returned. If the
* command fails, null will be returned.
*
* @param query The query restricting how to search for new newsgroups.
* @return An array of NewsgroupInfo instances containing the information
* for each new newsgroup added to the NNTP server. If no newsgroups
* were added, a zero length array will be returned. If the command
* fails, null will be returned.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public NewsgroupInfo[] listNewNewsgroups(NewGroupsOrNewsQuery query)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(newgroups(
query.getDate(), query.getTime(),
query.isGMT(), query.getDistributions())))
return null;
return __readNewsgroupListing();
}
/***
* List all new articles added to the NNTP server since a particular
* date subject to the conditions of the specified query. If no new
* new news is found, a zero length array will be returned. If the
* command fails, null will be returned. You must add at least one
* newsgroup to the query, else the command will fail. Each String
* in the returned array is a unique message identifier including the
* enclosing < and >.
*
* @param query The query restricting how to search for new news. You
* must add at least one newsgroup to the query.
* @return An array of String instances containing the unique message
* identifiers for each new article added to the NNTP server. If no
* new news is found, a zero length array will be returned. If the
* command fails, null will be returned.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String[] listNewNews(NewGroupsOrNewsQuery query)
throws IOException
{
int size;
String line;
Vector
* For example
*
* @return True if successfully completed, false if not.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean completePendingCommand() throws IOException
{
return NNTPReply.isPositiveCompletion(getReply());
}
/***
* Post an article to the NNTP server. This method returns a
* DotTerminatedMessageWriter instance to which the article can be
* written. Null is returned if the posting attempt fails. You
* should check {@link NNTP#isAllowedToPost isAllowedToPost() }
* before trying to post. However, a posting
* attempt can fail due to malformed headers.
*
* You must not issue any commands to the NNTP server (i.e., call any
* (other methods) until you finish writing to the returned Writer
* instance and close it. The NNTP protocol uses the same stream for
* issuing commands as it does for returning results. Therefore the
* returned Writer actually writes directly to the NNTP connection.
* After you close the writer, you can execute new commands. If you
* do not follow these requirements your program will not work properly.
*
* Different NNTP servers will require different header formats, but
* you can use the provided
* {@link org.apache.commons.net.nntp.SimpleNNTPHeader}
* class to construct the bare minimum acceptable header for most
* news readers. To construct more complicated headers you should
* refer to RFC 822. When the Java Mail API is finalized, you will be
* able to use it to compose fully compliant Internet text messages.
* The DotTerminatedMessageWriter takes care of doubling line-leading
* dots and ending the message with a single dot upon closing, so all
* you have to worry about is writing the header and the message.
*
* Upon closing the returned Writer, you need to call
* {@link #completePendingCommand completePendingCommand() }
* to finalize the posting and verify its success or failure from
* the server reply.
*
* @return A DotTerminatedMessageWriter to which the article (including
* header) can be written. Returns null if the command fails.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Writer postArticle() throws IOException
{
if (!NNTPReply.isPositiveIntermediate(post()))
return null;
return new DotTerminatedMessageWriter(_writer_);
}
public Writer forwardArticle(String articleId) throws IOException
{
if (!NNTPReply.isPositiveIntermediate(ihave(articleId)))
return null;
return new DotTerminatedMessageWriter(_writer_);
}
/***
* Logs out of the news server gracefully by sending the QUIT command.
* However, you must still disconnect from the server before you can open
* a new connection.
*
* @return True if successfully completed, false if not.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean logout() throws IOException
{
return NNTPReply.isPositiveCompletion(quit());
}
/**
* Log into a news server by sending the AUTHINFO USER/AUTHINFO
* PASS command sequence. This is usually sent in response to a
* 480 reply code from the NNTP server.
*
* @param username a valid username
* @param password the corresponding password
* @return True for successful login, false for a failure
* @throws IOException
*/
public boolean authenticate(String username, String password)
throws IOException
{
int replyCode = authinfoUser(username);
if (replyCode == NNTPReply.MORE_AUTH_INFO_REQUIRED)
{
replyCode = authinfoPass(password);
if (replyCode == NNTPReply.AUTHENTICATION_ACCEPTED)
{
_isAllowedToPost = true;
return true;
}
}
return false;
}
/***
* Private implementation of XOVER functionality.
*
* See {@link NNTP#xover}
* for legal agument formats. Alternatively, read RFC 2980 :-)
*
* @param articleRange
* @return Returns a DotTerminatedMessageReader if successful, null
* otherwise
* @exception IOException
*/
private Reader __retrieveArticleInfo(String articleRange)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(xover(articleRange)))
return null;
return new DotTerminatedMessageReader(_reader_);
}
/**
* Return article headers for a specified post.
*
* @param articleNumber the article to retrieve headers for
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException
*/
public Reader retrieveArticleInfo(int articleNumber) throws IOException
{
return __retrieveArticleInfo(Integer.toString(articleNumber));
}
/**
* Return article headers for all articles between lowArticleNumber
* and highArticleNumber, inclusively.
*
* @param lowArticleNumber
* @param highArticleNumber
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException
*/
public Reader retrieveArticleInfo(int lowArticleNumber,
int highArticleNumber)
throws IOException
{
return
__retrieveArticleInfo(lowArticleNumber + "-" +
highArticleNumber);
}
/***
* Private implementation of XHDR functionality.
*
* See {@link NNTP#xhdr}
* for legal agument formats. Alternatively, read RFC 1036.
*
* @param header
* @param articleRange
* @return Returns a DotTerminatedMessageReader if successful, null
* otherwise
* @exception IOException
*/
private Reader __retrieveHeader(String header, String articleRange)
throws IOException
{
if (!NNTPReply.isPositiveCompletion(xhdr(header, articleRange)))
return null;
return new DotTerminatedMessageReader(_reader_);
}
/**
* Return an article header for a specified post.
*
* @param header the header to retrieve
* @param articleNumber the article to retrieve the header for
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException
*/
public Reader retrieveHeader(String header, int articleNumber)
throws IOException
{
return __retrieveHeader(header, Integer.toString(articleNumber));
}
/**
* Return an article header for all articles between lowArticleNumber
* and highArticleNumber, inclusively.
*
* @param header
* @param lowArticleNumber
* @param highArticleNumber
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException
*/
public Reader retrieveHeader(String header, int lowArticleNumber,
int highArticleNumber)
throws IOException
{
return
__retrieveHeader(header,lowArticleNumber + "-" + highArticleNumber);
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/NNTP.java 0000644 0001750 0001750 00000124333 11354512541 025067 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ProtocolCommandSupport;
import org.apache.commons.net.SocketClient;
/***
* The NNTP class is not meant to be used by itself and is provided
* only so that you may easily implement your own NNTP client if
* you so desire. If you have no need to perform your own implementation,
* you should use {@link org.apache.commons.net.nntp.NNTPClient}.
* The NNTP class is made public to provide access to various NNTP constants
* and to make it easier for adventurous programmers (or those with special
* needs) to interact with the NNTP protocol and implement their own clients.
* A set of methods with names corresponding to the NNTP command names are
* provided to facilitate this interaction.
*
* You should keep in mind that the NNTP server may choose to prematurely
* close a connection if the client has been idle for longer than a
* given time period or if the server is being shutdown by the operator or
* some other reason. The NNTP class will detect a
* premature NNTP server connection closing when it receives a
* {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED }
* response to a command.
* When that occurs, the NNTP class method encountering that reply will throw
* an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
* .
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @author Rory Winston
* @author Ted Wise
* @see NNTPClient
* @see NNTPConnectionClosedException
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class NNTP extends SocketClient
{
/*** The default NNTP port. Its value is 119 according to RFC 977. ***/
public static final int DEFAULT_PORT = 119;
// We have to ensure that the protocol communication is in ASCII
// but we use ISO-8859-1 just in case 8-bit characters cross
// the wire.
private static final String __DEFAULT_ENCODING = "ISO-8859-1";
private StringBuffer __commandBuffer;
boolean _isAllowedToPost;
int _replyCode;
String _replyString;
/**
* Wraps {@link SocketClient#_input_}
* to communicate with server. Initialized by {@link #_connectAction_}.
* All server reads should be done through this variable.
*/
protected BufferedReader _reader_;
/**
* Wraps {@link SocketClient#_output_}
* to communicate with server. Initialized by {@link #_connectAction_}.
* All server reads should be done through this variable.
*/
protected BufferedWriter _writer_;
/***
* A ProtocolCommandSupport object used to manage the registering of
* ProtocolCommandListeners and te firing of ProtocolCommandEvents.
***/
protected ProtocolCommandSupport _commandSupport_;
/***
* The default NNTP constructor. Sets the default port to
*
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.addProtocolCommandListener(listener);
}
/***
* Removes a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.removeProtocolCommandListener(listener);
}
/***
* Closes the connection to the NNTP server and sets to null
* some internal data so that the memory may be reclaimed by the
* garbage collector. The reply text and code information from the
* last command is voided so that the memory it used may be reclaimed.
*
* @exception IOException If an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
super.disconnect();
_reader_ = null;
_writer_ = null;
_replyString = null;
_isAllowedToPost = false;
}
/***
* Indicates whether or not the client is allowed to post articles to
* the server it is currently connected to.
*
* @return True if the client can post articles to the server, false
* otherwise.
***/
public boolean isAllowedToPost()
{
return _isAllowedToPost;
}
/***
* Sends an NNTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString }.
*
* @param command The text representation of the NNTP command to send.
* @param args The arguments to the NNTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the NNTP reply code returned by the server
* in response to the command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command, String args) throws IOException
{
String message;
__commandBuffer.setLength(0);
__commandBuffer.append(command);
if (args != null)
{
__commandBuffer.append(' ');
__commandBuffer.append(args);
}
__commandBuffer.append(SocketClient.NETASCII_EOL);
_writer_.write(message = __commandBuffer.toString());
_writer_.flush();
if (_commandSupport_.getListenerCount() > 0)
_commandSupport_.fireCommandSent(command, message);
__getReply();
return _replyCode;
}
/***
* Sends an NNTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString }.
*
* @param command The NNTPCommand constant corresponding to the NNTP command
* to send.
* @param args The arguments to the NNTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the NNTP reply code returned by the server
* in response to the command.
* in response to the command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command, String args) throws IOException
{
return sendCommand(NNTPCommand._commands[command], args);
}
/***
* Sends an NNTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString }.
*
* @param command The text representation of the NNTP command to send.
* @return The integer value of the NNTP reply code returned by the server
* in response to the command.
* in response to the command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command) throws IOException
{
return sendCommand(command, null);
}
/***
* Sends an NNTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString }.
*
* @param command The NNTPCommand constant corresponding to the NNTP command
* to send.
* @return The integer value of the NNTP reply code returned by the server
* in response to the command.
* in response to the command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command) throws IOException
{
return sendCommand(command, null);
}
/***
* Returns the integer value of the reply code of the last NNTP reply.
* You will usually only use this method after you connect to the
* NNTP server to check that the connection was successful since
*
* @return The integer value of the reply code of the last NNTP reply.
***/
public int getReplyCode()
{
return _replyCode;
}
/***
* Fetches a reply from the NNTP server and returns the integer reply
* code. After calling this method, the actual reply text can be accessed
* from {@link #getReplyString getReplyString }. Only use this
* method if you are implementing your own NNTP client or if you need to
* fetch a secondary response from the NNTP server.
*
* @return The integer value of the reply code of the fetched NNTP reply.
* in response to the command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while
* receiving the server reply.
***/
public int getReply() throws IOException
{
__getReply();
return _replyCode;
}
/***
* Returns the entire text of the last NNTP server response exactly
* as it was received, not including the end of line marker.
*
* @return The entire text from the last NNTP response as a String.
***/
public String getReplyString()
{
return _replyString;
}
/***
* A convenience method to send the NNTP ARTICLE command to the server,
* receive the initial reply, and return the reply code.
*
* @param messageId The message identifier of the requested article,
* including the encapsulating < and > characters.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int article(String messageId) throws IOException
{
return sendCommand(NNTPCommand.ARTICLE, messageId);
}
/***
* A convenience method to send the NNTP ARTICLE command to the server,
* receive the initial reply, and return the reply code.
*
* @param articleNumber The number of the article to request from the
* currently selected newsgroup.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int article(int articleNumber) throws IOException
{
return sendCommand(NNTPCommand.ARTICLE, Integer.toString(articleNumber));
}
/***
* A convenience method to send the NNTP ARTICLE command to the server,
* receive the initial reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int article() throws IOException
{
return sendCommand(NNTPCommand.ARTICLE);
}
/***
* A convenience method to send the NNTP BODY command to the server,
* receive the initial reply, and return the reply code.
*
* @param messageId The message identifier of the requested article,
* including the encapsulating < and > characters.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int body(String messageId) throws IOException
{
return sendCommand(NNTPCommand.BODY, messageId);
}
/***
* A convenience method to send the NNTP BODY command to the server,
* receive the initial reply, and return the reply code.
*
* @param articleNumber The number of the article to request from the
* currently selected newsgroup.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int body(int articleNumber) throws IOException
{
return sendCommand(NNTPCommand.BODY, Integer.toString(articleNumber));
}
/***
* A convenience method to send the NNTP BODY command to the server,
* receive the initial reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int body() throws IOException
{
return sendCommand(NNTPCommand.BODY);
}
/***
* A convenience method to send the NNTP HEAD command to the server,
* receive the initial reply, and return the reply code.
*
* @param messageId The message identifier of the requested article,
* including the encapsulating < and > characters.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int head(String messageId) throws IOException
{
return sendCommand(NNTPCommand.HEAD, messageId);
}
/***
* A convenience method to send the NNTP HEAD command to the server,
* receive the initial reply, and return the reply code.
*
* @param articleNumber The number of the article to request from the
* currently selected newsgroup.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int head(int articleNumber) throws IOException
{
return sendCommand(NNTPCommand.HEAD, Integer.toString(articleNumber));
}
/***
* A convenience method to send the NNTP HEAD command to the server,
* receive the initial reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int head() throws IOException
{
return sendCommand(NNTPCommand.HEAD);
}
/***
* A convenience method to send the NNTP STAT command to the server,
* receive the initial reply, and return the reply code.
*
* @param messageId The message identifier of the requested article,
* including the encapsulating < and > characters.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat(String messageId) throws IOException
{
return sendCommand(NNTPCommand.STAT, messageId);
}
/***
* A convenience method to send the NNTP STAT command to the server,
* receive the initial reply, and return the reply code.
*
* @param articleNumber The number of the article to request from the
* currently selected newsgroup.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat(int articleNumber) throws IOException
{
return sendCommand(NNTPCommand.STAT, Integer.toString(articleNumber));
}
/***
* A convenience method to send the NNTP STAT command to the server,
* receive the initial reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat() throws IOException
{
return sendCommand(NNTPCommand.STAT);
}
/***
* A convenience method to send the NNTP GROUP command to the server,
* receive the reply, and return the reply code.
*
* @param newsgroup The name of the newsgroup to select.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int group(String newsgroup) throws IOException
{
return sendCommand(NNTPCommand.GROUP, newsgroup);
}
/***
* A convenience method to send the NNTP HELP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help() throws IOException
{
return sendCommand(NNTPCommand.HELP);
}
/***
* A convenience method to send the NNTP IHAVE command to the server,
* receive the reply, and return the reply code.
*
* @param messageId The article identifier,
* including the encapsulating < and > characters.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int ihave(String messageId) throws IOException
{
return sendCommand(NNTPCommand.IHAVE, messageId);
}
/***
* A convenience method to send the NNTP LAST command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int last() throws IOException
{
return sendCommand(NNTPCommand.LAST);
}
/***
* A convenience method to send the NNTP LIST command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int list() throws IOException
{
return sendCommand(NNTPCommand.LIST);
}
/***
* A convenience method to send the NNTP NEXT command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int next() throws IOException
{
return sendCommand(NNTPCommand.NEXT);
}
/***
* A convenience method to send the NNTP NEWGROUPS command to the server,
* receive the reply, and return the reply code.
*
* @param date The date after which to check for new groups.
* Date format is YYMMDD
* @param time The time after which to check for new groups.
* Time format is HHMMSS using a 24-hour clock.
* @param GMT True if the time is in GMT, false if local server time.
* @param distributions Comma-separated distribution list to check for
* new groups. Set to null if no distributions.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int newgroups(String date, String time, boolean GMT,
String distributions) throws IOException
{
StringBuilder buffer = new StringBuilder();
buffer.append(date);
buffer.append(' ');
buffer.append(time);
if (GMT)
{
buffer.append(' ');
buffer.append("GMT");
}
if (distributions != null)
{
buffer.append(" <");
buffer.append(distributions);
buffer.append('>');
}
return sendCommand(NNTPCommand.NEWGROUPS, buffer.toString());
}
/***
* A convenience method to send the NNTP NEWGROUPS command to the server,
* receive the reply, and return the reply code.
*
* @param newsgroups A comma-separated list of newsgroups to check for new
* news.
* @param date The date after which to check for new news.
* Date format is YYMMDD
* @param time The time after which to check for new news.
* Time format is HHMMSS using a 24-hour clock.
* @param GMT True if the time is in GMT, false if local server time.
* @param distributions Comma-separated distribution list to check for
* new news. Set to null if no distributions.
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int newnews(String newsgroups, String date, String time, boolean GMT,
String distributions) throws IOException
{
StringBuilder buffer = new StringBuilder();
buffer.append(newsgroups);
buffer.append(' ');
buffer.append(date);
buffer.append(' ');
buffer.append(time);
if (GMT)
{
buffer.append(' ');
buffer.append("GMT");
}
if (distributions != null)
{
buffer.append(" <");
buffer.append(distributions);
buffer.append('>');
}
return sendCommand(NNTPCommand.NEWNEWS, buffer.toString());
}
/***
* A convenience method to send the NNTP POST command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int post() throws IOException
{
return sendCommand(NNTPCommand.POST);
}
/***
* A convenience method to send the NNTP QUIT command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int quit() throws IOException
{
return sendCommand(NNTPCommand.QUIT);
}
/***
* A convenience method to send the AUTHINFO USER command to the server,
* receive the reply, and return the reply code. (See RFC 2980)
*
* @param username A valid username.
* @return The reply code received from the server. The server should
* return a 381 or 281 for this command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int authinfoUser(String username) throws IOException {
String userParameter = "USER " + username;
return sendCommand(NNTPCommand.AUTHINFO, userParameter);
}
/***
* A convenience method to send the AUTHINFO PASS command to the server,
* receive the reply, and return the reply code. If this step is
* required, it should immediately follow the AUTHINFO USER command
* (See RFC 2980)
*
* @param password a valid password.
* @return The reply code received from the server. The server should
* return a 281 or 502 for this command.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int authinfoPass(String password) throws IOException {
String passParameter = "PASS " + password;
return sendCommand(NNTPCommand.AUTHINFO, passParameter);
}
/***
* A convenience method to send the NNTP XOVER command to the server,
* receive the reply, and return the reply code.
*
* @param selectedArticles a String representation of the range of
* article headers required. This may be an article number, or a
* range of article numbers in the form "XXXX-YYYY", where XXXX
* and YYYY are valid article numbers in the current group. It
* also may be of the form "XXX-", meaning "return XXX and all
* following articles" In this revision, the last format is not
* possible (yet).
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int xover(String selectedArticles) throws IOException {
return sendCommand(NNTPCommand.XOVER, selectedArticles);
}
/***
* A convenience method to send the NNTP XHDR command to the server,
* receive the reply, and return the reply code.
*
* @param header a String naming a header line (e.g., "subject"). See
* RFC-1036 for a list of valid header lines.
* @param selectedArticles a String representation of the range of
* article headers required. This may be an article number, or a
* range of article numbers in the form "XXXX-YYYY", where XXXX
* and YYYY are valid article numbers in the current group. It
* also may be of the form "XXX-", meaning "return XXX and all
* following articles" In this revision, the last format is not
* possible (yet).
* @return The reply code received from the server.
* @exception NNTPConnectionClosedException
* If the NNTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int xhdr(String header, String selectedArticles) throws IOException {
StringBuilder command = new StringBuilder(header);
command.append(" ");
command.append(selectedArticles);
return sendCommand(NNTPCommand.XHDR, command.toString());
}
/**
* A convenience wrapper for the extended LIST command that takes
* an argument, allowing us to selectively list multiple groups.
*
* @param wildmat A wildmat (pseudo-regex) pattern. See RFC 2980 for
* details.
* @return the reply code received from the server.
* @throws IOException
*/
public int listActive(String wildmat) throws IOException {
StringBuilder command = new StringBuilder("ACTIVE ");
command.append(wildmat);
return sendCommand(NNTPCommand.LIST, command.toString());
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/NNTPCommand.java 0000644 0001750 0001750 00000005301 10542533103 026352 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/***
* NNTPCommand stores a set of constants for NNTP command codes. To interpret
* the meaning of the codes, familiarity with RFC 977 is assumed.
*
* @author Daniel F. Savarese
* @author Rory Winston
* @author Ted Wise
***/
public final class NNTPCommand
{
public static final int ARTICLE = 0;
public static final int BODY = 1;
public static final int GROUP = 2;
public static final int HEAD = 3;
public static final int HELP = 4;
public static final int IHAVE = 5;
public static final int LAST = 6;
public static final int LIST = 7;
public static final int NEWGROUPS = 8;
public static final int NEWNEWS = 9;
public static final int NEXT = 10;
public static final int POST = 11;
public static final int QUIT = 12;
public static final int SLAVE = 13;
public static final int STAT = 14;
public static final int AUTHINFO = 15;
public static final int XOVER = 16;
public static final int XHDR = 17;
// Cannot be instantiated
private NNTPCommand()
{}
static final String[] _commands = {
"ARTICLE", "BODY", "GROUP", "HEAD", "HELP", "IHAVE", "LAST", "LIST",
"NEWGROUPS", "NEWNEWS", "NEXT", "POST", "QUIT", "SLAVE", "STAT",
"AUTHINFO", "XOVER", "XHDR"
};
/***
* Retrieve the NNTP protocol command string corresponding to a specified
* command code.
*
* @param command The command code.
* @return The NNTP protcol command string corresponding to a specified
* command code.
***/
public static final String getCommand(int command)
{
return _commands[command];
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java 0000644 0001750 0001750 00000012325 11354512541 027347 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/***
* This class is used to construct the bare minimum
* acceptable header for most news readers. To construct more
* complicated headers you should refer to RFC 822. When the
* Java Mail API is finalized, you will be
* able to use it to compose fully compliant Internet text messages.
*
* The main purpose of the class is to faciliatate the article posting
* process, by relieving the programmer from having to explicitly format
* an article header. For example:
*
*
* @author Daniel F. Savarese
* @see NNTPClient
***/
public class SimpleNNTPHeader
{
private String __subject, __from;
private StringBuilder __newsgroups;
private StringBuilder __headerFields;
private int __newsgroupCount;
/***
* Creates a new SimpleNNTPHeader instance initialized with the given
* from and subject header field values.
*
* @param from The value of the
* @param newsgroup The newsgroup to add to the article's newsgroup
* distribution list.
***/
public void addNewsgroup(String newsgroup)
{
if (__newsgroupCount++ > 0)
__newsgroups.append(',');
__newsgroups.append(newsgroup);
}
/***
* Adds an arbitrary header field with the given value to the article
* header. These headers will be written after the From, Newsgroups,
* and Subject fields when the SimpleNNTPHeader is convertered to a string.
* An example use would be:
*
* @param headerField The header field to add, not including the colon.
* @param value The value of the added header field.
***/
public void addHeaderField(String headerField, String value)
{
__headerFields.append(headerField);
__headerFields.append(": ");
__headerFields.append(value);
__headerFields.append('\n');
}
/***
* Returns the address used in the
* @return The from address.
***/
public String getFromAddress()
{
return __from;
}
/***
* Returns the subject used in the
* @return The subject.
***/
public String getSubject()
{
return __subject;
}
/***
* Returns the contents of the
* @return The comma-separated list of newsgroups to which the article
* is being posted.
***/
public String getNewsgroups()
{
return __newsgroups.toString();
}
/***
* Converts the SimpleNNTPHeader to a properly formatted header in
* the form of a String, including the blank line used to separate
* the header from the article body.
*
* @return The article header in the form of a String.
***/
@Override
public String toString()
{
StringBuilder header = new StringBuilder();
header.append("From: ");
header.append(__from);
header.append("\nNewsgroups: ");
header.append(__newsgroups.toString());
header.append("\nSubject: ");
header.append(__subject);
header.append('\n');
if (__headerFields.length() > 0)
header.append(__headerFields.toString());
header.append('\n');
return header.toString();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java 0000644 0001750 0001750 00000010643 11466122735 027121 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/***
* NewsgroupInfo stores information pertaining to a newsgroup returned by
* the NNTP GROUP, LIST, and NEWGROUPS commands, implemented by
* {@link org.apache.commons.net.nntp.NNTPClient#selectNewsgroup selectNewsgroup }
* ,
* {@link org.apache.commons.net.nntp.NNTPClient#listNewsgroups listNewsgroups }
* , and
* {@link org.apache.commons.net.nntp.NNTPClient#listNewNewsgroups listNewNewsgroups }
* respectively.
*
*
* @author Daniel F. Savarese
* @see NNTPClient
***/
public final class NewsgroupInfo
{
/***
* A constant indicating that the posting permission of a newsgroup is
* unknown. For example, the NNTP GROUP command does not return posting
* information, so NewsgroupInfo instances obtained from that command
* willhave an UNKNOWN_POSTING_PERMISSION.
***/
public static final int UNKNOWN_POSTING_PERMISSION = 0;
/*** A constant indicating that a newsgroup is moderated. ***/
public static final int MODERATED_POSTING_PERMISSION = 1;
/*** A constant indicating that a newsgroup is public and unmoderated. ***/
public static final int PERMITTED_POSTING_PERMISSION = 2;
/***
* A constant indicating that a newsgroup is closed for general posting.
***/
public static final int PROHIBITED_POSTING_PERMISSION = 3;
private String __newsgroup;
private int __estimatedArticleCount;
private int __firstArticle, __lastArticle;
private int __postingPermission;
void _setNewsgroup(String newsgroup)
{
__newsgroup = newsgroup;
}
void _setArticleCount(int count)
{
__estimatedArticleCount = count;
}
void _setFirstArticle(int first)
{
__firstArticle = first;
}
void _setLastArticle(int last)
{
__lastArticle = last;
}
void _setPostingPermission(int permission)
{
__postingPermission = permission;
}
/***
* Get the newsgroup name.
*
* @return The name of the newsgroup.
***/
public String getNewsgroup()
{
return __newsgroup;
}
/***
* Get the estimated number of articles in the newsgroup. The
* accuracy of this value will depend on the server implementation.
*
* @return The estimated number of articles in the newsgroup.
***/
public int getArticleCount()
{
return __estimatedArticleCount;
}
/***
* Get the number of the first article in the newsgroup.
*
* @return The number of the first article in the newsgroup.
***/
public int getFirstArticle()
{
return __firstArticle;
}
/***
* Get the number of the last article in the newsgroup.
*
* @return The number of the last article in the newsgroup.
***/
public int getLastArticle()
{
return __lastArticle;
}
/***
* Get the posting permission of the newsgroup. This will be one of
* the
* @return The posting permission status of the newsgroup.
***/
public int getPostingPermission()
{
return __postingPermission;
}
/*
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(__newsgroup);
buffer.append(' ');
buffer.append(__lastArticle);
buffer.append(' ');
buffer.append(__firstArticle);
buffer.append(' ');
switch(__postingPermission) {
case 1: buffer.append('m'); break;
case 2: buffer.append('y'); break;
case 3: buffer.append('n'); break;
}
return buffer.toString();
}
*/
}
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/Threadable.java 0000644 0001750 0001750 00000002431 11014672436 026340 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
/**
* A placeholder interface for threadable message objects
* Author: Rory Winston
*
* @author Daniel F. Savarese
***/
public final class NNTPReply
{
// TODO - drop all these numeric constants?
public static final int CODE_100 = 100;
public static final int CODE_199 = 199;
public static final int CODE_200 = 200;
public static final int CODE_201 = 201;
public static final int CODE_202 = 202;
public static final int CODE_205 = 205;
public static final int CODE_211 = 211;
public static final int CODE_215 = 215;
public static final int CODE_220 = 220;
public static final int CODE_221 = 221;
public static final int CODE_222 = 222;
public static final int CODE_223 = 223;
public static final int CODE_230 = 230;
public static final int CODE_231 = 231;
public static final int CODE_235 = 235;
public static final int CODE_240 = 240;
public static final int CODE_281 = 281;
public static final int CODE_335 = 335;
public static final int CODE_340 = 340;
public static final int CODE_381 = 381;
public static final int CODE_400 = 400;
public static final int CODE_408 = 408; // Not actually needed; kept for API compatibility
public static final int CODE_411 = 411;
public static final int CODE_412 = 412;
public static final int CODE_420 = 420;
public static final int CODE_421 = 421;
public static final int CODE_422 = 422;
public static final int CODE_423 = 423;
public static final int CODE_430 = 430;
public static final int CODE_435 = 435;
public static final int CODE_436 = 436;
public static final int CODE_437 = 437;
public static final int CODE_440 = 440;
public static final int CODE_441 = 441;
/** @since 2.2 */
public static final int CODE_480 = 480;
public static final int CODE_482 = 482;
public static final int CODE_500 = 500;
public static final int CODE_501 = 501;
public static final int CODE_502 = 502;
public static final int CODE_503 = 503;
public static final int HELP_TEXT_FOLLOWS = CODE_100;
public static final int DEBUG_OUTPUT = CODE_199;
public static final int SERVER_READY_POSTING_ALLOWED = CODE_200;
public static final int SERVER_READY_POSTING_NOT_ALLOWED = CODE_201;
public static final int SLAVE_STATUS_NOTED = CODE_202;
public static final int CLOSING_CONNECTION = CODE_205;
public static final int GROUP_SELECTED = CODE_211;
public static final int ARTICLE_RETRIEVED_HEAD_AND_BODY_FOLLOW = CODE_220;
public static final int ARTICLE_RETRIEVED_HEAD_FOLLOWS = CODE_221;
public static final int ARTICLE_RETRIEVED_BODY_FOLLOWS = CODE_222;
public static final int
ARTICLE_RETRIEVED_REQUEST_TEXT_SEPARATELY = CODE_223;
public static final int ARTICLE_LIST_BY_MESSAGE_ID_FOLLOWS = CODE_230;
public static final int NEW_NEWSGROUP_LIST_FOLLOWS = CODE_231;
public static final int ARTICLE_TRANSFERRED_OK = CODE_235;
public static final int ARTICLE_POSTED_OK = CODE_240;
public static final int AUTHENTICATION_ACCEPTED = CODE_281;
public static final int SEND_ARTICLE_TO_TRANSFER = CODE_335;
public static final int SEND_ARTICLE_TO_POST = CODE_340;
public static final int MORE_AUTH_INFO_REQUIRED = CODE_381;
public static final int SERVICE_DISCONTINUED = CODE_400;
public static final int NO_SUCH_NEWSGROUP = CODE_411;
public static final int NO_NEWSGROUP_SELECTED = CODE_412;
public static final int NO_CURRENT_ARTICLE_SELECTED = CODE_420;
public static final int NO_NEXT_ARTICLE = CODE_421;
public static final int NO_PREVIOUS_ARTICLE = CODE_422;
public static final int NO_SUCH_ARTICLE_NUMBER = CODE_423;
public static final int NO_SUCH_ARTICLE_FOUND = CODE_430;
public static final int ARTICLE_NOT_WANTED = CODE_435;
public static final int TRANSFER_FAILED = CODE_436;
public static final int ARTICLE_REJECTED = CODE_437;
public static final int POSTING_NOT_ALLOWED = CODE_440;
public static final int POSTING_FAILED = CODE_441;
/** @since 2.2 - corrected value to 480 */
public static final int AUTHENTICATION_REQUIRED = CODE_480;
public static final int AUTHENTICATION_REJECTED = CODE_482;
public static final int COMMAND_NOT_RECOGNIZED = CODE_500;
public static final int COMMAND_SYNTAX_ERROR = CODE_501;
public static final int PERMISSION_DENIED = CODE_502;
public static final int PROGRAM_FAULT = CODE_503;
// Cannot be instantiated
private NNTPReply()
{}
/***
* Determine if a reply code is an informational response. All
* codes beginning with a 1 are positive informational responses.
* Informational responses are used to provide human readable
* information such as help text.
*
* @param reply The reply code to test.
* @return True if a reply code is an informational response, false
* if not.
***/
public static boolean isInformational(int reply)
{
return (reply >= 100 && reply < 200);
}
/***
* Determine if a reply code is a positive completion response. All
* codes beginning with a 2 are positive completion responses.
* The NNTP server will send a positive completion response on the final
* successful completion of a command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive completion response, false
* if not.
***/
public static boolean isPositiveCompletion(int reply)
{
return (reply >= 200 && reply < 300);
}
/***
* Determine if a reply code is a positive intermediate response. All
* codes beginning with a 3 are positive intermediate responses.
* The NNTP server will send a positive intermediate response on the
* successful completion of one part of a multi-part command or
* sequence of commands. For example, after a successful POST command,
* a positive intermediate response will be sent to indicate that the
* server is ready to receive the article to be posted.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive intermediate response, false
* if not.
***/
public static boolean isPositiveIntermediate(int reply)
{
return (reply >= 300 && reply < 400);
}
/***
* Determine if a reply code is a negative transient response. All
* codes beginning with a 4 are negative transient responses.
* The NNTP server will send a negative transient response on the
* failure of a correctly formatted command that could not be performed
* for some reason. For example, retrieving an article that does not
* exist will result in a negative transient response.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative transient response, false
* if not.
***/
public static boolean isNegativeTransient(int reply)
{
return (reply >= 400 && reply < 500);
}
/***
* Determine if a reply code is a negative permanent response. All
* codes beginning with a 5 are negative permanent responses.
* The NNTP server will send a negative permanent response when
* it does not implement a command, a command is incorrectly formatted,
* or a serious program error occurs.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative permanent response, false
* if not.
***/
public static boolean isNegativePermanent(int reply)
{
return (reply >= 500 && reply < 600);
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/nntp/Article.java 0000644 0001750 0001750 00000016271 11466233505 025700 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.nntp;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
* This is a class that contains the basic state needed for message retrieval and threading.
* With thanks to Jamie Zawinski
*
* @author Daniel F. Savarese
***/
public final class WhoisClient extends FingerClient
{
/***
* The default whois host to query. It is set to whois.internic.net.
***/
public static final String DEFAULT_HOST = "whois.internic.net";
/***
* The default whois port. It is set to 43 according to RFC 954.
***/
public static final int DEFAULT_PORT = 43;
/***
* The default whois constructor. Initializes the
* default port to
* @param handle The handle to lookup.
* @return The result of the whois query.
* @exception IOException If an I/O error occurs during the operation.
***/
public String query(String handle) throws IOException
{
return query(false, handle);
}
/***
* Queries the connected whois server for information regarding
* the given handle and returns the InputStream of the network connection.
* It is up to the programmer to be familiar with the handle syntax
* of the whois server. You must first connect to a finger server before
* calling this method, and you should disconnect after finishing reading
* the stream.
*
* @param handle The handle to lookup.
* @return The InputStream of the network connection of the whois query.
* Can be read to obtain whois results.
* @exception IOException If an I/O error occurs during the operation.
***/
public InputStream getInputStream(String handle) throws IOException
{
return getInputStream(false, handle);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/DatagramSocketClient.java 0000644 0001750 0001750 00000022173 10542533103 027353 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/***
* The DatagramSocketClient provides the basic operations that are required
* of client objects accessing datagram sockets. It is meant to be
* subclassed to avoid having to rewrite the same code over and over again
* to open a socket, close a socket, set timeouts, etc. Of special note
* is the {@link #setDatagramSocketFactory setDatagramSocketFactory }
* method, which allows you to control the type of DatagramSocket the
* DatagramSocketClient creates for network communications. This is
* especially useful for adding things like proxy support as well as better
* support for applets. For
* example, you could create a
* {@link org.apache.commons.net.DatagramSocketFactory}
* that
* requests browser security capabilities before creating a socket.
* All classes derived from DatagramSocketClient should use the
* {@link #_socketFactory_ _socketFactory_ } member variable to
* create DatagramSocket instances rather than instantiating
* them by directly invoking a constructor. By honoring this contract
* you guarantee that a user will always be able to provide his own
* Socket implementations by substituting his own SocketFactory.
*
*
* @author Daniel F. Savarese
* @see DatagramSocketFactory
***/
public abstract class DatagramSocketClient
{
/***
* The default DatagramSocketFactory shared by all DatagramSocketClient
* instances.
***/
private static final DatagramSocketFactory __DEFAULT_SOCKET_FACTORY =
new DefaultDatagramSocketFactory();
/*** The timeout to use after opening a socket. ***/
protected int _timeout_;
/*** The datagram socket used for the connection. ***/
protected DatagramSocket _socket_;
/***
* A status variable indicating if the client's socket is currently open.
***/
protected boolean _isOpen_;
/*** The datagram socket's DatagramSocketFactory. ***/
protected DatagramSocketFactory _socketFactory_;
/***
* Default constructor for DatagramSocketClient. Initializes
* _socket_ to null, _timeout_ to 0, and _isOpen_ to false.
***/
public DatagramSocketClient()
{
_socket_ = null;
_timeout_ = 0;
_isOpen_ = false;
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
}
/***
* Opens a DatagramSocket on the local host at the first available port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
*
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @exception SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open() throws SocketException
{
_socket_ = _socketFactory_.createDatagramSocket();
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket on the local host at a specified port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
*
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @param port The port to use for the socket.
* @exception SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port) throws SocketException
{
_socket_ = _socketFactory_.createDatagramSocket(port);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Opens a DatagramSocket at the specified address on the local host
* at a specified port.
* Also sets the timeout on the socket to the default timeout set
* by {@link #setDefaultTimeout setDefaultTimeout() }.
*
* _isOpen_ is set to true after calling this method and _socket_
* is set to the newly opened socket.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @exception SocketException If the socket could not be opened or the
* timeout could not be set.
***/
public void open(int port, InetAddress laddr) throws SocketException
{
_socket_ = _socketFactory_.createDatagramSocket(port, laddr);
_socket_.setSoTimeout(_timeout_);
_isOpen_ = true;
}
/***
* Closes the DatagramSocket used for the connection.
* You should call this method after you've finished using the class
* instance and also before you call {@link #open open() }
* again. _isOpen_ is set to false and _socket_ is set to null.
* If you call this method when the client socket is not open,
* a NullPointerException is thrown.
***/
public void close()
{
_socket_.close();
_socket_ = null;
_isOpen_ = false;
}
/***
* Returns true if the client has a currently open socket.
*
* @return True if the client has a curerntly open socket, false otherwise.
***/
public boolean isOpen()
{
return _isOpen_;
}
/***
* Set the default timeout in milliseconds to use when opening a socket.
* After a call to open, the timeout for the socket is set using this value.
* This method should be used prior to a call to {@link #open open()}
* and should not be confused with {@link #setSoTimeout setSoTimeout()}
* which operates on the currently open socket. _timeout_ contains
* the new timeout value.
*
* @param timeout The timeout in milliseconds to use for the datagram socket
* connection.
***/
public void setDefaultTimeout(int timeout)
{
_timeout_ = timeout;
}
/***
* Returns the default timeout in milliseconds that is used when
* opening a socket.
*
* @return The default timeout in milliseconds that is used when
* opening a socket.
***/
public int getDefaultTimeout()
{
return _timeout_;
}
/***
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
* by {@link #open open()}.
*
* @param timeout The timeout in milliseconds to use for the currently
* open datagram socket connection.
***/
public void setSoTimeout(int timeout) throws SocketException
{
_socket_.setSoTimeout(timeout);
}
/***
* Returns the timeout in milliseconds of the currently opened socket.
* If you call this method when the client socket is not open,
* a NullPointerException is thrown.
*
* @return The timeout in milliseconds of the currently opened socket.
***/
public int getSoTimeout() throws SocketException
{
return _socket_.getSoTimeout();
}
/***
* Returns the port number of the open socket on the local host used
* for the connection. If you call this method when the client socket
* is not open, a NullPointerException is thrown.
*
* @return The port number of the open socket on the local host used
* for the connection.
***/
public int getLocalPort()
{
return _socket_.getLocalPort();
}
/***
* Returns the local address to which the client's socket is bound.
* If you call this method when the client socket is not open, a
* NullPointerException is thrown.
*
* @return The local address to which the client's socket is bound.
***/
public InetAddress getLocalAddress()
{
return _socket_.getLocalAddress();
}
/***
* Sets the DatagramSocketFactory used by the DatagramSocketClient
* to open DatagramSockets. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
*
* @param factory The new DatagramSocketFactory the DatagramSocketClient
* should use.
***/
public void setDatagramSocketFactory(DatagramSocketFactory factory)
{
if (factory == null)
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
else
_socketFactory_ = factory;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/ 0000755 0001750 0001750 00000000000 11617452467 023103 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/io/Util.java 0000644 0001750 0001750 00000033530 10542533103 024646 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
/***
* The Util class cannot be instantiated and stores short static convenience
* methods that are often quite useful.
*
*
* @see CopyStreamException
* @see CopyStreamListener
* @see CopyStreamAdapter
* @author Daniel F. Savarese
***/
public final class Util
{
/***
* The default buffer size used by {@link #copyStream copyStream }
* and {@link #copyReader copyReader }. It's value is 1024.
***/
public static final int DEFAULT_COPY_BUFFER_SIZE = 1024;
// Cannot be instantiated
private Util()
{ }
/***
* Copies the contents of an InputStream to an OutputStream using a
* copy buffer of a given size and notifies the provided
* CopyStreamListener of the progress of the copy operation by calling
* its bytesTransferred(long, int) method after each write to the
* destination. If you wish to notify more than one listener you should
* use a CopyStreamAdapter as the listener and register the additional
* listeners with the CopyStreamAdapter.
*
* The contents of the InputStream are
* read until the end of the stream is reached, but neither the
* source nor the destination are closed. You must do this yourself
* outside of the method call. The number of bytes read/written is
* returned.
*
* @param source The source InputStream.
* @param dest The destination OutputStream.
* @param bufferSize The number of bytes to buffer during the copy.
* @param streamSize The number of bytes in the stream being copied.
* Should be set to CopyStreamEvent.UNKNOWN_STREAM_SIZE if unknown.
* @param listener The CopyStreamListener to notify of progress. If
* this parameter is null, notification is not attempted.
* @param flush Whether to flush the output stream after every
* write. This is necessary for interactive sessions that rely on
* buffered streams. If you don't flush, the data will stay in
* the stream buffer.
* @exception CopyStreamException If an error occurs while reading from the
* source or writing to the destination. The CopyStreamException
* will contain the number of bytes confirmed to have been
* transferred before an
* IOException occurred, and it will also contain the IOException
* that caused the error. These values can be retrieved with
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize, long streamSize,
CopyStreamListener listener,
boolean flush)
throws CopyStreamException
{
int bytes;
long total;
byte[] buffer;
buffer = new byte[bufferSize];
total = 0;
try
{
while ((bytes = source.read(buffer)) != -1)
{
// Technically, some read(byte[]) methods may return 0 and we cannot
// accept that as an indication of EOF.
if (bytes == 0)
{
bytes = source.read();
if (bytes < 0)
break;
dest.write(bytes);
if(flush)
dest.flush();
++total;
if (listener != null)
listener.bytesTransferred(total, 1, streamSize);
continue;
}
dest.write(buffer, 0, bytes);
if(flush)
dest.flush();
total += bytes;
if (listener != null)
listener.bytesTransferred(total, bytes, streamSize);
}
}
catch (IOException e)
{
throw new CopyStreamException("IOException caught while copying.",
total, e);
}
return total;
}
/***
* Copies the contents of an InputStream to an OutputStream using a
* copy buffer of a given size and notifies the provided
* CopyStreamListener of the progress of the copy operation by calling
* its bytesTransferred(long, int) method after each write to the
* destination. If you wish to notify more than one listener you should
* use a CopyStreamAdapter as the listener and register the additional
* listeners with the CopyStreamAdapter.
*
* The contents of the InputStream are
* read until the end of the stream is reached, but neither the
* source nor the destination are closed. You must do this yourself
* outside of the method call. The number of bytes read/written is
* returned.
*
* @param source The source InputStream.
* @param dest The destination OutputStream.
* @param bufferSize The number of bytes to buffer during the copy.
* @param streamSize The number of bytes in the stream being copied.
* Should be set to CopyStreamEvent.UNKNOWN_STREAM_SIZE if unknown.
* @param listener The CopyStreamListener to notify of progress. If
* this parameter is null, notification is not attempted.
* @exception CopyStreamException If an error occurs while reading from the
* source or writing to the destination. The CopyStreamException
* will contain the number of bytes confirmed to have been
* transferred before an
* IOException occurred, and it will also contain the IOException
* that caused the error. These values can be retrieved with
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize, long streamSize,
CopyStreamListener listener)
throws CopyStreamException
{
return copyStream(source, dest, bufferSize, streamSize, listener,
true);
}
/***
* Copies the contents of an InputStream to an OutputStream using a
* copy buffer of a given size. The contents of the InputStream are
* read until the end of the stream is reached, but neither the
* source nor the destination are closed. You must do this yourself
* outside of the method call. The number of bytes read/written is
* returned.
*
* @param source The source InputStream.
* @param dest The destination OutputStream.
* @return The number of bytes read/written in the copy operation.
* @exception CopyStreamException If an error occurs while reading from the
* source or writing to the destination. The CopyStreamException
* will contain the number of bytes confirmed to have been
* transferred before an
* IOException occurred, and it will also contain the IOException
* that caused the error. These values can be retrieved with
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyStream(InputStream source, OutputStream dest,
int bufferSize)
throws CopyStreamException
{
return copyStream(source, dest, bufferSize,
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
}
/***
* Same as
* The contents of the Reader are
* read until its end is reached, but neither the source nor the
* destination are closed. You must do this yourself outside of the
* method call. The number of characters read/written is returned.
*
* @param source The source Reader.
* @param dest The destination writer.
* @param bufferSize The number of characters to buffer during the copy.
* @param streamSize The number of characters in the stream being copied.
* Should be set to CopyStreamEvent.UNKNOWN_STREAM_SIZE if unknown.
* @param listener The CopyStreamListener to notify of progress. If
* this parameter is null, notification is not attempted.
* @return The number of characters read/written in the copy operation.
* @exception CopyStreamException If an error occurs while reading from the
* source or writing to the destination. The CopyStreamException
* will contain the number of bytes confirmed to have been
* transferred before an
* IOException occurred, and it will also contain the IOException
* that caused the error. These values can be retrieved with
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyReader(Reader source, Writer dest,
int bufferSize, long streamSize,
CopyStreamListener listener)
throws CopyStreamException
{
int chars;
long total;
char[] buffer;
buffer = new char[bufferSize];
total = 0;
try
{
while ((chars = source.read(buffer)) != -1)
{
// Technically, some read(char[]) methods may return 0 and we cannot
// accept that as an indication of EOF.
if (chars == 0)
{
chars = source.read();
if (chars < 0)
break;
dest.write(chars);
dest.flush();
++total;
if (listener != null)
listener.bytesTransferred(total, chars, streamSize);
continue;
}
dest.write(buffer, 0, chars);
dest.flush();
total += chars;
if (listener != null)
listener.bytesTransferred(total, chars, streamSize);
}
}
catch (IOException e)
{
throw new CopyStreamException("IOException caught while copying.",
total, e);
}
return total;
}
/***
* Copies the contents of a Reader to a Writer using a
* copy buffer of a given size. The contents of the Reader are
* read until its end is reached, but neither the source nor the
* destination are closed. You must do this yourself outside of the
* method call. The number of characters read/written is returned.
*
* @param source The source Reader.
* @param dest The destination writer.
* @param bufferSize The number of characters to buffer during the copy.
* @return The number of characters read/written in the copy operation.
* @exception CopyStreamException If an error occurs while reading from the
* source or writing to the destination. The CopyStreamException
* will contain the number of bytes confirmed to have been
* transferred before an
* IOException occurred, and it will also contain the IOException
* that caused the error. These values can be retrieved with
* the CopyStreamException getTotalBytesTransferred() and
* getIOException() methods.
***/
public static final long copyReader(Reader source, Writer dest,
int bufferSize)
throws CopyStreamException
{
return copyReader(source, dest, bufferSize,
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null);
}
/***
* Same as
*
* @see CopyStreamEvent
* @see CopyStreamListener
* @see Util
* @author Daniel F. Savarese
* @version $Id: CopyStreamAdapter.java 929649 2010-03-31 18:12:07Z sebb $
*/
public class CopyStreamAdapter implements CopyStreamListener
{
private final ListenerList internalListeners;
/**
* Creates a new copyStreamAdapter.
*/
public CopyStreamAdapter()
{
internalListeners = new ListenerList();
}
/**
* This method is invoked by a CopyStreamEvent source after copying
* a block of bytes from a stream. The CopyStreamEvent will contain
* the total number of bytes transferred so far and the number of bytes
* transferred in the last write. The CopyStreamAdapater will relay
* the event to all of its registered listeners, listing itself as the
* source of the event.
* @param event The CopyStreamEvent fired by the copying of a block of
* bytes.
*/
public void bytesTransferred(CopyStreamEvent event)
{
bytesTransferred(event.getTotalBytesTransferred(),
event.getBytesTransferred(),
event.getStreamSize());
}
/**
* This method is not part of the JavaBeans model and is used by the
* static methods in the org.apache.commons.io.Util class for efficiency.
* It is invoked after a block of bytes to inform the listener of the
* transfer. The CopyStreamAdapater will create a CopyStreamEvent
* from the arguments and relay the event to all of its registered
* listeners, listing itself as the source of the event.
* @param totalBytesTransferred The total number of bytes transferred
* so far by the copy operation.
* @param bytesTransferred The number of bytes copied by the most recent
* write.
* @param streamSize The number of bytes in the stream being copied.
* This may be equal to CopyStreamEvent.UNKNOWN_STREAM_SIZE if
* the size is unknown.
*/
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred, long streamSize)
{
CopyStreamEvent event;
event = new CopyStreamEvent(this,
totalBytesTransferred,
bytesTransferred,
streamSize);
for (EventListener listener : internalListeners)
{
((CopyStreamListener) (listener)).bytesTransferred(event);
}
}
/**
* Registers a CopyStreamListener to receive CopyStreamEvents.
* Although this method is not declared to be synchronized, it is
* implemented in a thread safe manner.
* @param listener The CopyStreamlistener to register.
*/
public void addCopyStreamListener(CopyStreamListener listener)
{
internalListeners.addListener(listener);
}
/**
* Unregisters a CopyStreamListener. Although this method is not
* synchronized, it is implemented in a thread safe manner.
* @param listener The CopyStreamlistener to unregister.
*/
public void removeCopyStreamListener(CopyStreamListener listener)
{
internalListeners.removeListener(listener);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java 0000644 0001750 0001750 00000006475 11354710167 027042 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.util.EventObject;
/**
* A CopyStreamEvent is triggered after every write performed by a
* stream copying operation. The event stores the number of bytes
* transferred by the write triggering the event as well as the total
* number of bytes transferred so far by the copy operation.
*
*
* @see CopyStreamListener
* @see CopyStreamAdapter
* @see Util
* @author Daniel F. Savarese
* @version $Id: CopyStreamEvent.java 929649 2010-03-31 18:12:07Z sebb $
*/
public class CopyStreamEvent extends EventObject
{
/**
* Constant used to indicate the stream size is unknown.
*/
public static final long UNKNOWN_STREAM_SIZE = -1;
private final int bytesTransferred;
private final long totalBytesTransferred;
private final long streamSize;
/**
* Creates a new CopyStreamEvent instance.
* @param source The source of the event.
* @param totalBytesTransferred The total number of bytes transferred so
* far during a copy operation.
* @param bytesTransferred The number of bytes transferred during the
* write that triggered the CopyStreamEvent.
* @param streamSize The number of bytes in the stream being copied.
* This may be set to
* This class handles the doubling of line-starting periods,
* converts single linefeeds to NETASCII newlines, and on closing
* will send the final message terminator dot and NETASCII newline
* sequence.
*
*
* @author Daniel F. Savarese
***/
public final class DotTerminatedMessageWriter extends Writer
{
private static final int __NOTHING_SPECIAL_STATE = 0;
private static final int __LAST_WAS_CR_STATE = 1;
private static final int __LAST_WAS_NL_STATE = 2;
private int __state;
private Writer __output;
/***
* Creates a DotTerminatedMessageWriter that wraps an existing Writer
* output destination.
*
* @param output The Writer output destination to write the message.
***/
public DotTerminatedMessageWriter(Writer output)
{
super(output);
__output = output;
__state = __NOTHING_SPECIAL_STATE;
}
/***
* Writes a character to the output. Note that a call to this method
* may result in multiple writes to the underling Writer in order to
* convert naked linefeeds to NETASCII line separators and to double
* line-leading periods. This is transparent to the programmer and
* is only mentioned for completeness.
*
* @param ch The character to write.
* @exception IOException If an error occurs while writing to the
* underlying output.
***/
@Override
public void write(int ch) throws IOException
{
synchronized (lock)
{
switch (ch)
{
case '\r':
__state = __LAST_WAS_CR_STATE;
__output.write('\r');
return ;
case '\n':
if (__state != __LAST_WAS_CR_STATE)
__output.write('\r');
__output.write('\n');
__state = __LAST_WAS_NL_STATE;
return ;
case '.':
// Double the dot at the beginning of a line
if (__state == __LAST_WAS_NL_STATE)
__output.write('.');
//$FALL-THROUGH$
default:
__state = __NOTHING_SPECIAL_STATE;
__output.write(ch);
return ;
}
}
}
/***
* Writes a number of characters from a character array to the output
* starting from a given offset.
*
* @param buffer The character array to write.
* @param offset The offset into the array at which to start copying data.
* @param length The number of characters to write.
* @exception IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(char[] buffer, int offset, int length) throws IOException
{
synchronized (lock)
{
while (length-- > 0)
write(buffer[offset++]);
}
}
/***
* Writes a character array to the output.
*
* @param buffer The character array to write.
* @exception IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(char[] buffer) throws IOException
{
write(buffer, 0, buffer.length);
}
/***
* Writes a String to the output.
*
* @param string The String to write.
* @exception IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(String string) throws IOException
{
write(string.toCharArray());
}
/***
* Writes part of a String to the output starting from a given offset.
*
* @param string The String to write.
* @param offset The offset into the String at which to start copying data.
* @param length The number of characters to write.
* @exception IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void write(String string, int offset, int length) throws IOException
{
write(string.toCharArray(), offset, length);
}
/***
* Flushes the underlying output, writing all buffered output.
*
* @exception IOException If an error occurs while writing to the underlying
* output.
***/
@Override
public void flush() throws IOException
{
synchronized (lock)
{
__output.flush();
}
}
/***
* Flushes the underlying output, writing all buffered output, but doesn't
* actually close the underlying stream. The underlying stream may still
* be used for communicating with the server and therefore is not closed.
*
* @exception IOException If an error occurs while writing to the underlying
* output or closing the Writer.
***/
@Override
public void close() throws IOException
{
synchronized (lock)
{
if (__output == null)
return ;
if (__state == __LAST_WAS_CR_STATE)
__output.write('\n');
else if (__state != __LAST_WAS_NL_STATE)
__output.write("\r\n");
__output.write(".\r\n");
__output.flush();
__output = null;
}
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java 0000644 0001750 0001750 00000007041 11330134214 030122 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/***
* This class wraps an output stream, replacing all singly occurring
* <LF> (linefeed) characters with <CR><LF> (carriage return
* followed by linefeed), which is the NETASCII standard for representing
* a newline.
* You would use this class to implement ASCII file transfers requiring
* conversion to NETASCII.
*
*
* @author Daniel F. Savarese
***/
public final class ToNetASCIIOutputStream extends FilterOutputStream
{
private boolean __lastWasCR;
/***
* Creates a ToNetASCIIOutputStream instance that wraps an existing
* OutputStream.
*
* @param output The OutputStream to wrap.
***/
public ToNetASCIIOutputStream(OutputStream output)
{
super(output);
__lastWasCR = false;
}
/***
* Writes a byte to the stream. Note that a call to this method
* may result in multiple writes to the underlying input stream in order
* to convert naked newlines to NETASCII line separators.
* This is transparent to the programmer and is only mentioned for
* completeness.
*
* @param ch The byte to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(int ch)
throws IOException
{
switch (ch)
{
case '\r':
__lastWasCR = true;
out.write('\r');
return ;
case '\n':
if (!__lastWasCR)
out.write('\r');
//$FALL-THROUGH$
default:
__lastWasCR = false;
out.write(ch);
return ;
}
}
/***
* Writes a byte array to the stream.
*
* @param buffer The byte array to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[])
throws IOException
{
write(buffer, 0, buffer.length);
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset.
*
* @param buffer The byte array to write.
* @param offset The offset into the array at which to start copying data.
* @param length The number of bytes to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[], int offset, int length)
throws IOException
{
while (length-- > 0)
write(buffer[offset++]);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/CopyStreamListener.java 0000644 0001750 0001750 00000006255 10542533103 027531 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.util.EventListener;
/**
* The CopyStreamListener class can accept CopyStreamEvents to keep track
* of the progress of a stream copying operation. However, it is currently
* not used that way within NetComponents for performance reasons. Rather
* the bytesTransferred(long, int) method is called directly rather than
* passing an event to bytesTransferred(CopyStreamEvent), saving the creation
* of a CopyStreamEvent instance. Also, the only place where
* CopyStreamListener is currently used within NetComponents is in the
* static methods of the uninstantiable org.apache.commons.io.Util class, which
* would preclude the use of addCopyStreamListener and
* removeCopyStreamListener methods. However, future additions may use the
* JavaBean event model, which is why the hooks have been included from the
* beginning.
*
*
* @see CopyStreamEvent
* @see CopyStreamAdapter
* @see Util
* @author Daniel F. Savarese
* @version $Id: CopyStreamListener.java 489397 2006-12-21 16:28:51Z rwinston $
*/
public interface CopyStreamListener extends EventListener
{
/**
* This method is invoked by a CopyStreamEvent source after copying
* a block of bytes from a stream. The CopyStreamEvent will contain
* the total number of bytes transferred so far and the number of bytes
* transferred in the last write.
* @param event The CopyStreamEvent fired by the copying of a block of
* bytes.
*/
public void bytesTransferred(CopyStreamEvent event);
/**
* This method is not part of the JavaBeans model and is used by the
* static methods in the org.apache.commons.io.Util class for efficiency.
* It is invoked after a block of bytes to inform the listener of the
* transfer.
* @param totalBytesTransferred The total number of bytes transferred
* so far by the copy operation.
* @param bytesTransferred The number of bytes copied by the most recent
* write.
* @param streamSize The number of bytes in the stream being copied.
* This may be equal to CopyStreamEvent.UNKNOWN_STREAM_SIZE if
* the size is unknown.
*/
public void bytesTransferred(long totalBytesTransferred,
int bytesTransferred,
long streamSize);
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/SocketInputStream.java 0000644 0001750 0001750 00000004374 11354710167 027372 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
/***
* This class wraps an input stream, storing a reference to its originating
* socket. When the stream is closed, it will also close the socket
* immediately afterward. This class is useful for situations where you
* are dealing with a stream originating from a socket, but do not have
* a reference to the socket, and want to make sure it closes when the
* stream closes.
*
*
* @author Daniel F. Savarese
* @see SocketOutputStream
***/
public class SocketInputStream extends FilterInputStream
{
private final Socket __socket;
/***
* Creates a SocketInputStream instance wrapping an input stream and
* storing a reference to a socket that should be closed on closing
* the stream.
*
* @param socket The socket to close on closing the stream.
* @param stream The input stream to wrap.
***/
public SocketInputStream(Socket socket, InputStream stream)
{
super(stream);
__socket = socket;
}
/***
* Closes the stream and immediately afterward closes the referenced
* socket.
*
* @exception IOException If there is an error in closing the stream
* or socket.
***/
@Override
public void close() throws IOException
{
super.close();
__socket.close();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java 0000644 0001750 0001750 00000012053 10766271714 030465 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/***
* This class wraps an output stream, replacing all occurrences
* of <CR><LF> (carriage return followed by a linefeed),
* which is the NETASCII standard for representing a newline, with the
* local line separator representation. You would use this class to
* implement ASCII file transfers requiring conversion from NETASCII.
*
* Because of the translation process, a call to
*
* @author Daniel F. Savarese
***/
public final class FromNetASCIIOutputStream extends FilterOutputStream
{
private boolean __lastWasCR;
/***
* Creates a FromNetASCIIOutputStream instance that wraps an existing
* OutputStream.
*
* @param output The OutputStream to wrap.
***/
public FromNetASCIIOutputStream(OutputStream output)
{
super(output);
__lastWasCR = false;
}
private void __write(int ch) throws IOException
{
switch (ch)
{
case '\r':
__lastWasCR = true;
// Don't write anything. We need to see if next one is linefeed
break;
case '\n':
if (__lastWasCR)
{
out.write(FromNetASCIIInputStream._lineSeparatorBytes);
__lastWasCR = false;
break;
}
__lastWasCR = false;
out.write('\n');
break;
default:
if (__lastWasCR)
{
out.write('\r');
__lastWasCR = false;
}
out.write(ch);
break;
}
}
/***
* Writes a byte to the stream. Note that a call to this method
* might not actually write a byte to the underlying stream until a
* subsequent character is written, from which it can be determined if
* a NETASCII line separator was encountered.
* This is transparent to the programmer and is only mentioned for
* completeness.
*
* @param ch The byte to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(int ch)
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
out.write(ch);
return ;
}
__write(ch);
}
/***
* Writes a byte array to the stream.
*
* @param buffer The byte array to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[])
throws IOException
{
write(buffer, 0, buffer.length);
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset.
*
* @param buffer The byte array to write.
* @param offset The offset into the array at which to start copying data.
* @param length The number of bytes to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public synchronized void write(byte buffer[], int offset, int length)
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
// FilterOutputStream method is very slow.
//super.write(buffer, offset, length);
out.write(buffer, offset, length);
return ;
}
while (length-- > 0)
__write(buffer[offset++]);
}
/***
* Closes the stream, writing all pending data.
*
* @exception IOException If an error occurs while closing the stream.
***/
@Override
public synchronized void close()
throws IOException
{
if (FromNetASCIIInputStream._noConversionRequired)
{
super.close();
return ;
}
if (__lastWasCR)
out.write('\r');
super.close();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java 0000644 0001750 0001750 00000012143 11330134214 027720 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/***
* This class wraps an input stream, replacing all singly occurring
* <LF> (linefeed) characters with <CR><LF> (carriage return
* followed by linefeed), which is the NETASCII standard for representing
* a newline.
* You would use this class to implement ASCII file transfers requiring
* conversion to NETASCII.
*
*
* @author Daniel F. Savarese
***/
public final class ToNetASCIIInputStream extends FilterInputStream
{
private static final int __NOTHING_SPECIAL = 0;
private static final int __LAST_WAS_CR = 1;
private static final int __LAST_WAS_NL = 2;
private int __status;
/***
* Creates a ToNetASCIIInputStream instance that wraps an existing
* InputStream.
*
* @param input The InputStream to .
***/
public ToNetASCIIInputStream(InputStream input)
{
super(input);
__status = __NOTHING_SPECIAL;
}
/***
* Reads and returns the next byte in the stream. If the end of the
* message has been reached, returns -1.
*
* @return The next character in the stream. Returns -1 if the end of the
* stream has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read() throws IOException
{
int ch;
if (__status == __LAST_WAS_NL)
{
__status = __NOTHING_SPECIAL;
return '\n';
}
ch = in.read();
switch (ch)
{
case '\r':
__status = __LAST_WAS_CR;
return '\r';
case '\n':
if (__status != __LAST_WAS_CR)
{
__status = __LAST_WAS_NL;
return '\r';
}
//$FALL-THROUGH$
default:
__status = __NOTHING_SPECIAL;
return ch;
}
// statement not reached
//return ch;
}
/***
* Reads the next number of bytes from the stream into an array and
* returns the number of bytes read. Returns -1 if the end of the
* stream has been reached.
*
* @param buffer The byte array in which to store the data.
* @return The number of bytes read. Returns -1 if the
* end of the message has been reached.
* @exception IOException If an error occurs in reading the underlying
* stream.
***/
@Override
public int read(byte buffer[]) throws IOException
{
return read(buffer, 0, buffer.length);
}
/***
* Reads the next number of bytes from the stream into an array and returns
* the number of bytes read. Returns -1 if the end of the
* message has been reached. The characters are stored in the array
* starting from the given offset and up to the length specified.
*
* @param buffer The byte array in which to store the data.
* @param offset The offset into the array at which to start storing data.
* @param length The number of bytes to read.
* @return The number of bytes read. Returns -1 if the
* end of the stream has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read(byte buffer[], int offset, int length) throws IOException
{
int ch, off;
if (length < 1)
return 0;
ch = available();
if (length > ch)
length = ch;
// If nothing is available, block to read only one character
if (length < 1)
length = 1;
if ((ch = read()) == -1)
return -1;
off = offset;
do
{
buffer[offset++] = (byte)ch;
}
while (--length > 0 && (ch = read()) != -1);
return (offset - off);
}
/*** Returns false. Mark is not supported. ***/
@Override
public boolean markSupported()
{
return false;
}
@Override
public int available() throws IOException
{
int result;
result = in.available();
if (__status == __LAST_WAS_NL)
return (result + 1);
return result;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/CopyStreamException.java 0000644 0001750 0001750 00000005131 11354710167 027703 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.IOException;
/**
* The CopyStreamException class is thrown by the org.apache.commons.io.Util
* copyStream() methods. It stores the number of bytes confirmed to
* have been transferred before an I/O error as well as the IOException
* responsible for the failure of a copy operation.
* @see Util
* @author Daniel F. Savarese
* @version $Id: CopyStreamException.java 929649 2010-03-31 18:12:07Z sebb $
*/
public class CopyStreamException extends IOException
{
private final long totalBytesTransferred;
private final IOException ioException;
/**
* Creates a new CopyStreamException instance.
* @param message A message describing the error.
* @param bytesTransferred The total number of bytes transferred before
* an exception was thrown in a copy operation.
* @param exception The IOException thrown during a copy operation.
*/
public CopyStreamException(String message,
long bytesTransferred,
IOException exception)
{
super(message);
totalBytesTransferred = bytesTransferred;
ioException = exception;
}
/**
* Returns the total number of bytes confirmed to have
* been transferred by a failed copy operation.
* @return The total number of bytes confirmed to have
* been transferred by a failed copy operation.
*/
public long getTotalBytesTransferred()
{
return totalBytesTransferred;
}
/**
* Returns the IOException responsible for the failure of a copy operation.
* @return The IOException responsible for the failure of a copy operation.
*/
public IOException getIOException()
{
return ioException;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java 0000644 0001750 0001750 00000022010 11347053246 031124 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
/**
* DotTerminatedMessageReader is a class used to read messages from a
* server that are terminated by a single dot followed by a
* <CR><LF>
* sequence and with double dots appearing at the begining of lines which
* do not signal end of message yet start with a dot. Various Internet
* protocols such as NNTP and POP3 produce messages of this type.
*
* This class handles stripping of the duplicate period at the beginning
* of lines starting with a period, converts NETASCII newlines to the
* local line separator format, truncates the end of message indicator,
* and ensures you cannot read past the end of the message.
* @author Daniel F. Savarese
* @version $Id: DotTerminatedMessageReader.java 922748 2010-03-14 03:23:18Z sebb $
*/
public final class DotTerminatedMessageReader extends Reader
{
private static final String LS = System.getProperty("line.separator");
char[] LS_CHARS;
private boolean atBeginning;
private boolean eof;
private int pos;
private char[] internalBuffer;
private PushbackReader internalReader;
/**
* Creates a DotTerminatedMessageReader that wraps an existing Reader
* input source.
* @param reader The Reader input source containing the message.
*/
public DotTerminatedMessageReader(Reader reader)
{
super(reader);
LS_CHARS = LS.toCharArray();
internalBuffer = new char[LS_CHARS.length + 3];
pos = internalBuffer.length;
// Assumes input is at start of message
atBeginning = true;
eof = false;
internalReader = new PushbackReader(reader);
}
/**
* Reads and returns the next character in the message. If the end of the
* message has been reached, returns -1. Note that a call to this method
* may result in multiple reads from the underlying input stream to decode
* the message properly (removing doubled dots and so on). All of
* this is transparent to the programmer and is only mentioned for
* completeness.
* @return The next character in the message. Returns -1 if the end of the
* message has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
*/
@Override
public int read() throws IOException
{
int ch;
synchronized (lock)
{
if (pos < internalBuffer.length)
{
return internalBuffer[pos++];
}
if (eof)
{
return -1;
}
if ((ch = internalReader.read()) == -1)
{
eof = true;
return -1;
}
if (atBeginning)
{
atBeginning = false;
if (ch == '.')
{
ch = internalReader.read();
if (ch != '.')
{
// read newline
eof = true;
internalReader.read();
return -1;
}
else
{
return '.';
}
}
}
if (ch == '\r')
{
ch = internalReader.read();
if (ch == '\n')
{
ch = internalReader.read();
if (ch == '.')
{
ch = internalReader.read();
if (ch != '.')
{
// read newline and indicate end of file
internalReader.read();
eof = true;
}
else
{
internalBuffer[--pos] = (char) ch;
}
}
else
{
internalReader.unread(ch);
}
pos -= LS_CHARS.length;
System.arraycopy(LS_CHARS, 0, internalBuffer, pos,
LS_CHARS.length);
ch = internalBuffer[pos++];
}
else if (ch == '\r') {
internalReader.unread(ch);
}
else
{
internalBuffer[--pos] = (char) ch;
return '\r';
}
}
return ch;
}
}
/**
* Reads the next characters from the message into an array and
* returns the number of characters read. Returns -1 if the end of the
* message has been reached.
* @param buffer The character array in which to store the characters.
* @return The number of characters read. Returns -1 if the
* end of the message has been reached.
* @exception IOException If an error occurs in reading the underlying
* stream.
*/
@Override
public int read(char[] buffer) throws IOException
{
return read(buffer, 0, buffer.length);
}
/**
* Reads the next characters from the message into an array and
* returns the number of characters read. Returns -1 if the end of the
* message has been reached. The characters are stored in the array
* starting from the given offset and up to the length specified.
* @param buffer The character array in which to store the characters.
* @param offset The offset into the array at which to start storing
* characters.
* @param length The number of characters to read.
* @return The number of characters read. Returns -1 if the
* end of the message has been reached.
* @exception IOException If an error occurs in reading the underlying
* stream.
*/
@Override
public int read(char[] buffer, int offset, int length) throws IOException
{
int ch, off;
synchronized (lock)
{
if (length < 1)
{
return 0;
}
if ((ch = read()) == -1)
{
return -1;
}
off = offset;
do
{
buffer[offset++] = (char) ch;
}
while (--length > 0 && (ch = read()) != -1);
return (offset - off);
}
}
/**
* Determines if the message is ready to be read.
* @return True if the message is ready to be read, false if not.
* @exception IOException If an error occurs while checking the underlying
* stream.
*/
@Override
public boolean ready() throws IOException
{
synchronized (lock)
{
return (pos < internalBuffer.length || internalReader.ready());
}
}
/**
* Closes the message for reading. This doesn't actually close the
* underlying stream. The underlying stream may still be used for
* communicating with the server and therefore is not closed.
*
* If the end of the message has not yet been reached, this method
* will read the remainder of the message until it reaches the end,
* so that the underlying stream may continue to be used properly
* for communicating with the server. If you do not fully read
* a message, you MUST close it, otherwise your program will likely
* hang or behave improperly.
* @exception IOException If an error occurs while reading the
* underlying stream.
*/
@Override
public void close() throws IOException
{
synchronized (lock)
{
if (internalReader == null)
{
return;
}
if (!eof)
{
while (read() != -1)
{
// read to EOF
}
}
eof = true;
atBeginning = false;
pos = internalBuffer.length;
internalReader = null;
}
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/SocketOutputStream.java 0000644 0001750 0001750 00000005720 11354710167 027567 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/***
* This class wraps an output stream, storing a reference to its originating
* socket. When the stream is closed, it will also close the socket
* immediately afterward. This class is useful for situations where you
* are dealing with a stream originating from a socket, but do not have
* a reference to the socket, and want to make sure it closes when the
* stream closes.
*
*
* @author Daniel F. Savarese
* @see SocketInputStream
***/
public class SocketOutputStream extends FilterOutputStream
{
private final Socket __socket;
/***
* Creates a SocketOutputStream instance wrapping an output stream and
* storing a reference to a socket that should be closed on closing
* the stream.
*
* @param socket The socket to close on closing the stream.
* @param stream The input stream to wrap.
***/
public SocketOutputStream(Socket socket, OutputStream stream)
{
super(stream);
__socket = socket;
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset. This method bypasses the equivalent method in
* FilterOutputStream because the FilterOutputStream implementation is
* very inefficient.
*
* @param buffer The byte array to write.
* @param offset The offset into the array at which to start copying data.
* @param length The number of bytes to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public void write(byte buffer[], int offset, int length) throws IOException
{
out.write(buffer, offset, length);
}
/***
* Closes the stream and immediately afterward closes the referenced
* socket.
*
* @exception IOException If there is an error in closing the stream
* or socket.
***/
@Override
public void close() throws IOException
{
super.close();
__socket.close();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java 0000644 0001750 0001750 00000014741 11456046441 030264 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
/***
* This class wraps an input stream, replacing all occurrences
* of <CR><LF> (carriage return followed by a linefeed),
* which is the NETASCII standard for representing a newline, with the
* local line separator representation. You would use this class to
* implement ASCII file transfers requiring conversion from NETASCII.
*
*
* @author Daniel F. Savarese
***/
public final class FromNetASCIIInputStream extends PushbackInputStream
{
static final boolean _noConversionRequired;
static final String _lineSeparator;
static final byte[] _lineSeparatorBytes;
static {
_lineSeparator = System.getProperty("line.separator");
_noConversionRequired = _lineSeparator.equals("\r\n");
_lineSeparatorBytes = _lineSeparator.getBytes();
}
private int __length = 0;
/***
* Returns true if the NetASCII line separator differs from the system
* line separator, false if they are the same. This method is useful
* to determine whether or not you need to instantiate a
* FromNetASCIIInputStream object.
*
* @return True if the NETASCII line separator differs from the local
* system line separator, false if they are the same.
***/
public static final boolean isConversionRequired()
{
return !_noConversionRequired;
}
/***
* Creates a FromNetASCIIInputStream instance that wraps an existing
* InputStream.
***/
public FromNetASCIIInputStream(InputStream input)
{
super(input, _lineSeparatorBytes.length + 1);
}
private int __read() throws IOException
{
int ch;
ch = super.read();
if (ch == '\r')
{
ch = super.read();
if (ch == '\n')
{
unread(_lineSeparatorBytes);
ch = super.read();
// This is a kluge for read(byte[], ...) to read the right amount
--__length;
}
else
{
if (ch != -1)
unread(ch);
return '\r';
}
}
return ch;
}
/***
* Reads and returns the next byte in the stream. If the end of the
* message has been reached, returns -1. Note that a call to this method
* may result in multiple reads from the underlying input stream in order
* to convert NETASCII line separators to the local line separator format.
* This is transparent to the programmer and is only mentioned for
* completeness.
*
* @return The next character in the stream. Returns -1 if the end of the
* stream has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read() throws IOException
{
if (_noConversionRequired)
return super.read();
return __read();
}
/***
* Reads the next number of bytes from the stream into an array and
* returns the number of bytes read. Returns -1 if the end of the
* stream has been reached.
*
* @param buffer The byte array in which to store the data.
* @return The number of bytes read. Returns -1 if the
* end of the message has been reached.
* @exception IOException If an error occurs in reading the underlying
* stream.
***/
@Override
public int read(byte buffer[]) throws IOException
{
return read(buffer, 0, buffer.length);
}
/***
* Reads the next number of bytes from the stream into an array and returns
* the number of bytes read. Returns -1 if the end of the
* message has been reached. The characters are stored in the array
* starting from the given offset and up to the length specified.
*
* @param buffer The byte array in which to store the data.
* @param offset The offset into the array at which to start storing data.
* @param length The number of bytes to read.
* @return The number of bytes read. Returns -1 if the
* end of the stream has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read(byte buffer[], int offset, int length) throws IOException
{
if (_noConversionRequired)
return super.read(buffer, offset, length);
if (length < 1)
return 0;
int ch, off;
ch = available();
__length = (length > ch ? ch : length);
// If nothing is available, block to read only one character
if (__length < 1)
__length = 1;
if ((ch = __read()) == -1)
return -1;
off = offset;
do
{
buffer[offset++] = (byte)ch;
}
while (--__length > 0 && (ch = __read()) != -1);
return (offset - off);
}
// PushbackInputStream in JDK 1.1.3 returns the wrong thing
// TODO - can we delete this override now?
/***
* Returns the number of bytes that can be read without blocking EXCEPT
* when newline conversions have to be made somewhere within the
* available block of bytes. In other words, you really should not
* rely on the value returned by this method if you are trying to avoid
* blocking.
***/
@Override
public int available() throws IOException
{
if (in == null) {
throw new IOException("Stream closed");
}
return (buf.length - pos) + in.available();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ProtocolCommandListener.java 0000644 0001750 0001750 00000004257 10542533103 030134 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.util.EventListener;
/***
* There exists a large class of IETF protocols that work by sending an
* ASCII text command and arguments to a server, and then receiving an
* ASCII text reply. For debugging and other purposes, it is extremely
* useful to log or keep track of the contents of the protocol messages.
* The ProtocolCommandListener interface coupled with the
* {@link ProtocolCommandEvent} class facilitate this process.
*
* To receive ProtocolCommandEvents, you merely implement the
* ProtocolCommandListener interface and register the class as a listener
* with a ProtocolCommandEvent source such as
* {@link org.apache.commons.net.ftp.FTPClient}.
*
*
* @see ProtocolCommandEvent
* @see ProtocolCommandSupport
* @author Daniel F. Savarese
***/
public interface ProtocolCommandListener extends EventListener
{
/***
* This method is invoked by a ProtocolCommandEvent source after
* sending a protocol command to a server.
*
* @param event The ProtocolCommandEvent fired.
***/
public void protocolCommandSent(ProtocolCommandEvent event);
/***
* This method is invoked by a ProtocolCommandEvent source after
* receiving a reply from a server.
*
* @param event The ProtocolCommandEvent fired.
***/
public void protocolReplyReceived(ProtocolCommandEvent event);
}
commons-net-2.2/src/main/java/org/apache/commons/net/finger/ 0000755 0001750 0001750 00000000000 11617452467 023746 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/finger/FingerClient.java 0000644 0001750 0001750 00000016027 11416066007 027154 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.finger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import org.apache.commons.net.SocketClient;
/***
* The FingerClient class implements the client side of the Internet Finger
* Protocol defined in RFC 1288. To finger a host you create a
* FingerClient instance, connect to the host, query the host, and finally
* disconnect from the host. If the finger service you want to query is on
* a non-standard port, connect to the host at that port.
* Here's a sample use:
*
*
* @author Daniel F. Savarese
***/
public class FingerClient extends SocketClient
{
/***
* The default FINGER port. Set to 79 according to RFC 1288.
***/
public static final int DEFAULT_PORT = 79;
private static final String __LONG_FLAG = "/W ";
private transient char[] __buffer = new char[1024];
/***
* The default FingerClient constructor. Initializes the
* default port to
* @param longOutput Set to true if long output is requested, false if not.
* @param username The name of the user to finger.
* @return The result of the finger query.
* @exception IOException If an I/O error occurs while reading the socket.
***/
public String query(boolean longOutput, String username) throws IOException
{
int read;
StringBuilder result = new StringBuilder(__buffer.length);
BufferedReader input;
input =
new BufferedReader(new InputStreamReader(getInputStream(longOutput,
username)));
try {
while (true)
{
read = input.read(__buffer, 0, __buffer.length);
if (read <= 0)
break;
result.append(__buffer, 0, read);
}
} finally {
input.close();
}
return result.toString();
}
/***
* Fingers the connected host and returns the output
* as a String. You must first connect to a finger server before
* calling this method, and you should disconnect afterward.
* This is equivalent to calling
* @param longOutput Set to true if long output is requested, false if not.
* @return The result of the finger query.
* @exception IOException If an I/O error occurs while reading the socket.
***/
public String query(boolean longOutput) throws IOException
{
return query(longOutput, "");
}
/***
* Fingers a user and returns the input stream from the network connection
* of the finger query. You must first connect to a finger server before
* calling this method, and you should disconnect after finishing reading
* the stream.
*
* @param longOutput Set to true if long output is requested, false if not.
* @param username The name of the user to finger.
* @return The InputStream of the network connection of the finger query.
* Can be read to obtain finger results.
* @exception IOException If an I/O error during the operation.
***/
public InputStream getInputStream(boolean longOutput, String username)
throws IOException
{
return getInputStream(longOutput, username, null);
}
/***
* Fingers a user and returns the input stream from the network connection
* of the finger query. You must first connect to a finger server before
* calling this method, and you should disconnect after finishing reading
* the stream.
*
* @param longOutput Set to true if long output is requested, false if not.
* @param username The name of the user to finger.
* @param encoding the character encoding that should be used for the query,
* null for the platform's default encoding
* @return The InputStream of the network connection of the finger query.
* Can be read to obtain finger results.
* @exception IOException If an I/O error during the operation.
***/
public InputStream getInputStream(boolean longOutput, String username, String encoding)
throws IOException
{
DataOutputStream output;
StringBuilder buffer = new StringBuilder(64);
if (longOutput)
buffer.append(__LONG_FLAG);
buffer.append(username);
buffer.append(SocketClient.NETASCII_EOL);
byte[] encodedQuery =
(encoding == null ? buffer.toString().getBytes() : buffer.toString().getBytes(encoding));
output = new DataOutputStream(new BufferedOutputStream(_output_, 1024));
output.write(encodedQuery, 0, encodedQuery.length);
output.flush();
return _input_;
}
/***
* Fingers the connected host and returns the input stream from
* the network connection of the finger query. This is equivalent to
* calling getInputStream(longOutput, ""). You must first connect to a
* finger server before calling this method, and you should disconnect
* after finishing reading the stream.
*
* @param longOutput Set to true if long output is requested, false if not.
* @return The InputStream of the network connection of the finger query.
* Can be read to obtain finger results.
* @exception IOException If an I/O error during the operation.
***/
public InputStream getInputStream(boolean longOutput) throws IOException
{
return getInputStream(longOutput, "");
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/chargen/ 0000755 0001750 0001750 00000000000 11617452467 024103 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/chargen/CharGenTCPClient.java 0000644 0001750 0001750 00000006277 10761044665 027773 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.chargen;
import java.io.InputStream;
import org.apache.commons.net.SocketClient;
/***
* The CharGenTCPClient class is a TCP implementation of a client for the
* character generator protocol described in RFC 864. It can also be
* used for Systat (RFC 866), Quote of the Day (RFC 865), and netstat
* (port 15). All of these protocols involve connecting to the appropriate
* port, and reading data from an input stream. The chargen protocol
* actually sends data until the receiving end closes the connection. All
* of the others send only a fixed amount of data and then close the
* connection.
*
* To use the CharGenTCPClient class, just establish a
* connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* and call {@link #getInputStream getInputStream() } to access
* the data. Don't close the input stream when you're done with it. Rather,
* call {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
*
*
* @author Daniel F. Savarese
* @see CharGenUDPClient
***/
public final class CharGenTCPClient extends SocketClient
{
/*** The systat port value of 11 according to RFC 866. ***/
public static final int SYSTAT_PORT = 11;
/*** The netstat port value of 19. ***/
public static final int NETSTAT_PORT = 15;
/*** The quote of the day port value of 17 according to RFC 865. ***/
public static final int QUOTE_OF_DAY_PORT = 17;
/*** The character generator port value of 19 according to RFC 864. ***/
public static final int CHARGEN_PORT = 19;
/*** The default chargen port. It is set to 19 according to RFC 864. ***/
public static final int DEFAULT_PORT = 19;
/***
* The default constructor for CharGenTCPClient. It merely sets the
* default port to
* @return An InputStream from which the server generated data can be read.
***/
public InputStream getInputStream()
{
return _input_;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/chargen/CharGenUDPClient.java 0000644 0001750 0001750 00000011737 11354710167 027766 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.chargen;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import org.apache.commons.net.DatagramSocketClient;
/***
* The CharGenUDPClient class is a UDP implementation of a client for the
* character generator protocol described in RFC 864. It can also be
* used for Systat (RFC 866), Quote of the Day (RFC 865), and netstat
* (port 15). All of these protocols involve sending a datagram to the
* appropriate port, and reading data contained in one or more reply
* datagrams. The chargen and quote of the day protocols only send
* one reply datagram containing 512 bytes or less of data. The other
* protocols may reply with more than one datagram, in which case you
* must wait for a timeout to determine that all reply datagrams have
* been sent.
*
* To use the CharGenUDPClient class, just open a local UDP port
* with {@link org.apache.commons.net.DatagramSocketClient#open open }
* and call {@link #send send } to send the datagram that will
* initiate the data reply. For chargen or quote of the day, just
* call {@link #receive receive }, and you're done. For netstat and
* systat, call receive in a while loop, and catch a SocketException and
* InterruptedIOException to detect a timeout (don't forget to set the
* timeout duration beforehand). Don't forget to call
* {@link org.apache.commons.net.DatagramSocketClient#close close() }
* to clean up properly.
*
*
* @author Daniel F. Savarese
* @see CharGenTCPClient
***/
public final class CharGenUDPClient extends DatagramSocketClient
{
/*** The systat port value of 11 according to RFC 866. ***/
public static final int SYSTAT_PORT = 11;
/*** The netstat port value of 19. ***/
public static final int NETSTAT_PORT = 15;
/*** The quote of the day port value of 17 according to RFC 865. ***/
public static final int QUOTE_OF_DAY_PORT = 17;
/*** The character generator port value of 19 according to RFC 864. ***/
public static final int CHARGEN_PORT = 19;
/*** The default chargen port. It is set to 19 according to RFC 864. ***/
public static final int DEFAULT_PORT = 19;
private final byte[] __receiveData;
private final DatagramPacket __receivePacket;
private final DatagramPacket __sendPacket;
/***
* The default CharGenUDPClient constructor. It initializes some internal
* data structures for sending and receiving the necessary datagrams for
* the chargen and related protocols.
***/
public CharGenUDPClient()
{
// CharGen return packets have a maximum length of 512
__receiveData = new byte[512];
__receivePacket = new DatagramPacket(__receiveData, __receiveData.length);
__sendPacket = new DatagramPacket(new byte[0], 0);
}
/***
* Sends the data initiation datagram. This data in the packet is ignored
* by the server, and merely serves to signal that the server should send
* its reply.
*
* @param host The address of the server.
* @param port The port of the service.
* @exception IOException If an error occurs while sending the datagram.
***/
public void send(InetAddress host, int port) throws IOException
{
__sendPacket.setAddress(host);
__sendPacket.setPort(port);
_socket_.send(__sendPacket);
}
/*** Same as
* @return The reply data from the server.
* @exception IOException If an error occurs while receiving the datagram.
***/
public byte[] receive() throws IOException
{
int length;
byte[] result;
_socket_.receive(__receivePacket);
result = new byte[length = __receivePacket.getLength()];
System.arraycopy(__receiveData, 0, result, 0, length);
return result;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/ 0000755 0001750 0001750 00000000000 11617452466 023456 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/smtp/SMTPClient.java 0000644 0001750 0001750 00000062257 11014673543 026247 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
import java.io.IOException;
import java.io.Writer;
import java.net.InetAddress;
import org.apache.commons.net.io.DotTerminatedMessageWriter;
/***
* SMTPClient encapsulates all the functionality necessary to send files
* through an SMTP server. This class takes care of all
* low level details of interacting with an SMTP server and provides
* a convenient higher level interface. As with all classes derived
* from {@link org.apache.commons.net.SocketClient},
* you must first connect to the server with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before doing anything, and finally
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* after you're completely finished interacting with the server.
* Then you need to check the SMTP reply code to see if the connection
* was successful. For example:
*
* Immediately after connecting is the only real time you need to check the
* reply code (because connect is of type void). The convention for all the
* SMTP command methods in SMTPClient is such that they either return a
* boolean value or some other value.
* The boolean methods return true on a successful completion reply from
* the SMTP server and false on a reply resulting in an error condition or
* failure. The methods returning a value other than boolean return a value
* containing the higher level data produced by the SMTP command, or null if a
* reply resulted in an error condition or failure. If you want to access
* the exact SMTP reply code causing a success or failure, you must call
* {@link org.apache.commons.net.smtp.SMTP#getReplyCode getReplyCode } after
* a success or failure.
*
* You should keep in mind that the SMTP server may choose to prematurely
* close a connection for various reasons. The SMTPClient class will detect a
* premature SMTP server connection closing when it receives a
* {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
* response to a command.
* When that occurs, the method encountering that reply will throw
* an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
* .
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @see SMTP
* @see SimpleSMTPHeader
* @see RelayPath
* @see SMTPConnectionClosedException
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class SMTPClient extends SMTP
{
/**
* Default SMTPClient constructor. Creates a new SMTPClient instance.
*/
public SMTPClient() { }
/**
* Overloaded constructor that takes an encoding specification
* @param encoding The encoding to use
* @since 2.0
*/
public SMTPClient(String encoding) {
super(encoding);
}
/***
* At least one SMTPClient method ({@link #sendMessageData sendMessageData })
* does not complete the entire sequence of SMTP commands to complete a
* transaction. These types of commands require some action by the
* programmer after the reception of a positive intermediate command.
* After the programmer's code completes its actions, it must call this
* method to receive the completion reply from the server and verify the
* success of the entire transaction.
*
* For example,
*
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean completePendingCommand() throws IOException
{
return SMTPReply.isPositiveCompletion(getReply());
}
/***
* Login to the SMTP server by sending the HELO command with the
* given hostname as an argument. Before performing any mail commands,
* you must first login.
*
* @param hostname The hostname with which to greet the SMTP server.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean login(String hostname) throws IOException
{
return SMTPReply.isPositiveCompletion(helo(hostname));
}
/***
* Login to the SMTP server by sending the HELO command with the
* client hostname as an argument. Before performing any mail commands,
* you must first login.
*
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean login() throws IOException
{
String name;
InetAddress host;
host = getLocalAddress();
name = host.getHostName();
if (name == null)
return false;
return SMTPReply.isPositiveCompletion(helo(name));
}
/***
* Set the sender of a message using the SMTP MAIL command, specifying
* a reverse relay path. The sender must be set first before any
* recipients may be specified, otherwise the mail server will reject
* your commands.
*
* @param path The reverse relay path pointing back to the sender.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setSender(RelayPath path) throws IOException
{
return SMTPReply.isPositiveCompletion(mail(path.toString()));
}
/***
* Set the sender of a message using the SMTP MAIL command, specifying
* the sender's email address. The sender must be set first before any
* recipients may be specified, otherwise the mail server will reject
* your commands.
*
* @param address The sender's email address.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setSender(String address) throws IOException
{
return SMTPReply.isPositiveCompletion(mail("<" + address + ">"));
}
/***
* Add a recipient for a message using the SMTP RCPT command, specifying
* a forward relay path. The sender must be set first before any
* recipients may be specified, otherwise the mail server will reject
* your commands.
*
* @param path The forward relay path pointing to the recipient.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean addRecipient(RelayPath path) throws IOException
{
return SMTPReply.isPositiveCompletion(rcpt(path.toString()));
}
/***
* Add a recipient for a message using the SMTP RCPT command, the
* recipient's email address. The sender must be set first before any
* recipients may be specified, otherwise the mail server will reject
* your commands.
*
* @param address The recipient's email address.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean addRecipient(String address) throws IOException
{
return SMTPReply.isPositiveCompletion(rcpt("<" + address + ">"));
}
/***
* Send the SMTP DATA command in preparation to send an email message.
* This method returns a DotTerminatedMessageWriter instance to which
* the message can be written. Null is returned if the DATA command
* fails.
*
* You must not issue any commands to the SMTP server (i.e., call any
* (other methods) until you finish writing to the returned Writer
* instance and close it. The SMTP protocol uses the same stream for
* issuing commands as it does for returning results. Therefore the
* returned Writer actually writes directly to the SMTP connection.
* After you close the writer, you can execute new commands. If you
* do not follow these requirements your program will not work properly.
*
* You can use the provided
* {@link org.apache.commons.net.smtp.SimpleSMTPHeader}
* class to construct a bare minimum header.
* To construct more complicated headers you should
* refer to RFC 822. When the Java Mail API is finalized, you will be
* able to use it to compose fully compliant Internet text messages.
* The DotTerminatedMessageWriter takes care of doubling line-leading
* dots and ending the message with a single dot upon closing, so all
* you have to worry about is writing the header and the message.
*
* Upon closing the returned Writer, you need to call
* {@link #completePendingCommand completePendingCommand() }
* to finalize the transaction and verify its success or failure from
* the server reply.
*
* @return A DotTerminatedMessageWriter to which the message (including
* header) can be written. Returns null if the command fails.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public Writer sendMessageData() throws IOException
{
if (!SMTPReply.isPositiveIntermediate(data()))
return null;
return new DotTerminatedMessageWriter(_writer);
}
/***
* A convenience method for sending short messages. This method fetches
* the Writer returned by {@link #sendMessageData sendMessageData() }
* and writes the specified String to it. After writing the message,
* this method calls {@link #completePendingCommand completePendingCommand() }
* to finalize the transaction and returns
* its success or failure.
*
* @param message The short email message to send.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean sendShortMessageData(String message) throws IOException
{
Writer writer;
writer = sendMessageData();
if (writer == null)
return false;
writer.write(message);
writer.close();
return completePendingCommand();
}
/***
* A convenience method for a sending short email without having to
* explicitly set the sender and recipient(s). This method
* sets the sender and recipient using
* {@link #setSender setSender } and
* {@link #addRecipient addRecipient }, and then sends the
* message using {@link #sendShortMessageData sendShortMessageData }.
*
* @param sender The email address of the sender.
* @param recipient The email address of the recipient.
* @param message The short email message to send.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean sendSimpleMessage(String sender, String recipient,
String message)
throws IOException
{
if (!setSender(sender))
return false;
if (!addRecipient(recipient))
return false;
return sendShortMessageData(message);
}
/***
* A convenience method for a sending short email without having to
* explicitly set the sender and recipient(s). This method
* sets the sender and recipients using
* {@link #setSender setSender } and
* {@link #addRecipient addRecipient }, and then sends the
* message using {@link #sendShortMessageData sendShortMessageData }.
*
* @param sender The email address of the sender.
* @param recipients An array of recipient email addresses.
* @param message The short email message to send.
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean sendSimpleMessage(String sender, String[] recipients,
String message)
throws IOException
{
boolean oneSuccess = false;
int count;
if (!setSender(sender))
return false;
for (count = 0; count < recipients.length; count++)
{
if (addRecipient(recipients[count]))
oneSuccess = true;
}
if (!oneSuccess)
return false;
return sendShortMessageData(message);
}
/***
* Logout of the SMTP server by sending the QUIT command.
*
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean logout() throws IOException
{
return SMTPReply.isPositiveCompletion(quit());
}
/***
* Aborts the current mail transaction, resetting all server stored
* sender, recipient, and mail data, cleaing all buffers and tables.
*
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean reset() throws IOException
{
return SMTPReply.isPositiveCompletion(rset());
}
/***
* Verify that a username or email address is valid, i.e., that mail
* can be delivered to that mailbox on the server.
*
* @param username The username or email address to validate.
* @return True if the username is valid, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean verify(String username) throws IOException
{
int result;
result = vrfy(username);
return (result == SMTPReply.ACTION_OK ||
result == SMTPReply.USER_NOT_LOCAL_WILL_FORWARD);
}
/***
* Fetches the system help information from the server and returns the
* full string.
*
* @return The system help string obtained from the server. null if the
* information could not be obtained.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String listHelp() throws IOException
{
if (SMTPReply.isPositiveCompletion(help()))
return getReplyString();
return null;
}
/***
* Fetches the help information for a given command from the server and
* returns the full string.
*
* @param command The command on which to ask for help.
* @return The command help string obtained from the server. null if the
* information could not be obtained.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String listHelp(String command) throws IOException
{
if (SMTPReply.isPositiveCompletion(help(command)))
return getReplyString();
return null;
}
/***
* Sends a NOOP command to the SMTP server. This is useful for preventing
* server timeouts.
*
* @return True if successfully completed, false if not.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean sendNoOp() throws IOException
{
return SMTPReply.isPositiveCompletion(noop());
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java 0000644 0001750 0001750 00000003566 10542533103 032127 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
import java.io.IOException;
/***
* SMTPConnectionClosedException is used to indicate the premature or
* unexpected closing of an SMTP connection resulting from a
* {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
* response (SMTP reply code 421) to a
* failed SMTP command. This exception is derived from IOException and
* therefore may be caught either as an IOException or specifically as an
* SMTPConnectionClosedException.
*
*
* @author Daniel F. Savarese
* @see SMTP
* @see SMTPClient
***/
public final class SMTPConnectionClosedException extends IOException
{
/*** Constructs a SMTPConnectionClosedException with no message ***/
public SMTPConnectionClosedException()
{
super();
}
/***
* Constructs a SMTPConnectionClosedException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public SMTPConnectionClosedException(String message)
{
super(message);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/RelayPath.java 0000644 0001750 0001750 00000005665 11354512541 026213 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
import java.util.Enumeration;
import java.util.Vector;
/***
* A class used to represent forward and reverse relay paths. The
* SMTP MAIL command requires a reverse relay path while the SMTP RCPT
* command requires a forward relay path. See RFC 821 for more details.
* In general, you will not have to deal with relay paths.
*
*
* @author Daniel F. Savarese
* @see SMTPClient
***/
public final class RelayPath
{
Vector
* @param emailAddress The destination email address.
***/
public RelayPath(String emailAddress)
{
_path = new Vector
* @param hostname The host to add to the relay path.
***/
public void addRelay(String hostname)
{
_path.addElement(hostname);
}
/***
* Return the properly formatted string representation of the relay path.
*
* @return The properly formatted string representation of the relay path.
***/
@Override
public String toString()
{
StringBuilder buffer = new StringBuilder();
Enumeration
* The main purpose of the class is to faciliatate the mail sending
* process, by relieving the programmer from having to explicitly format
* a simple message header. For example:
*
*
* @author Daniel F. Savarese
* @see SMTPClient
***/
public class SimpleSMTPHeader
{
private String __subject, __from, __to;
private StringBuffer __headerFields, __cc;
/***
* Creates a new SimpleSMTPHeader instance initialized with the given
* from, to, and subject header field values.
*
* @param from The value of the
* @param headerField The header field to add, not including the colon.
* @param value The value of the added header field.
***/
public void addHeaderField(String headerField, String value)
{
__headerFields.append(headerField);
__headerFields.append(": ");
__headerFields.append(value);
__headerFields.append('\n');
}
/***
* Add an email address to the CC (carbon copy or courtesy copy) list.
*
* @param address The email address to add to the CC list.
***/
public void addCC(String address)
{
if (__cc == null)
__cc = new StringBuffer();
else
__cc.append(", ");
__cc.append(address);
}
/***
* Converts the SimpleSMTPHeader to a properly formatted header in
* the form of a String, including the blank line used to separate
* the header from the article body. The header fields CC and Subject
* are only included when they are non-null.
*
* @return The message header in the form of a String.
***/
@Override
public String toString()
{
StringBuilder header = new StringBuilder();
if (__headerFields.length() > 0)
header.append(__headerFields.toString());
header.append("From: ");
header.append(__from);
header.append("\nTo: ");
header.append(__to);
if (__cc != null)
{
header.append("\nCc: ");
header.append(__cc.toString());
}
if (__subject != null)
{
header.append("\nSubject: ");
header.append(__subject);
}
header.append('\n');
header.append('\n');
return header.toString();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/SMTP.java 0000644 0001750 0001750 00000073753 11347053246 025114 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ProtocolCommandSupport;
import org.apache.commons.net.SocketClient;
/***
* SMTP provides the basic the functionality necessary to implement your
* own SMTP client. To derive the full benefits of the SMTP class requires
* some knowledge of the FTP protocol defined in RFC 821. However, there
* is no reason why you should have to use the SMTP class. The
* {@link org.apache.commons.net.smtp.SMTPClient} class,
* derived from SMTP,
* implements all the functionality required of an SMTP client. The
* SMTP class is made public to provide access to various SMTP constants
* and to make it easier for adventurous programmers (or those with
* special needs) to interact with the SMTP protocol and implement their
* own clients. A set of methods with names corresponding to the SMTP
* command names are provided to facilitate this interaction.
*
* You should keep in mind that the SMTP server may choose to prematurely
* close a connection for various reasons. The SMTP class will detect a
* premature SMTP server connection closing when it receives a
* {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
* response to a command.
* When that occurs, the SMTP class method encountering that reply will throw
* an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
* .
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @see SMTPClient
* @see SMTPConnectionClosedException
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class SMTP extends SocketClient
{
/*** The default SMTP port (25). ***/
public static final int DEFAULT_PORT = 25;
// We have to ensure that the protocol communication is in ASCII
// but we use ISO-8859-1 just in case 8-bit characters cross
// the wire.
private static final String __DEFAULT_ENCODING = "ISO-8859-1";
/** The encoding to use (user-settable) */
private String encoding = __DEFAULT_ENCODING;
private StringBuffer __commandBuffer;
BufferedReader _reader;
BufferedWriter _writer;
int _replyCode;
ArrayList
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.addProtocolCommandListener(listener);
}
/***
* Removes a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandistener(ProtocolCommandListener listener)
{
_commandSupport_.removeProtocolCommandListener(listener);
}
/***
* Closes the connection to the SMTP server and sets to null
* some internal data so that the memory may be reclaimed by the
* garbage collector. The reply text and code information from the
* last command is voided so that the memory it used may be reclaimed.
*
* @exception IOException If an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
super.disconnect();
_reader = null;
_writer = null;
_replyString = null;
_replyLines.clear();
_newReplyString = false;
}
/***
* Sends an SMTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The text representation of the SMTP command to send.
* @param args The arguments to the SMTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the SMTP reply code returned by the server
* in response to the command.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command, String args) throws IOException
{
return __sendCommand(command, args, true);
}
/***
* Sends an SMTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The SMTPCommand constant corresponding to the SMTP command
* to send.
* @param args The arguments to the SMTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the SMTP reply code returned by the server
* in response to the command.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command, String args) throws IOException
{
return sendCommand(SMTPCommand._commands[command], args);
}
/***
* Sends an SMTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The text representation of the SMTP command to send.
* @return The integer value of the SMTP reply code returned by the server
* in response to the command.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command) throws IOException
{
return sendCommand(command, null);
}
/***
* Sends an SMTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The SMTPCommand constant corresponding to the SMTP command
* to send.
* @return The integer value of the SMTP reply code returned by the server
* in response to the command.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command) throws IOException
{
return sendCommand(command, null);
}
/***
* Returns the integer value of the reply code of the last SMTP reply.
* You will usually only use this method after you connect to the
* SMTP server to check that the connection was successful since
*
* @return The integer value of the reply code of the last SMTP reply.
***/
public int getReplyCode()
{
return _replyCode;
}
/***
* Fetches a reply from the SMTP server and returns the integer reply
* code. After calling this method, the actual reply text can be accessed
* from either calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }. Only use this
* method if you are implementing your own SMTP client or if you need to
* fetch a secondary response from the SMTP server.
*
* @return The integer value of the reply code of the fetched SMTP reply.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while receiving the
* server reply.
***/
public int getReply() throws IOException
{
__getReply();
return _replyCode;
}
/***
* Returns the lines of text from the last SMTP server response as an array
* of strings, one entry per line. The end of line markers of each are
* stripped from each line.
*
* @return The lines of text from the last SMTP response as an array.
***/
public String[] getReplyStrings()
{
return _replyLines.toArray(new String[_replyLines.size()]);
}
/***
* Returns the entire text of the last SMTP server response exactly
* as it was received, including all end of line markers in NETASCII
* format.
*
* @return The entire text from the last SMTP response as a String.
***/
public String getReplyString()
{
StringBuilder buffer;
if (!_newReplyString)
return _replyString;
buffer = new StringBuilder();
for (String line : _replyLines)
{
buffer.append(line);
buffer.append(SocketClient.NETASCII_EOL);
}
_newReplyString = false;
return (_replyString = buffer.toString());
}
/***
* A convenience method to send the SMTP HELO command to the server,
* receive the reply, and return the reply code.
*
* @param hostname The hostname of the sender.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int helo(String hostname) throws IOException
{
return sendCommand(SMTPCommand.HELO, hostname);
}
/***
* A convenience method to send the SMTP MAIL command to the server,
* receive the reply, and return the reply code.
*
* @param reversePath The reverese path.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int mail(String reversePath) throws IOException
{
return __sendCommand(SMTPCommand.MAIL, reversePath, false);
}
/***
* A convenience method to send the SMTP RCPT command to the server,
* receive the reply, and return the reply code.
*
* @param forwardPath The forward path.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rcpt(String forwardPath) throws IOException
{
return __sendCommand(SMTPCommand.RCPT, forwardPath, false);
}
/***
* A convenience method to send the SMTP DATA command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int data() throws IOException
{
return sendCommand(SMTPCommand.DATA);
}
/***
* A convenience method to send the SMTP SEND command to the server,
* receive the reply, and return the reply code.
*
* @param reversePath The reverese path.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int send(String reversePath) throws IOException
{
return sendCommand(SMTPCommand.SEND, reversePath);
}
/***
* A convenience method to send the SMTP SOML command to the server,
* receive the reply, and return the reply code.
*
* @param reversePath The reverese path.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int soml(String reversePath) throws IOException
{
return sendCommand(SMTPCommand.SOML, reversePath);
}
/***
* A convenience method to send the SMTP SAML command to the server,
* receive the reply, and return the reply code.
*
* @param reversePath The reverese path.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int saml(String reversePath) throws IOException
{
return sendCommand(SMTPCommand.SAML, reversePath);
}
/***
* A convenience method to send the SMTP RSET command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rset() throws IOException
{
return sendCommand(SMTPCommand.RSET);
}
/***
* A convenience method to send the SMTP VRFY command to the server,
* receive the reply, and return the reply code.
*
* @param user The user address to verify.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int vrfy(String user) throws IOException
{
return sendCommand(SMTPCommand.VRFY, user);
}
/***
* A convenience method to send the SMTP VRFY command to the server,
* receive the reply, and return the reply code.
*
* @param name The name to expand.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int expn(String name) throws IOException
{
return sendCommand(SMTPCommand.EXPN, name);
}
/***
* A convenience method to send the SMTP HELP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help() throws IOException
{
return sendCommand(SMTPCommand.HELP);
}
/***
* A convenience method to send the SMTP HELP command to the server,
* receive the reply, and return the reply code.
*
* @param command The command name on which to request help.
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help(String command) throws IOException
{
return sendCommand(SMTPCommand.HELP, command);
}
/***
* A convenience method to send the SMTP NOOP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int noop() throws IOException
{
return sendCommand(SMTPCommand.NOOP);
}
/***
* A convenience method to send the SMTP TURN command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int turn() throws IOException
{
return sendCommand(SMTPCommand.TURN);
}
/***
* A convenience method to send the SMTP QUIT command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception SMTPConnectionClosedException
* If the SMTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send SMTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int quit() throws IOException
{
return sendCommand(SMTPCommand.QUIT);
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/SMTPReply.java 0000644 0001750 0001750 00000015350 10542533103 026104 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
/***
* SMTPReply stores a set of constants for SMTP reply codes. To interpret
* the meaning of the codes, familiarity with RFC 821 is assumed.
* The mnemonic constant names are transcriptions from the code descriptions
* of RFC 821. For those who think in terms of the actual reply code values,
* a set of CODE_NUM constants are provided where NUM is the numerical value
* of the code.
*
*
* @author Daniel F. Savarese
***/
public final class SMTPReply
{
public static final int CODE_211 = 211;
public static final int CODE_214 = 214;
public static final int CODE_215 = 215;
public static final int CODE_220 = 220;
public static final int CODE_221 = 221;
public static final int CODE_250 = 250;
public static final int CODE_251 = 251;
public static final int CODE_354 = 354;
public static final int CODE_421 = 421;
public static final int CODE_450 = 450;
public static final int CODE_451 = 451;
public static final int CODE_452 = 452;
public static final int CODE_500 = 500;
public static final int CODE_501 = 501;
public static final int CODE_502 = 502;
public static final int CODE_503 = 503;
public static final int CODE_504 = 504;
public static final int CODE_550 = 550;
public static final int CODE_551 = 551;
public static final int CODE_552 = 552;
public static final int CODE_553 = 553;
public static final int CODE_554 = 554;
public static final int SYSTEM_STATUS = CODE_211;
public static final int HELP_MESSAGE = CODE_214;
public static final int SERVICE_READY = CODE_220;
public static final int SERVICE_CLOSING_TRANSMISSION_CHANNEL = CODE_221;
public static final int ACTION_OK = CODE_250;
public static final int USER_NOT_LOCAL_WILL_FORWARD = CODE_251;
public static final int START_MAIL_INPUT = CODE_354;
public static final int SERVICE_NOT_AVAILABLE = CODE_421;
public static final int ACTION_NOT_TAKEN = CODE_450;
public static final int ACTION_ABORTED = CODE_451;
public static final int INSUFFICIENT_STORAGE = CODE_452;
public static final int UNRECOGNIZED_COMMAND = CODE_500;
public static final int SYNTAX_ERROR_IN_ARGUMENTS = CODE_501;
public static final int COMMAND_NOT_IMPLEMENTED = CODE_502;
public static final int BAD_COMMAND_SEQUENCE = CODE_503;
public static final int COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER = CODE_504;
public static final int MAILBOX_UNAVAILABLE = CODE_550;
public static final int USER_NOT_LOCAL = CODE_551;
public static final int STORAGE_ALLOCATION_EXCEEDED = CODE_552;
public static final int MAILBOX_NAME_NOT_ALLOWED = CODE_553;
public static final int TRANSACTION_FAILED = CODE_554;
// Cannot be instantiated
private SMTPReply()
{}
/***
* Determine if a reply code is a positive preliminary response. All
* codes beginning with a 1 are positive preliminary responses.
* Postitive preliminary responses are used to indicate tentative success.
* No further commands can be issued to the SMTP server after a positive
* preliminary response until a follow up response is received from the
* server.
*
* Note: No SMTP commands defined in RFC 822 provide this
* type of reply.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive preliminary response, false
* if not.
***/
public static boolean isPositivePreliminary(int reply)
{
return (reply >= 100 && reply < 200);
}
/***
* Determine if a reply code is a positive completion response. All
* codes beginning with a 2 are positive completion responses.
* The SMTP server will send a positive completion response on the final
* successful completion of a command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive completion response, false
* if not.
***/
public static boolean isPositiveCompletion(int reply)
{
return (reply >= 200 && reply < 300);
}
/***
* Determine if a reply code is a positive intermediate response. All
* codes beginning with a 3 are positive intermediate responses.
* The SMTP server will send a positive intermediate response on the
* successful completion of one part of a multi-part sequence of
* commands. For example, after a successful DATA command, a positive
* intermediate response will be sent to indicate that the server is
* ready to receive the message data.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive intermediate response, false
* if not.
***/
public static boolean isPositiveIntermediate(int reply)
{
return (reply >= 300 && reply < 400);
}
/***
* Determine if a reply code is a negative transient response. All
* codes beginning with a 4 are negative transient responses.
* The SMTP server will send a negative transient response on the
* failure of a command that can be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative transient response, false
* if not.
***/
public static boolean isNegativeTransient(int reply)
{
return (reply >= 400 && reply < 500);
}
/***
* Determine if a reply code is a negative permanent response. All
* codes beginning with a 5 are negative permanent responses.
* The SMTP server will send a negative permanent response on the
* failure of a command that cannot be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative permanent response, false
* if not.
***/
public static boolean isNegativePermanent(int reply)
{
return (reply >= 500 && reply < 600);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/smtp/SMTPCommand.java 0000644 0001750 0001750 00000006454 10542533103 026374 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.smtp;
/***
* SMTPCommand stores a set of constants for SMTP command codes. To interpret
* the meaning of the codes, familiarity with RFC 821 is assumed.
* The mnemonic constant names are transcriptions from the code descriptions
* of RFC 821. For those who think in terms of the actual SMTP commands,
* a set of constants such as {@link #HELO HELO } are provided
* where the constant name is the same as the SMTP command.
*
*
* @author Daniel F. Savarese
***/
public final class SMTPCommand
{
public static final int HELO = 0;
public static final int MAIL = 1;
public static final int RCPT = 2;
public static final int DATA = 3;
public static final int SEND = 4;
public static final int SOML = 5;
public static final int SAML = 6;
public static final int RSET = 7;
public static final int VRFY = 8;
public static final int EXPN = 9;
public static final int HELP = 10;
public static final int NOOP = 11;
public static final int TURN = 12;
public static final int QUIT = 13;
public static final int HELLO = HELO;
public static final int LOGIN = HELO;
public static final int MAIL_FROM = MAIL;
public static final int RECIPIENT = RCPT;
public static final int SEND_MESSAGE_DATA = DATA;
public static final int SEND_FROM = SEND;
public static final int SEND_OR_MAIL_FROM = SOML;
public static final int SEND_AND_MAIL_FROM = SAML;
public static final int RESET = RSET;
public static final int VERIFY = VRFY;
public static final int EXPAND = EXPN;
// public static final int HELP = HELP;
// public static final int NOOP = NOOP;
// public static final int TURN = TURN;
// public static final int QUIT = QUIT;
public static final int LOGOUT = QUIT;
// Cannot be instantiated
private SMTPCommand()
{}
static final String[] _commands = {
"HELO", "MAIL FROM:", "RCPT TO:", "DATA", "SEND FROM:", "SOML FROM:",
"SAML FROM:", "RSET", "VRFY", "EXPN", "HELP", "NOOP", "TURN", "QUIT"
};
/***
* Retrieve the SMTP protocol command string corresponding to a specified
* command code.
*
* @param command The command code.
* @return The SMTP protcol command string corresponding to a specified
* command code.
***/
public static final String getCommand(int command)
{
return _commands[command];
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/ 0000755 0001750 0001750 00000000000 11617452467 023451 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java 0000644 0001750 0001750 00000006037 10542533103 030353 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* A class derived from TFTPRequestPacket definiing a TFTP read request
* packet type.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPReadRequestPacket extends TFTPRequestPacket
{
/***
* Creates a read request packet to be sent to a host at a
* given port with a filename and transfer mode request.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
public TFTPReadRequestPacket(InetAddress destination, int port,
String filename, int mode)
{
super(destination, port, TFTPPacket.READ_REQUEST, filename, mode);
}
/***
* Creates a read request packet of based on a received
* datagram and assumes the datagram has already been identified as a
* read request. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet.
***/
TFTPReadRequestPacket(DatagramPacket datagram) throws TFTPPacketException
{
super(TFTPPacket.READ_REQUEST, datagram);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPRequestPacket.java 0000644 0001750 0001750 00000020665 11416072763 027575 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* An abstract class derived from TFTPPacket definiing a TFTP Request
* packet type. It is subclassed by the
* {@link org.apache.commons.net.tftp.TFTPReadRequestPacket}
* and
* {@link org.apache.commons.net.tftp.TFTPWriteRequestPacket}
* classes.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPReadRequestPacket
* @see TFTPWriteRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public abstract class TFTPRequestPacket extends TFTPPacket
{
/***
* An array containing the string names of the transfer modes and indexed
* by the transfer mode constants.
***/
static final String[] _modeStrings = { "netascii", "octet" };
/***
* A null terminated byte array representation of the ascii names of the
* transfer mode constants. This is convenient for creating the TFTP
* request packets.
***/
private static final byte[] _modeBytes[] = {
{ (byte)'n', (byte)'e', (byte)'t', (byte)'a', (byte)'s', (byte)'c',
(byte)'i', (byte)'i', 0 },
{ (byte)'o', (byte)'c', (byte)'t', (byte)'e', (byte)'t', 0 }
};
/*** The transfer mode of the request. ***/
private final int _mode;
/*** The filename of the request. ***/
private final String _filename;
/***
* Creates a request packet of a given type to be sent to a host at a
* given port with a filename and transfer mode request.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param type The type of the request (either TFTPPacket.READ_REQUEST or
* TFTPPacket.WRITE_REQUEST).
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
TFTPRequestPacket(InetAddress destination, int port,
int type, String filename, int mode)
{
super(type, destination, port);
_filename = filename;
_mode = mode;
}
/***
* Creates a request packet of a given type based on a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param type The type of the request (either TFTPPacket.READ_REQUEST or
* TFTPPacket.WRITE_REQUEST).
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet of the appropriate type.
***/
TFTPRequestPacket(int type, DatagramPacket datagram)
throws TFTPPacketException
{
super(type, datagram.getAddress(), datagram.getPort());
byte[] data = datagram.getData();
if (getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
StringBuilder buffer = new StringBuilder();
int index = 2;
int length = datagram.getLength();
while (index < length && data[index] != 0)
{
buffer.append((char)data[index]);
++index;
}
_filename = buffer.toString();
if (index >= length)
throw new TFTPPacketException("Bad filename and mode format.");
buffer.setLength(0);
++index; // need to advance beyond the end of string marker
while (index < length && data[index] != 0)
{
buffer.append((char)data[index]);
++index;
}
String modeString = buffer.toString().toLowerCase(java.util.Locale.ENGLISH);
length = _modeStrings.length;
int mode = 0;
for (index = 0; index < length; index++)
{
if (modeString.equals(_modeStrings[index]))
{
mode = index;
break;
}
}
_mode = mode;
if (index >= length)
{
throw new TFTPPacketException("Unrecognized TFTP transfer mode: " + modeString);
// May just want to default to binary mode instead of throwing
// exception.
//_mode = TFTP.OCTET_MODE;
}
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
*
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
@Override
final DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
{
int fileLength, modeLength;
fileLength = _filename.length();
modeLength = _modeBytes[_mode].length;
data[0] = 0;
data[1] = (byte)_type;
System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
data[fileLength + 2] = 0;
System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
modeLength);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(fileLength + modeLength + 3);
return datagram;
}
/***
* Creates a UDP datagram containing all the TFTP
* request packet data in the proper format.
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the {@link org.apache.commons.net.tftp.TFTPClient}
* class. Under normal circumstances, you should not have a need to call
* this method.
*
* @return A UDP datagram containing the TFTP request packet.
***/
@Override
public final DatagramPacket newDatagram()
{
int fileLength, modeLength;
byte[] data;
fileLength = _filename.length();
modeLength = _modeBytes[_mode].length;
data = new byte[fileLength + modeLength + 4];
data[0] = 0;
data[1] = (byte)_type;
System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
data[fileLength + 2] = 0;
System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
modeLength);
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the transfer mode of the request.
*
* @return The transfer mode of the request.
***/
public final int getMode()
{
return _mode;
}
/***
* Returns the requested filename.
*
* @return The requested filename.
***/
public final String getFilename()
{
return _filename;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPPacket.java 0000644 0001750 0001750 00000020072 10542533103 026201 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* TFTPPacket is an abstract class encapsulating the functionality common
* to the 5 types of TFTP packets. It also provides a static factory
* method that will create the correct TFTP packet instance from a
* datagram. This relieves the programmer from having to figure out what
* kind of TFTP packet is contained in a datagram and create it himself.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacketException
* @see TFTP
***/
public abstract class TFTPPacket
{
/***
* The minimum size of a packet. This is 4 bytes. It is enough
* to store the opcode and blocknumber or other required data
* depending on the packet type.
***/
static final int MIN_PACKET_SIZE = 4;
/***
* This is the actual TFTP spec
* identifier and is equal to 1.
* Identifier returned by {@link #getType getType()}
* indicating a read request packet.
***/
public static final int READ_REQUEST = 1;
/***
* This is the actual TFTP spec
* identifier and is equal to 2.
* Identifier returned by {@link #getType getType()}
* indicating a write request packet.
***/
public static final int WRITE_REQUEST = 2;
/***
* This is the actual TFTP spec
* identifier and is equal to 3.
* Identifier returned by {@link #getType getType()}
* indicating a data packet.
***/
public static final int DATA = 3;
/***
* This is the actual TFTP spec
* identifier and is equal to 4.
* Identifier returned by {@link #getType getType()}
* indicating an acknowledgement packet.
***/
public static final int ACKNOWLEDGEMENT = 4;
/***
* This is the actual TFTP spec
* identifier and is equal to 5.
* Identifier returned by {@link #getType getType()}
* indicating an error packet.
***/
public static final int ERROR = 5;
/***
* The TFTP data packet maximum segment size in bytes. This is 512
* and is useful for those familiar with the TFTP protocol who want
* to use the {@link org.apache.commons.net.tftp.TFTP}
* class methods to implement their own TFTP servers or clients.
***/
public static final int SEGMENT_SIZE = 512;
/*** The type of packet. ***/
int _type;
/*** The port the packet came from or is going to. ***/
int _port;
/*** The host the packet is going to be sent or where it came from. ***/
InetAddress _address;
/***
* When you receive a datagram that you expect to be a TFTP packet, you use
* this factory method to create the proper TFTPPacket object
* encapsulating the data contained in that datagram. This method is the
* only way you can instantiate a TFTPPacket derived class from a
* datagram.
*
* @param datagram The datagram containing a TFTP packet.
* @return The TFTPPacket object corresponding to the datagram.
* @exception TFTPPacketException If the datagram does not contain a valid
* TFTP packet.
***/
public final static TFTPPacket newTFTPPacket(DatagramPacket datagram)
throws TFTPPacketException
{
byte[] data;
TFTPPacket packet = null;
if (datagram.getLength() < MIN_PACKET_SIZE)
throw new TFTPPacketException(
"Bad packet. Datagram data length is too short.");
data = datagram.getData();
switch (data[1])
{
case READ_REQUEST:
packet = new TFTPReadRequestPacket(datagram);
break;
case WRITE_REQUEST:
packet = new TFTPWriteRequestPacket(datagram);
break;
case DATA:
packet = new TFTPDataPacket(datagram);
break;
case ACKNOWLEDGEMENT:
packet = new TFTPAckPacket(datagram);
break;
case ERROR:
packet = new TFTPErrorPacket(datagram);
break;
default:
throw new TFTPPacketException(
"Bad packet. Invalid TFTP operator code.");
}
return packet;
}
/***
* This constructor is not visible outside of the package. It is used
* by subclasses within the package to initialize base data.
*
* @param type The type of the packet.
* @param address The host the packet came from or is going to be sent.
* @param port The port the packet came from or is going to be sent.
**/
TFTPPacket(int type, InetAddress address, int port)
{
_type = type;
_address = address;
_port = port;
}
/***
* This is an abstract method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* should be set as the datagram's data and the datagram returned.
*
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
abstract DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data);
/***
* Creates a UDP datagram containing all the TFTP packet
* data in the proper format.
* This is an abstract method, exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the {@link org.apache.commons.net.tftp.TFTPClient}
* class.
* Under normal circumstances, you should not have a need to call this
* method.
*
* @return A UDP datagram containing the TFTP packet.
***/
public abstract DatagramPacket newDatagram();
/***
* Returns the type of the packet.
*
* @return The type of the packet.
***/
public final int getType()
{
return _type;
}
/***
* Returns the address of the host where the packet is going to be sent
* or where it came from.
*
* @return The type of the packet.
***/
public final InetAddress getAddress()
{
return _address;
}
/***
* Returns the port where the packet is going to be sent
* or where it came from.
*
* @return The port where the packet came from or where it is going.
***/
public final int getPort()
{
return _port;
}
/*** Sets the port where the packet is going to be sent. ***/
public final void setPort(int port)
{
_port = port;
}
/*** Sets the host address where the packet is going to be sent. ***/
public final void setAddress(InetAddress address)
{
_address = address;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTP.java 0000644 0001750 0001750 00000026001 10542533103 025047 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.SocketException;
import org.apache.commons.net.DatagramSocketClient;
/***
* The TFTP class exposes a set of methods to allow you to deal with the TFTP
* protocol directly, in case you want to write your own TFTP client or
* server. However, almost every user should only be concerend with
* the {@link org.apache.commons.net.DatagramSocketClient#open open() },
* and {@link org.apache.commons.net.DatagramSocketClient#close close() },
* methods. Additionally,the a
* {@link org.apache.commons.net.DatagramSocketClient#setDefaultTimeout setDefaultTimeout() }
* method may be of importance for performance tuning.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals.
*
*
* @author Daniel F. Savarese
* @see org.apache.commons.net.DatagramSocketClient
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTPClient
***/
public class TFTP extends DatagramSocketClient
{
/***
* The ascii transfer mode. Its value is 0 and equivalent to NETASCII_MODE
***/
public static final int ASCII_MODE = 0;
/***
* The netascii transfer mode. Its value is 0.
***/
public static final int NETASCII_MODE = 0;
/***
* The binary transfer mode. Its value is 1 and equivalent to OCTET_MODE.
***/
public static final int BINARY_MODE = 1;
/***
* The image transfer mode. Its value is 1 and equivalent to OCTET_MODE.
***/
public static final int IMAGE_MODE = 1;
/***
* The octet transfer mode. Its value is 1.
***/
public static final int OCTET_MODE = 1;
/***
* The default number of milliseconds to wait to receive a datagram
* before timing out. The default is 5000 milliseconds (5 seconds).
***/
public static final int DEFAULT_TIMEOUT = 5000;
/***
* The default TFTP port according to RFC 783 is 69.
***/
public static final int DEFAULT_PORT = 69;
/***
* The size to use for TFTP packet buffers. Its 4 plus the
* TFTPPacket.SEGMENT_SIZE, i.e. 516.
***/
static final int PACKET_SIZE = TFTPPacket.SEGMENT_SIZE + 4;
/*** A buffer used to accelerate receives in bufferedReceive() ***/
private byte[] __receiveBuffer;
/*** A datagram used to minimize memory allocation in bufferedReceive() ***/
private DatagramPacket __receiveDatagram;
/*** A datagram used to minimize memory allocation in bufferedSend() ***/
private DatagramPacket __sendDatagram;
/***
* A buffer used to accelerate sends in bufferedSend().
* It is left package visible so that TFTPClient may be slightly more
* efficient during file sends. It saves the creation of an
* additional buffer and prevents a buffer copy in _newDataPcket().
***/
byte[] _sendBuffer;
/***
* Returns the TFTP string representation of a TFTP transfer mode.
* Will throw an ArrayIndexOutOfBoundsException if an invalid transfer
* mode is specified.
*
* @param mode The TFTP transfer mode. One of the MODE constants.
* @return The TFTP string representation of the TFTP transfer mode.
***/
public static final String getModeName(int mode)
{
return TFTPRequestPacket._modeStrings[mode];
}
/***
* Creates a TFTP instance with a default timeout of DEFAULT_TIMEOUT,
* a null socket, and buffered operations disabled.
***/
public TFTP()
{
setDefaultTimeout(DEFAULT_TIMEOUT);
__receiveBuffer = null;
__receiveDatagram = null;
}
/***
* This method synchronizes a connection by discarding all packets that
* may be in the local socket buffer. This method need only be called
* when you implement your own TFTP client or server.
*
* @exception IOException if an I/O error occurs.
***/
public final void discardPackets() throws IOException
{
int to;
DatagramPacket datagram;
datagram = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
to = getSoTimeout();
setSoTimeout(1);
try
{
while (true)
_socket_.receive(datagram);
}
catch (SocketException e)
{
// Do nothing. We timed out so we hope we're caught up.
}
catch (InterruptedIOException e)
{
// Do nothing. We timed out so we hope we're caught up.
}
setSoTimeout(to);
}
/***
* This is a special method to perform a more efficient packet receive.
* It should only be used after calling
* {@link #beginBufferedOps beginBufferedOps() }. beginBufferedOps()
* initializes a set of buffers used internally that prevent the new
* allocation of a DatagramPacket and byte array for each send and receive.
* To use these buffers you must call the bufferedReceive() and
* bufferedSend() methods instead of send() and receive(). You must
* also be certain that you don't manipulate the resulting packet in
* such a way that it interferes with future buffered operations.
* For example, a TFTPDataPacket received with bufferedReceive() will
* have a reference to the internal byte buffer. You must finish using
* this data before calling bufferedReceive() again, or else the data
* will be overwritten by the the call.
*
* @return The TFTPPacket received.
* @exception InterruptedIOException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception SocketException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception IOException If some other I/O error occurs.
* @exception TFTPPacketException If an invalid TFTP packet is received.
***/
public final TFTPPacket bufferedReceive() throws IOException,
InterruptedIOException, SocketException, TFTPPacketException
{
__receiveDatagram.setData(__receiveBuffer);
__receiveDatagram.setLength(__receiveBuffer.length);
_socket_.receive(__receiveDatagram);
return TFTPPacket.newTFTPPacket(__receiveDatagram);
}
/***
* This is a special method to perform a more efficient packet send.
* It should only be used after calling
* {@link #beginBufferedOps beginBufferedOps() }. beginBufferedOps()
* initializes a set of buffers used internally that prevent the new
* allocation of a DatagramPacket and byte array for each send and receive.
* To use these buffers you must call the bufferedReceive() and
* bufferedSend() methods instead of send() and receive(). You must
* also be certain that you don't manipulate the resulting packet in
* such a way that it interferes with future buffered operations.
* For example, a TFTPDataPacket received with bufferedReceive() will
* have a reference to the internal byte buffer. You must finish using
* this data before calling bufferedReceive() again, or else the data
* will be overwritten by the the call.
*
* @param packet The TFTP packet to send.
* @exception IOException If some I/O error occurs.
***/
public final void bufferedSend(TFTPPacket packet) throws IOException
{
_socket_.send(packet._newDatagram(__sendDatagram, _sendBuffer));
}
/***
* Initializes the internal buffers. Buffers are used by
* {@link #bufferedSend bufferedSend() } and
* {@link #bufferedReceive bufferedReceive() }. This
* method must be called before calling either one of those two
* methods. When you finish using buffered operations, you must
* call {@link #endBufferedOps endBufferedOps() }.
***/
public final void beginBufferedOps()
{
__receiveBuffer = new byte[PACKET_SIZE];
__receiveDatagram =
new DatagramPacket(__receiveBuffer, __receiveBuffer.length);
_sendBuffer = new byte[PACKET_SIZE];
__sendDatagram =
new DatagramPacket(_sendBuffer, _sendBuffer.length);
}
/***
* Releases the resources used to perform buffered sends and receives.
***/
public final void endBufferedOps()
{
__receiveBuffer = null;
__receiveDatagram = null;
_sendBuffer = null;
__sendDatagram = null;
}
/***
* Sends a TFTP packet to its destination.
*
* @param packet The TFTP packet to send.
* @exception IOException If some I/O error occurs.
***/
public final void send(TFTPPacket packet) throws IOException
{
_socket_.send(packet.newDatagram());
}
/***
* Receives a TFTPPacket.
*
* @return The TFTPPacket received.
* @exception InterruptedIOException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception SocketException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception IOException If some other I/O error occurs.
* @exception TFTPPacketException If an invalid TFTP packet is received.
***/
public final TFTPPacket receive() throws IOException, InterruptedIOException,
SocketException, TFTPPacketException
{
DatagramPacket packet;
packet = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
_socket_.receive(packet);
return TFTPPacket.newTFTPPacket(packet);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPAckPacket.java 0000644 0001750 0001750 00000012413 10766271714 026637 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* A final class derived from TFTPPacket definiing the TFTP Acknowledgement
* packet type.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPAckPacket extends TFTPPacket
{
/*** The block number being acknowledged by the packet. ***/
int _blockNumber;
/***
* Creates an acknowledgment packet to be sent to a host at a given port
* acknowledging receipt of a block.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param blockNumber The block number being acknowledged.
***/
public TFTPAckPacket(InetAddress destination, int port, int blockNumber)
{
super(TFTPPacket.ACKNOWLEDGEMENT, destination, port);
_blockNumber = blockNumber;
}
/***
* Creates an acknowledgement packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param datagram The datagram containing the received acknowledgement.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* acknowledgement packet.
***/
TFTPAckPacket(DatagramPacket datagram) throws TFTPPacketException
{
super(TFTPPacket.ACKNOWLEDGEMENT, datagram.getAddress(),
datagram.getPort());
byte[] data;
data = datagram.getData();
if (getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_blockNumber = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
*
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
@Override
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
{
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(4);
return datagram;
}
/***
* Creates a UDP datagram containing all the TFTP
* acknowledgement packet data in the proper format.
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the {@link org.apache.commons.net.tftp.TFTPClient}
* class. Under normal circumstances, you should not have a need to call this
* method.
*
* @return A UDP datagram containing the TFTP acknowledgement packet.
***/
@Override
public DatagramPacket newDatagram()
{
byte[] data;
data = new byte[4];
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the block number of the acknowledgement.
*
* @return The block number of the acknowledgement.
***/
public int getBlockNumber()
{
return _blockNumber;
}
/*** Sets the block number of the acknowledgement. ***/
public void setBlockNumber(int blockNumber)
{
_blockNumber = blockNumber;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java 0000644 0001750 0001750 00000006050 10542533103 030565 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* A class derived from TFTPRequestPacket definiing a TFTP write request
* packet type.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPWriteRequestPacket extends TFTPRequestPacket
{
/***
* Creates a write request packet to be sent to a host at a
* given port with a filename and transfer mode request.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
public TFTPWriteRequestPacket(InetAddress destination, int port,
String filename, int mode)
{
super(destination, port, TFTPPacket.WRITE_REQUEST, filename, mode);
}
/***
* Creates a write request packet of based on a received
* datagram and assumes the datagram has already been identified as a
* write request. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet.
***/
TFTPWriteRequestPacket(DatagramPacket datagram) throws TFTPPacketException
{
super(TFTPPacket.WRITE_REQUEST, datagram);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPClient.java 0000644 0001750 0001750 00000060205 11445714020 026214 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import org.apache.commons.net.io.FromNetASCIIOutputStream;
import org.apache.commons.net.io.ToNetASCIIInputStream;
/***
* The TFTPClient class encapsulates all the aspects of the TFTP protocol
* necessary to receive and send files through TFTP. It is derived from
* the {@link org.apache.commons.net.tftp.TFTP} because
* it is more convenient than using aggregation, and as a result exposes
* the same set of methods to allow you to deal with the TFTP protocol
* directly. However, almost every user should only be concerend with the
* the {@link org.apache.commons.net.DatagramSocketClient#open open() },
* {@link org.apache.commons.net.DatagramSocketClient#close close() },
* {@link #sendFile sendFile() }, and
* {@link #receiveFile receiveFile() } methods. Additionally, the
* {@link #setMaxTimeouts setMaxTimeouts() } and
* {@link org.apache.commons.net.DatagramSocketClient#setDefaultTimeout setDefaultTimeout() }
* methods may be of importance for performance
* tuning.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals.
*
*
* @author Daniel F. Savarese
* @see TFTP
* @see TFTPPacket
* @see TFTPPacketException
***/
public class TFTPClient extends TFTP
{
/***
* The default number of times a receive attempt is allowed to timeout
* before ending attempts to retry the receive and failing. The default
* is 5 timeouts.
***/
public static final int DEFAULT_MAX_TIMEOUTS = 5;
/*** The maximum number of timeouts allowed before failing. ***/
private int __maxTimeouts;
/***
* Creates a TFTPClient instance with a default timeout of DEFAULT_TIMEOUT,
* maximum timeouts value of DEFAULT_MAX_TIMEOUTS, a null socket,
* and buffered operations disabled.
***/
public TFTPClient()
{
__maxTimeouts = DEFAULT_MAX_TIMEOUTS;
}
/***
* Sets the maximum number of times a receive attempt is allowed to
* timeout during a receiveFile() or sendFile() operation before ending
* attempts to retry the receive and failing.
* The default is DEFAULT_MAX_TIMEOUTS.
*
* @param numTimeouts The maximum number of timeouts to allow. Values
* less than 1 should not be used, but if they are, they are
* treated as 1.
***/
public void setMaxTimeouts(int numTimeouts)
{
if (numTimeouts < 1)
__maxTimeouts = 1;
else
__maxTimeouts = numTimeouts;
}
/***
* Returns the maximum number of times a receive attempt is allowed to
* timeout before ending attempts to retry the receive and failing.
*
* @return The maximum number of timeouts allowed.
***/
public int getMaxTimeouts()
{
return __maxTimeouts;
}
/***
* Requests a named file from a remote host, writes the
* file to an OutputStream, closes the connection, and returns the number
* of bytes read. A local UDP socket must first be created by
* {@link org.apache.commons.net.DatagramSocketClient#open open()} before
* invoking this method. This method will not close the OutputStream
* containing the file; you must close it after the method invocation.
*
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param host The remote host serving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public int receiveFile(String filename, int mode, OutputStream output,
InetAddress host, int port) throws IOException
{
int bytesRead, timeouts, lastBlock, block, hostPort, dataLength;
TFTPPacket sent, received = null;
TFTPErrorPacket error;
TFTPDataPacket data;
TFTPAckPacket ack = new TFTPAckPacket(host, port, 0);
beginBufferedOps();
dataLength = lastBlock = hostPort = bytesRead = 0;
block = 1;
if (mode == TFTP.ASCII_MODE)
output = new FromNetASCIIOutputStream(output);
sent =
new TFTPReadRequestPacket(host, port, filename, mode);
_sendPacket:
do
{
bufferedSend(sent);
_receivePacket:
while (true)
{
timeouts = 0;
while (timeouts < __maxTimeouts)
{
try
{
received = bufferedReceive();
break;
}
catch (SocketException e)
{
if (++timeouts >= __maxTimeouts)
{
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
}
catch (InterruptedIOException e)
{
if (++timeouts >= __maxTimeouts)
{
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
}
catch (TFTPPacketException e)
{
endBufferedOps();
throw new IOException("Bad packet: " + e.getMessage());
}
}
// The first time we receive we get the port number and
// answering host address (for hosts with multiple IPs)
if (lastBlock == 0)
{
hostPort = received.getPort();
ack.setPort(hostPort);
if(!host.equals(received.getAddress()))
{
host = received.getAddress();
ack.setAddress(host);
sent.setAddress(host);
}
}
// Comply with RFC 783 indication that an error acknowledgement
// should be sent to originator if unexpected TID or host.
if (host.equals(received.getAddress()) &&
received.getPort() == hostPort)
{
switch (received.getType())
{
case TFTPPacket.ERROR:
error = (TFTPErrorPacket)received;
endBufferedOps();
throw new IOException("Error code " + error.getError() +
" received: " + error.getMessage());
case TFTPPacket.DATA:
data = (TFTPDataPacket)received;
dataLength = data.getDataLength();
lastBlock = data.getBlockNumber();
if (lastBlock == block)
{
try
{
output.write(data.getData(), data.getDataOffset(),
dataLength);
}
catch (IOException e)
{
error = new TFTPErrorPacket(host, hostPort,
TFTPErrorPacket.OUT_OF_SPACE,
"File write failed.");
bufferedSend(error);
endBufferedOps();
throw e;
}
++block;
if (block > 65535)
{
// wrap the block number
block = 0;
}
break _receivePacket;
}
else
{
discardPackets();
if (lastBlock == (block == 0 ? 65535 : (block - 1)))
continue _sendPacket; // Resend last acknowledgement.
continue _receivePacket; // Start fetching packets again.
}
//break;
default:
endBufferedOps();
throw new IOException("Received unexpected packet type.");
}
}
else
{
error = new TFTPErrorPacket(received.getAddress(),
received.getPort(),
TFTPErrorPacket.UNKNOWN_TID,
"Unexpected host or port.");
bufferedSend(error);
continue _sendPacket;
}
// We should never get here, but this is a safety to avoid
// infinite loop. If only Java had the goto statement.
//break;
}
ack.setBlockNumber(lastBlock);
sent = ack;
bytesRead += dataLength;
} // First data packet less than 512 bytes signals end of stream.
while (dataLength == TFTPPacket.SEGMENT_SIZE);
bufferedSend(sent);
endBufferedOps();
return bytesRead;
}
/***
* Requests a named file from a remote host, writes the
* file to an OutputStream, closes the connection, and returns the number
* of bytes read. A local UDP socket must first be created by
* {@link org.apache.commons.net.DatagramSocketClient#open open()} before
* invoking this method. This method will not close the OutputStream
* containing the file; you must close it after the method invocation.
*
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param hostname The name of the remote host serving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public int receiveFile(String filename, int mode, OutputStream output,
String hostname, int port)
throws UnknownHostException, IOException
{
return receiveFile(filename, mode, output, InetAddress.getByName(hostname),
port);
}
/***
* Same as calling receiveFile(filename, mode, output, host, TFTP.DEFAULT_PORT).
*
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param host The remote host serving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public int receiveFile(String filename, int mode, OutputStream output,
InetAddress host)
throws IOException
{
return receiveFile(filename, mode, output, host, DEFAULT_PORT);
}
/***
* Same as calling receiveFile(filename, mode, output, hostname, TFTP.DEFAULT_PORT).
*
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param hostname The name of the remote host serving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public int receiveFile(String filename, int mode, OutputStream output,
String hostname)
throws UnknownHostException, IOException
{
return receiveFile(filename, mode, output, InetAddress.getByName(hostname),
DEFAULT_PORT);
}
/***
* Requests to send a file to a remote host, reads the file from an
* InputStream, sends the file to the remote host, and closes the
* connection. A local UDP socket must first be created by
* {@link org.apache.commons.net.DatagramSocketClient#open open()} before
* invoking this method. This method will not close the InputStream
* containing the file; you must close it after the method invocation.
*
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param host The remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public void sendFile(String filename, int mode, InputStream input,
InetAddress host, int port) throws IOException
{
int bytesRead, timeouts, lastBlock, block, hostPort, dataLength, offset, totalThisPacket;
TFTPPacket sent, received = null;
TFTPErrorPacket error;
TFTPDataPacket data =
new TFTPDataPacket(host, port, 0, _sendBuffer, 4, 0);
TFTPAckPacket ack;
boolean justStarted = true;
beginBufferedOps();
dataLength = lastBlock = hostPort = bytesRead = totalThisPacket = 0;
block = 0;
boolean lastAckWait = false;
if (mode == TFTP.ASCII_MODE)
input = new ToNetASCIIInputStream(input);
sent =
new TFTPWriteRequestPacket(host, port, filename, mode);
_sendPacket:
do
{
// first time: block is 0, lastBlock is 0, send a request packet.
// subsequent: block is integer starting at 1, send data packet.
bufferedSend(sent);
// this is trying to receive an ACK
_receivePacket:
while (true)
{
timeouts = 0;
while (timeouts < __maxTimeouts)
{
try
{
received = bufferedReceive();
break;
}
catch (SocketException e)
{
if (++timeouts >= __maxTimeouts)
{
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
}
catch (InterruptedIOException e)
{
if (++timeouts >= __maxTimeouts)
{
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
}
catch (TFTPPacketException e)
{
endBufferedOps();
throw new IOException("Bad packet: " + e.getMessage());
}
} // end of while loop over tries to receive
// The first time we receive we get the port number and
// answering host address (for hosts with multiple IPs)
if (justStarted)
{
justStarted = false;
hostPort = received.getPort();
data.setPort(hostPort);
if(!host.equals(received.getAddress()))
{
host = received.getAddress();
data.setAddress(host);
sent.setAddress(host);
}
}
// Comply with RFC 783 indication that an error acknowledgement
// should be sent to originator if unexpected TID or host.
if (host.equals(received.getAddress()) &&
received.getPort() == hostPort)
{
switch (received.getType())
{
case TFTPPacket.ERROR:
error = (TFTPErrorPacket)received;
endBufferedOps();
throw new IOException("Error code " + error.getError() +
" received: " + error.getMessage());
case TFTPPacket.ACKNOWLEDGEMENT:
ack = (TFTPAckPacket)received;
lastBlock = ack.getBlockNumber();
if (lastBlock == block)
{
++block;
if (block > 65535)
{
// wrap the block number
block = 0;
}
if (lastAckWait) {
break _sendPacket;
}
else {
break _receivePacket;
}
}
else
{
discardPackets();
if (lastBlock == (block == 0 ? 65535 : (block - 1)))
continue _sendPacket; // Resend last acknowledgement.
continue _receivePacket; // Start fetching packets again.
}
//break;
default:
endBufferedOps();
throw new IOException("Received unexpected packet type.");
}
}
else
{
error = new TFTPErrorPacket(received.getAddress(),
received.getPort(),
TFTPErrorPacket.UNKNOWN_TID,
"Unexpected host or port.");
bufferedSend(error);
continue _sendPacket;
}
// We should never get here, but this is a safety to avoid
// infinite loop. If only Java had the goto statement.
//break;
}
// OK, we have just gotten ACK about the last data we sent. Make another
// and send it
dataLength = TFTPPacket.SEGMENT_SIZE;
offset = 4;
totalThisPacket = 0;
while (dataLength > 0 &&
(bytesRead = input.read(_sendBuffer, offset, dataLength)) > 0)
{
offset += bytesRead;
dataLength -= bytesRead;
totalThisPacket += bytesRead;
}
if( totalThisPacket < TFTPPacket.SEGMENT_SIZE ) {
/* this will be our last packet -- send, wait for ack, stop */
lastAckWait = true;
}
data.setBlockNumber(block);
data.setData(_sendBuffer, 4, totalThisPacket);
sent = data;
}
while ( totalThisPacket > 0 || lastAckWait );
// Note: this was looping while dataLength == 0 || lastAckWait,
// which was discarding the last packet if it was not full size
// Should send the packet.
endBufferedOps();
}
/***
* Requests to send a file to a remote host, reads the file from an
* InputStream, sends the file to the remote host, and closes the
* connection. A local UDP socket must first be created by
* {@link org.apache.commons.net.DatagramSocketClient#open open()} before
* invoking this method. This method will not close the InputStream
* containing the file; you must close it after the method invocation.
*
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param hostname The name of the remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
String hostname, int port)
throws UnknownHostException, IOException
{
sendFile(filename, mode, input, InetAddress.getByName(hostname), port);
}
/***
* Same as calling sendFile(filename, mode, input, host, TFTP.DEFAULT_PORT).
*
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param host The name of the remote host receiving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
InetAddress host)
throws IOException
{
sendFile(filename, mode, input, host, DEFAULT_PORT);
}
/***
* Same as calling sendFile(filename, mode, input, hostname, TFTP.DEFAULT_PORT).
*
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param hostname The name of the remote host receiving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
String hostname)
throws UnknownHostException, IOException
{
sendFile(filename, mode, input, InetAddress.getByName(hostname),
DEFAULT_PORT);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPPacketException.java 0000644 0001750 0001750 00000003507 10542533103 030064 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
/***
* A class used to signify the occurrence of an error in the creation of
* a TFTP packet. It is not declared final so that it may be subclassed
* to identify more specific errors. You would only want to do this if
* you were building your own TFTP client or server on top of the
* {@link org.apache.commons.net.tftp.TFTP}
* class if you
* wanted more functionality than the
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods provide.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTP
***/
public class TFTPPacketException extends Exception
{
/***
* Simply calls the corresponding constructor of its superclass.
***/
public TFTPPacketException()
{
super();
}
/***
* Simply calls the corresponding constructor of its superclass.
***/
public TFTPPacketException(String message)
{
super(message);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPDataPacket.java 0000644 0001750 0001750 00000017712 10766271714 027021 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* A final class derived from TFTPPacket definiing the TFTP Data
* packet type.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPDataPacket extends TFTPPacket
{
/*** The maximum number of bytes in a TFTP data packet (512) ***/
public static final int MAX_DATA_LENGTH = 512;
/*** The minimum number of bytes in a TFTP data packet (0) ***/
public static final int MIN_DATA_LENGTH = 0;
/*** The block number of the packet. ***/
int _blockNumber;
/*** The length of the data. ***/
int _length;
/*** The offset into the _data array at which the data begins. ***/
int _offset;
/*** The data stored in the packet. ***/
byte[] _data;
/***
* Creates a data packet to be sent to a host at a given port
* with a given block number. The actual data to be sent is passed as
* an array, an offset, and a length. The offset is the offset into
* the byte array where the data starts. The length is the length of
* the data. If the length is greater than MAX_DATA_LENGTH, it is
* truncated.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param blockNumber The block number of the data.
* @param data The byte array containing the data.
* @param offset The offset into the array where the data starts.
* @param length The length of the data.
***/
public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
byte[] data, int offset, int length)
{
super(TFTPPacket.DATA, destination, port);
_blockNumber = blockNumber;
_data = data;
_offset = offset;
if (length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
else
_length = length;
}
public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
byte[] data)
{
this(destination, port, blockNumber, data, 0, data.length);
}
/***
* Creates a data packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param datagram The datagram containing the received data.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* data packet.
***/
TFTPDataPacket(DatagramPacket datagram) throws TFTPPacketException
{
super(TFTPPacket.DATA, datagram.getAddress(), datagram.getPort());
_data = datagram.getData();
_offset = 4;
if (getType() != _data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_blockNumber = (((_data[2] & 0xff) << 8) | (_data[3] & 0xff));
_length = datagram.getLength() - 4;
if (_length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
*
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
@Override
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
{
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
// Doublecheck we're not the same
if (data != _data)
System.arraycopy(_data, _offset, data, 4, _length);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(_length + 4);
return datagram;
}
/***
* Creates a UDP datagram containing all the TFTP
* data packet data in the proper format.
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the {@link org.apache.commons.net.tftp.TFTPClient}
* class.
* Under normal circumstances, you should not have a need to call this
* method.
*
* @return A UDP datagram containing the TFTP data packet.
***/
@Override
public DatagramPacket newDatagram()
{
byte[] data;
data = new byte[_length + 4];
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
System.arraycopy(_data, _offset, data, 4, _length);
return new DatagramPacket(data, _length + 4, _address, _port);
}
/***
* Returns the block number of the data packet.
*
* @return The block number of the data packet.
***/
public int getBlockNumber()
{
return _blockNumber;
}
/*** Sets the block number of the data packet. ***/
public void setBlockNumber(int blockNumber)
{
_blockNumber = blockNumber;
}
/***
* Sets the data for the data packet.
*
* @param data The byte array containing the data.
* @param offset The offset into the array where the data starts.
* @param length The length of the data.
***/
public void setData(byte[] data, int offset, int length)
{
_data = data;
_offset = offset;
_length = length;
if (length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
else
_length = length;
}
/***
* Returns the length of the data part of the data packet.
*
* @return The length of the data part of the data packet.
***/
public int getDataLength()
{
return _length;
}
/***
* Returns the offset into the byte array where the packet data actually
* starts.
*
* @return The offset into the byte array where the packet data actually
* starts.
***/
public int getDataOffset()
{
return _offset;
}
/***
* Returns the byte array containing the packet data.
*
* @return The byte array containing the packet data.
***/
public byte[] getData()
{
return _data;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/tftp/TFTPErrorPacket.java 0000644 0001750 0001750 00000016011 11354512541 027216 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.tftp;
import java.net.DatagramPacket;
import java.net.InetAddress;
/***
* A final class derived from TFTPPacket definiing the TFTP Error
* packet type.
*
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* {@link org.apache.commons.net.tftp.TFTPClient} class
* {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
* and
* {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
* methods.
*
*
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPErrorPacket extends TFTPPacket
{
/*** The undefined error code according to RFC 783, value 0. ***/
public static final int UNDEFINED = 0;
/*** The file not found error code according to RFC 783, value 1. ***/
public static final int FILE_NOT_FOUND = 1;
/*** The access violation error code according to RFC 783, value 2. ***/
public static final int ACCESS_VIOLATION = 2;
/*** The disk full error code according to RFC 783, value 3. ***/
public static final int OUT_OF_SPACE = 3;
/***
* The illegal TFTP operation error code according to RFC 783, value 4.
***/
public static final int ILLEGAL_OPERATION = 4;
/*** The unknown transfer id error code according to RFC 783, value 5. ***/
public static final int UNKNOWN_TID = 5;
/*** The file already exists error code according to RFC 783, value 6. ***/
public static final int FILE_EXISTS = 6;
/*** The no such user error code according to RFC 783, value 7. ***/
public static final int NO_SUCH_USER = 7;
/*** The error code of this packet. ***/
int _error;
/*** The error message of this packet. ***/
String _message;
/***
* Creates an error packet to be sent to a host at a given port
* with an error code and error message.
*
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param error The error code of the packet.
* @param message The error message of the packet.
***/
public TFTPErrorPacket(InetAddress destination, int port,
int error, String message)
{
super(TFTPPacket.ERROR, destination, port);
_error = error;
_message = message;
}
/***
* Creates an error packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
*
* @param datagram The datagram containing the received error.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* error packet.
***/
TFTPErrorPacket(DatagramPacket datagram) throws TFTPPacketException
{
super(TFTPPacket.ERROR, datagram.getAddress(), datagram.getPort());
int index, length;
byte[] data;
StringBuilder buffer;
data = datagram.getData();
length = datagram.getLength();
if (getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_error = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
if (length < 5)
throw new TFTPPacketException("Bad error packet. No message.");
index = 4;
buffer = new StringBuilder();
while (index < length && data[index] != 0)
{
buffer.append((char)data[index]);
++index;
}
_message = buffer.toString();
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
*
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
@Override
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
{
int length;
length = _message.length();
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_error & 0xffff) >> 8);
data[3] = (byte)(_error & 0xff);
System.arraycopy(_message.getBytes(), 0, data, 4, length);
data[length + 4] = 0;
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(length + 4);
return datagram;
}
/***
* Creates a UDP datagram containing all the TFTP
* error packet data in the proper format.
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the {@link org.apache.commons.net.tftp.TFTPClient}
* class.
* Under normal circumstances, you should not have a need to call this
* method.
*
* @return A UDP datagram containing the TFTP error packet.
***/
@Override
public DatagramPacket newDatagram()
{
byte[] data;
int length;
length = _message.length();
data = new byte[length + 5];
data[0] = 0;
data[1] = (byte)_type;
data[2] = (byte)((_error & 0xffff) >> 8);
data[3] = (byte)(_error & 0xff);
System.arraycopy(_message.getBytes(), 0, data, 4, length);
data[length + 4] = 0;
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the error code of the packet.
*
* @return The error code of the packet.
***/
public int getError()
{
return _error;
}
/***
* Returns the error message of the packet.
*
* @return The error message of the packet.
***/
public String getMessage()
{
return _message;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/PrintCommandListener.java 0000644 0001750 0001750 00000003271 11416072763 027435 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.io.PrintWriter;
import org.apache.commons.net.ProtocolCommandEvent;
import org.apache.commons.net.ProtocolCommandListener;
/***
* This is a support class for some of the example programs. It is
* a sample implementation of the ProtocolCommandListener interface
* which just prints out to a specified stream all command/reply traffic.
*
*
* @since 2.0
***/
public class PrintCommandListener implements ProtocolCommandListener
{
private final PrintWriter __writer;
public PrintCommandListener(PrintWriter writer)
{
__writer = writer;
}
public void protocolCommandSent(ProtocolCommandEvent event)
{
__writer.print(event.getMessage());
__writer.flush();
}
public void protocolReplyReceived(ProtocolCommandEvent event)
{
__writer.print(event.getMessage());
__writer.flush();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/pop3/ 0000755 0001750 0001750 00000000000 11617452466 023354 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/pop3/POP3Command.java 0000644 0001750 0001750 00000004670 10542533103 026226 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.pop3;
/***
* POP3Command stores POP3 command code constants.
*
*
* @author Daniel F. Savarese
***/
public final class POP3Command
{
/*** Send user name. ***/
public static final int USER = 0;
/*** Send password. ***/
public static final int PASS = 1;
/*** Quit session. ***/
public static final int QUIT = 2;
/*** Get status. ***/
public static final int STAT = 3;
/*** List message(s). ***/
public static final int LIST = 4;
/*** Retrieve message(s). ***/
public static final int RETR = 5;
/*** Delete message(s). ***/
public static final int DELE = 6;
/*** No operation. Used as a session keepalive. ***/
public static final int NOOP = 7;
/*** Reset session. ***/
public static final int RSET = 8;
/*** Authorization. ***/
public static final int APOP = 9;
/*** Retrieve top number lines from message. ***/
public static final int TOP = 10;
/*** List unique message identifier(s). ***/
public static final int UIDL = 11;
static final String[] _commands = {
"USER", "PASS", "QUIT", "STAT", "LIST", "RETR", "DELE", "NOOP", "RSET",
"APOP", "TOP", "UIDL"
};
// Cannot be instantiated.
private POP3Command()
{}
/***
* Get the POP3 protocol string command corresponding to a command code.
*
* @return The POP3 protocol string command corresponding to a command code.
***/
public static final String getCommand(int command)
{
return _commands[command];
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/pop3/POP3MessageInfo.java 0000644 0001750 0001750 00000005503 11416072763 027057 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.pop3;
/***
* POP3MessageInfo is used to return information about messages stored on
* a POP3 server. Its fields are used to mean slightly different things
* depending on the information being returned.
*
* In response to a status command,
* In response to a message listings,
* In response to unique identifier listings,
*
* @author Daniel F. Savarese
***/
public final class POP3MessageInfo
{
// TODO - make these fields final? They are all set on construction
public int number;
public int size;
public String identifier;
/***
* Creates a POP3MessageInfo instance with
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @see POP3MessageInfo
* @see org.apache.commons.net.io.DotTerminatedMessageReader
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class POP3Client extends POP3
{
private static POP3MessageInfo __parseStatus(String line)
{
int num, size;
StringTokenizer tokenizer;
tokenizer = new StringTokenizer(line);
if (!tokenizer.hasMoreElements())
return null;
num = size = 0;
try
{
num = Integer.parseInt(tokenizer.nextToken());
if (!tokenizer.hasMoreElements())
return null;
size = Integer.parseInt(tokenizer.nextToken());
}
catch (NumberFormatException e)
{
return null;
}
return new POP3MessageInfo(num, size);
}
private static POP3MessageInfo __parseUID(String line)
{
int num;
StringTokenizer tokenizer;
tokenizer = new StringTokenizer(line);
if (!tokenizer.hasMoreElements())
return null;
num = 0;
try
{
num = Integer.parseInt(tokenizer.nextToken());
if (!tokenizer.hasMoreElements())
return null;
line = tokenizer.nextToken();
}
catch (NumberFormatException e)
{
return null;
}
return new POP3MessageInfo(num, line);
}
/***
* Login to the POP3 server with the given username and password. You
* must first connect to the server with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before attempting to login. A login attempt is only valid if
* the client is in the
* {@link org.apache.commons.net.pop3.POP3#AUTHORIZATION_STATE AUTHORIZATION_STATE }
* . After logging in, the client enters the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* .
*
* @param username The account name being logged in to.
* @param password The plain text password of the account.
* @return True if the login attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process of
* logging in.
***/
public boolean login(String username, String password) throws IOException
{
if (getState() != AUTHORIZATION_STATE)
return false;
if (sendCommand(POP3Command.USER, username) != POP3Reply.OK)
return false;
if (sendCommand(POP3Command.PASS, password) != POP3Reply.OK)
return false;
setState(TRANSACTION_STATE);
return true;
}
/***
* Login to the POP3 server with the given username and authentication
* information. Use this method when connecting to a server requiring
* authentication using the APOP command. Because the timestamp
* produced in the greeting banner varies from server to server, it is
* not possible to consistently extract the information. Therefore,
* after connecting to the server, you must call
* {@link org.apache.commons.net.pop3.POP3#getReplyString getReplyString }
* and parse out the timestamp information yourself.
*
* You must first connect to the server with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before attempting to login. A login attempt is only valid if
* the client is in the
* {@link org.apache.commons.net.pop3.POP3#AUTHORIZATION_STATE AUTHORIZATION_STATE }
* . After logging in, the client enters the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . After connecting, you must parse out the
* server specific information to use as a timestamp, and pass that
* information to this method. The secret is a shared secret known
* to you and the server. See RFC 1939 for more details regarding
* the APOP command.
*
* @param username The account name being logged in to.
* @param timestamp The timestamp string to combine with the secret.
* @param secret The shared secret which produces the MD5 digest when
* combined with the timestamp.
* @return True if the login attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process of
* logging in.
* @exception NoSuchAlgorithmException If the MD5 encryption algorithm
* cannot be instantiated by the Java runtime system.
***/
public boolean login(String username, String timestamp, String secret)
throws IOException, NoSuchAlgorithmException
{
int i;
byte[] digest;
StringBuilder buffer, digestBuffer;
MessageDigest md5;
if (getState() != AUTHORIZATION_STATE)
return false;
md5 = MessageDigest.getInstance("MD5");
timestamp += secret;
digest = md5.digest(timestamp.getBytes());
digestBuffer = new StringBuilder(128);
for (i = 0; i < digest.length; i++)
digestBuffer.append(Integer.toHexString(digest[i] & 0xff));
buffer = new StringBuilder(256);
buffer.append(username);
buffer.append(' ');
buffer.append(digestBuffer.toString());
if (sendCommand(POP3Command.APOP, buffer.toString()) != POP3Reply.OK)
return false;
setState(TRANSACTION_STATE);
return true;
}
/***
* Logout of the POP3 server. To fully disconnect from the server
* you must call
* {@link org.apache.commons.net.pop3.POP3#disconnect disconnect }.
* A logout attempt is valid in any state. If
* the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* , it enters the
* {@link org.apache.commons.net.pop3.POP3#UPDATE_STATE UPDATE_STATE }
* on a successful logout.
*
* @return True if the logout attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process
* of logging out.
***/
public boolean logout() throws IOException
{
if (getState() == TRANSACTION_STATE)
setState(UPDATE_STATE);
sendCommand(POP3Command.QUIT);
return (_replyCode == POP3Reply.OK);
}
/***
* Send a NOOP command to the POP3 server. This is useful for keeping
* a connection alive since most POP3 servers will timeout after 10
* minutes of inactivity. A noop attempt will only succeed if
* the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* .
*
* @return True if the noop attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process of
* sending the NOOP command.
***/
public boolean noop() throws IOException
{
if (getState() == TRANSACTION_STATE)
return (sendCommand(POP3Command.NOOP) == POP3Reply.OK);
return false;
}
/***
* Delete a message from the POP3 server. The message is only marked
* for deletion by the server. If you decide to unmark the message, you
* must issuse a {@link #reset reset } command. Messages marked
* for deletion are only deleted by the server on
* {@link #logout logout }.
* A delete attempt can only succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* .
*
* @param messageId The message number to delete.
* @return True if the deletion attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process of
* sending the delete command.
***/
public boolean deleteMessage(int messageId) throws IOException
{
if (getState() == TRANSACTION_STATE)
return (sendCommand(POP3Command.DELE, Integer.toString(messageId))
== POP3Reply.OK);
return false;
}
/***
* Reset the POP3 session. This is useful for undoing any message
* deletions that may have been performed. A reset attempt can only
* succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* .
*
* @return True if the reset attempt was successful, false if not.
* @exception IOException If a network I/O error occurs in the process of
* sending the reset command.
***/
public boolean reset() throws IOException
{
if (getState() == TRANSACTION_STATE)
return (sendCommand(POP3Command.RSET) == POP3Reply.OK);
return false;
}
/***
* Get the mailbox status. A status attempt can only
* succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . Returns a POP3MessageInfo instance
* containing the number of messages in the mailbox and the total
* size of the messages in bytes. Returns null if the status the
* attempt fails.
*
* @return A POP3MessageInfo instance containing the number of
* messages in the mailbox and the total size of the messages
* in bytes. Returns null if the status the attempt fails.
* @exception IOException If a network I/O error occurs in the process of
* sending the status command.
***/
public POP3MessageInfo status() throws IOException
{
if (getState() != TRANSACTION_STATE)
return null;
if (sendCommand(POP3Command.STAT) != POP3Reply.OK)
return null;
return __parseStatus(_lastReplyLine.substring(3));
}
/***
* List an individual message. A list attempt can only
* succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . Returns a POP3MessageInfo instance
* containing the number of the listed message and the
* size of the message in bytes. Returns null if the list
* attempt fails (e.g., if the specified message number does
* not exist).
*
* @param messageId The number of the message list.
* @return A POP3MessageInfo instance containing the number of the
* listed message and the size of the message in bytes. Returns
* null if the list attempt fails.
* @exception IOException If a network I/O error occurs in the process of
* sending the list command.
***/
public POP3MessageInfo listMessage(int messageId) throws IOException
{
if (getState() != TRANSACTION_STATE)
return null;
if (sendCommand(POP3Command.LIST, Integer.toString(messageId))
!= POP3Reply.OK)
return null;
return __parseStatus(_lastReplyLine.substring(3));
}
/***
* List all messages. A list attempt can only
* succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . Returns an array of POP3MessageInfo instances,
* each containing the number of a message and its size in bytes.
* If there are no messages, this method returns a zero length array.
* If the list attempt fails, it returns null.
*
* @return An array of POP3MessageInfo instances representing all messages
* in the order they appear in the mailbox,
* each containing the number of a message and its size in bytes.
* If there are no messages, this method returns a zero length array.
* If the list attempt fails, it returns null.
* @exception IOException If a network I/O error occurs in the process of
* sending the list command.
***/
public POP3MessageInfo[] listMessages() throws IOException
{
POP3MessageInfo[] messages;
Enumeration
* @param messageId The number of the message list.
* @return A POP3MessageInfo instance containing the number of the
* listed message and the unique identifier for that message.
* Returns null if the list attempt fails.
* @exception IOException If a network I/O error occurs in the process of
* sending the list unique identifier command.
***/
public POP3MessageInfo listUniqueIdentifier(int messageId)
throws IOException
{
if (getState() != TRANSACTION_STATE)
return null;
if (sendCommand(POP3Command.UIDL, Integer.toString(messageId))
!= POP3Reply.OK)
return null;
return __parseUID(_lastReplyLine.substring(3));
}
/***
* List the unique identifiers for all messages. A list attempt can only
* succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . Returns an array of POP3MessageInfo instances,
* each containing the number of a message and its unique identifier.
* If there are no messages, this method returns a zero length array.
* If the list attempt fails, it returns null.
*
* @return An array of POP3MessageInfo instances representing all messages
* in the order they appear in the mailbox,
* each containing the number of a message and its unique identifier
* If there are no messages, this method returns a zero length array.
* If the list attempt fails, it returns null.
* @exception IOException If a network I/O error occurs in the process of
* sending the list unique identifier command.
***/
public POP3MessageInfo[] listUniqueIdentifiers() throws IOException
{
POP3MessageInfo[] messages;
Enumeration
* You must not issue any commands to the POP3 server (i.e., call any
* other methods) until you finish reading the message from the
* returned Reader instance.
* The POP3 protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the POP3 connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param messageId The number of the message to fetch.
* @return A DotTerminatedMessageReader instance
* from which the entire message can be read.
* Returns null if the retrieval attempt fails (e.g., if the specified
* message number does not exist).
* @exception IOException If a network I/O error occurs in the process of
* sending the retrieve message command.
***/
public Reader retrieveMessage(int messageId) throws IOException
{
if (getState() != TRANSACTION_STATE)
return null;
if (sendCommand(POP3Command.RETR, Integer.toString(messageId))
!= POP3Reply.OK)
return null;
return new DotTerminatedMessageReader(_reader);
}
/***
* Retrieve only the specified top number of lines of a message from the
* POP3 server. A retrieve top lines attempt
* can only succeed if the client is in the
* {@link org.apache.commons.net.pop3.POP3#TRANSACTION_STATE TRANSACTION_STATE }
* . Returns a DotTerminatedMessageReader instance
* from which the specified top number of lines of the message can be
* read.
* Returns null if the retrieval attempt fails (e.g., if the specified
* message number does not exist).
*
* You must not issue any commands to the POP3 server (i.e., call any
* other methods) until you finish reading the message from the returned
* Reader instance.
* The POP3 protocol uses the same stream for issuing commands as it does
* for returning results. Therefore the returned Reader actually reads
* directly from the POP3 connection. After the end of message has been
* reached, new commands can be executed and their replies read. If
* you do not follow these requirements, your program will not work
* properly.
*
* @param messageId The number of the message to fetch.
* @param numLines The top number of lines to fetch. This must be >= 0.
* @return A DotTerminatedMessageReader instance
* from which the specified top number of lines of the message can be
* read.
* Returns null if the retrieval attempt fails (e.g., if the specified
* message number does not exist).
* @exception IOException If a network I/O error occurs in the process of
* sending the top command.
***/
public Reader retrieveMessageTop(int messageId, int numLines)
throws IOException
{
if (numLines < 0 || getState() != TRANSACTION_STATE)
return null;
if (sendCommand(POP3Command.TOP, Integer.toString(messageId) + " " +
Integer.toString(numLines)) != POP3Reply.OK)
return null;
return new DotTerminatedMessageReader(_reader);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/pop3/POP3Reply.java 0000644 0001750 0001750 00000002337 10766305177 025761 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.pop3;
/***
* POP3Reply stores POP3 reply code constants.
*
*
* @author Daniel F. Savarese
***/
public final class POP3Reply
{
/*** The reply code indicating success of an operation. ***/
public static final int OK = 0;
/*** The reply code indicating failure of an operation. ***/
public static final int ERROR = 1;
// Cannot be instantiated.
private POP3Reply()
{}
}
commons-net-2.2/src/main/java/org/apache/commons/net/pop3/POP3.java 0000644 0001750 0001750 00000026632 11354512541 024736 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.pop3;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.Vector;
import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ProtocolCommandSupport;
import org.apache.commons.net.SocketClient;
/***
* The POP3 class is not meant to be used by itself and is provided
* only so that you may easily implement your own POP3 client if
* you so desire. If you have no need to perform your own implementation,
* you should use {@link org.apache.commons.net.pop3.POP3Client}.
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @see POP3Client
* @see org.apache.commons.net.MalformedServerReplyException
***/
public class POP3 extends SocketClient
{
/*** The default POP3 port. Set to 110 according to RFC 1288. ***/
public static final int DEFAULT_PORT = 110;
/***
* A constant representing the state where the client is not yet connected
* to a POP3 server.
***/
public static final int DISCONNECTED_STATE = -1;
/*** A constant representing the POP3 authorization state. ***/
public static final int AUTHORIZATION_STATE = 0;
/*** A constant representing the POP3 transaction state. ***/
public static final int TRANSACTION_STATE = 1;
/*** A constant representing the POP3 update state. ***/
public static final int UPDATE_STATE = 2;
static final String _OK = "+OK";
static final String _ERROR = "-ERR";
// We have to ensure that the protocol communication is in ASCII
// but we use ISO-8859-1 just in case 8-bit characters cross
// the wire.
private static final String __DEFAULT_ENCODING = "ISO-8859-1";
private int __popState;
private BufferedWriter __writer;
private StringBuffer __commandBuffer;
BufferedReader _reader;
int _replyCode;
String _lastReplyLine;
Vector
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.addProtocolCommandListener(listener);
}
/***
* Removes a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandistener(ProtocolCommandListener listener)
{
_commandSupport_.removeProtocolCommandListener(listener);
}
/***
* Sets POP3 client state. This must be one of the
*
* @param state The new state.
***/
public void setState(int state)
{
__popState = state;
}
/***
* Returns the current POP3 client state.
*
* @return The current POP3 client state.
***/
public int getState()
{
return __popState;
}
/***
* Retrieves the additional lines of a multi-line server reply.
***/
public void getAdditionalReply() throws IOException
{
String line;
line = _reader.readLine();
while (line != null)
{
_replyLines.addElement(line);
if (line.equals("."))
break;
line = _reader.readLine();
}
}
/***
* Disconnects the client from the server, and sets the state to
*
* @exception IOException If there is an error in disconnecting.
***/
@Override
public void disconnect() throws IOException
{
super.disconnect();
_reader = null;
__writer = null;
_lastReplyLine = null;
_replyLines.setSize(0);
setState(DISCONNECTED_STATE);
}
/***
* Sends a command an arguments to the server and returns the reply code.
*
* @param command The POP3 command to send.
* @param args The command arguments.
* @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
***/
public int sendCommand(String command, String args) throws IOException
{
String message;
__commandBuffer.setLength(0);
__commandBuffer.append(command);
if (args != null)
{
__commandBuffer.append(' ');
__commandBuffer.append(args);
}
__commandBuffer.append(SocketClient.NETASCII_EOL);
__writer.write(message = __commandBuffer.toString());
__writer.flush();
if (_commandSupport_.getListenerCount() > 0)
_commandSupport_.fireCommandSent(command, message);
__getReply();
return _replyCode;
}
/***
* Sends a command with no arguments to the server and returns the
* reply code.
*
* @param command The POP3 command to send.
* @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
***/
public int sendCommand(String command) throws IOException
{
return sendCommand(command, null);
}
/***
* Sends a command an arguments to the server and returns the reply code.
*
* @param command The POP3 command to send
* (one of the POP3Command constants).
* @param args The command arguments.
* @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
***/
public int sendCommand(int command, String args) throws IOException
{
return sendCommand(POP3Command._commands[command], args);
}
/***
* Sends a command with no arguments to the server and returns the
* reply code.
*
* @param command The POP3 command to send
* (one of the POP3Command constants).
* @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
***/
public int sendCommand(int command) throws IOException
{
return sendCommand(POP3Command._commands[command], null);
}
/***
* Returns an array of lines received as a reply to the last command
* sent to the server. The lines have end of lines truncated. If
* the reply is a single line, but its format ndicates it should be
* a multiline reply, then you must call
* {@link #getAdditionalReply getAdditionalReply() } to
* fetch the rest of the reply, and then call
* @return The last server response.
***/
public String[] getReplyStrings()
{
String[] lines;
lines = new String[_replyLines.size()];
_replyLines.copyInto(lines);
return lines;
}
/***
* Returns the reply to the last command sent to the server.
* The value is a single string containing all the reply lines including
* newlines. If the reply is a single line, but its format ndicates it
* should be a multiline reply, then you must call
* {@link #getAdditionalReply getAdditionalReply() } to
* fetch the rest of the reply, and then call
* @return The last server response.
***/
public String getReplyString()
{
Enumeration
*
* @author Daniel F. Savarese
***/
public class MalformedServerReplyException extends IOException
{
/*** Constructs a MalformedServerReplyException with no message ***/
public MalformedServerReplyException()
{
super();
}
/***
* Constructs a MalformedServerReplyException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public MalformedServerReplyException(String message)
{
super(message);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/SocketClient.java 0000644 0001750 0001750 00000052527 11466231525 025731 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
/**
* The SocketClient provides the basic operations that are required of
* client objects accessing sockets. It is meant to be
* subclassed to avoid having to rewrite the same code over and over again
* to open a socket, close a socket, set timeouts, etc. Of special note
* is the {@link #setSocketFactory setSocketFactory }
* method, which allows you to control the type of Socket the SocketClient
* creates for initiating network connections. This is especially useful
* for adding SSL or proxy support as well as better support for applets. For
* example, you could create a
* {@link javax.net.SocketFactory} that
* requests browser security capabilities before creating a socket.
* All classes derived from SocketClient should use the
* {@link #_socketFactory_ _socketFactory_ } member variable to
* create Socket and ServerSocket instances rather than instanting
* them by directly invoking a constructor. By honoring this contract
* you guarantee that a user will always be able to provide his own
* Socket implementations by substituting his own SocketFactory.
* @author Daniel F. Savarese
* @see SocketFactory
*/
public abstract class SocketClient
{
/**
* The end of line character sequence used by most IETF protocols. That
* is a carriage return followed by a newline: "\r\n"
*/
public static final String NETASCII_EOL = "\r\n";
/** The default SocketFactory shared by all SocketClient instances. */
private static final SocketFactory __DEFAULT_SOCKET_FACTORY =
SocketFactory.getDefault();
/** The default {@link ServerSocketFactory} */
private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY =
ServerSocketFactory.getDefault();
/** The timeout to use after opening a socket. */
protected int _timeout_;
/** The socket used for the connection. */
protected Socket _socket_;
/** The default port the client should connect to. */
protected int _defaultPort_;
/** The socket's InputStream. */
protected InputStream _input_;
/** The socket's OutputStream. */
protected OutputStream _output_;
/** The socket's SocketFactory. */
protected SocketFactory _socketFactory_;
/** The socket's ServerSocket Factory. */
protected ServerSocketFactory _serverSocketFactory_;
/** The socket's connect timeout (0 = infinite timeout) */
private static final int DEFAULT_CONNECT_TIMEOUT = 0;
protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
/** Hint for SO_RCVBUF size */
int receiveBufferSize = -1;
/** Hint for SO_SNDBUF size */
int sendBufferSize = -1;
/**
* Default constructor for SocketClient. Initializes
* _socket_ to null, _timeout_ to 0, _defaultPort to 0,
* _isConnected_ to false, and _socketFactory_ to a shared instance of
* {@link org.apache.commons.net.DefaultSocketFactory}.
*/
public SocketClient()
{
_socket_ = null;
_input_ = null;
_output_ = null;
_timeout_ = 0;
_defaultPort_ = 0;
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
_serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
}
/**
* Because there are so many connect() methods, the _connectAction_()
* method is provided as a means of performing some action immediately
* after establishing a connection, rather than reimplementing all
* of the connect() methods. The last action performed by every
* connect() method after opening a socket is to call this method.
*
* This method sets the timeout on the just opened socket to the default
* timeout set by {@link #setDefaultTimeout setDefaultTimeout() },
* sets _input_ and _output_ to the socket's InputStream and OutputStream
* respectively, and sets _isConnected_ to true.
*
* Subclasses overriding this method should start by calling
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port)
throws SocketException, IOException
{
_socket_ = _socketFactory_.createSocket();
if (receiveBufferSize != -1) _socket_.setReceiveBufferSize(receiveBufferSize);
if (sendBufferSize != -1) _socket_.setSendBufferSize(sendBufferSize);
_socket_.connect(new InetSocketAddress(host, port), connectTimeout);
_connectAction_();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port)
throws SocketException, IOException
{
connect(InetAddress.getByName(hostname), port);
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param host The remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException
{
_socket_ = _socketFactory_.createSocket();
if (receiveBufferSize != -1) _socket_.setReceiveBufferSize(receiveBufferSize);
if (sendBufferSize != -1) _socket_.setSendBufferSize(sendBufferSize);
_socket_.bind(new InetSocketAddress(localAddr, localPort));
_socket_.connect(new InetSocketAddress(host, port), connectTimeout);
_connectAction_();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address and port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param hostname The name of the remote host.
* @param port The port to connect to on the remote host.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname, int port,
InetAddress localAddr, int localPort)
throws SocketException, IOException
{
connect(InetAddress.getByName(hostname), port, localAddr, localPort);
}
/**
* Opens a Socket connected to a remote host at the current default port
* and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param host The remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
*/
public void connect(InetAddress host) throws SocketException, IOException
{
connect(host, _defaultPort_);
}
/**
* Opens a Socket connected to a remote host at the current default
* port and originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
*
* @param hostname The name of the remote host.
* @exception SocketException If the socket timeout could not be set.
* @exception IOException If the socket could not be opened. In most
* cases you will only want to catch IOException since SocketException is
* derived from it.
* @exception UnknownHostException If the hostname cannot be resolved.
*/
public void connect(String hostname) throws SocketException, IOException
{
connect(hostname, _defaultPort_);
}
/**
* Disconnects the socket connection.
* You should call this method after you've finished using the class
* instance and also before you call
* {@link #connect connect() }
* again. _isConnected_ is set to false, _socket_ is set to null,
* _input_ is set to null, and _output_ is set to null.
*
* @exception IOException If there is an error closing the socket.
*/
public void disconnect() throws IOException
{
closeQuietly(_socket_);
closeQuietly(_input_);
closeQuietly(_output_);
_socket_ = null;
_input_ = null;
_output_ = null;
}
private void closeQuietly(Socket socket) {
if (socket != null){
try {
socket.close();
} catch (IOException e) {
}
}
}
private void closeQuietly(Closeable close){
if (close != null){
try {
close.close();
} catch (IOException e) {
}
}
}
/**
* Returns true if the client is currently connected to a server.
*
* @return True if the client is currently connected to a server,
* false otherwise.
*/
public boolean isConnected()
{
if (_socket_ == null)
return false;
return _socket_.isConnected();
}
/**
* Sets the default port the SocketClient should connect to when a port
* is not specified. The {@link #_defaultPort_ _defaultPort_ }
* variable stores this value. If never set, the default port is equal
* to zero.
*
* @param port The default port to set.
*/
public void setDefaultPort(int port)
{
_defaultPort_ = port;
}
/**
* Returns the current value of the default port (stored in
* {@link #_defaultPort_ _defaultPort_ }).
*
* @return The current value of the default port.
*/
public int getDefaultPort()
{
return _defaultPort_;
}
/**
* Set the default timeout in milliseconds to use when opening a socket.
* This value is only used previous to a call to
* {@link #connect connect()}
* and should not be confused with {@link #setSoTimeout setSoTimeout()}
* which operates on an the currently opened socket. _timeout_ contains
* the new timeout value.
*
* @param timeout The timeout in milliseconds to use for the socket
* connection.
*/
public void setDefaultTimeout(int timeout)
{
_timeout_ = timeout;
}
/**
* Returns the default timeout in milliseconds that is used when
* opening a socket.
*
* @return The default timeout in milliseconds that is used when
* opening a socket.
*/
public int getDefaultTimeout()
{
return _timeout_;
}
/**
* Set the timeout in milliseconds of a currently open connection.
* Only call this method after a connection has been opened
* by {@link #connect connect()}.
*
* @param timeout The timeout in milliseconds to use for the currently
* open socket connection.
* @exception SocketException If the operation fails.
*/
public void setSoTimeout(int timeout) throws SocketException
{
_socket_.setSoTimeout(timeout);
}
/**
* Set the underlying socket send buffer size.
*
* @param size The size of the buffer in bytes.
* @throws SocketException
* @since 2.0
*/
public void setSendBufferSize(int size) throws SocketException {
sendBufferSize = size;
}
/**
* Sets the underlying socket receive buffer size.
*
* @param size The size of the buffer in bytes.
* @throws SocketException
* @since 2.0
*/
public void setReceiveBufferSize(int size) throws SocketException {
receiveBufferSize = size;
}
/**
* Returns the timeout in milliseconds of the currently opened socket.
*
* @return The timeout in milliseconds of the currently opened socket.
* @exception SocketException If the operation fails.
*/
public int getSoTimeout() throws SocketException
{
return _socket_.getSoTimeout();
}
/**
* Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
* currently opened socket.
*
* @param on True if Nagle's algorithm is to be enabled, false if not.
* @exception SocketException If the operation fails.
*/
public void setTcpNoDelay(boolean on) throws SocketException
{
_socket_.setTcpNoDelay(on);
}
/**
* Returns true if Nagle's algorithm is enabled on the currently opened
* socket.
*
* @return True if Nagle's algorithm is enabled on the currently opened
* socket, false otherwise.
* @exception SocketException If the operation fails.
*/
public boolean getTcpNoDelay() throws SocketException
{
return _socket_.getTcpNoDelay();
}
/**
* Sets the SO_KEEPALIVE flag on the currently opened socket.
*
* From the Javadocs, the default keepalive time is 2 hours (although this is
* implementation dependent). It looks as though the Windows WSA sockets implementation
* allows a specific keepalive value to be set, although this seems not to be the case on
* other systems.
* @param keepAlive If true, keepAlive is turned on
* @throws SocketException
* @since 2.2
*/
public void setKeepAlive(boolean keepAlive) throws SocketException {
_socket_.setKeepAlive(keepAlive);
}
/**
* Returns the current value of the SO_KEEPALIVE flag on the currently opened socket.
*
* @return True if SO_KEEPALIVE is enabled.
* @throws SocketException
* @since 2.2
*/
public boolean getKeepAlive() throws SocketException {
return _socket_.getKeepAlive();
}
/**
* Sets the SO_LINGER timeout on the currently opened socket.
*
* @param on True if linger is to be enabled, false if not.
* @param val The linger timeout (in hundredths of a second?)
* @exception SocketException If the operation fails.
*/
public void setSoLinger(boolean on, int val) throws SocketException
{
_socket_.setSoLinger(on, val);
}
/**
* Returns the current SO_LINGER timeout of the currently opened socket.
*
* @return The current SO_LINGER timeout. If SO_LINGER is disabled returns
* -1.
* @exception SocketException If the operation fails.
*/
public int getSoLinger() throws SocketException
{
return _socket_.getSoLinger();
}
/**
* Returns the port number of the open socket on the local host used
* for the connection.
*
* @return The port number of the open socket on the local host used
* for the connection.
*/
public int getLocalPort()
{
return _socket_.getLocalPort();
}
/**
* Returns the local address to which the client's socket is bound.
*
* @return The local address to which the client's socket is bound.
*/
public InetAddress getLocalAddress()
{
return _socket_.getLocalAddress();
}
/**
* Returns the port number of the remote host to which the client is
* connected.
*
* @return The port number of the remote host to which the client is
* connected.
*/
public int getRemotePort()
{
return _socket_.getPort();
}
/**
* @return The remote address to which the client is connected.
*/
public InetAddress getRemoteAddress()
{
return _socket_.getInetAddress();
}
/**
* Verifies that the remote end of the given socket is connected to the
* the same host that the SocketClient is currently connected to. This
* is useful for doing a quick security check when a client needs to
* accept a connection from a server, such as an FTP data connection or
* a BSD R command standard error stream.
*
* @return True if the remote hosts are the same, false if not.
*/
public boolean verifyRemote(Socket socket)
{
InetAddress host1, host2;
host1 = socket.getInetAddress();
host2 = getRemoteAddress();
return host1.equals(host2);
}
/**
* Sets the SocketFactory used by the SocketClient to open socket
* connections. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
*
* @param factory The new SocketFactory the SocketClient should use.
*/
public void setSocketFactory(SocketFactory factory)
{
if (factory == null)
_socketFactory_ = __DEFAULT_SOCKET_FACTORY;
else
_socketFactory_ = factory;
}
/**
* Sets the ServerSocketFactory used by the SocketClient to open ServerSocket
* connections. If the factory value is null, then a default
* factory is used (only do this to reset the factory after having
* previously altered it).
*
* @param factory The new ServerSocketFactory the SocketClient should use.
* @since 2.0
*/
public void setServerSocketFactory(ServerSocketFactory factory) {
if (factory == null)
_serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
else
_serverSocketFactory_ = factory;
}
/**
* Sets the connection timeout in milliseconds, which will be passed to the {@link Socket} object's
* connect() method.
* @param connectTimeout The connection timeout to use (in ms)
* @since 2.0
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* Get the underlying socket connection timeout.
* @return timeout (in ms)
* @since 2.0
*/
public int getConnectTimeout() {
return connectTimeout;
}
/**
* Get the underlying {@link ServerSocketFactory}
* @return The server socket factory
* @since 2.2
*/
public ServerSocketFactory getServerSocketFactory() {
return _serverSocketFactory_;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/DefaultSocketFactory.java 0000644 0001750 0001750 00000014224 10766271714 027425 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
/***
* DefaultSocketFactory implements the SocketFactory interface by
* simply wrapping the java.net.Socket and java.net.ServerSocket
* constructors. It is the default SocketFactory used by
* {@link org.apache.commons.net.SocketClient}
* implementations.
*
*
* @author Daniel F. Savarese
* @see SocketFactory
* @see SocketClient
* @see SocketClient#setSocketFactory
***/
public class DefaultSocketFactory extends SocketFactory
{
/***
* Creates a Socket connected to the given host and port.
*
* @param host The hostname to connect to.
* @param port The port to connect to.
* @return A Socket connected to the given host and port.
* @exception UnknownHostException If the hostname cannot be resolved.
* @exception IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(String host, int port)
throws UnknownHostException, IOException
{
return new Socket(host, port);
}
/***
* Creates a Socket connected to the given host and port.
*
* @param address The address of the host to connect to.
* @param port The port to connect to.
* @return A Socket connected to the given host and port.
* @exception IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(InetAddress address, int port)
throws IOException
{
return new Socket(address, port);
}
/***
* Creates a Socket connected to the given host and port and
* originating from the specified local address and port.
*
* @param host The hostname to connect to.
* @param port The port to connect to.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @return A Socket connected to the given host and port.
* @exception UnknownHostException If the hostname cannot be resolved.
* @exception IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(String host, int port,
InetAddress localAddr, int localPort)
throws UnknownHostException, IOException
{
return new Socket(host, port, localAddr, localPort);
}
/***
* Creates a Socket connected to the given host and port and
* originating from the specified local address and port.
*
* @param address The address of the host to connect to.
* @param port The port to connect to.
* @param localAddr The local address to use.
* @param localPort The local port to use.
* @return A Socket connected to the given host and port.
* @exception IOException If an I/O error occurs while creating the Socket.
***/
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddr, int localPort)
throws IOException
{
return new Socket(address, port, localAddr, localPort);
}
/***
* Creates a ServerSocket bound to a specified port. A port
* of 0 will create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @return A ServerSocket that will listen on a specified port.
* @exception IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port) throws IOException
{
return new ServerSocket(port);
}
/***
* Creates a ServerSocket bound to a specified port with a given
* maximum queue length for incoming connections. A port of 0 will
* create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @param backlog The maximum length of the queue for incoming connections.
* @return A ServerSocket that will listen on a specified port.
* @exception IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return new ServerSocket(port, backlog);
}
/***
* Creates a ServerSocket bound to a specified port on a given local
* address with a given maximum queue length for incoming connections.
* A port of 0 will
* create the ServerSocket on a system-determined free port.
*
* @param port The port on which to listen, or 0 to use any free port.
* @param backlog The maximum length of the queue for incoming connections.
* @param bindAddr The local address to which the ServerSocket should bind.
* @return A ServerSocket that will listen on a specified port.
* @exception IOException If an I/O error occurs while creating
* the ServerSocket.
***/
public ServerSocket createServerSocket(int port, int backlog,
InetAddress bindAddr)
throws IOException
{
return new ServerSocket(port, backlog, bindAddr);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/DatagramSocketFactory.java 0000644 0001750 0001750 00000004611 10542533103 027541 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/***
* The DatagramSocketFactory interface provides a means for the
* programmer to control the creation of datagram sockets and
* provide his own DatagramSocket implementations for use by all
* classes derived from
* {@link org.apache.commons.net.DatagramSocketClient}
* .
* This allows you to provide your own DatagramSocket implementations and
* to perform security checks or browser capability requests before
* creating a DatagramSocket.
*
*
* @author Daniel F. Savarese
***/
public interface DatagramSocketFactory
{
/***
* Creates a DatagramSocket on the local host at the first available port.
*
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket() throws SocketException;
/***
* Creates a DatagramSocket on the local host at a specified port.
*
* @param port The port to use for the socket.
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port) throws SocketException;
/***
* Creates a DatagramSocket at the specified address on the local host
* at a specified port.
*
* @param port The port to use for the socket.
* @param laddr The local address to use.
* @exception SocketException If the socket could not be created.
***/
public DatagramSocket createDatagramSocket(int port, InetAddress laddr)
throws SocketException;
}
commons-net-2.2/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java 0000644 0001750 0001750 00000010706 11416072763 030032 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.io.Serializable;
import java.util.EventListener;
import org.apache.commons.net.util.ListenerList;
/***
* ProtocolCommandSupport is a convenience class for managing a list of
* ProtocolCommandListeners and firing ProtocolCommandEvents. You can
* simply delegate ProtocolCommandEvent firing and listener
* registering/unregistering tasks to this class.
*
*
* @see ProtocolCommandEvent
* @see ProtocolCommandListener
* @author Daniel F. Savarese
***/
public class ProtocolCommandSupport implements Serializable
{
private final Object __source;
private final ListenerList __listeners;
/***
* Creates a ProtocolCommandSupport instant using the indicated source
* as the source of fired ProtocolCommandEvents.
*
* @param source The source to use for all generated ProtocolCommandEvents.
***/
public ProtocolCommandSupport(Object source)
{
__listeners = new ListenerList();
__source = source;
}
/***
* Fires a ProtocolCommandEvent signalling the sending of a command to all
* registered listeners, invoking their
* {@link org.apache.commons.net.ProtocolCommandListener#protocolCommandSent protocolCommandSent() }
* methods.
*
* @param command The string representation of the command type sent, not
* including the arguments (e.g., "STAT" or "GET").
* @param message The entire command string verbatim as sent to the server,
* including all arguments.
***/
public void fireCommandSent(String command, String message)
{
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, command, message);
for (EventListener listener : __listeners)
{
((ProtocolCommandListener)listener).protocolCommandSent(event);
}
}
/***
* Fires a ProtocolCommandEvent signalling the reception of a command reply
* to all registered listeners, invoking their
* {@link org.apache.commons.net.ProtocolCommandListener#protocolReplyReceived protocolReplyReceived() }
* methods.
*
* @param replyCode The integer code indicating the natureof the reply.
* This will be the protocol integer value for protocols
* that use integer reply codes, or the reply class constant
* corresponding to the reply for protocols like POP3 that use
* strings like OK rather than integer codes (i.e., POP3Repy.OK).
* @param message The entire reply as received from the server.
***/
public void fireReplyReceived(int replyCode, String message)
{
ProtocolCommandEvent event;
event = new ProtocolCommandEvent(__source, replyCode, message);
for (EventListener listener : __listeners)
{
((ProtocolCommandListener)listener).protocolReplyReceived(event);
}
}
/***
* Adds a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
__listeners.addListener(listener);
}
/***
* Removes a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandListener(ProtocolCommandListener listener)
{
__listeners.removeListener(listener);
}
/***
* Returns the number of ProtocolCommandListeners currently registered.
*
* @return The number of ProtocolCommandListeners currently registered.
***/
public int getListenerCount()
{
return __listeners.getListenerCount();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/ 0000755 0001750 0001750 00000000000 11617452467 023767 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/telnet/WindowSizeOptionHandler.java 0000644 0001750 0001750 00000012240 11416446036 031412 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* Implements the telnet window size option RFC 1073.
*
* @author Yuval Kashtan
* @version $Id: WindowSizeOptionHandler.java 963157 2010-07-11 22:56:30Z sebb $
* @since 2.0
***/
public class WindowSizeOptionHandler extends TelnetOptionHandler
{
/***
* Horizontal Size
***/
private int m_nWidth = 80;
/***
* Vertical Size
***/
private int m_nHeight = 24;
/***
* Window size option
***/
protected static final int WINDOW_SIZE = 31;
/***
* Constructor for the WindowSizeOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param nWidth - Window width.
* @param nHeight - Window Height
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public WindowSizeOptionHandler(
int nWidth,
int nHeight,
boolean initlocal,
boolean initremote,
boolean acceptlocal,
boolean acceptremote
) {
super (
TelnetOption.WINDOW_SIZE,
initlocal,
initremote,
acceptlocal,
acceptremote
);
m_nWidth = nWidth;
m_nHeight = nHeight;
}
/***
* Constructor for the WindowSizeOptionHandler. Initial and accept
* behaviour flags are set to false
*
* @param nWidth - Window width.
* @param nHeight - Window Height
***/
public WindowSizeOptionHandler(
int nWidth,
int nHeight
) {
super (
TelnetOption.WINDOW_SIZE,
false,
false,
false,
false
);
m_nWidth = nWidth;
m_nHeight = nHeight;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return terminal type information
***/
@Override
public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
* This will send the client Height and Width to the server.
*
* @return array to send to remote system
***/
@Override
public int[] startSubnegotiationLocal()
{
int nCompoundWindowSize = m_nWidth * 0x10000 + m_nHeight;
int nResponseSize = 5;
int nIndex;
int nShift;
int nTurnedOnBits;
if ((m_nWidth % 0x100) == 0xFF) {
nResponseSize += 1;
}
if ((m_nWidth / 0x100) == 0xFF) {
nResponseSize += 1;
}
if ((m_nHeight % 0x100) == 0xFF) {
nResponseSize += 1;
}
if ((m_nHeight / 0x100) == 0xFF) {
nResponseSize += 1;
}
//
// allocate response array
//
int response[] = new int[nResponseSize];
//
// Build response array.
// ---------------------
// 1. put option name.
// 2. loop through Window size and fill the values,
// 3. duplicate 'ff' if needed.
//
response[0] = WINDOW_SIZE; // 1 //
for ( // 2 //
nIndex=1, nShift = 24;
nIndex < nResponseSize;
nIndex++, nShift -=8
) {
nTurnedOnBits = 0xFF;
nTurnedOnBits <<= nShift;
response[nIndex] = (nCompoundWindowSize & nTurnedOnBits) >>> nShift;
if (response[nIndex] == 0xff) { // 3 //
nIndex++;
response[nIndex] = 0xff;
}
}
return response;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationRemote()
{
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetOption.java 0000644 0001750 0001750 00000015056 11416315620 027247 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* The TelnetOption class cannot be instantiated and only serves as a
* storehouse for telnet option constants.
*
* Details regarding Telnet option specification can be found in RFC 855.
*
*
* @author Daniel F. Savarese
* @see org.apache.commons.net.telnet.Telnet
* @see org.apache.commons.net.telnet.TelnetClient
***/
public class TelnetOption
{
/*** The maximum value an option code can have. This value is 255. ***/
public static final int MAX_OPTION_VALUE = 255;
public static final int BINARY = 0;
public static final int ECHO = 1;
public static final int PREPARE_TO_RECONNECT = 2;
public static final int SUPPRESS_GO_AHEAD = 3;
public static final int APPROXIMATE_MESSAGE_SIZE = 4;
public static final int STATUS = 5;
public static final int TIMING_MARK = 6;
public static final int REMOTE_CONTROLLED_TRANSMISSION = 7;
public static final int NEGOTIATE_OUTPUT_LINE_WIDTH = 8;
public static final int NEGOTIATE_OUTPUT_PAGE_SIZE = 9;
public static final int NEGOTIATE_CARRIAGE_RETURN = 10;
public static final int NEGOTIATE_HORIZONTAL_TAB_STOP = 11;
public static final int NEGOTIATE_HORIZONTAL_TAB = 12;
public static final int NEGOTIATE_FORMFEED = 13;
public static final int NEGOTIATE_VERTICAL_TAB_STOP = 14;
public static final int NEGOTIATE_VERTICAL_TAB = 15;
public static final int NEGOTIATE_LINEFEED = 16;
public static final int EXTENDED_ASCII = 17;
public static final int FORCE_LOGOUT = 18;
public static final int BYTE_MACRO = 19;
public static final int DATA_ENTRY_TERMINAL = 20;
public static final int SUPDUP = 21;
public static final int SUPDUP_OUTPUT = 22;
public static final int SEND_LOCATION = 23;
public static final int TERMINAL_TYPE = 24;
public static final int END_OF_RECORD = 25;
public static final int TACACS_USER_IDENTIFICATION = 26;
public static final int OUTPUT_MARKING = 27;
public static final int TERMINAL_LOCATION_NUMBER = 28;
public static final int REGIME_3270 = 29;
public static final int X3_PAD = 30;
public static final int WINDOW_SIZE = 31;
public static final int TERMINAL_SPEED = 32;
public static final int REMOTE_FLOW_CONTROL = 33;
public static final int LINEMODE = 34;
public static final int X_DISPLAY_LOCATION = 35;
public static final int OLD_ENVIRONMENT_VARIABLES = 36;
public static final int AUTHENTICATION = 37;
public static final int ENCRYPTION = 38;
public static final int NEW_ENVIRONMENT_VARIABLES = 39;
public static final int EXTENDED_OPTIONS_LIST = 255;
@SuppressWarnings("unused")
private static final int __FIRST_OPTION = BINARY;
private static final int __LAST_OPTION = EXTENDED_OPTIONS_LIST;
private static final String __optionString[] = {
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS",
"TIMING MARK", "RCTE", "NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD",
"NAOFFD", "NAOVTS", "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT",
"BYTE MACRO", "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", "TACACS UID",
"OUTPUT MARKING", "TTYLOC", "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED",
"LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
"ENCRYPT", "NEW-ENVIRON", "TN3270E", "XAUTH", "CHARSET", "RSP",
"Com Port Control", "Suppress Local Echo", "Start TLS",
"KERMIT", "SEND-URL", "FORWARD_X", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "TELOPT PRAGMA LOGON", "TELOPT SSPI LOGON",
"TELOPT PRAGMA HEARTBEAT", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"Extended-Options-List"
};
/***
* Returns the string representation of the telnet protocol option
* corresponding to the given option code.
*
* @param code The option code of the telnet protocol option
* @return The string representation of the telnet protocol option.
***/
public static final String getOption(int code)
{
if(__optionString[code].length() == 0)
{
return "UNASSIGNED";
}
else
{
return __optionString[code];
}
}
/***
* Determines if a given option code is valid. Returns true if valid,
* false if not.
*
* @param code The option code to test.
* @return True if the option code is valid, false if not.
**/
public static final boolean isValidOption(int code)
{
return (code <= __LAST_OPTION);
}
// Cannot be instantiated
private TelnetOption()
{ }
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java 0000644 0001750 0001750 00000051541 11416437422 030256 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
/***
*
*
*
*
*
* @author Daniel F. Savarese
* @author Bruno D'Avanzo
***/
final class TelnetInputStream extends BufferedInputStream implements Runnable
{
/** End of file has been reached */
private static final int EOF = -1;
/** Read would block */
private static final int WOULD_BLOCK = -2;
// TODO should these be private enums?
static final int _STATE_DATA = 0, _STATE_IAC = 1, _STATE_WILL = 2,
_STATE_WONT = 3, _STATE_DO = 4, _STATE_DONT = 5,
_STATE_SB = 6, _STATE_SE = 7, _STATE_CR = 8, _STATE_IAC_SB = 9;
private boolean __hasReachedEOF, __isClosed;
private boolean __readIsWaiting;
private int __receiveState, __queueHead, __queueTail, __bytesAvailable;
private final int[] __queue;
private final TelnetClient __client;
private final Thread __thread;
private IOException __ioException;
/* TERMINAL-TYPE option (start)*/
private final int __suboption[] = new int[256];
private int __suboption_count = 0;
/* TERMINAL-TYPE option (end)*/
private boolean __threaded;
TelnetInputStream(InputStream input, TelnetClient client,
boolean readerThread)
{
super(input);
__client = client;
__receiveState = _STATE_DATA;
__isClosed = true;
__hasReachedEOF = false;
// Make it 2049, because when full, one slot will go unused, and we
// want a 2048 byte buffer just to have a round number (base 2 that is)
__queue = new int[2049];
__queueHead = 0;
__queueTail = 0;
__bytesAvailable = 0;
__ioException = null;
__readIsWaiting = false;
__threaded = false;
if(readerThread)
__thread = new Thread(this);
else
__thread = null;
}
TelnetInputStream(InputStream input, TelnetClient client) {
this(input, client, true);
}
void _start()
{
if(__thread == null)
return;
int priority;
__isClosed = false;
// TODO remove this
// Need to set a higher priority in case JVM does not use pre-emptive
// threads. This should prevent scheduler induced deadlock (rather than
// deadlock caused by a bug in this code).
priority = Thread.currentThread().getPriority() + 1;
if (priority > Thread.MAX_PRIORITY)
priority = Thread.MAX_PRIORITY;
__thread.setPriority(priority);
__thread.setDaemon(true);
__thread.start();
__threaded = true;
}
// synchronized(__client) critical sections are to protect against
// TelnetOutputStream writing through the telnet client at same time
// as a processDo/Will/etc. command invoked from TelnetInputStream
// tries to write.
/**
* Get the next byte of data.
* IAC commands are processed internally and do not return data.
*
* @param mayBlock true if method is allowed to block
* @return the next byte of data,
* or -1 (EOF) if end of stread reached,
* or -2 (WOULD_BLOCK) if mayBlock is false and there is no data available
*/
private int __read(boolean mayBlock) throws IOException
{
int ch;
while (true)
{
// If there is no more data AND we were told not to block, just return WOULD_BLOCK (-2). (More efficient than exception.)
if(!mayBlock && super.available() == 0)
return WOULD_BLOCK;
// Otherwise, exit only when we reach end of stream.
if ((ch = super.read()) < 0)
return EOF;
ch = (ch & 0xff);
/* Code Section added for supporting AYT (start)*/
synchronized (__client)
{
__client._processAYTResponse();
}
/* Code Section added for supporting AYT (end)*/
/* Code Section added for supporting spystreams (start)*/
__client._spyRead(ch);
/* Code Section added for supporting spystreams (end)*/
switch (__receiveState)
{
case _STATE_CR:
if (ch == '\0')
{
// Strip null
continue;
}
// How do we handle newline after cr?
// else if (ch == '\n' && _requestedDont(TelnetOption.ECHO) &&
// Handle as normal data by falling through to _STATE_DATA case
//$FALL-THROUGH$
case _STATE_DATA:
if (ch == TelnetCommand.IAC)
{
__receiveState = _STATE_IAC;
continue;
}
if (ch == '\r')
{
synchronized (__client)
{
if (__client._requestedDont(TelnetOption.BINARY))
__receiveState = _STATE_CR;
else
__receiveState = _STATE_DATA;
}
}
else
__receiveState = _STATE_DATA;
break;
case _STATE_IAC:
switch (ch)
{
case TelnetCommand.WILL:
__receiveState = _STATE_WILL;
continue;
case TelnetCommand.WONT:
__receiveState = _STATE_WONT;
continue;
case TelnetCommand.DO:
__receiveState = _STATE_DO;
continue;
case TelnetCommand.DONT:
__receiveState = _STATE_DONT;
continue;
/* TERMINAL-TYPE option (start)*/
case TelnetCommand.SB:
__suboption_count = 0;
__receiveState = _STATE_SB;
continue;
/* TERMINAL-TYPE option (end)*/
case TelnetCommand.IAC:
__receiveState = _STATE_DATA;
break; // exit to enclosing switch to return IAC from read
default:
__receiveState = _STATE_DATA;
__client._processCommand(ch); // Notify the user
continue; // move on the next char
}
break; // exit and return from read
case _STATE_WILL:
synchronized (__client)
{
__client._processWill(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_WONT:
synchronized (__client)
{
__client._processWont(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_DO:
synchronized (__client)
{
__client._processDo(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_DONT:
synchronized (__client)
{
__client._processDont(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
/* TERMINAL-TYPE option (start)*/
case _STATE_SB:
switch (ch)
{
case TelnetCommand.IAC:
__receiveState = _STATE_IAC_SB;
continue;
default:
// store suboption char
__suboption[__suboption_count++] = ch;
break;
}
__receiveState = _STATE_SB;
continue;
case _STATE_IAC_SB:
switch (ch)
{
case TelnetCommand.SE:
synchronized (__client)
{
__client._processSuboption(__suboption, __suboption_count);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
default:
__receiveState = _STATE_SB;
break;
}
__receiveState = _STATE_DATA;
continue;
/* TERMINAL-TYPE option (end)*/
}
break;
}
return ch;
}
// synchronized(__client) critical sections are to protect against
// TelnetOutputStream writing through the telnet client at same time
// as a processDo/Will/etc. command invoked from TelnetInputStream
// tries to write.
private void __processChar(int ch) throws InterruptedException
{
// Critical section because we're altering __bytesAvailable,
// __queueTail, and the contents of _queue.
synchronized (__queue)
{
while (__bytesAvailable >= __queue.length - 1)
{
// The queue is full. We need to wait before adding any more data to it. Hopefully the stream owner
// will consume some data soon!
if(__threaded)
{
__queue.notify();
try
{
__queue.wait();
}
catch (InterruptedException e)
{
throw e;
}
}
else
{
// We've been asked to add another character to the queue, but it is already full and there's
// no other thread to drain it. This should not have happened!
throw new IllegalStateException("Queue is full! Cannot process another character.");
}
}
// Need to do this in case we're not full, but block on a read
if (__readIsWaiting && __threaded)
{
__queue.notify();
}
__queue[__queueTail] = ch;
++__bytesAvailable;
if (++__queueTail >= __queue.length)
__queueTail = 0;
}
}
@Override
public int read() throws IOException
{
// Critical section because we're altering __bytesAvailable,
// __queueHead, and the contents of _queue in addition to
// testing value of __hasReachedEOF.
synchronized (__queue)
{
while (true)
{
if (__ioException != null)
{
IOException e;
e = __ioException;
__ioException = null;
throw e;
}
if (__bytesAvailable == 0)
{
// Return EOF if at end of file
if (__hasReachedEOF)
return EOF;
// Otherwise, we have to wait for queue to get something
if(__threaded)
{
__queue.notify();
try
{
__readIsWaiting = true;
__queue.wait();
__readIsWaiting = false;
}
catch (InterruptedException e)
{
throw new InterruptedIOException("Fatal thread interruption during read.");
}
}
else
{
//__alreadyread = false;
__readIsWaiting = true;
int ch;
boolean mayBlock = true; // block on the first read only
do
{
try
{
if ((ch = __read(mayBlock)) < 0) // EOF or WOULD_BLOCK
if(ch != WOULD_BLOCK)
return (ch); // must be EOF
}
catch (InterruptedIOException e)
{
synchronized (__queue)
{
__ioException = e;
__queue.notifyAll();
try
{
__queue.wait(100);
}
catch (InterruptedException interrupted)
{
}
}
return EOF;
}
try
{
if(ch != WOULD_BLOCK)
{
__processChar(ch);
}
}
catch (InterruptedException e)
{
if (__isClosed)
return EOF;
}
// Reads should not block on subsequent iterations. Potentially, this could happen if the
// remaining buffered socket data consists entirely of Telnet command sequence and no "user" data.
mayBlock = false;
}
// Continue reading as long as there is data available and the queue is not full.
while (super.available() > 0 && __bytesAvailable < __queue.length - 1);
__readIsWaiting = false;
}
continue;
}
else
{
int ch;
ch = __queue[__queueHead];
if (++__queueHead >= __queue.length)
__queueHead = 0;
--__bytesAvailable;
// Need to explicitly notify() so available() works properly
if(__bytesAvailable == 0 && __threaded) {
__queue.notify();
}
return ch;
}
}
}
}
/***
* Reads the next number of bytes from the stream into an array and
* returns the number of bytes read. Returns -1 if the end of the
* stream has been reached.
*
* @param buffer The byte array in which to store the data.
* @return The number of bytes read. Returns -1 if the
* end of the message has been reached.
* @exception IOException If an error occurs in reading the underlying
* stream.
***/
@Override
public int read(byte buffer[]) throws IOException
{
return read(buffer, 0, buffer.length);
}
/***
* Reads the next number of bytes from the stream into an array and returns
* the number of bytes read. Returns -1 if the end of the
* message has been reached. The characters are stored in the array
* starting from the given offset and up to the length specified.
*
* @param buffer The byte array in which to store the data.
* @param offset The offset into the array at which to start storing data.
* @param length The number of bytes to read.
* @return The number of bytes read. Returns -1 if the
* end of the stream has been reached.
* @exception IOException If an error occurs while reading the underlying
* stream.
***/
@Override
public int read(byte buffer[], int offset, int length) throws IOException
{
int ch, off;
if (length < 1)
return 0;
// Critical section because run() may change __bytesAvailable
synchronized (__queue)
{
if (length > __bytesAvailable)
length = __bytesAvailable;
}
if ((ch = read()) == EOF)
return EOF;
off = offset;
do
{
buffer[offset++] = (byte)ch;
}
while (--length > 0 && (ch = read()) != EOF);
//__client._spyRead(buffer, off, offset - off);
return (offset - off);
}
/*** Returns false. Mark is not supported. ***/
@Override
public boolean markSupported()
{
return false;
}
@Override
public int available() throws IOException
{
// Critical section because run() may change __bytesAvailable
synchronized (__queue)
{
return __bytesAvailable;
}
}
// Cannot be synchronized. Will cause deadlock if run() is blocked
// in read because BufferedInputStream read() is synchronized.
@Override
public void close() throws IOException
{
// Completely disregard the fact thread may still be running.
// We can't afford to block on this close by waiting for
// thread to terminate because few if any JVM's will actually
// interrupt a system read() from the interrupt() method.
super.close();
synchronized (__queue)
{
__hasReachedEOF = true;
__isClosed = true;
if (__thread != null && __thread.isAlive())
{
__thread.interrupt();
}
__queue.notifyAll();
}
__threaded = false;
}
public void run()
{
int ch;
try
{
_outerLoop:
while (!__isClosed)
{
try
{
if ((ch = __read(true)) < 0)
break;
}
catch (InterruptedIOException e)
{
synchronized (__queue)
{
__ioException = e;
__queue.notifyAll();
try
{
__queue.wait(100);
}
catch (InterruptedException interrupted)
{
if (__isClosed)
break _outerLoop;
}
continue;
}
} catch(RuntimeException re) {
// We treat any runtime exceptions as though the
// stream has been closed. We close the
// underlying stream just to be sure.
super.close();
// Breaking the loop has the effect of setting
// the state to closed at the end of the method.
break _outerLoop;
}
try
{
__processChar(ch);
}
catch (InterruptedException e)
{
if (__isClosed)
break _outerLoop;
}
}
}
catch (IOException ioe)
{
synchronized (__queue)
{
__ioException = ioe;
}
}
synchronized (__queue)
{
__isClosed = true; // Possibly redundant
__hasReachedEOF = true;
__queue.notify();
}
__threaded = false;
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java 0000644 0001750 0001750 00000006234 10766271714 030555 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* Simple option handler that can be used for options
* that don't require subnegotiation.
*
* @author Bruno D'Avanzo
***/
public class SimpleOptionHandler extends TelnetOptionHandler
{
/***
* Constructor for the SimpleOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param optcode - option code.
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public SimpleOptionHandler(int optcode,
boolean initlocal,
boolean initremote,
boolean acceptlocal,
boolean acceptremote)
{
super(optcode, initlocal, initremote,
acceptlocal, acceptremote);
}
/***
* Constructor for the SimpleOptionHandler. Initial and accept
* behaviour flags are set to false
*
* @param optcode - option code.
***/
public SimpleOptionHandler(int optcode)
{
super(optcode, false, false, false, false);
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationLocal()
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationRemote()
{
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetClient.java 0000644 0001750 0001750 00000022166 11151644177 027225 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.io.FromNetASCIIInputStream;
import org.apache.commons.net.io.ToNetASCIIOutputStream;
/***
* The TelnetClient class implements the simple network virtual
* terminal (NVT) for the Telnet protocol according to RFC 854. It
* does not implement any of the extra Telnet options because it
* is meant to be used within a Java program providing automated
* access to Telnet accessible resources.
*
* The class can be used by first connecting to a server using the
* SocketClient
* {@link org.apache.commons.net.SocketClient#connect connect}
* method. Then an InputStream and OutputStream for sending and
* receiving data over the Telnet connection can be obtained by
* using the {@link #getInputStream getInputStream() } and
* {@link #getOutputStream getOutputStream() } methods.
* When you finish using the streams, you must call
* {@link #disconnect disconnect } rather than simply
* closing the streams.
*
*
* @author Daniel F. Savarese
* @author Bruno D'Avanzo
***/
public class TelnetClient extends Telnet
{
private InputStream __input;
private OutputStream __output;
protected boolean readerThread = true;
/***
* Default TelnetClient constructor.
***/
public TelnetClient()
{
/* TERMINAL-TYPE option (start)*/
super ("VT100");
/* TERMINAL-TYPE option (end)*/
__input = null;
__output = null;
}
/* TERMINAL-TYPE option (start)*/
public TelnetClient(String termtype)
{
super (termtype);
__input = null;
__output = null;
}
/* TERMINAL-TYPE option (end)*/
void _flushOutputStream() throws IOException
{
_output_.flush();
}
void _closeOutputStream() throws IOException
{
_output_.close();
}
/***
* Handles special connection requirements.
*
* @exception IOException If an error occurs during connection setup.
***/
@Override
protected void _connectAction_() throws IOException
{
super._connectAction_();
InputStream input;
TelnetInputStream tmp;
if (FromNetASCIIInputStream.isConversionRequired())
input = new FromNetASCIIInputStream(_input_);
else
input = _input_;
tmp = new TelnetInputStream(input, this, readerThread);
if(readerThread)
{
tmp._start();
}
// __input CANNOT refer to the TelnetInputStream. We run into
// blocking problems when some classes use TelnetInputStream, so
// we wrap it with a BufferedInputStream which we know is safe.
// This blocking behavior requires further investigation, but right
// now it looks like classes like InputStreamReader are not implemented
// in a safe manner.
__input = new BufferedInputStream(tmp);
__output = new ToNetASCIIOutputStream(new TelnetOutputStream(this));
}
/***
* Disconnects the telnet session, closing the input and output streams
* as well as the socket. If you have references to the
* input and output streams of the telnet connection, you should not
* close them yourself, but rather call disconnect to properly close
* the connection.
***/
@Override
public void disconnect() throws IOException
{
if (__input != null)
__input.close();
if (__output != null)
__output.close();
super.disconnect();
}
/***
* Returns the telnet connection output stream. You should not close the
* stream when you finish with it. Rather, you should call
* {@link #disconnect disconnect }.
*
* @return The telnet connection output stream.
***/
public OutputStream getOutputStream()
{
return __output;
}
/***
* Returns the telnet connection input stream. You should not close the
* stream when you finish with it. Rather, you should call
* {@link #disconnect disconnect }.
*
* @return The telnet connection input stream.
***/
public InputStream getInputStream()
{
return __input;
}
/***
* Returns the state of the option on the local side.
*
* @param option - Option to be checked.
*
* @return The state of the option on the local side.
***/
public boolean getLocalOptionState(int option)
{
/* BUG (option active when not already acknowledged) (start)*/
return (_stateIsWill(option) && _requestedWill(option));
/* BUG (option active when not already acknowledged) (end)*/
}
/***
* Returns the state of the option on the remote side.
*
* @param option - Option to be checked.
*
* @return The state of the option on the remote side.
***/
public boolean getRemoteOptionState(int option)
{
/* BUG (option active when not already acknowledged) (start)*/
return (_stateIsDo(option) && _requestedDo(option));
/* BUG (option active when not already acknowledged) (end)*/
}
/* open TelnetOptionHandler functionality (end)*/
/* Code Section added for supporting AYT (start)*/
/***
* Sends an Are You There sequence and waits for the result.
*
* @param timeout - Time to wait for a response (millis.)
*
* @return true if AYT received a response, false otherwise
*
* @throws InterruptedException
* @throws IllegalArgumentException
* @throws IOException
***/
public boolean sendAYT(long timeout)
throws IOException, IllegalArgumentException, InterruptedException
{
return (_sendAYT(timeout));
}
/* Code Section added for supporting AYT (start)*/
/* open TelnetOptionHandler functionality (start)*/
/***
* Registers a new TelnetOptionHandler for this telnet client to use.
*
* @param opthand - option handler to be registered.
*
* @throws InvalidTelnetOptionException
***/
@Override
public void addOptionHandler(TelnetOptionHandler opthand)
throws InvalidTelnetOptionException
{
super.addOptionHandler(opthand);
}
/* open TelnetOptionHandler functionality (end)*/
/***
* Unregisters a TelnetOptionHandler.
*
* @param optcode - Code of the option to be unregistered.
*
* @throws InvalidTelnetOptionException
***/
@Override
public void deleteOptionHandler(int optcode)
throws InvalidTelnetOptionException
{
super.deleteOptionHandler(optcode);
}
/* Code Section added for supporting spystreams (start)*/
/***
* Registers an OutputStream for spying what's going on in
* the TelnetClient session.
*
* @param spystream - OutputStream on which session activity
* will be echoed.
***/
public void registerSpyStream(OutputStream spystream)
{
super._registerSpyStream(spystream);
}
/***
* Stops spying this TelnetClient.
*
***/
public void stopSpyStream()
{
super._stopSpyStream();
}
/* Code Section added for supporting spystreams (end)*/
/***
* Registers a notification handler to which will be sent
* notifications of received telnet option negotiation commands.
*
* @param notifhand - TelnetNotificationHandler to be registered
***/
@Override
public void registerNotifHandler(TelnetNotificationHandler notifhand)
{
super.registerNotifHandler(notifhand);
}
/***
* Unregisters the current notification handler.
*
***/
@Override
public void unregisterNotifHandler()
{
super.unregisterNotifHandler();
}
/***
* Sets the status of the reader thread.
* The reader thread status will apply to all subsequent connections
*
* @param flag - true switches the reader thread on, false switches it off
***/
public void setReaderThread(boolean flag)
{
readerThread = flag;
}
/***
* Gets the status of the reader thread.
*
* @return true if the reader thread is on, false otherwise
***/
public boolean getReaderThread()
{
return (readerThread);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetOutputStream.java 0000644 0001750 0001750 00000010324 11416072763 030454 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
import java.io.IOException;
import java.io.OutputStream;
/***
*
*
*
*
*
* @author Daniel F. Savarese
***/
final class TelnetOutputStream extends OutputStream
{
private final TelnetClient __client;
// TODO there does not appear to be any way to change this value - should it be a ctor parameter?
private boolean __convertCRtoCRLF = true;
private boolean __lastWasCR = false;
TelnetOutputStream(TelnetClient client)
{
__client = client;
}
/***
* Writes a byte to the stream.
*
* @param ch The byte to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public void write(int ch) throws IOException
{
synchronized (__client)
{
ch &= 0xff;
if (__client._requestedWont(TelnetOption.BINARY))
{
if (__lastWasCR)
{
if (__convertCRtoCRLF)
{
__client._sendByte('\n');
if (ch == '\n')
{
__lastWasCR = false;
return ;
}
}
else if (ch != '\n')
__client._sendByte('\0');
}
__lastWasCR = false;
switch (ch)
{
case '\r':
__client._sendByte('\r');
__lastWasCR = true;
break;
case TelnetCommand.IAC:
__client._sendByte(TelnetCommand.IAC);
__client._sendByte(TelnetCommand.IAC);
break;
default:
__client._sendByte(ch);
break;
}
}
else if (ch == TelnetCommand.IAC)
{
__client._sendByte(ch);
__client._sendByte(TelnetCommand.IAC);
}
else
__client._sendByte(ch);
}
}
/***
* Writes a byte array to the stream.
*
* @param buffer The byte array to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public void write(byte buffer[]) throws IOException
{
write(buffer, 0, buffer.length);
}
/***
* Writes a number of bytes from a byte array to the stream starting from
* a given offset.
*
* @param buffer The byte array to write.
* @param offset The offset into the array at which to start copying data.
* @param length The number of bytes to write.
* @exception IOException If an error occurs while writing to the underlying
* stream.
***/
@Override
public void write(byte buffer[], int offset, int length) throws IOException
{
synchronized (__client)
{
while (length-- > 0)
write(buffer[offset++]);
}
}
/*** Flushes the stream. ***/
@Override
public void flush() throws IOException
{
__client._flushOutputStream();
}
/*** Closes the stream. ***/
@Override
public void close() throws IOException
{
__client._closeOutputStream();
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java 0000644 0001750 0001750 00000010411 11416072763 031725 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* Implements the telnet terminal type option RFC 1091.
*
* @author Bruno D'Avanzo
***/
public class TerminalTypeOptionHandler extends TelnetOptionHandler
{
/***
* Terminal type
***/
private final String termType;
/***
* Terminal type option
***/
protected static final int TERMINAL_TYPE = 24;
/***
* Send (for subnegotiation)
***/
protected static final int TERMINAL_TYPE_SEND = 1;
/***
* Is (for subnegotiation)
***/
protected static final int TERMINAL_TYPE_IS = 0;
/***
* Constructor for the TerminalTypeOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param termtype - terminal type that will be negotiated.
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public TerminalTypeOptionHandler(String termtype,
boolean initlocal,
boolean initremote,
boolean acceptlocal,
boolean acceptremote)
{
super(TelnetOption.TERMINAL_TYPE, initlocal, initremote,
acceptlocal, acceptremote);
termType = termtype;
}
/***
* Constructor for the TerminalTypeOptionHandler. Initial and accept
* behaviour flags are set to false
*
* @param termtype - terminal type that will be negotiated.
***/
public TerminalTypeOptionHandler(String termtype)
{
super(TelnetOption.TERMINAL_TYPE, false, false, false, false);
termType = termtype;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return terminal type information
***/
@Override
public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
{
if ((suboptionData != null) && (suboptionLength > 1)
&& (termType != null))
{
if ((suboptionData[0] == TERMINAL_TYPE)
&& (suboptionData[1] == TERMINAL_TYPE_SEND))
{
int response[] = new int[termType.length() + 2];
response[0] = TERMINAL_TYPE;
response[1] = TERMINAL_TYPE_IS;
for (int ii = 0; ii < termType.length(); ii++)
{
response[ii + 2] = termType.charAt(ii);
}
return response;
}
}
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationLocal()
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationRemote()
{
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java 0000644 0001750 0001750 00000003355 11416072763 032444 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* The InvalidTelnetOptionException is the exception that is
* thrown whenever a TelnetOptionHandler with an invlaid
* option code is registered in TelnetClient with addOptionHandler.
*
* @author Bruno D'Avanzo
***/
public class InvalidTelnetOptionException extends Exception
{
/***
* Option code
***/
private final int optionCode;
/***
* Error message
***/
private final String msg;
/***
* Constructor for the exception.
*
* @param message - Error message.
* @param optcode - Option code.
***/
public InvalidTelnetOptionException(String message, int optcode)
{
optionCode = optcode;
msg = message;
}
/***
* Gets the error message of ths exception.
*
* @return the error message.
***/
@Override
public String getMessage()
{
return (msg + ": " + optionCode);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetCommand.java 0000644 0001750 0001750 00000011174 10542533103 027347 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/**
* The TelnetCommand class cannot be instantiated and only serves as a
* storehouse for telnet command constants.
* @author Daniel F. Savarese
* @see org.apache.commons.net.telnet.Telnet
* @see org.apache.commons.net.telnet.TelnetClient
*/
public final class TelnetCommand
{
/*** The maximum value a command code can have. This value is 255. ***/
public static final int MAX_COMMAND_VALUE = 255;
/*** Interpret As Command code. Value is 255 according to RFC 854. ***/
public static final int IAC = 255;
/*** Don't use option code. Value is 254 according to RFC 854. ***/
public static final int DONT = 254;
/*** Request to use option code. Value is 253 according to RFC 854. ***/
public static final int DO = 253;
/*** Refuse to use option code. Value is 252 according to RFC 854. ***/
public static final int WONT = 252;
/*** Agree to use option code. Value is 251 according to RFC 854. ***/
public static final int WILL = 251;
/*** Start subnegotiation code. Value is 250 according to RFC 854. ***/
public static final int SB = 250;
/*** Go Ahead code. Value is 249 according to RFC 854. ***/
public static final int GA = 249;
/*** Erase Line code. Value is 248 according to RFC 854. ***/
public static final int EL = 248;
/*** Erase Character code. Value is 247 according to RFC 854. ***/
public static final int EC = 247;
/*** Are You There code. Value is 246 according to RFC 854. ***/
public static final int AYT = 246;
/*** Abort Output code. Value is 245 according to RFC 854. ***/
public static final int AO = 245;
/*** Interrupt Process code. Value is 244 according to RFC 854. ***/
public static final int IP = 244;
/*** Break code. Value is 243 according to RFC 854. ***/
public static final int BREAK = 243;
/*** Data mark code. Value is 242 according to RFC 854. ***/
public static final int DM = 242;
/*** No Operation code. Value is 241 according to RFC 854. ***/
public static final int NOP = 241;
/*** End subnegotiation code. Value is 240 according to RFC 854. ***/
public static final int SE = 240;
/*** End of record code. Value is 239. ***/
public static final int EOR = 239;
/*** Abort code. Value is 238. ***/
public static final int ABORT = 238;
/*** Suspend process code. Value is 237. ***/
public static final int SUSP = 237;
/*** End of file code. Value is 236. ***/
public static final int EOF = 236;
/*** Synchronize code. Value is 242. ***/
public static final int SYNCH = 242;
/*** String representations of commands. ***/
private static final String __commandString[] = {
"IAC", "DONT", "DO", "WONT", "WILL", "SB", "GA", "EL", "EC", "AYT",
"AO", "IP", "BRK", "DMARK", "NOP", "SE", "EOR", "ABORT", "SUSP", "EOF"
};
private static final int __FIRST_COMMAND = IAC;
private static final int __LAST_COMMAND = EOF;
/***
* Returns the string representation of the telnet protocol command
* corresponding to the given command code.
*
* @param code The command code of the telnet protocol command.
* @return The string representation of the telnet protocol command.
***/
public static final String getCommand(int code)
{
return __commandString[__FIRST_COMMAND - code];
}
/***
* Determines if a given command code is valid. Returns true if valid,
* false if not.
*
* @param code The command code to test.
* @return True if the command code is valid, false if not.
**/
public static final boolean isValidCommand(int code)
{
return (code <= __FIRST_COMMAND && code >= __LAST_COMMAND);
}
// Cannot be instantiated
private TelnetCommand()
{ }
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java 0000644 0001750 0001750 00000005760 10766271714 031363 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* Implements the telnet suppress go ahead option RFC 858.
*
* @author Bruno D'Avanzo
***/
public class SuppressGAOptionHandler extends TelnetOptionHandler
{
/***
* Constructor for the SuppressGAOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public SuppressGAOptionHandler(boolean initlocal, boolean initremote,
boolean acceptlocal, boolean acceptremote)
{
super(TelnetOption.SUPPRESS_GO_AHEAD, initlocal, initremote,
acceptlocal, acceptremote);
}
/***
* Constructor for the SuppressGAOptionHandler. Initial and accept
* behaviour flags are set to false
***/
public SuppressGAOptionHandler()
{
super(TelnetOption.SUPPRESS_GO_AHEAD, false, false, false, false);
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationLocal()
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationRemote()
{
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/Telnet.java 0000644 0001750 0001750 00000106625 11416437422 026066 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.commons.net.SocketClient;
/**
* @author Daniel F. Savarese
* @author Bruno D'Avanzo
*/
class Telnet extends SocketClient
{
static final boolean debug = /*true;*/ false;
static final boolean debugoptions = /*true;*/ false;
static final byte[] _COMMAND_DO = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.DO
};
static final byte[] _COMMAND_DONT = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.DONT
};
static final byte[] _COMMAND_WILL = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.WILL
};
static final byte[] _COMMAND_WONT = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.WONT
};
static final byte[] _COMMAND_SB = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.SB
};
static final byte[] _COMMAND_SE = {
(byte)TelnetCommand.IAC, (byte)TelnetCommand.SE
};
static final int _WILL_MASK = 0x01, _DO_MASK = 0x02,
_REQUESTED_WILL_MASK = 0x04, _REQUESTED_DO_MASK = 0x08;
/* public */
static final int DEFAULT_PORT = 23;
int[] _doResponse, _willResponse, _options;
/* TERMINAL-TYPE option (start)*/
/***
* Terminal type option
***/
protected static final int TERMINAL_TYPE = 24;
/***
* Send (for subnegotiation)
***/
protected static final int TERMINAL_TYPE_SEND = 1;
/***
* Is (for subnegotiation)
***/
protected static final int TERMINAL_TYPE_IS = 0;
/***
* Is sequence (for subnegotiation)
***/
static final byte[] _COMMAND_IS = {
(byte) TERMINAL_TYPE, (byte) TERMINAL_TYPE_IS
};
/***
* Terminal type
***/
private String terminalType = null;
/* TERMINAL-TYPE option (end)*/
/* open TelnetOptionHandler functionality (start)*/
/***
* Array of option handlers
***/
private TelnetOptionHandler optionHandlers[];
/* open TelnetOptionHandler functionality (end)*/
/* Code Section added for supporting AYT (start)*/
/***
* AYT sequence
***/
static final byte[] _COMMAND_AYT = {
(byte) TelnetCommand.IAC, (byte) TelnetCommand.AYT
};
/***
* monitor to wait for AYT
***/
private Object aytMonitor = new Object();
/***
* flag for AYT
***/
private boolean aytFlag = true;
/* Code Section added for supporting AYT (end)*/
/***
* The stream on which to spy
***/
private volatile OutputStream spyStream = null;
/***
* The notification handler
***/
private TelnetNotificationHandler __notifhand = null;
/***
* Empty Constructor
***/
Telnet()
{
setDefaultPort(DEFAULT_PORT);
_doResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
_willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
_options = new int[TelnetOption.MAX_OPTION_VALUE + 1];
optionHandlers =
new TelnetOptionHandler[TelnetOption.MAX_OPTION_VALUE + 1];
}
/* TERMINAL-TYPE option (start)*/
/***
* This constructor lets you specify the terminal type.
*
* @param termtype - terminal type to be negotiated (ej. VT100)
***/
Telnet(String termtype)
{
setDefaultPort(DEFAULT_PORT);
_doResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
_willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
_options = new int[TelnetOption.MAX_OPTION_VALUE + 1];
terminalType = termtype;
optionHandlers =
new TelnetOptionHandler[TelnetOption.MAX_OPTION_VALUE + 1];
}
/* TERMINAL-TYPE option (end)*/
/***
* Looks for the state of the option.
*
* @return returns true if a will has been acknowledged
*
* @param option - option code to be looked up.
***/
boolean _stateIsWill(int option)
{
return ((_options[option] & _WILL_MASK) != 0);
}
/***
* Looks for the state of the option.
*
* @return returns true if a wont has been acknowledged
*
* @param option - option code to be looked up.
***/
boolean _stateIsWont(int option)
{
return !_stateIsWill(option);
}
/***
* Looks for the state of the option.
*
* @return returns true if a do has been acknowledged
*
* @param option - option code to be looked up.
***/
boolean _stateIsDo(int option)
{
return ((_options[option] & _DO_MASK) != 0);
}
/***
* Looks for the state of the option.
*
* @return returns true if a dont has been acknowledged
*
* @param option - option code to be looked up.
***/
boolean _stateIsDont(int option)
{
return !_stateIsDo(option);
}
/***
* Looks for the state of the option.
*
* @return returns true if a will has been reuqested
*
* @param option - option code to be looked up.
***/
boolean _requestedWill(int option)
{
return ((_options[option] & _REQUESTED_WILL_MASK) != 0);
}
/***
* Looks for the state of the option.
*
* @return returns true if a wont has been reuqested
*
* @param option - option code to be looked up.
***/
boolean _requestedWont(int option)
{
return !_requestedWill(option);
}
/***
* Looks for the state of the option.
*
* @return returns true if a do has been reuqested
*
* @param option - option code to be looked up.
***/
boolean _requestedDo(int option)
{
return ((_options[option] & _REQUESTED_DO_MASK) != 0);
}
/***
* Looks for the state of the option.
*
* @return returns true if a dont has been reuqested
*
* @param option - option code to be looked up.
***/
boolean _requestedDont(int option)
{
return !_requestedDo(option);
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWill(int option)
{
_options[option] |= _WILL_MASK;
/* open TelnetOptionHandler functionality (start)*/
if (_requestedWill(option))
{
if (optionHandlers[option] != null)
{
optionHandlers[option].setWill(true);
int subneg[] =
optionHandlers[option].startSubnegotiationLocal();
if (subneg != null)
{
try
{
_sendSubnegotiation(subneg);
}
catch (IOException e)
{
System.err.println(
"Exception in option subnegotiation"
+ e.getMessage());
}
}
}
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setDo(int option)
{
_options[option] |= _DO_MASK;
/* open TelnetOptionHandler functionality (start)*/
if (_requestedDo(option))
{
if (optionHandlers[option] != null)
{
optionHandlers[option].setDo(true);
int subneg[] =
optionHandlers[option].startSubnegotiationRemote();
if (subneg != null)
{
try
{
_sendSubnegotiation(subneg);
}
catch (IOException e)
{
System.err.println("Exception in option subnegotiation"
+ e.getMessage());
}
}
}
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWantWill(int option)
{
_options[option] |= _REQUESTED_WILL_MASK;
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWantDo(int option)
{
_options[option] |= _REQUESTED_DO_MASK;
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWont(int option)
{
_options[option] &= ~_WILL_MASK;
/* open TelnetOptionHandler functionality (start)*/
if (optionHandlers[option] != null)
{
optionHandlers[option].setWill(false);
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setDont(int option)
{
_options[option] &= ~_DO_MASK;
/* open TelnetOptionHandler functionality (start)*/
if (optionHandlers[option] != null)
{
optionHandlers[option].setDo(false);
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWantWont(int option)
{
_options[option] &= ~_REQUESTED_WILL_MASK;
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
***/
void _setWantDont(int option)
{
_options[option] &= ~_REQUESTED_DO_MASK;
}
/**
* Processes a COMMAND.
*
* @param command - option code to be set.
**/
void _processCommand(int command)
{
if (debugoptions)
{
System.err.println("RECEIVED COMMAND: " + command);
}
if (__notifhand != null)
{
__notifhand.receivedNegotiation(
TelnetNotificationHandler.RECEIVED_COMMAND, command);
}
}
/**
* Processes a DO request.
*
* @param option - option code to be set.
* @throws IOException - Exception in I/O.
**/
void _processDo(int option) throws IOException
{
if (debugoptions)
{
System.err.println("RECEIVED DO: "
+ TelnetOption.getOption(option));
}
if (__notifhand != null)
{
__notifhand.receivedNegotiation(
TelnetNotificationHandler.RECEIVED_DO,
option);
}
boolean acceptNewState = false;
/* open TelnetOptionHandler functionality (start)*/
if (optionHandlers[option] != null)
{
acceptNewState = optionHandlers[option].getAcceptLocal();
}
else
{
/* open TelnetOptionHandler functionality (end)*/
/* TERMINAL-TYPE option (start)*/
if (option == TERMINAL_TYPE)
{
if ((terminalType != null) && (terminalType.length() > 0))
{
acceptNewState = true;
}
}
/* TERMINAL-TYPE option (end)*/
/* open TelnetOptionHandler functionality (start)*/
}
/* open TelnetOptionHandler functionality (end)*/
if (_willResponse[option] > 0)
{
--_willResponse[option];
if (_willResponse[option] > 0 && _stateIsWill(option))
{
--_willResponse[option];
}
}
if (_willResponse[option] == 0)
{
if (_requestedWont(option))
{
switch (option)
{
default:
break;
}
if (acceptNewState)
{
_setWantWill(option);
_sendWill(option);
}
else
{
++_willResponse[option];
_sendWont(option);
}
}
else
{
// Other end has acknowledged option.
switch (option)
{
default:
break;
}
}
}
_setWill(option);
}
/**
* Processes a DONT request.
*
* @param option - option code to be set.
* @throws IOException - Exception in I/O.
**/
void _processDont(int option) throws IOException
{
if (debugoptions)
{
System.err.println("RECEIVED DONT: "
+ TelnetOption.getOption(option));
}
if (__notifhand != null)
{
__notifhand.receivedNegotiation(
TelnetNotificationHandler.RECEIVED_DONT,
option);
}
if (_willResponse[option] > 0)
{
--_willResponse[option];
if (_willResponse[option] > 0 && _stateIsWont(option))
{
--_willResponse[option];
}
}
if (_willResponse[option] == 0 && _requestedWill(option))
{
switch (option)
{
default:
break;
}
/* FIX for a BUG in the negotiation (start)*/
if ((_stateIsWill(option)) || (_requestedWill(option)))
{
_sendWont(option);
}
_setWantWont(option);
/* FIX for a BUG in the negotiation (end)*/
}
_setWont(option);
}
/**
* Processes a WILL request.
*
* @param option - option code to be set.
* @throws IOException - Exception in I/O.
**/
void _processWill(int option) throws IOException
{
if (debugoptions)
{
System.err.println("RECEIVED WILL: "
+ TelnetOption.getOption(option));
}
if (__notifhand != null)
{
__notifhand.receivedNegotiation(
TelnetNotificationHandler.RECEIVED_WILL,
option);
}
boolean acceptNewState = false;
/* open TelnetOptionHandler functionality (start)*/
if (optionHandlers[option] != null)
{
acceptNewState = optionHandlers[option].getAcceptRemote();
}
/* open TelnetOptionHandler functionality (end)*/
if (_doResponse[option] > 0)
{
--_doResponse[option];
if (_doResponse[option] > 0 && _stateIsDo(option))
{
--_doResponse[option];
}
}
if (_doResponse[option] == 0 && _requestedDont(option))
{
switch (option)
{
default:
break;
}
if (acceptNewState)
{
_setWantDo(option);
_sendDo(option);
}
else
{
++_doResponse[option];
_sendDont(option);
}
}
_setDo(option);
}
/**
* Processes a WONT request.
*
* @param option - option code to be set.
* @throws IOException - Exception in I/O.
**/
void _processWont(int option) throws IOException
{
if (debugoptions)
{
System.err.println("RECEIVED WONT: "
+ TelnetOption.getOption(option));
}
if (__notifhand != null)
{
__notifhand.receivedNegotiation(
TelnetNotificationHandler.RECEIVED_WONT,
option);
}
if (_doResponse[option] > 0)
{
--_doResponse[option];
if (_doResponse[option] > 0 && _stateIsDont(option))
{
--_doResponse[option];
}
}
if (_doResponse[option] == 0 && _requestedDo(option))
{
switch (option)
{
default:
break;
}
/* FIX for a BUG in the negotiation (start)*/
if ((_stateIsDo(option)) || (_requestedDo(option)))
{
_sendDont(option);
}
_setWantDont(option);
/* FIX for a BUG in the negotiation (end)*/
}
_setDont(option);
}
/* TERMINAL-TYPE option (start)*/
/**
* Processes a suboption negotiation.
*
* @param suboption - subnegotiation data received
* @param suboptionLength - length of data received
* @throws IOException - Exception in I/O.
**/
void _processSuboption(int suboption[], int suboptionLength)
throws IOException
{
if (debug)
{
System.err.println("PROCESS SUBOPTION.");
}
/* open TelnetOptionHandler functionality (start)*/
if (suboptionLength > 0)
{
if (optionHandlers[suboption[0]] != null)
{
int responseSuboption[] =
optionHandlers[suboption[0]].answerSubnegotiation(suboption,
suboptionLength);
_sendSubnegotiation(responseSuboption);
}
else
{
if (suboptionLength > 1)
{
if (debug)
{
for (int ii = 0; ii < suboptionLength; ii++)
{
System.err.println("SUB[" + ii + "]: "
+ suboption[ii]);
}
}
if ((suboption[0] == TERMINAL_TYPE)
&& (suboption[1] == TERMINAL_TYPE_SEND))
{
_sendTerminalType();
}
}
}
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sends terminal type information.
*
* @throws IOException - Exception in I/O.
***/
final synchronized void _sendTerminalType()
throws IOException
{
if (debug)
{
System.err.println("SEND TERMINAL-TYPE: " + terminalType);
}
if (terminalType != null)
{
_output_.write(_COMMAND_SB);
_output_.write(_COMMAND_IS);
_output_.write(terminalType.getBytes());
_output_.write(_COMMAND_SE);
_output_.flush();
}
}
/* TERMINAL-TYPE option (end)*/
/* open TelnetOptionHandler functionality (start)*/
/**
* Manages subnegotiation for Terminal Type.
*
* @param subn - subnegotiation data to be sent
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendSubnegotiation(int subn[])
throws IOException
{
if (debug)
{
System.err.println("SEND SUBNEGOTIATION: ");
if (subn != null)
{
for (int ii = 0; ii < subn.length; ii++)
{
System.err.println("subn[" + ii + "]=" + subn[ii]);
}
}
}
if (subn != null)
{
byte byteresp[] = new byte[subn.length];
for (int ii = 0; ii < subn.length; ii++)
{
byteresp[ii] = (byte) subn[ii];
}
_output_.write(_COMMAND_SB);
_output_.write(byteresp);
_output_.write(_COMMAND_SE);
/* Code Section added for sending the negotiation ASAP (start)*/
_output_.flush();
/* Code Section added for sending the negotiation ASAP (end)*/
}
}
/* open TelnetOptionHandler functionality (end)*/
/* Code Section added for supporting AYT (start)*/
/***
* Processes the response of an AYT
***/
final synchronized void _processAYTResponse()
{
if (!aytFlag)
{
synchronized (aytMonitor)
{
aytFlag = true;
try
{
aytMonitor.notifyAll();
}
catch (IllegalMonitorStateException e)
{
System.err.println("Exception notifying:" + e.getMessage());
}
}
}
}
/* Code Section added for supporting AYT (end)*/
/***
* Called upon connection.
*
* @throws IOException - Exception in I/O.
***/
@Override
protected void _connectAction_() throws IOException
{
/* (start). BUGFIX: clean the option info for each connection*/
for (int ii = 0; ii < TelnetOption.MAX_OPTION_VALUE + 1; ii++)
{
_doResponse[ii] = 0;
_willResponse[ii] = 0;
_options[ii] = 0;
if (optionHandlers[ii] != null)
{
optionHandlers[ii].setDo(false);
optionHandlers[ii].setWill(false);
}
}
/* (end). BUGFIX: clean the option info for each connection*/
super._connectAction_();
_input_ = new BufferedInputStream(_input_);
_output_ = new BufferedOutputStream(_output_);
/* open TelnetOptionHandler functionality (start)*/
for (int ii = 0; ii < TelnetOption.MAX_OPTION_VALUE + 1; ii++)
{
if (optionHandlers[ii] != null)
{
if (optionHandlers[ii].getInitLocal())
{
try
{
_requestWill(optionHandlers[ii].getOptionCode());
}
catch (IOException e)
{
System.err.println(
"Exception while initializing option: "
+ e.getMessage());
}
}
if (optionHandlers[ii].getInitRemote())
{
try
{
_requestDo(optionHandlers[ii].getOptionCode());
}
catch (IOException e)
{
System.err.println(
"Exception while initializing option: "
+ e.getMessage());
}
}
}
}
/* open TelnetOptionHandler functionality (end)*/
}
/**
* Sends a DO.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendDo(int option)
throws IOException
{
if (debug || debugoptions)
{
System.err.println("DO: " + TelnetOption.getOption(option));
}
_output_.write(_COMMAND_DO);
_output_.write(option);
/* Code Section added for sending the negotiation ASAP (start)*/
_output_.flush();
/* Code Section added for sending the negotiation ASAP (end)*/
}
/**
* Requests a DO.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _requestDo(int option)
throws IOException
{
if ((_doResponse[option] == 0 && _stateIsDo(option))
|| _requestedDo(option))
{
return ;
}
_setWantDo(option);
++_doResponse[option];
_sendDo(option);
}
/**
* Sends a DONT.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendDont(int option)
throws IOException
{
if (debug || debugoptions)
{
System.err.println("DONT: " + TelnetOption.getOption(option));
}
_output_.write(_COMMAND_DONT);
_output_.write(option);
/* Code Section added for sending the negotiation ASAP (start)*/
_output_.flush();
/* Code Section added for sending the negotiation ASAP (end)*/
}
/**
* Requests a DONT.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _requestDont(int option)
throws IOException
{
if ((_doResponse[option] == 0 && _stateIsDont(option))
|| _requestedDont(option))
{
return ;
}
_setWantDont(option);
++_doResponse[option];
_sendDont(option);
}
/**
* Sends a WILL.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendWill(int option)
throws IOException
{
if (debug || debugoptions)
{
System.err.println("WILL: " + TelnetOption.getOption(option));
}
_output_.write(_COMMAND_WILL);
_output_.write(option);
/* Code Section added for sending the negotiation ASAP (start)*/
_output_.flush();
/* Code Section added for sending the negotiation ASAP (end)*/
}
/**
* Requests a WILL.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _requestWill(int option)
throws IOException
{
if ((_willResponse[option] == 0 && _stateIsWill(option))
|| _requestedWill(option))
{
return ;
}
_setWantWill(option);
++_doResponse[option];
_sendWill(option);
}
/**
* Sends a WONT.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendWont(int option)
throws IOException
{
if (debug || debugoptions)
{
System.err.println("WONT: " + TelnetOption.getOption(option));
}
_output_.write(_COMMAND_WONT);
_output_.write(option);
/* Code Section added for sending the negotiation ASAP (start)*/
_output_.flush();
/* Code Section added for sending the negotiation ASAP (end)*/
}
/**
* Requests a WONT.
*
* @param option - Option code.
* @throws IOException - Exception in I/O.
**/
final synchronized void _requestWont(int option)
throws IOException
{
if ((_willResponse[option] == 0 && _stateIsWont(option))
|| _requestedWont(option))
{
return ;
}
_setWantWont(option);
++_doResponse[option];
_sendWont(option);
}
/**
* Sends a byte.
*
* @param b - byte to send
* @throws IOException - Exception in I/O.
**/
final synchronized void _sendByte(int b)
throws IOException
{
_output_.write(b);
/* Code Section added for supporting spystreams (start)*/
_spyWrite(b);
/* Code Section added for supporting spystreams (end)*/
}
/* Code Section added for supporting AYT (start)*/
/**
* Sends an Are You There sequence and waits for the result.
*
* @param timeout - Time to wait for a response (millis.)
* @throws IOException - Exception in I/O.
* @throws IllegalArgumentException - Illegal argument
* @throws InterruptedException - Interrupted during wait.
* @return true if AYT received a response, false otherwise
**/
final boolean _sendAYT(long timeout)
throws IOException, IllegalArgumentException, InterruptedException
{
boolean retValue = false;
synchronized (aytMonitor)
{
synchronized (this)
{
aytFlag = false;
_output_.write(_COMMAND_AYT);
_output_.flush();
}
try
{
aytMonitor.wait(timeout);
if (aytFlag == false)
{
retValue = false;
aytFlag = true;
}
else
{
retValue = true;
}
}
catch (IllegalMonitorStateException e)
{
System.err.println("Exception processing AYT:"
+ e.getMessage());
}
}
return (retValue);
}
/* Code Section added for supporting AYT (end)*/
/* open TelnetOptionHandler functionality (start)*/
/**
* Registers a new TelnetOptionHandler for this telnet to use.
*
* @param opthand - option handler to be registered.
* @throws InvalidTelnetOptionException - The option code is invalid.
**/
void addOptionHandler(TelnetOptionHandler opthand)
throws InvalidTelnetOptionException
{
int optcode = opthand.getOptionCode();
if (TelnetOption.isValidOption(optcode))
{
if (optionHandlers[optcode] == null)
{
optionHandlers[optcode] = opthand;
if (isConnected())
{
if (opthand.getInitLocal())
{
try
{
_requestWill(optcode);
}
catch (IOException e)
{
System.err.println(
"Exception while initializing option: "
+ e.getMessage());
}
}
if (opthand.getInitRemote())
{
try
{
_requestDo(optcode);
}
catch (IOException e)
{
System.err.println(
"Exception while initializing option: "
+ e.getMessage());
}
}
}
}
else
{
throw (new InvalidTelnetOptionException(
"Already registered option", optcode));
}
}
else
{
throw (new InvalidTelnetOptionException(
"Invalid Option Code", optcode));
}
}
/**
* Unregisters a TelnetOptionHandler.
*
* @param optcode - Code of the option to be unregistered.
* @throws InvalidTelnetOptionException - The option code is invalid.
**/
void deleteOptionHandler(int optcode)
throws InvalidTelnetOptionException
{
if (TelnetOption.isValidOption(optcode))
{
if (optionHandlers[optcode] == null)
{
throw (new InvalidTelnetOptionException(
"Unregistered option", optcode));
}
else
{
TelnetOptionHandler opthand = optionHandlers[optcode];
optionHandlers[optcode] = null;
if (opthand.getWill())
{
try
{
_requestWont(optcode);
}
catch (IOException e)
{
System.err.println(
"Exception while turning off option: "
+ e.getMessage());
}
}
if (opthand.getDo())
{
try
{
_requestDont(optcode);
}
catch (IOException e)
{
System.err.println(
"Exception while turning off option: "
+ e.getMessage());
}
}
}
}
else
{
throw (new InvalidTelnetOptionException(
"Invalid Option Code", optcode));
}
}
/* open TelnetOptionHandler functionality (end)*/
/* Code Section added for supporting spystreams (start)*/
/***
* Registers an OutputStream for spying what's going on in
* the Telnet session.
*
* @param spystream - OutputStream on which session activity
* will be echoed.
***/
void _registerSpyStream(OutputStream spystream)
{
spyStream = spystream;
}
/***
* Stops spying this Telnet.
*
***/
void _stopSpyStream()
{
spyStream = null;
}
/***
* Sends a read char on the spy stream.
*
* @param ch - character read from the session
***/
void _spyRead(int ch)
{
OutputStream spy = spyStream;
if (spy != null)
{
try
{
if (ch != '\r')
{
spy.write(ch);
if (ch == '\n')
{
spy.write('\r');
}
spy.flush();
}
}
catch (IOException e)
{
spyStream = null;
}
}
}
/***
* Sends a written char on the spy stream.
*
* @param ch - character written to the session
***/
void _spyWrite(int ch)
{
if (!(_stateIsDo(TelnetOption.ECHO)
&& _requestedDo(TelnetOption.ECHO)))
{
OutputStream spy = spyStream;
if (spy != null)
{
try
{
spy.write(ch);
spy.flush();
}
catch (IOException e)
{
spyStream = null;
}
}
}
}
/* Code Section added for supporting spystreams (end)*/
/***
* Registers a notification handler to which will be sent
* notifications of received telnet option negotiation commands.
*
* @param notifhand - TelnetNotificationHandler to be registered
***/
public void registerNotifHandler(TelnetNotificationHandler notifhand)
{
__notifhand = notifhand;
}
/***
* Unregisters the current notification handler.
*
***/
public void unregisterNotifHandler()
{
__notifhand = null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java 0000644 0001750 0001750 00000004460 11466231525 031726 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* The TelnetNotificationHandler interface can be used to handle
* notification of options negotiation commands received on a telnet
* session.
*
* The user can implement this interface and register a
* TelnetNotificationHandler by using the registerNotificationHandler()
* of TelnetClient to be notified of option negotiation commands.
*
*
* @author Bruno D'Avanzo
***/
public interface TelnetNotificationHandler
{
/***
* The remote party sent a DO command.
***/
public static final int RECEIVED_DO = 1;
/***
* The remote party sent a DONT command.
***/
public static final int RECEIVED_DONT = 2;
/***
* The remote party sent a WILL command.
***/
public static final int RECEIVED_WILL = 3;
/***
* The remote party sent a WONT command.
***/
public static final int RECEIVED_WONT = 4;
/***
* The remote party sent a COMMAND.
* @since 2.2
***/
public static final int RECEIVED_COMMAND = 5;
/***
* Callback method called when TelnetClient receives an
* command or option negotiation command
*
* @param negotiation_code - type of (negotiation) command received
* (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT, RECEIVED_COMMAND)
*
* @param option_code - code of the option negotiated, or the command code itself (e.g. NOP).
*
***/
public void receivedNegotiation(int negotiation_code, int option_code);
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java 0000644 0001750 0001750 00000005723 10766271714 030204 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* Implements the telnet echo option RFC 857.
*
* @author Bruno D'Avanzo
***/
public class EchoOptionHandler extends TelnetOptionHandler
{
/***
* Constructor for the EchoOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public EchoOptionHandler(boolean initlocal, boolean initremote,
boolean acceptlocal, boolean acceptremote)
{
super(TelnetOption.ECHO, initlocal, initremote,
acceptlocal, acceptremote);
}
/***
* Constructor for the EchoOptionHandler. Initial and accept
* behaviour flags are set to false
***/
public EchoOptionHandler()
{
super(TelnetOption.ECHO, false, false, false, false);
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] answerSubnegotiation(int suboptionData[],
int suboptionLength)
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationLocal()
{
return null;
}
/***
* Implements the abstract method of TelnetOptionHandler.
*
* @return always null (no response to subnegotiation)
***/
@Override
public int[] startSubnegotiationRemote()
{
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java 0000644 0001750 0001750 00000020164 10542533103 030536 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.telnet;
/***
* The TelnetOptionHandler class is the base class to be used
* for implementing handlers for telnet options.
*
* TelnetOptionHandler implements basic option handling
* functionality and defines abstract methods that must be
* implemented to define subnegotiation behaviour.
*
* @author Bruno D'Avanzo
***/
public abstract class TelnetOptionHandler
{
/***
* Option code
***/
private int optionCode = -1;
/***
* true if the option should be activated on the local side
***/
private boolean initialLocal = false;
/***
* true if the option should be activated on the remote side
***/
private boolean initialRemote = false;
/***
* true if the option should be accepted on the local side
***/
private boolean acceptLocal = false;
/***
* true if the option should be accepted on the remote side
***/
private boolean acceptRemote = false;
/***
* true if the option is active on the local side
***/
private boolean doFlag = false;
/***
* true if the option is active on the remote side
***/
private boolean willFlag = false;
/***
* Constructor for the TelnetOptionHandler. Allows defining desired
* initial setting for local/remote activation of this option and
* behaviour in case a local/remote activation request for this
* option is received.
*
* @param optcode - Option code.
* @param initlocal - if set to true, a WILL is sent upon connection.
* @param initremote - if set to true, a DO is sent upon connection.
* @param acceptlocal - if set to true, any DO request is accepted.
* @param acceptremote - if set to true, any WILL request is accepted.
***/
public TelnetOptionHandler(int optcode,
boolean initlocal,
boolean initremote,
boolean acceptlocal,
boolean acceptremote)
{
optionCode = optcode;
initialLocal = initlocal;
initialRemote = initremote;
acceptLocal = acceptlocal;
acceptRemote = acceptremote;
}
/***
* Returns the option code for this option.
*
* @return Option code.
***/
public int getOptionCode()
{
return (optionCode);
}
/***
* Returns a boolean indicating whether to accept a DO
* request coming from the other end.
*
* @return true if a DO request shall be accepted.
***/
public boolean getAcceptLocal()
{
return (acceptLocal);
}
/***
* Returns a boolean indicating whether to accept a WILL
* request coming from the other end.
*
* @return true if a WILL request shall be accepted.
***/
public boolean getAcceptRemote()
{
return (acceptRemote);
}
/***
* Set behaviour of the option for DO requests coming from
* the other end.
*
* @param accept - if true, subsequent DO requests will be accepted.
***/
public void setAcceptLocal(boolean accept)
{
acceptLocal = accept;
}
/***
* Set behaviour of the option for WILL requests coming from
* the other end.
*
* @param accept - if true, subsequent WILL requests will be accepted.
***/
public void setAcceptRemote(boolean accept)
{
acceptRemote = accept;
}
/***
* Returns a boolean indicating whether to send a WILL request
* to the other end upon connection.
*
* @return true if a WILL request shall be sent upon connection.
***/
public boolean getInitLocal()
{
return (initialLocal);
}
/***
* Returns a boolean indicating whether to send a DO request
* to the other end upon connection.
*
* @return true if a DO request shall be sent upon connection.
***/
public boolean getInitRemote()
{
return (initialRemote);
}
/***
* Tells this option whether to send a WILL request upon connection.
*
* @param init - if true, a WILL request will be sent upon subsequent
* connections.
***/
public void setInitLocal(boolean init)
{
initialLocal = init;
}
/***
* Tells this option whether to send a DO request upon connection.
*
* @param init - if true, a DO request will be sent upon subsequent
* connections.
***/
public void setInitRemote(boolean init)
{
initialRemote = init;
}
/***
* Method called upon reception of a subnegotiation for this option
* coming from the other end.
* Must be implemented by the actual TelnetOptionHandler to specify
* which response must be sent for the subnegotiation request.
*
* @param suboptionData - the sequence received, whithout IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
*
* @return response to be sent to the subnegotiation sequence. TelnetClient
* will add IAC SB & IAC SE. null means no response
***/
public abstract int[] answerSubnegotiation(int suboptionData[],
int suboptionLength);
/***
* This method is invoked whenever this option is acknowledged active on
* the local end (TelnetClient sent a WILL, remote side sent a DO).
* The method is used to specify a subnegotiation sequence that will be
* sent by TelnetClient when the option is activated.
*
* @return subnegotiation sequence to be sent by TelnetClient. TelnetClient
* will add IAC SB & IAC SE. null means no subnegotiation.
***/
public abstract int[] startSubnegotiationLocal();
/***
* This method is invoked whenever this option is acknowledged active on
* the remote end (TelnetClient sent a DO, remote side sent a WILL).
* The method is used to specify a subnegotiation sequence that will be
* sent by TelnetClient when the option is activated.
*
* @return subnegotiation sequence to be sent by TelnetClient. TelnetClient
* will add IAC SB & IAC SE. null means no subnegotiation.
***/
public abstract int[] startSubnegotiationRemote();
/***
* Returns a boolean indicating whether a WILL request sent to the other
* side has been acknowledged.
*
* @return true if a WILL sent to the other side has been acknowledged.
***/
boolean getWill()
{
return willFlag;
}
/***
* Tells this option whether a WILL request sent to the other
* side has been acknowledged (invoked by TelnetClient).
*
* @param state - if true, a WILL request has been acknowledged.
***/
void setWill(boolean state)
{
willFlag = state;
}
/***
* Returns a boolean indicating whether a DO request sent to the other
* side has been acknowledged.
*
* @return true if a DO sent to the other side has been acknowledged.
***/
boolean getDo()
{
return doFlag;
}
/***
* Tells this option whether a DO request sent to the other
* side has been acknowledged (invoked by TelnetClient).
*
* @param state - if true, a DO request has been acknowledged.
***/
void setDo(boolean state)
{
doFlag = state;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/time/ 0000755 0001750 0001750 00000000000 11617452467 023432 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/time/TimeUDPClient.java 0000644 0001750 0001750 00000011133 11416072763 026674 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.time;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.DatagramSocketClient;
/***
* The TimeUDPClient class is a UDP implementation of a client for the
* Time protocol described in RFC 868. To use the class, merely
* open a local datagram socket with
* {@link org.apache.commons.net.DatagramSocketClient#open open }
* and call {@link #getTime getTime } or
* {@link #getTime getDate } to retrieve the time. Then call
* {@link org.apache.commons.net.DatagramSocketClient#close close }
* to close the connection properly. Unlike
* {@link org.apache.commons.net.time.TimeTCPClient},
* successive calls to {@link #getTime getTime } or
* {@link #getDate getDate } are permitted
* without re-establishing a connection. That is because UDP is a
* connectionless protocol and the Time protocol is stateless.
*
*
* @author Daniel F. Savarese
* @see TimeTCPClient
***/
public final class TimeUDPClient extends DatagramSocketClient
{
/*** The default time port. It is set to 37 according to RFC 868. ***/
public static final int DEFAULT_PORT = 37;
/***
* The number of seconds between 00:00 1 January 1900 and
* 00:00 1 January 1970. This value can be useful for converting
* time values to other formats.
***/
public static final long SECONDS_1900_TO_1970 = 2208988800L;
private final byte[] __dummyData = new byte[1];
private final byte[] __timeData = new byte[4];
/***
* Retrieves the time from the specified server and port and
* returns it. The time is the number of seconds since
* 00:00 (midnight) 1 January 1900 GMT, as specified by RFC 868.
* This method reads the raw 32-bit big-endian
* unsigned integer from the server, converts it to a Java long, and
* returns the value.
*
* @param host The address of the server.
* @param port The port of the service.
* @return The time value retrieved from the server.
* @exception IOException If an error occurs while retrieving the time.
***/
public long getTime(InetAddress host, int port) throws IOException
{
long time;
DatagramPacket sendPacket, receivePacket;
sendPacket =
new DatagramPacket(__dummyData, __dummyData.length, host, port);
receivePacket = new DatagramPacket(__timeData, __timeData.length);
_socket_.send(sendPacket);
_socket_.receive(receivePacket);
time = 0L;
time |= (((__timeData[0] & 0xff) << 24) & 0xffffffffL);
time |= (((__timeData[1] & 0xff) << 16) & 0xffffffffL);
time |= (((__timeData[2] & 0xff) << 8) & 0xffffffffL);
time |= ((__timeData[3] & 0xff) & 0xffffffffL);
return time;
}
/*** Same as
* @param host The address of the server.
* @param port The port of the service.
* @return A Date value containing the time retrieved from the server
* converted to the local timezone.
* @exception IOException If an error occurs while fetching the time.
***/
public Date getDate(InetAddress host, int port) throws IOException
{
return new Date((getTime(host, port) - SECONDS_1900_TO_1970)*1000L);
}
/*** Same as
*
* @author Daniel F. Savarese
* @see TimeUDPClient
***/
public final class TimeTCPClient extends SocketClient
{
/*** The default time port. It is set to 37 according to RFC 868. ***/
public static final int DEFAULT_PORT = 37;
/***
* The number of seconds between 00:00 1 January 1900 and
* 00:00 1 January 1970. This value can be useful for converting
* time values to other formats.
***/
public static final long SECONDS_1900_TO_1970 = 2208988800L;
/***
* The default TimeTCPClient constructor. It merely sets the default
* port to
* The server will have closed the connection at this point, so you should
* call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* after calling this method. To retrieve another time, you must
* initiate another connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before calling
* @return The time value retrieved from the server.
* @exception IOException If an error occurs while fetching the time.
***/
public long getTime() throws IOException
{
DataInputStream input;
input = new DataInputStream(_input_);
return (input.readInt() & 0xffffffffL);
}
/***
* Retrieves the time from the server and returns a Java Date
* containing the time converted to the local timezone.
*
* The server will have closed the connection at this point, so you should
* call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* after calling this method. To retrieve another time, you must
* initiate another connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before calling
* @return A Date value containing the time retrieved from the server
* converted to the local timezone.
* @exception IOException If an error occurs while fetching the time.
***/
public Date getDate() throws IOException
{
return new Date((getTime() - SECONDS_1900_TO_1970)*1000L);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/ 0000755 0001750 0001750 00000000000 11617452467 023265 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java 0000644 0001750 0001750 00000003537 10542533103 031601 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.IOException;
/***
* FTPConnectionClosedException is used to indicate the premature or
* unexpected closing of an FTP connection resulting from a
* {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
* response (FTP reply code 421) to a
* failed FTP command. This exception is derived from IOException and
* therefore may be caught either as an IOException or specifically as an
* FTPConnectionClosedException.
*
*
* @author Daniel F. Savarese
* @see FTP
* @see FTPClient
***/
public class FTPConnectionClosedException extends IOException
{
/*** Constructs a FTPConnectionClosedException with no message ***/
public FTPConnectionClosedException()
{
super();
}
/***
* Constructs a FTPConnectionClosedException with a specified message.
*
* @param message The message explaining the reason for the exception.
***/
public FTPConnectionClosedException(String message)
{
super(message);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java 0000644 0001750 0001750 00000003420 11416066410 027222 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* Custom {@link TrustManager} implementation.
*
* @version $Id: FTPSTrustManager.java 962837 2010-07-10 12:52:24Z sebb $
* @since 2.0
*/
public class FTPSTrustManager implements X509TrustManager
{
private static final X509Certificate[] EMPTY_X509CERTIFICATE_ARRAY = new X509Certificate[]{};
/**
* No-op
*/
public void checkClientTrusted(X509Certificate[] certificates, String authType)
{
return;
}
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException
{
for (int i = 0; i < certificates.length; ++i)
{
certificates[i].checkValidity();
}
}
public X509Certificate[] getAcceptedIssuers()
{
return EMPTY_X509CERTIFICATE_ARRAY;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/Configurable.java 0000644 0001750 0001750 00000002476 11014664535 026531 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
/**
* This interface adds the aspect of configurability by means of
* a supplied FTPClientConfig object to other classes in the
* system, especially listing parsers.
*/
public interface Configurable {
/**
* @param config the object containing the configuration data
* @throws IllegalArgumentException if the elements of the
*
*
* @author Daniel F. Savarese
* @see FTPFileEntryParser
* @see FTPClient#listFiles
***/
public class FTPFile implements Serializable
{
/** A constant indicating an FTPFile is a file. ***/
public static final int FILE_TYPE = 0;
/** A constant indicating an FTPFile is a directory. ***/
public static final int DIRECTORY_TYPE = 1;
/** A constant indicating an FTPFile is a symbolic link. ***/
public static final int SYMBOLIC_LINK_TYPE = 2;
/** A constant indicating an FTPFile is of unknown type. ***/
public static final int UNKNOWN_TYPE = 3;
/** A constant indicating user access permissions. ***/
public static final int USER_ACCESS = 0;
/** A constant indicating group access permissions. ***/
public static final int GROUP_ACCESS = 1;
/** A constant indicating world access permissions. ***/
public static final int WORLD_ACCESS = 2;
/** A constant indicating file/directory read permission. ***/
public static final int READ_PERMISSION = 0;
/** A constant indicating file/directory write permission. ***/
public static final int WRITE_PERMISSION = 1;
/**
* A constant indicating file execute permission or directory listing
* permission.
***/
public static final int EXECUTE_PERMISSION = 2;
int _type, _hardLinkCount;
long _size;
String _rawListing, _user, _group, _name, _link;
Calendar _date;
boolean[] _permissions[];
/*** Creates an empty FTPFile. ***/
public FTPFile()
{
_permissions = new boolean[3][3];
_rawListing = null;
_type = UNKNOWN_TYPE;
_hardLinkCount = 0;
_size = 0;
_user = null;
_group = null;
_date = null;
_name = null;
}
/***
* Set the original FTP server raw listing from which the FTPFile was
* created.
*
* @param rawListing The raw FTP server listing.
***/
public void setRawListing(String rawListing)
{
_rawListing = rawListing;
}
/***
* Get the original FTP server raw listing used to initialize the FTPFile.
*
* @return The original FTP server raw listing used to initialize the
* FTPFile.
***/
public String getRawListing()
{
return _rawListing;
}
/***
* Determine if the file is a directory.
*
* @return True if the file is of type
* @return True if the file is of type
* @return True if the file is of type
* @return True if the file is of type
* @param type The integer code representing the type of the file.
***/
public void setType(int type)
{
_type = type;
}
/***
* Return the type of the file (one of the
* @return The type of the file.
***/
public int getType()
{
return _type;
}
/***
* Set the name of the file.
*
* @param name The name of the file.
***/
public void setName(String name)
{
_name = name;
}
/***
* Return the name of the file.
*
* @return The name of the file.
***/
public String getName()
{
return _name;
}
/**
* Set the file size in bytes.
* @param size The file size in bytes.
*/
public void setSize(long size)
{
_size = size;
}
/***
* Return the file size in bytes.
*
* @return The file size in bytes.
***/
public long getSize()
{
return _size;
}
/***
* Set the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @param links The number of hard links to this file.
***/
public void setHardLinkCount(int links)
{
_hardLinkCount = links;
}
/***
* Return the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @return The number of hard links to this file.
***/
public int getHardLinkCount()
{
return _hardLinkCount;
}
/***
* Set the name of the group owning the file. This may be
* a string representation of the group number.
*
* @param group The name of the group owning the file.
***/
public void setGroup(String group)
{
_group = group;
}
/***
* Returns the name of the group owning the file. Sometimes this will be
* a string representation of the group number.
*
* @return The name of the group owning the file.
***/
public String getGroup()
{
return _group;
}
/***
* Set the name of the user owning the file. This may be
* a string representation of the user number;
*
* @param user The name of the user owning the file.
***/
public void setUser(String user)
{
_user = user;
}
/***
* Returns the name of the user owning the file. Sometimes this will be
* a string representation of the user number.
*
* @return The name of the user owning the file.
***/
public String getUser()
{
return _user;
}
/***
* If the FTPFile is a symbolic link, use this method to set the name of the
* file being pointed to by the symbolic link.
*
* @param link The file pointed to by the symbolic link.
***/
public void setLink(String link)
{
_link = link;
}
/***
* If the FTPFile is a symbolic link, this method returns the name of the
* file being pointed to by the symbolic link. Otherwise it returns null.
*
* @return The file pointed to by the symbolic link (null if the FTPFile
* is not a symbolic link).
***/
public String getLink()
{
return _link;
}
/***
* Set the file timestamp. This usually the last modification time.
* The parameter is not cloned, so do not alter its value after calling
* this method.
*
* @param date A Calendar instance representing the file timestamp.
***/
public void setTimestamp(Calendar date)
{
_date = date;
}
/***
* Returns the file timestamp. This usually the last modification time.
*
* @return A Calendar instance representing the file timestamp.
***/
public Calendar getTimestamp()
{
return _date;
}
/***
* Set if the given access group (one of the
* @param access The access group (one of the
* @param access The access group (one of the
* @return A string representation of the FTPFile information.
***/
@Override
public String toString()
{
return _rawListing;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java 0000644 0001750 0001750 00000004521 11466231525 030566 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
/**
* Server socket factory for FTPS connections.
* @since 2.2
*/
public class FTPSServerSocketFactory extends ServerSocketFactory {
/** Factory for secure socket factories */
private final SSLContext context;
public FTPSServerSocketFactory(SSLContext context) {
this.context = context;
}
@Override
public ServerSocket createServerSocket(int port) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port));
}
@Override
public ServerSocket createServerSocket(int port, int backlog) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
}
@Override
public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
return init(this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
}
/**
* Sets the socket so newly accepted connections will use SSL client mode.
*
* @param socket the SSLServerSocket to initialise
* @return the socket
* @throws ClassCastException if socket is not an instance of SSLServerSocket
*/
public ServerSocket init(ServerSocket socket) {
((SSLServerSocket) socket).setUseClientMode(true);
return socket;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java 0000644 0001750 0001750 00000055516 11351151237 027044 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.text.DateFormatSymbols;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
/**
*
* This class implements an alternate means of configuring the
* {@link org.apache.commons.net.ftp.FTPClient FTPClient} object and
* also subordinate objects which it uses. Any class implementing the
* {@link org.apache.commons.net.ftp.Configurable Configurable }
* interface can be configured by this object.
*
* In particular this class was designed primarily to support configuration
* of FTP servers which express file timestamps in formats and languages
* other than those for the US locale, which although it is the most common
* is not universal. Unfortunately, nothing in the FTP spec allows this to
* be determined in an automated way, so manual configuration such as this
* is necessary.
*
* This functionality was designed to allow existing clients to work exactly
* as before without requiring use of this component. This component should
* only need to be explicitly invoked by the user of this package for problem
* cases that previous implementations could not solve.
*
* Unpaged (whole list) access on a UNIX server that uses French month names
* but uses the "standard"
* Paged access on a UNIX server that uses Danish month names
* and "European" date formatting in Denmark's time zone, when you
* are in some other time zone.
*
* Unpaged (whole list) access on a VMS server that uses month names
* in a language not {@link #getSupportedLanguageCodes() supported} by the system.
* but uses the "standard"
* Unpaged (whole list) access on a Windows-NT server in a different time zone.
* (Note, since the NT Format uses numeric date formatting, language issues
* are irrelevant here).
*
* getter for the {@link #setShortMonthNames(String) shortMonthNames}
* property.
*
* getter for the {@link #setServerLanguageCode(String) serverLanguageCode} property.
*
* getter for the {@link #setLenientFutureDates(boolean) lenientFutureDates} property.
*
* setter for the defaultDateFormatStr property. This property
* specifies the main date format that will be used by a parser configured
* by this configuration to parse file timestamps. If this is not
* specified, such a parser will use as a default value, the most commonly
* used format which will be in as used in
* This should be in the format described for
*
* setter for the recentDateFormatStr property. This property
* specifies a secondary date format that will be used by a parser
* configured by this configuration to parse file timestamps, typically
* those less than a year old. If this is not specified, such a parser
* will not attempt to parse using an alternate format.
*
* setter for the lenientFutureDates property. This boolean property
* (default: false) only has meaning when a
* {@link #setRecentDateFormatStr(String) recentDateFormatStr} property
* has been set. In that case, if this property is set true, then the
* parser, when it encounters a listing parseable with the recent date
* format, will only consider a date to belong to the previous year if
* it is more than one day in the future. This will allow all
* out-of-synch situations (whether based on "slop" - i.e. servers simply
* out of synch with one another or because of time zone differences -
* but in the latter case it is highly recommended to use the
* {@link #setServerTimeZoneId(String) serverTimeZoneId} property
* instead) to resolve correctly.
*
* This is used primarily in unix-based systems.
*
* setter for the serverTimeZoneId property. This property
* allows a time zone to be specified corresponding to that known to be
* used by an FTP server in file listings. This might be particularly
* useful to clients such as Ant that try to use these timestamps for
* dependency checking.
*
* This should be one of the identifiers used by
*
* setter for the shortMonthNames property.
* This property allows the user to specify a set of month names
* used by the server that is different from those that may be
* specified using the {@link #setServerLanguageCode(String) serverLanguageCode}
* property.
*
* This should be a string containing twelve strings each composed of
* three characters, delimited by pipe (|) characters. Currently,
* only 8-bit ASCII characters are known to be supported. For example,
* a set of month names used by a hypothetical Icelandic FTP server might
* conceivably be specified as
*
* setter for the serverLanguageCode property. This property allows
* user to specify a
*
* two-letter ISO-639 language code that will be used to
* configure the set of month names used by the file timestamp parser.
* If neither this nor the {@link #setShortMonthNames(String) shortMonthNames}
* is specified, parsing will assume English month names, which may or
* may not be significant, depending on whether the date format(s)
* specified via {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* and/or {@link #setRecentDateFormatStr(String) recentDateFormatStr} are using
* numeric or alphabetic month names.
* If the code supplied is not supported here,
* Please note that this attribute will NOT be used to determine a
* locale-based date format for the language.
* Experience has shown that many if not most FTP servers outside the
* United States employ the standard
* Here are some examples showing how to use one of the classes that
* implement this interface.
*
* The first example shows how to get an iterable list of files in which the
* more expensive
* @param listEntry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
FTPFile parseFTPEntry(String listEntry);
/**
* Reads the next entry using the supplied BufferedReader object up to
* whatever delemits one entry from the next. Implementors must define
* this for the particular ftp system being parsed. In many but not all
* cases, this can be defined simply by calling BufferedReader.readLine().
*
* @param reader The BufferedReader object from which entries are to be
* read.
*
* @return A string representing the next ftp entry or null if none found.
* @exception IOException thrown on any IO Error reading from the reader.
*/
String readNextEntry(BufferedReader reader) throws IOException;
/**
* This method is a hook for those implementors (such as
* VMSVersioningFTPEntryParser, and possibly others) which need to
* perform some action upon the FTPFileList after it has been created
* from the server stream, but before any clients see the list.
*
* The default implementation can be a no-op.
*
* @param original Original list after it has been created from the server stream
*
* @return Original list as processed by this method.
*/
List
*
* @author Daniel F. Savarese
***/
/** TODO replace this with an enum */
public final class FTPCommand
{
public static final int USER = 0;
public static final int PASS = 1;
public static final int ACCT = 2;
public static final int CWD = 3;
public static final int CDUP = 4;
public static final int SMNT = 5;
public static final int REIN = 6;
public static final int QUIT = 7;
public static final int PORT = 8;
public static final int PASV = 9;
public static final int TYPE = 10;
public static final int STRU = 11;
public static final int MODE = 12;
public static final int RETR = 13;
public static final int STOR = 14;
public static final int STOU = 15;
public static final int APPE = 16;
public static final int ALLO = 17;
public static final int REST = 18;
public static final int RNFR = 19;
public static final int RNTO = 20;
public static final int ABOR = 21;
public static final int DELE = 22;
public static final int RMD = 23;
public static final int MKD = 24;
public static final int PWD = 25;
public static final int LIST = 26;
public static final int NLST = 27;
public static final int SITE = 28;
public static final int SYST = 29;
public static final int STAT = 30;
public static final int HELP = 31;
public static final int NOOP = 32;
/** @since 2.0 */
public static final int MDTM = 33;
/** @since 2.2 */
public static final int FEAT = 34;
/** @since 2.2 */
public static final int MFMT = 35;
/** @since 2.2 */
public static final int EPSV = 36;
/** @since 2.2 */
public static final int EPRT = 37;
// Must agree with final entry above; used to check array size
private static final int LAST = EPRT;
public static final int USERNAME = USER;
public static final int PASSWORD = PASS;
public static final int ACCOUNT = ACCT;
public static final int CHANGE_WORKING_DIRECTORY = CWD;
public static final int CHANGE_TO_PARENT_DIRECTORY = CDUP;
public static final int STRUCTURE_MOUNT = SMNT;
public static final int REINITIALIZE = REIN;
public static final int LOGOUT = QUIT;
public static final int DATA_PORT = PORT;
public static final int PASSIVE = PASV;
public static final int REPRESENTATION_TYPE = TYPE;
public static final int FILE_STRUCTURE = STRU;
public static final int TRANSFER_MODE = MODE;
public static final int RETRIEVE = RETR;
public static final int STORE = STOR;
public static final int STORE_UNIQUE = STOU;
public static final int APPEND = APPE;
public static final int ALLOCATE = ALLO;
public static final int RESTART = REST;
public static final int RENAME_FROM = RNFR;
public static final int RENAME_TO = RNTO;
public static final int ABORT = ABOR;
public static final int DELETE = DELE;
public static final int REMOVE_DIRECTORY = RMD;
public static final int MAKE_DIRECTORY = MKD;
public static final int PRINT_WORKING_DIRECTORY = PWD;
// public static final int LIST = LIST;
public static final int NAME_LIST = NLST;
public static final int SITE_PARAMETERS = SITE;
public static final int SYSTEM = SYST;
public static final int STATUS = STAT;
//public static final int HELP = HELP;
//public static final int NOOP = NOOP;
/** @since 2.0 */
public static final int MOD_TIME = MDTM;
/** @since 2.2 */
public static final int FEATURES = FEAT;
/** @since 2.2 */
public static final int GET_MOD_TIME = MDTM;
/** @since 2.2 */
public static final int SET_MOD_TIME = MFMT;
// Cannot be instantiated
private FTPCommand()
{}
private static final String[] _commands = {
"USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT",
"PASV", "TYPE", "STRU", "MODE", "RETR", "STOR", "STOU", "APPE", "ALLO",
"REST", "RNFR", "RNTO", "ABOR", "DELE", "RMD", "MKD", "PWD", "LIST",
"NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "FEAT", "MFMT",
"EPSV", "EPRT" };
// default access needed for Unit test
static void checkArray(){
int expectedLength = LAST+1;
if (_commands.length != expectedLength) {
throw new RuntimeException("Incorrect _commands array. Should have length "
+expectedLength+" found "+_commands.length);
}
}
/**
* Retrieve the FTP protocol command string corresponding to a specified
* command code.
*
* @param command The command code.
* @return The FTP protcol command string corresponding to a specified
* command code.
*/
public static final String getCommand(int command)
{
return _commands[command];
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPReply.java 0000644 0001750 0001750 00000024467 11466231525 025602 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
/***
* FTPReply stores a set of constants for FTP reply codes. To interpret
* the meaning of the codes, familiarity with RFC 959 is assumed.
* The mnemonic constant names are transcriptions from the code descriptions
* of RFC 959. For those who think in terms of the actual reply code values,
* a set of CODE_NUM constants are provided where NUM is the numerical value
* of the code.
*
*
* @author Daniel F. Savarese
* TODO replace with an enum
***/
public final class FTPReply
{
public static final int CODE_110 = 110;
public static final int CODE_120 = 120;
public static final int CODE_125 = 125;
public static final int CODE_150 = 150;
public static final int CODE_200 = 200;
public static final int CODE_202 = 202;
public static final int CODE_211 = 211;
public static final int CODE_212 = 212;
public static final int CODE_213 = 213;
public static final int CODE_214 = 214;
public static final int CODE_215 = 215;
public static final int CODE_220 = 220;
public static final int CODE_221 = 221;
public static final int CODE_225 = 225;
public static final int CODE_226 = 226;
public static final int CODE_227 = 227;
/** @since 2.2 */
public static final int CODE_229 = 229;
public static final int CODE_230 = 230;
public static final int CODE_250 = 250;
public static final int CODE_257 = 257;
public static final int CODE_331 = 331;
public static final int CODE_332 = 332;
public static final int CODE_350 = 350;
public static final int CODE_421 = 421;
public static final int CODE_425 = 425;
public static final int CODE_426 = 426;
public static final int CODE_450 = 450;
public static final int CODE_451 = 451;
public static final int CODE_452 = 452;
public static final int CODE_500 = 500;
public static final int CODE_501 = 501;
public static final int CODE_502 = 502;
public static final int CODE_503 = 503;
public static final int CODE_504 = 504;
public static final int CODE_521 = 521;
public static final int CODE_530 = 530;
public static final int CODE_532 = 532;
public static final int CODE_550 = 550;
public static final int CODE_551 = 551;
public static final int CODE_552 = 552;
public static final int CODE_553 = 553;
public static final int RESTART_MARKER = CODE_110;
public static final int SERVICE_NOT_READY = CODE_120;
public static final int DATA_CONNECTION_ALREADY_OPEN = CODE_125;
public static final int FILE_STATUS_OK = CODE_150;
public static final int COMMAND_OK = CODE_200;
public static final int COMMAND_IS_SUPERFLUOUS = CODE_202;
public static final int SYSTEM_STATUS = CODE_211;
public static final int DIRECTORY_STATUS = CODE_212;
public static final int FILE_STATUS = CODE_213;
public static final int HELP_MESSAGE = CODE_214;
public static final int NAME_SYSTEM_TYPE = CODE_215;
public static final int SERVICE_READY = CODE_220;
public static final int SERVICE_CLOSING_CONTROL_CONNECTION = CODE_221;
public static final int DATA_CONNECTION_OPEN = CODE_225;
public static final int CLOSING_DATA_CONNECTION = CODE_226;
public static final int ENTERING_PASSIVE_MODE = CODE_227;
/** @since 2.2 */
public static final int ENTERING_EPSV_MODE = CODE_229;
public static final int USER_LOGGED_IN = CODE_230;
public static final int FILE_ACTION_OK = CODE_250;
public static final int PATHNAME_CREATED = CODE_257;
public static final int NEED_PASSWORD = CODE_331;
public static final int NEED_ACCOUNT = CODE_332;
public static final int FILE_ACTION_PENDING = CODE_350;
public static final int SERVICE_NOT_AVAILABLE = CODE_421;
public static final int CANNOT_OPEN_DATA_CONNECTION = CODE_425;
public static final int TRANSFER_ABORTED = CODE_426;
public static final int FILE_ACTION_NOT_TAKEN = CODE_450;
public static final int ACTION_ABORTED = CODE_451;
public static final int INSUFFICIENT_STORAGE = CODE_452;
public static final int UNRECOGNIZED_COMMAND = CODE_500;
public static final int SYNTAX_ERROR_IN_ARGUMENTS = CODE_501;
public static final int COMMAND_NOT_IMPLEMENTED = CODE_502;
public static final int BAD_COMMAND_SEQUENCE = CODE_503;
public static final int COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER = CODE_504;
public static final int NOT_LOGGED_IN = CODE_530;
public static final int NEED_ACCOUNT_FOR_STORING_FILES = CODE_532;
public static final int FILE_UNAVAILABLE = CODE_550;
public static final int PAGE_TYPE_UNKNOWN = CODE_551;
public static final int STORAGE_ALLOCATION_EXCEEDED = CODE_552;
public static final int FILE_NAME_NOT_ALLOWED = CODE_553;
// FTPS Reply Codes
/** @since 2.0 */
public static final int CODE_234 = 234;
/** @since 2.0 */
public static final int CODE_235 = 235;
/** @since 2.0 */
public static final int CODE_334 = 334;
/** @since 2.0 */
public static final int CODE_335 = 335;
/** @since 2.0 */
public static final int CODE_431 = 431;
/** @since 2.2 */
public static final int CODE_522 = 522;
/** @since 2.0 */
public static final int CODE_533 = 533;
/** @since 2.0 */
public static final int CODE_534 = 534;
/** @since 2.0 */
public static final int CODE_535 = 535;
/** @since 2.0 */
public static final int CODE_536 = 536;
/** @since 2.0 */
public static final int SECURITY_DATA_EXCHANGE_COMPLETE = CODE_234;
/** @since 2.0 */
public static final int SECURITY_DATA_EXCHANGE_SUCCESSFULLY = CODE_235;
/** @since 2.0 */
public static final int SECURITY_MECHANISM_IS_OK = CODE_334;
/** @since 2.0 */
public static final int SECURITY_DATA_IS_ACCEPTABLE = CODE_335;
/** @since 2.0 */
public static final int UNAVAILABLE_RESOURCE = CODE_431;
/** @since 2.2 */
public static final int BAD_TLS_NEGOTIATION_OR_DATA_ENCRYPTION_REQUIRED = CODE_522;
/** @since 2.0 */
public static final int DENIED_FOR_POLICY_REASONS = CODE_533;
/** @since 2.0 */
public static final int REQUEST_DENIED = CODE_534;
/** @since 2.0 */
public static final int FAILED_SECURITY_CHECK = CODE_535;
/** @since 2.0 */
public static final int REQUESTED_PROT_LEVEL_NOT_SUPPORTED = CODE_536;
// IPv6 error codes
// Note this is also used as an FTPS error code reply
/** @since 2.2 */
public static final int EXTENDED_PORT_FAILURE = CODE_522;
// Cannot be instantiated
private FTPReply()
{}
/***
* Determine if a reply code is a positive preliminary response. All
* codes beginning with a 1 are positive preliminary responses.
* Postitive preliminary responses are used to indicate tentative success.
* No further commands can be issued to the FTP server after a positive
* preliminary response until a follow up response is received from the
* server.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive preliminary response, false
* if not.
***/
public static boolean isPositivePreliminary(int reply)
{
return (reply >= 100 && reply < 200);
}
/***
* Determine if a reply code is a positive completion response. All
* codes beginning with a 2 are positive completion responses.
* The FTP server will send a positive completion response on the final
* successful completion of a command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive completion response, false
* if not.
***/
public static boolean isPositiveCompletion(int reply)
{
return (reply >= 200 && reply < 300);
}
/***
* Determine if a reply code is a positive intermediate response. All
* codes beginning with a 3 are positive intermediate responses.
* The FTP server will send a positive intermediate response on the
* successful completion of one part of a multi-part sequence of
* commands. For example, after a successful USER command, a positive
* intermediate response will be sent to indicate that the server is
* ready for the PASS command.
*
* @param reply The reply code to test.
* @return True if a reply code is a postive intermediate response, false
* if not.
***/
public static boolean isPositiveIntermediate(int reply)
{
return (reply >= 300 && reply < 400);
}
/***
* Determine if a reply code is a negative transient response. All
* codes beginning with a 4 are negative transient responses.
* The FTP server will send a negative transient response on the
* failure of a command that can be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative transient response, false
* if not.
***/
public static boolean isNegativeTransient(int reply)
{
return (reply >= 400 && reply < 500);
}
/***
* Determine if a reply code is a negative permanent response. All
* codes beginning with a 5 are negative permanent responses.
* The FTP server will send a negative permanent response on the
* failure of a command that cannot be reattempted with success.
*
* @param reply The reply code to test.
* @return True if a reply code is a negative permanent response, false
* if not.
***/
public static boolean isNegativePermanent(int reply)
{
return (reply >= 500 && reply < 600);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java 0000644 0001750 0001750 00000030163 11466235516 027535 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
* This class handles the entire process of parsing a listing of
* file entries from the server.
*
* This object defines a two-part parsing mechanism.
*
* The first part is comprised of reading the raw input into an internal
* list of strings. Every item in this list corresponds to an actual
* file. All extraneous matter emitted by the server will have been
* removed by the end of this phase. This is accomplished in conjunction
* with the FTPFileEntryParser associated with this engine, by calling
* its methods
* The second part is composed of the actual parsing, again in conjunction
* with the particular parser used by this engine. This is controlled
* by an iterator over the internal list of strings. This may be done
* either in block mode, by calling the
* Examples:
*
* Paged access:
*
* For unpaged access, simply use FTPClient.listFiles(). That method
* uses this class transparently.
* @version $Id: FTPListParseEngine.java 1032954 2010-11-09 12:15:10Z sebb $
*/
public class FTPListParseEngine {
private List
* NOTE: This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
*/
public FTPFile[] getNext(int quantityRequested) {
List
* NOTE: This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
*/
public FTPFile[] getPrevious(int quantityRequested) {
List
* NOTE: This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
* @exception IOException
*/
public FTPFile[] getFiles()
throws IOException
{
return getFiles(FTPFileFilters.ALL);
}
/**
* Returns an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* The files are filtered before being added to the array.
*
* @param filter FTPFileFilter, must not be
* NOTE: This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it, or use the
* a filter such as {@link FTPFileFilters#NON_NULL} which does not
* allow null entries.
* @since 2.2
* @exception IOException
*/
public FTPFile[] getFiles(FTPFileFilter filter)
throws IOException
{
List
* Immediately after connecting is the only real time you need to check the
* reply code (because connect is of type void). The convention for all the
* FTP command methods in FTPClient is such that they either return a
* boolean value or some other value.
* The boolean methods return true on a successful completion reply from
* the FTP server and false on a reply resulting in an error condition or
* failure. The methods returning a value other than boolean return a value
* containing the higher level data produced by the FTP command, or null if a
* reply resulted in an error condition or failure. If you want to access
* the exact FTP reply code causing a success or failure, you must call
* {@link org.apache.commons.net.ftp.FTP#getReplyCode getReplyCode } after
* a success or failure.
*
* The default settings for FTPClient are for it to use
*
*
* Because the handling of sockets on different platforms can differ
* significantly, the FTPClient automatically issues a new PORT (or EPRT) command
* prior to every transfer requiring that the server connect to the client's
* data port. This ensures identical problem-free behavior on Windows, Unix,
* and Macintosh platforms. Additionally, it relieves programmers from
* having to issue the PORT (or EPRT) command themselves and dealing with platform
* dependent issues.
*
* Additionally, for security purposes, all data connections to the
* client are verified to ensure that they originated from the intended
* party (host and port). If a data connection is initiated by an unexpected
* party, the command will close the socket and throw an IOException. You
* may disable this behavior with
* {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}.
*
* You should keep in mind that the FTP server may choose to prematurely
* close a connection if the client has been idle for longer than a
* given time period (usually 900 seconds). The FTPClient class will detect a
* premature FTP server connection closing when it receives a
* {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
* response to a command.
* When that occurs, the FTP class method encountering that reply will throw
* an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
* .
*
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
* Listing API Examples
* Both paged and unpaged examples of directory listings are available,
* as follows:
*
* Unpaged (whole list) access, using a parser accessible by auto-detect:
*
* Paged access, using a parser not accessible by auto-detect. The class
* defined in the first parameter of initateListParsing should be derived
* from org.apache.commons.net.FTPFileEntryParser:
*
* Paged access, using a parser accessible by auto-detect:
*
* For examples of using FTPClient on servers whose directory listings
*
* @author Daniel F. Savarese
* @author Rory Winston
* @see FTP
* @see FTPConnectionClosedException
* @see FTPFileEntryParser
* @see FTPFileEntryParserFactory
* @see DefaultFTPFileEntryParserFactory
* @see FTPClientConfig
*
* @see org.apache.commons.net.MalformedServerReplyException
**/
public class FTPClient extends FTP
implements Configurable
{
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between the client (local) and server and that the server
* should connect to the client's data port to initiate a data transfer.
* This is the default data connection mode when and FTPClient instance
* is created.
***/
public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between two remote servers and that the server
* the client is connected to should connect to the other server's
* data port to initiate a data transfer.
***/
public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between the client (local) and server and that the server
* is in passive mode, requiring the client to connect to the
* server's data port to initiate a transfer.
***/
public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
/***
* A constant indicating the FTP session is expecting all transfers
* to occur between two remote servers and that the server
* the client is connected to is in passive mode, requiring the other
* server to connect to the first server's data port to initiate a data
* transfer.
***/
public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
private int __dataConnectionMode, __dataTimeout;
private int __passivePort;
private String __passiveHost;
private final Random __random;
private int __activeMinPort, __activeMaxPort;
private InetAddress __activeExternalHost;
private int __fileType;
@SuppressWarnings("unused") // fields are written, but currently not read
private int __fileFormat, __fileStructure, __fileTransferMode;
private boolean __remoteVerificationEnabled;
private long __restartOffset;
private FTPFileEntryParserFactory __parserFactory;
private int __bufferSize;
private boolean __listHiddenFiles;
private boolean __useEPSVwithIPv4; // whether to attempt EPSV with an IPv4 connection
// __systemName is a cached value that should not be referenced directly
// except when assigned in getSystemName and __initDefaults.
private String __systemName;
// __entryParser is a cached value that should not be referenced directly
// except when assigned in listFiles(String, String) and __initDefaults.
private FTPFileEntryParser __entryParser;
// Key used to create the parser; necessary to ensure that the parser type is not ignored
private String __entryParserKey;
private FTPClientConfig __configuration;
/** Pattern for PASV mode responses */
private static final String __parms = "\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
private static final java.util.regex.Pattern __parms_pat;
static {
__parms_pat = java.util.regex.Pattern.compile(__parms);
}
/***
* Default FTPClient constructor. Creates a new FTPClient instance
* with the data connection mode set to
*
* @param command The text representation of the FTP command to send.
* @param arg The arguments to the FTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return A Socket corresponding to the established data connection.
* Null is returned if an FTP protocol error is reported at
* any point during the establishment and initialization of
* the connection.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
protected Socket _openDataConnection_(int command, String arg)
throws IOException
{
Socket socket;
if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
__dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
return null;
final boolean isInet6Address = getRemoteAddress() instanceof Inet6Address;
if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
{
// if no activePortRange was set (correctly) -> getActivePort() = 0
// -> new ServerSocket(0) -> bind to any free local port
ServerSocket server = _serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());
// Try EPRT only if remote server is over IPv6, if not use PORT,
// because EPRT has no advantage over PORT on IPv4.
// It could even have the disadvantage,
// that EPRT will make the data connection fail, because
// today's intelligent NAT Firewalls are able to
// substitute IP addresses in the PORT command,
// but might not be able to recognize the EPRT command.
if (isInet6Address)
{
if (!FTPReply.isPositiveCompletion(eprt(getHostAddress(), server.getLocalPort())))
{
server.close();
return null;
}
}
else
{
if (!FTPReply.isPositiveCompletion(port(getHostAddress(), server.getLocalPort())))
{
server.close();
return null;
}
}
if ((__restartOffset > 0) && !restart(__restartOffset))
{
server.close();
return null;
}
if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
{
server.close();
return null;
}
// For now, let's just use the data timeout value for waiting for
// the data connection. It may be desirable to let this be a
// separately configurable value. In any case, we really want
// to allow preventing the accept from blocking indefinitely.
if (__dataTimeout >= 0)
server.setSoTimeout(__dataTimeout);
try {
socket = server.accept();
} finally {
server.close();
}
}
else
{ // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
// Try EPSV command first on IPv6 - and IPv4 if enabled.
// When using IPv4 with NAT it has the advantage
// to work with more rare configurations.
// E.g. if FTP server has a static PASV address (external network)
// and the client is coming from another internal network.
// In that case the data connection after PASV command would fail,
// while EPSV would make the client succeed by taking just the port.
boolean attemptEPSV = isUseEPSVwithIPv4() || isInet6Address;
if (attemptEPSV && epsv() == FTPReply.ENTERING_EPSV_MODE)
{
__parseExtendedPassiveModeReply(_replyLines.get(0));
}
else
{
if (isInet6Address) {
return null; // Must use EPSV for IPV6
}
// If EPSV failed on IPV4, revert to PASV
if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) {
return null;
}
__parsePassiveModeReply(_replyLines.get(0));
}
socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
if ((__restartOffset > 0) && !restart(__restartOffset))
{
socket.close();
return null;
}
if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
{
socket.close();
return null;
}
}
if (__remoteVerificationEnabled && !verifyRemote(socket))
{
InetAddress host1, host2;
host1 = socket.getInetAddress();
host2 = getRemoteAddress();
socket.close();
throw new IOException(
"Host attempting data connection " + host1.getHostAddress() +
" is not same as server " + host2.getHostAddress());
}
if (__dataTimeout >= 0)
socket.setSoTimeout(__dataTimeout);
return socket;
}
@Override
protected void _connectAction_() throws IOException
{
super._connectAction_();
__initDefaults();
}
/***
* Sets the timeout in milliseconds to use when reading from the
* data connection. This timeout will be set immediately after
* opening the data connection.
*
* @param timeout The default timeout in milliseconds that is used when
* opening a data connection socket.
***/
public void setDataTimeout(int timeout)
{
__dataTimeout = timeout;
}
/**
* set the factory used for parser creation to the supplied factory object.
*
* @param parserFactory
* factory object used to create FTPFileEntryParsers
*
* @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
* @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
*/
public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
__parserFactory = parserFactory;
}
/***
* Closes the connection to the FTP server and restores
* connection parameters to the default values.
*
* @exception IOException If an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
super.disconnect();
__initDefaults();
}
/***
* Enable or disable verification that the remote host taking part
* of a data connection is the same as the host to which the control
* connection is attached. The default is for verification to be
* enabled. You may set this value at any time, whether the
* FTPClient is currently connected or not.
*
* @param enable True to enable verification, false to disable verification.
***/
public void setRemoteVerificationEnabled(boolean enable)
{
__remoteVerificationEnabled = enable;
}
/***
* Return whether or not verification of the remote host participating
* in data connections is enabled. The default behavior is for
* verification to be enabled.
*
* @return True if verification is enabled, false if not.
***/
public boolean isRemoteVerificationEnabled()
{
return __remoteVerificationEnabled;
}
/***
* Login to the FTP server using the provided username and password.
*
* @param username The username to login under.
* @param password The password to use.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean login(String username, String password) throws IOException
{
user(username);
if (FTPReply.isPositiveCompletion(_replyCode))
return true;
// If we get here, we either have an error code, or an intermmediate
// reply requesting password.
if (!FTPReply.isPositiveIntermediate(_replyCode))
return false;
return FTPReply.isPositiveCompletion(pass(password));
}
/***
* Login to the FTP server using the provided username, password,
* and account. If no account is required by the server, only
* the username and password, the account information is not used.
*
* @param username The username to login under.
* @param password The password to use.
* @param account The account to use.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean login(String username, String password, String account)
throws IOException
{
user(username);
if (FTPReply.isPositiveCompletion(_replyCode))
return true;
// If we get here, we either have an error code, or an intermmediate
// reply requesting password.
if (!FTPReply.isPositiveIntermediate(_replyCode))
return false;
pass(password);
if (FTPReply.isPositiveCompletion(_replyCode))
return true;
if (!FTPReply.isPositiveIntermediate(_replyCode))
return false;
return FTPReply.isPositiveCompletion(acct(account));
}
/***
* Logout of the FTP server by sending the QUIT command.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean logout() throws IOException
{
return FTPReply.isPositiveCompletion(quit());
}
/***
* Change the current working directory of the FTP session.
*
* @param pathname The new current working directory.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean changeWorkingDirectory(String pathname) throws IOException
{
return FTPReply.isPositiveCompletion(cwd(pathname));
}
/***
* Change to the parent directory of the current working directory.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean changeToParentDirectory() throws IOException
{
return FTPReply.isPositiveCompletion(cdup());
}
/***
* Issue the FTP SMNT command.
*
* @param pathname The pathname to mount.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean structureMount(String pathname) throws IOException
{
return FTPReply.isPositiveCompletion(smnt(pathname));
}
/***
* Reinitialize the FTP session. Not all FTP servers support this
* command, which issues the FTP REIN command.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
boolean reinitialize() throws IOException
{
rein();
if (FTPReply.isPositiveCompletion(_replyCode) ||
(FTPReply.isPositivePreliminary(_replyCode) &&
FTPReply.isPositiveCompletion(getReply())))
{
__initDefaults();
return true;
}
return false;
}
/***
* Set the current data connection mode to
*
* N.B. currently calling any connect method will reset the mode to
* ACTIVE_LOCAL_DATA_CONNECTION_MODE.
***/
public void enterLocalPassiveMode()
{
__dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
// These will be set when just before a data connection is opened
// in _openDataConnection_()
__passiveHost = null;
__passivePort = -1;
}
/***
* Set the current data connection mode to
*
* @param host The passive mode server accepting connections for data
* transfers.
* @param port The passive mode server's data port.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean enterRemoteActiveMode(InetAddress host, int port)
throws IOException
{
if (FTPReply.isPositiveCompletion(port(host, port)))
{
__dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
__passiveHost = null;
__passivePort = -1;
return true;
}
return false;
}
/***
* Set the current data connection mode to
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean enterRemotePassiveMode() throws IOException
{
if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
return false;
__dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
__parsePassiveModeReply(_replyLines.get(0));
return true;
}
/***
* Returns the hostname or IP address (in the form of a string) returned
* by the server when entering passive mode. If not in passive mode,
* returns null. This method only returns a valid value AFTER a
* data connection has been opened after a call to
* {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
* This is because FTPClient sends a PASV command to the server only
* just before opening a data connection, and not when you call
* {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
*
* @return The passive host name if in passive mode, otherwise null.
***/
public String getPassiveHost()
{
return __passiveHost;
}
/***
* If in passive mode, returns the data port of the passive host.
* This method only returns a valid value AFTER a
* data connection has been opened after a call to
* {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
* This is because FTPClient sends a PASV command to the server only
* just before opening a data connection, and not when you call
* {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
*
* @return The data port of the passive server. If not in passive
* mode, undefined.
***/
public int getPassivePort()
{
return __passivePort;
}
/***
* Returns the current data connection mode (one of the
*
* @return The current data connection mode (one of the
*
* @return The client port for active mode.
*/
private int getActivePort()
{
if (__activeMinPort > 0 && __activeMaxPort >= __activeMinPort)
{
if (__activeMaxPort == __activeMinPort)
return __activeMaxPort;
// Get a random port between the min and max port range
return __random.nextInt(__activeMaxPort - __activeMinPort + 1) + __activeMinPort;
}
else
{
// default port
return 0;
}
}
/**
* Get the host address for active mode.
*
* @return The host address for active mode.
*/
private InetAddress getHostAddress()
{
if (__activeExternalHost != null)
{
return __activeExternalHost;
}
else
{
// default local address
return getLocalAddress();
}
}
/***
* Set the client side port range in active mode.
*
* @param minPort The lowest available port (inclusive).
* @param maxPort The highest available port (inclusive).
* @since 2.2
***/
public void setActivePortRange(int minPort, int maxPort)
{
this.__activeMinPort = minPort;
this.__activeMaxPort = maxPort;
}
/***
* Set the external IP address in active mode.
* Useful when there are multiple network cards.
*
* @param ipAddress The external IP address of this machine.
* @throws UnknownHostException
* @since 2.2
***/
public void setActiveExternalIPAddress(String ipAddress) throws UnknownHostException
{
this.__activeExternalHost = InetAddress.getByName(ipAddress);
}
/***
* Sets the file type to be transferred. This should be one of
*
* N.B. currently calling any connect method will reset the mode to
* ACTIVE_LOCAL_DATA_CONNECTION_MODE.
* @param fileType The
* N.B. currently calling any connect method will reset the mode to
* ACTIVE_LOCAL_DATA_CONNECTION_MODE.
*
* @param fileType The
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setFileType(int fileType, int formatOrByteSize)
throws IOException
{
if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
{
__fileType = fileType;
__fileFormat = formatOrByteSize;
return true;
}
return false;
}
/***
* Sets the file structure. The default structure is
*
* @param structure The structure of the file (one of the FTP class
*
* @param mode The new transfer mode to use (one of the FTP class
*
* @param filename The name of the file to retrieve.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean remoteRetrieve(String filename) throws IOException
{
if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
return FTPReply.isPositivePreliminary(retr(filename));
return false;
}
/***
* Initiate a server to server file transfer. This method tells the
* server to which the client is connected to store a file on
* the other server using the given filename. The other server must
* have had a
* @param filename The name to call the file that is to be stored.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean remoteStore(String filename) throws IOException
{
if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
return FTPReply.isPositivePreliminary(stor(filename));
return false;
}
/***
* Initiate a server to server file transfer. This method tells the
* server to which the client is connected to store a file on
* the other server using a unique filename based on the given filename.
* The other server must have had a
* @param filename The name on which to base the filename of the file
* that is to be stored.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean remoteStoreUnique(String filename) throws IOException
{
if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
return FTPReply.isPositivePreliminary(stou(filename));
return false;
}
/***
* Initiate a server to server file transfer. This method tells the
* server to which the client is connected to store a file on
* the other server using a unique filename.
* The other server must have had a
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean remoteStoreUnique() throws IOException
{
if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
return FTPReply.isPositivePreliminary(stou());
return false;
}
// For server to server transfers
/***
* Initiate a server to server file transfer. This method tells the
* server to which the client is connected to append to a given file on
* the other server. The other server must have had a
*
* @param filename The name of the file to be appended to, or if the
* file does not exist, the name to call the file being stored.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean remoteAppend(String filename) throws IOException
{
if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
return FTPReply.isPositivePreliminary(appe(filename));
return false;
}
/***
* There are a few FTPClient methods that do not complete the
* entire sequence of FTP commands to complete a transaction. These
* commands require some action by the programmer after the reception
* of a positive intermediate command. After the programmer's code
* completes its actions, it must call this method to receive
* the completion reply from the server and verify the success of the
* entire transaction.
*
* For example,
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean completePendingCommand() throws IOException
{
return FTPReply.isPositiveCompletion(getReply());
}
/***
* Retrieves a named file from the server and writes it to the given
* OutputStream. This method does NOT close the given OutputStream.
* If the current file type is ASCII, line separators in the file are
* converted to the local representation.
*
* Note: if you have used {@link #setRestartOffset(long)},
* the file data will start from the selected offset.
* @param remote The name of the remote file.
* @param local The local OutputStream to which to write the file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception CopyStreamException If an I/O error occurs while actually
* transferring the file. The CopyStreamException allows you to
* determine the number of bytes transferred and the IOException
* causing the error. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean retrieveFile(String remote, OutputStream local)
throws IOException
{
InputStream input;
Socket socket;
if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
return false;
input = new BufferedInputStream(socket.getInputStream(),
getBufferSize());
if (__fileType == ASCII_FILE_TYPE)
input = new FromNetASCIIInputStream(input);
// Treat everything else as binary for now
try
{
Util.copyStream(input, local, getBufferSize(),
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
false);
}
catch (IOException e)
{
try
{
socket.close();
}
catch (IOException f)
{}
throw e;
}
socket.close();
return completePendingCommand();
}
/***
* Returns an InputStream from which a named file from the server
* can be read. If the current file type is ASCII, the returned
* InputStream will convert line separators in the file to
* the local representation. You must close the InputStream when you
* finish reading from it. The InputStream itself will take care of
* closing the parent data connection socket upon being closed. To
* finalize the file transfer you must call
* {@link #completePendingCommand completePendingCommand } and
* check its return value to verify success.
*
* Note: if you have used {@link #setRestartOffset(long)},
* the file data will start from the selected offset.
*
* @param remote The name of the remote file.
* @return An InputStream from which the remote file can be read. If
* the data connection cannot be opened (e.g., the file does not
* exist), null is returned (in which case you may check the reply
* code to determine the exact reason for failure).
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public InputStream retrieveFileStream(String remote) throws IOException
{
InputStream input;
Socket socket;
if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
return null;
input = socket.getInputStream();
if (__fileType == ASCII_FILE_TYPE) {
// We buffer ascii transfers because the buffering has to
// be interposed between FromNetASCIIOutputSream and the underlying
// socket input stream. We don't buffer binary transfers
// because we don't want to impose a buffering policy on the
// programmer if possible. Programmers can decide on their
// own if they want to wrap the SocketInputStream we return
// for file types other than ASCII.
input = new BufferedInputStream(input,
getBufferSize());
input = new FromNetASCIIInputStream(input);
}
return new org.apache.commons.net.io.SocketInputStream(socket, input);
}
/***
* Stores a file on the server using the given name and taking input
* from the given InputStream. This method does NOT close the given
* InputStream. If the current file type is ASCII, line separators in
* the file are transparently converted to the NETASCII format (i.e.,
* you should not attempt to create a special InputStream to do this).
*
* @param remote The name to give the remote file.
* @param local The local InputStream from which to read the file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception CopyStreamException If an I/O error occurs while actually
* transferring the file. The CopyStreamException allows you to
* determine the number of bytes transferred and the IOException
* causing the error. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean storeFile(String remote, InputStream local)
throws IOException
{
return __storeFile(FTPCommand.STOR, remote, local);
}
/***
* Returns an OutputStream through which data can be written to store
* a file on the server using the given name. If the current file type
* is ASCII, the returned OutputStream will convert line separators in
* the file to the NETASCII format (i.e., you should not attempt to
* create a special OutputStream to do this). You must close the
* OutputStream when you finish writing to it. The OutputStream itself
* will take care of closing the parent data connection socket upon being
* closed. To finalize the file transfer you must call
* {@link #completePendingCommand completePendingCommand } and
* check its return value to verify success.
*
* @param remote The name to give the remote file.
* @return An OutputStream through which the remote file can be written. If
* the data connection cannot be opened (e.g., the file does not
* exist), null is returned (in which case you may check the reply
* code to determine the exact reason for failure).
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public OutputStream storeFileStream(String remote) throws IOException
{
return __storeFileStream(FTPCommand.STOR, remote);
}
/***
* Appends to a file on the server with the given name, taking input
* from the given InputStream. This method does NOT close the given
* InputStream. If the current file type is ASCII, line separators in
* the file are transparently converted to the NETASCII format (i.e.,
* you should not attempt to create a special InputStream to do this).
*
* @param remote The name of the remote file.
* @param local The local InputStream from which to read the data to
* be appended to the remote file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception CopyStreamException If an I/O error occurs while actually
* transferring the file. The CopyStreamException allows you to
* determine the number of bytes transferred and the IOException
* causing the error. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean appendFile(String remote, InputStream local)
throws IOException
{
return __storeFile(FTPCommand.APPE, remote, local);
}
/***
* Returns an OutputStream through which data can be written to append
* to a file on the server with the given name. If the current file type
* is ASCII, the returned OutputStream will convert line separators in
* the file to the NETASCII format (i.e., you should not attempt to
* create a special OutputStream to do this). You must close the
* OutputStream when you finish writing to it. The OutputStream itself
* will take care of closing the parent data connection socket upon being
* closed. To finalize the file transfer you must call
* {@link #completePendingCommand completePendingCommand } and
* check its return value to verify success.
*
* @param remote The name of the remote file.
* @return An OutputStream through which the remote file can be appended.
* If the data connection cannot be opened (e.g., the file does not
* exist), null is returned (in which case you may check the reply
* code to determine the exact reason for failure).
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public OutputStream appendFileStream(String remote) throws IOException
{
return __storeFileStream(FTPCommand.APPE, remote);
}
/***
* Stores a file on the server using a unique name derived from the
* given name and taking input
* from the given InputStream. This method does NOT close the given
* InputStream. If the current file type is ASCII, line separators in
* the file are transparently converted to the NETASCII format (i.e.,
* you should not attempt to create a special InputStream to do this).
*
* @param remote The name on which to base the unique name given to
* the remote file.
* @param local The local InputStream from which to read the file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception CopyStreamException If an I/O error occurs while actually
* transferring the file. The CopyStreamException allows you to
* determine the number of bytes transferred and the IOException
* causing the error. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean storeUniqueFile(String remote, InputStream local)
throws IOException
{
return __storeFile(FTPCommand.STOU, remote, local);
}
/***
* Returns an OutputStream through which data can be written to store
* a file on the server using a unique name derived from the given name.
* If the current file type
* is ASCII, the returned OutputStream will convert line separators in
* the file to the NETASCII format (i.e., you should not attempt to
* create a special OutputStream to do this). You must close the
* OutputStream when you finish writing to it. The OutputStream itself
* will take care of closing the parent data connection socket upon being
* closed. To finalize the file transfer you must call
* {@link #completePendingCommand completePendingCommand } and
* check its return value to verify success.
*
* @param remote The name on which to base the unique name given to
* the remote file.
* @return An OutputStream through which the remote file can be written. If
* the data connection cannot be opened (e.g., the file does not
* exist), null is returned (in which case you may check the reply
* code to determine the exact reason for failure).
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public OutputStream storeUniqueFileStream(String remote) throws IOException
{
return __storeFileStream(FTPCommand.STOU, remote);
}
/**
* Stores a file on the server using a unique name assigned by the
* server and taking input from the given InputStream. This method does
* NOT close the given
* InputStream. If the current file type is ASCII, line separators in
* the file are transparently converted to the NETASCII format (i.e.,
* you should not attempt to create a special InputStream to do this).
*
* @param local The local InputStream from which to read the file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception CopyStreamException If an I/O error occurs while actually
* transferring the file. The CopyStreamException allows you to
* determine the number of bytes transferred and the IOException
* causing the error. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public boolean storeUniqueFile(InputStream local) throws IOException
{
return __storeFile(FTPCommand.STOU, null, local);
}
/**
* Returns an OutputStream through which data can be written to store
* a file on the server using a unique name assigned by the server.
* If the current file type
* is ASCII, the returned OutputStream will convert line separators in
* the file to the NETASCII format (i.e., you should not attempt to
* create a special OutputStream to do this). You must close the
* OutputStream when you finish writing to it. The OutputStream itself
* will take care of closing the parent data connection socket upon being
* closed. To finalize the file transfer you must call
* {@link #completePendingCommand completePendingCommand } and
* check its return value to verify success.
*
* @return An OutputStream through which the remote file can be written. If
* the data connection cannot be opened (e.g., the file does not
* exist), null is returned (in which case you may check the reply
* code to determine the exact reason for failure).
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public OutputStream storeUniqueFileStream() throws IOException
{
return __storeFileStream(FTPCommand.STOU, null);
}
/***
* Reserve a number of bytes on the server for the next file transfer.
*
* @param bytes The number of bytes which the server should allocate.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean allocate(int bytes) throws IOException
{
return FTPReply.isPositiveCompletion(allo(bytes));
}
/**
* Query the server for supported features. The server may reply with a list of server-supported exensions.
* For example, a typical client-server interaction might be (from RFC 2289):
*
* @param bytes The number of bytes which the server should allocate.
* @param recordSize The size of a file record.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public boolean allocate(int bytes, int recordSize) throws IOException
{
return FTPReply.isPositiveCompletion(allo(bytes, recordSize));
}
/***
* Restart a
* @param offset The offset into the remote file at which to start the
* next file transfer.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
private boolean restart(long offset) throws IOException
{
__restartOffset = 0;
return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));
}
/***
* Sets the restart offset. The restart command is sent to the server
* only before sending the file transfer command. When this is done,
* the restart marker is reset to zero.
*
* @param offset The offset into the remote file at which to start the
* next file transfer. This must be a value greater than or
* equal to zero.
***/
public void setRestartOffset(long offset)
{
if (offset >= 0)
__restartOffset = offset;
}
/***
* Fetches the restart offset.
*
* @return offset The offset into the remote file at which to start the
* next file transfer.
***/
public long getRestartOffset()
{
return __restartOffset;
}
/***
* Renames a remote file.
*
* @param from The name of the remote file to rename.
* @param to The new name of the remote file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean rename(String from, String to) throws IOException
{
if (!FTPReply.isPositiveIntermediate(rnfr(from)))
return false;
return FTPReply.isPositiveCompletion(rnto(to));
}
/***
* Abort a transfer in progress.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean abort() throws IOException
{
return FTPReply.isPositiveCompletion(abor());
}
/***
* Deletes a file on the FTP server.
*
* @param pathname The pathname of the file to be deleted.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean deleteFile(String pathname) throws IOException
{
return FTPReply.isPositiveCompletion(dele(pathname));
}
/***
* Removes a directory on the FTP server (if empty).
*
* @param pathname The pathname of the directory to remove.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean removeDirectory(String pathname) throws IOException
{
return FTPReply.isPositiveCompletion(rmd(pathname));
}
/***
* Creates a new subdirectory on the FTP server in the current directory
* (if a relative pathname is given) or where specified (if an absolute
* pathname is given).
*
* @param pathname The pathname of the directory to create.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean makeDirectory(String pathname) throws IOException
{
return FTPReply.isPositiveCompletion(mkd(pathname));
}
/***
* Returns the pathname of the current working directory.
*
* @return The pathname of the current working directory. If it cannot
* be obtained, returns null.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String printWorkingDirectory() throws IOException
{
if (pwd() != FTPReply.PATHNAME_CREATED)
return null;
return __parsePathname(_replyLines.get( _replyLines.size() - 1));
}
/**
* Send a site specific command.
* @param arguments The site specific command and arguments.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public boolean sendSiteCommand(String arguments) throws IOException
{
return FTPReply.isPositiveCompletion(site(arguments));
}
/***
* Fetches the system type name from the server and returns the string.
* This value is cached for the duration of the connection after the
* first call to this method. In other words, only the first time
* that you invoke this method will it issue a SYST command to the
* FTP server. FTPClient will remember the value and return the
* cached value until a call to disconnect.
*
* @return The system type name obtained from the server. null if the
* information could not be obtained.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @deprecated Use {@link #getSystemType()} - which does not return null.
* Will be deleted in version 3.0
***/
@Deprecated
public String getSystemName() throws IOException
{
//if (syst() == FTPReply.NAME_SYSTEM_TYPE)
// Technically, we should expect a NAME_SYSTEM_TYPE response, but
// in practice FTP servers deviate, so we soften the condition to
// a positive completion.
if (__systemName == null && FTPReply.isPositiveCompletion(syst()))
__systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
return __systemName;
}
/***
* Fetches the system type from the server and returns the string.
* This value is cached for the duration of the connection after the
* first call to this method. In other words, only the first time
* that you invoke this method will it issue a SYST command to the
* FTP server. FTPClient will remember the value and return the
* cached value until a call to disconnect.
*
* @return The system type obtained from the server. Never null.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @since 2.2
***/
public String getSystemType() throws IOException
{
//if (syst() == FTPReply.NAME_SYSTEM_TYPE)
// Technically, we should expect a NAME_SYSTEM_TYPE response, but
// in practice FTP servers deviate, so we soften the condition to
// a positive completion.
if (__systemName == null){
if (FTPReply.isPositiveCompletion(syst())) {
// Assume that response is not empty here (cannot be null)
__systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
} else {
throw new IOException("Unable to determine system type - response: " + getReplyString());
}
}
return __systemName;
}
/***
* Fetches the system help information from the server and returns the
* full string.
*
* @return The system help string obtained from the server. null if the
* information could not be obtained.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String listHelp() throws IOException
{
if (FTPReply.isPositiveCompletion(help()))
return getReplyString();
return null;
}
/**
* Fetches the help information for a given command from the server and
* returns the full string.
* @param command The command on which to ask for help.
* @return The command help string obtained from the server. null if the
* information could not be obtained.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
*/
public String listHelp(String command) throws IOException
{
if (FTPReply.isPositiveCompletion(help(command)))
return getReplyString();
return null;
}
/***
* Sends a NOOP command to the FTP server. This is useful for preventing
* server timeouts.
*
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean sendNoOp() throws IOException
{
return FTPReply.isPositiveCompletion(noop());
}
/***
* Obtain a list of filenames in a directory (or just the name of a given
* file, which is not particularly useful). This information is obtained
* through the NLST command. If the given pathname is a directory and
* contains no files, a zero length array is returned only
* if the FTP server returned a positive completion code, otherwise
* null is returned (the FTP server returned a 550 error No files found.).
* If the directory is not empty, an array of filenames in the directory is
* returned. If the pathname corresponds
* to a file, only that file will be listed. The server may or may not
* expand glob expressions.
*
* @param pathname The file or directory to list.
* @return The list of filenames contained in the given path. null if
* the list could not be obtained. If there are no filenames in
* the directory, a zero-length array is returned.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String[] listNames(String pathname) throws IOException
{
String line;
Socket socket;
BufferedReader reader;
ArrayList
* @return The list of filenames contained in the current working
* directory. null if the list could not be obtained.
* If there are no filenames in the directory, a zero-length array
* is returned.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String[] listNames() throws IOException
{
return listNames(null);
}
/**
* Using the default system autodetect mechanism, obtain a
* list of file information for the current working directory
* or for just a single file.
*
* This information is obtained through the LIST command. The contents of
* the returned array is determined by the
* @param pathname The file or directory to list. Since the server may
* or may not expand glob expressions, using them here
* is not recommended and may well cause this method to
* fail.
*
* @return The list of file information contained in the given path in
* the format determined by the autodetection mechanism
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection
* as a result of the client being idle or some other
* reason causing the server to send FTP reply code 421.
* This exception may be caught either as an IOException
* or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply
* from the server.
* @exception ParserInitializationException
* Thrown if the parserKey parameter cannot be
* resolved by the selected parser factory.
* In the DefaultFTPEntryParserFactory, this will
* happen when parserKey is neither
* the fully qualified class name of a class
* implementing the interface
* org.apache.commons.net.ftp.FTPFileEntryParser
* nor a string containing one of the recognized keys
* mapping to such a parser or if class loader
* security issues prevent its being loaded.
* @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
* @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
* @see org.apache.commons.net.ftp.FTPFileEntryParser
*/
public FTPFile[] listFiles(String pathname)
throws IOException
{
String key = null;
FTPListParseEngine engine =
initiateListParsing(key, pathname);
return engine.getFiles();
}
/**
* Using the default system autodetect mechanism, obtain a
* list of file information for the current working directory.
*
* This information is obtained through the LIST command. The contents of
* the returned array is determined by the
* @return The list of file information contained in the current directory
* in the format determined by the autodetection mechanism.
*
* NOTE: This array may contain null members if any of the
* individual file listings failed to parse. The caller should
* check each entry for null before referencing it.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection
* as a result of the client being idle or some other
* reason causing the server to send FTP reply code 421.
* This exception may be caught either as an IOException
* or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply
* from the server.
* @exception ParserInitializationException
* Thrown if the parserKey parameter cannot be
* resolved by the selected parser factory.
* In the DefaultFTPEntryParserFactory, this will
* happen when parserKey is neither
* the fully qualified class name of a class
* implementing the interface
* org.apache.commons.net.ftp.FTPFileEntryParser
* nor a string containing one of the recognized keys
* mapping to such a parser or if class loader
* security issues prevent its being loaded.
* @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
* @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
* @see org.apache.commons.net.ftp.FTPFileEntryParser
*/
public FTPFile[] listFiles()
throws IOException
{
return listFiles((String) null);
}
/**
* Version of {@link #listFiles(String)} which allows a filter to be provided.
* For example:
* This method differs from using the listFiles() methods in that
* expensive FTPFile objects are not created until needed which may be
* an advantage on large lists.
*
* @return A FTPListParseEngine object that holds the raw information and
* is capable of providing parsed FTPFile objects, one for each file
* containing information contained in the given path in the format
* determined by the
* The server may or may not expand glob expressions. You should avoid
* using glob expressions because the return format for glob listings
* differs from server to server and will likely cause this method to fail.
*
* This method differs from using the listFiles() methods in that
* expensive FTPFile objects are not created until needed which may be
* an advantage on large lists.
*
*
* The server may or may not expand glob expressions. You should avoid
* using glob expressions because the return format for glob listings
* differs from server to server and will likely cause this method to fail.
*
* This method differs from using the listFiles() methods in that
* expensive FTPFile objects are not created until needed which may be
* an advantage on large lists.
*
* @param parserKey A string representing a designated code or fully-qualified
* class name of an
* @return The status information returned by the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String getStatus() throws IOException
{
if (FTPReply.isPositiveCompletion(stat()))
return getReplyString();
return null;
}
/***
* Issue the FTP STAT command to the server for a given pathname. This
* should produce a listing of the file or directory.
*
* @return The status information returned by the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public String getStatus(String pathname) throws IOException
{
if (FTPReply.isPositiveCompletion(stat(pathname)))
return getReplyString();
return null;
}
/**
* Issue the FTP MDTM command (not supported by all servers to retrieve the last
* modification time of a file. The modification string should be in the
* ISO 3077 form "YYYYMMDDhhmmss(.xxx)?". The timestamp represented should also be in
* GMT, but not all FTP servers honour this.
*
* @param pathname The file path to query.
* @return A string representing the last file modification time in
* To derive the full benefits of the FTP class requires some knowledge
* of the FTP protocol defined in RFC 959. However, there is no reason
* why you should have to use the FTP class. The
* {@link org.apache.commons.net.ftp.FTPClient} class,
* derived from FTP,
* implements all the functionality required of an FTP client. The
* FTP class is made public to provide access to various FTP constants
* and to make it easier for adventurous programmers (or those with
* special needs) to interact with the FTP protocol and implement their
* own clients. A set of methods with names corresponding to the FTP
* command names are provided to facilitate this interaction.
*
* You should keep in mind that the FTP server may choose to prematurely
* close a connection if the client has been idle for longer than a
* given time period (usually 900 seconds). The FTP class will detect a
* premature FTP server connection closing when it receives a
* {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
* response to a command.
* When that occurs, the FTP class method encountering that reply will throw
* an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
* .
* Rather than list it separately for each method, we mention here that
* every method communicating with the server and throwing an IOException
* can also throw a
* {@link org.apache.commons.net.MalformedServerReplyException}
* , which is a subclass
* of IOException. A MalformedServerReplyException will be thrown when
* the reply received from the server deviates enough from the protocol
* specification that it cannot be interpreted in a useful manner despite
* attempts to be as lenient as possible.
*
*
* @author Daniel F. Savarese
* @author Rory Winston
* @author Joseph Hindsley
* @see FTPClient
* @see FTPConnectionClosedException
* @see org.apache.commons.net.MalformedServerReplyException
* @version $Id: FTP.java 1032954 2010-11-09 12:15:10Z sebb $
***/
public class FTP extends SocketClient
{
/*** The default FTP data port (20). ***/
public static final int DEFAULT_DATA_PORT = 20;
/*** The default FTP control port (21). ***/
public static final int DEFAULT_PORT = 21;
/***
* A constant used to indicate the file(s) being transfered should
* be treated as ASCII. This is the default file type. All constants
* ending in
* @param listener The ProtocolCommandListener to add.
***/
public void addProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.addProtocolCommandListener(listener);
}
/***
* Removes a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
*
* @param listener The ProtocolCommandListener to remove.
***/
public void removeProtocolCommandListener(ProtocolCommandListener listener)
{
_commandSupport_.removeProtocolCommandListener(listener);
}
/***
* Closes the control connection to the FTP server and sets to null
* some internal data so that the memory may be reclaimed by the
* garbage collector. The reply text and code information from the
* last command is voided so that the memory it used may be reclaimed.
* Also sets {@link #_controlInput_} and {@link #_controlOutput_} to null.
*
* @exception IOException If an error occurs while disconnecting.
***/
@Override
public void disconnect() throws IOException
{
super.disconnect();
_controlInput_ = null;
_controlOutput_ = null;
_newReplyString = false;
_replyString = null;
}
/***
* Sends an FTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The text representation of the FTP command to send.
* @param args The arguments to the FTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command, String args) throws IOException
{
String message;
__commandBuffer.setLength(0);
__commandBuffer.append(command);
if (args != null)
{
__commandBuffer.append(' ');
__commandBuffer.append(args);
}
__commandBuffer.append(SocketClient.NETASCII_EOL);
if (_controlOutput_ == null){
throw new IOException("Connection is not open");
}
try{
_controlOutput_.write(message = __commandBuffer.toString());
_controlOutput_.flush();
}
catch (SocketException e)
{
if (!isConnected() || !socketIsConnected(_socket_))
{
throw new FTPConnectionClosedException("Connection unexpectedly closed.");
}
else
{
throw e;
}
}
if (_commandSupport_.getListenerCount() > 0)
_commandSupport_.fireCommandSent(command, message);
__getReply();
return _replyCode;
}
/**
* Checks if the socket is connected
*
* @param socket
* @return true if connected
*/
private boolean socketIsConnected(Socket socket)
{
if (socket == null)
{
return false;
}
return socket.isConnected();
}
/***
* Sends an FTP command to the server, waits for a reply and returns the
* numerical response code. After invocation, for more detailed
* information, the actual reply text can be accessed by calling
* {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The FTPCommand constant corresponding to the FTP command
* to send.
* @param args The arguments to the FTP command. If this parameter is
* set to null, then the command is sent with no argument.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command, String args) throws IOException
{
return sendCommand(FTPCommand.getCommand(command), args);
}
/***
* Sends an FTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The text representation of the FTP command to send.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(String command) throws IOException
{
return sendCommand(command, null);
}
/***
* Sends an FTP command with no arguments to the server, waits for a
* reply and returns the numerical response code. After invocation, for
* more detailed information, the actual reply text can be accessed by
* calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }.
*
* @param command The FTPCommand constant corresponding to the FTP command
* to send.
* @return The integer value of the FTP reply code returned by the server
* in response to the command.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int sendCommand(int command) throws IOException
{
return sendCommand(command, null);
}
/***
* Returns the integer value of the reply code of the last FTP reply.
* You will usually only use this method after you connect to the
* FTP server to check that the connection was successful since
*
* @return The integer value of the reply code of the last FTP reply.
***/
public int getReplyCode()
{
return _replyCode;
}
/***
* Fetches a reply from the FTP server and returns the integer reply
* code. After calling this method, the actual reply text can be accessed
* from either calling {@link #getReplyString getReplyString } or
* {@link #getReplyStrings getReplyStrings }. Only use this
* method if you are implementing your own FTP client or if you need to
* fetch a secondary response from the FTP server.
*
* @return The integer value of the reply code of the fetched FTP reply.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while receiving the
* server reply.
***/
public int getReply() throws IOException
{
__getReply();
return _replyCode;
}
/***
* Returns the lines of text from the last FTP server response as an array
* of strings, one entry per line. The end of line markers of each are
* stripped from each line.
*
* @return The lines of text from the last FTP response as an array.
***/
public String[] getReplyStrings()
{
return _replyLines.toArray(new String[_replyLines.size()]);
}
/***
* Returns the entire text of the last FTP server response exactly
* as it was received, including all end of line markers in NETASCII
* format.
*
* @return The entire text from the last FTP response as a String.
***/
public String getReplyString()
{
StringBuilder buffer;
if (!_newReplyString) {
return _replyString;
}
buffer = new StringBuilder(256);
for (String line : _replyLines) {
buffer.append(line);
buffer.append(SocketClient.NETASCII_EOL);
}
_newReplyString = false;
return (_replyString = buffer.toString());
}
/***
* A convenience method to send the FTP USER command to the server,
* receive the reply, and return the reply code.
*
* @param username The username to login under.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int user(String username) throws IOException
{
return sendCommand(FTPCommand.USER, username);
}
/**
* A convenience method to send the FTP PASS command to the server,
* receive the reply, and return the reply code.
* @param password The plain text password of the username being logged into.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int pass(String password) throws IOException
{
return sendCommand(FTPCommand.PASS, password);
}
/***
* A convenience method to send the FTP ACCT command to the server,
* receive the reply, and return the reply code.
*
* @param account The account name to access.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int acct(String account) throws IOException
{
return sendCommand(FTPCommand.ACCT, account);
}
/***
* A convenience method to send the FTP ABOR command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int abor() throws IOException
{
return sendCommand(FTPCommand.ABOR);
}
/***
* A convenience method to send the FTP CWD command to the server,
* receive the reply, and return the reply code.
*
* @param directory The new working directory.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int cwd(String directory) throws IOException
{
return sendCommand(FTPCommand.CWD, directory);
}
/***
* A convenience method to send the FTP CDUP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int cdup() throws IOException
{
return sendCommand(FTPCommand.CDUP);
}
/***
* A convenience method to send the FTP QUIT command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int quit() throws IOException
{
return sendCommand(FTPCommand.QUIT);
}
/***
* A convenience method to send the FTP REIN command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rein() throws IOException
{
return sendCommand(FTPCommand.REIN);
}
/***
* A convenience method to send the FTP SMNT command to the server,
* receive the reply, and return the reply code.
*
* @param dir The directory name.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int smnt(String dir) throws IOException
{
return sendCommand(FTPCommand.SMNT, dir);
}
/***
* A convenience method to send the FTP PORT command to the server,
* receive the reply, and return the reply code.
*
* @param host The host owning the port.
* @param port The new port.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int port(InetAddress host, int port) throws IOException
{
int num;
StringBuilder info = new StringBuilder(24);
info.append(host.getHostAddress().replace('.', ','));
num = port >>> 8;
info.append(',');
info.append(num);
info.append(',');
num = port & 0xff;
info.append(num);
return sendCommand(FTPCommand.PORT, info.toString());
}
/***
* A convenience method to send the FTP EPRT command to the server,
* receive the reply, and return the reply code.
*
* Examples:
*
* @see "http://www.faqs.org/rfcs/rfc2428.html"
*
* @param host The host owning the port.
* @param port The new port.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
***/
public int eprt(InetAddress host, int port) throws IOException
{
int num;
StringBuilder info = new StringBuilder();
String h;
// If IPv6, trim the zone index
h = host.getHostAddress();
num = h.indexOf("%");
if (num > 0)
h = h.substring(0, num);
info.append("|");
if (host instanceof Inet4Address)
info.append("1");
else if (host instanceof Inet6Address)
info.append("2");
info.append("|");
info.append(h);
info.append("|");
info.append(port);
info.append("|");
return sendCommand(FTPCommand.EPRT, info.toString());
}
/***
* A convenience method to send the FTP PASV command to the server,
* receive the reply, and return the reply code. Remember, it's up
* to you to interpret the reply string containing the host/port
* information.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int pasv() throws IOException
{
return sendCommand(FTPCommand.PASV);
}
/***
* A convenience method to send the FTP EPSV command to the server,
* receive the reply, and return the reply code. Remember, it's up
* to you to interpret the reply string containing the host/port
* information.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
***/
public int epsv() throws IOException
{
return sendCommand(FTPCommand.EPSV);
}
/**
* A convenience method to send the FTP TYPE command for text files
* to the server, receive the reply, and return the reply code.
* @param fileType The type of the file (one of the
* @param fileType The type of the file (one of the
* @param structure The structure of the file (one of the
*
* @param mode The transfer mode to use (one of the
*
* @param pathname The pathname of the file to retrieve.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int retr(String pathname) throws IOException
{
return sendCommand(FTPCommand.RETR, pathname);
}
/***
* A convenience method to send the FTP STOR command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @param pathname The pathname to use for the file when stored at
* the remote end of the transfer.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stor(String pathname) throws IOException
{
return sendCommand(FTPCommand.STOR, pathname);
}
/***
* A convenience method to send the FTP STOU command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stou() throws IOException
{
return sendCommand(FTPCommand.STOU);
}
/***
* A convenience method to send the FTP STOU command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
* @param pathname The base pathname to use for the file when stored at
* the remote end of the transfer. Some FTP servers
* require this.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int stou(String pathname) throws IOException
{
return sendCommand(FTPCommand.STOU, pathname);
}
/***
* A convenience method to send the FTP APPE command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @param pathname The pathname to use for the file when stored at
* the remote end of the transfer.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int appe(String pathname) throws IOException
{
return sendCommand(FTPCommand.APPE, pathname);
}
/***
* A convenience method to send the FTP ALLO command to the server,
* receive the reply, and return the reply code.
*
* @param bytes The number of bytes to allocate.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int allo(int bytes) throws IOException
{
return sendCommand(FTPCommand.ALLO, Integer.toString(bytes));
}
/**
* A convenience method to send the FTP FEAT command to the server, receive the reply,
* and return the reply code.
* @return The reply code received by the server
* @throws IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
*/
public int feat() throws IOException
{
return sendCommand(FTPCommand.FEAT);
}
/***
* A convenience method to send the FTP ALLO command to the server,
* receive the reply, and return the reply code.
*
* @param bytes The number of bytes to allocate.
* @param recordSize The size of a record.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int allo(int bytes, int recordSize) throws IOException
{
return sendCommand(FTPCommand.ALLO, Integer.toString(bytes) + " R " +
Integer.toString(recordSize));
}
/***
* A convenience method to send the FTP REST command to the server,
* receive the reply, and return the reply code.
*
* @param marker The marker at which to restart a transfer.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rest(String marker) throws IOException
{
return sendCommand(FTPCommand.REST, marker);
}
/**
* @since 2.0
**/
public int mdtm(String file) throws IOException
{
return sendCommand(FTPCommand.MDTM, file);
}
/**
* A convenience method to send the FTP MFMT command to the server,
* receive the reply, and return the reply code.
*
* @param pathname The pathname for which mtime is to be changed
* @param timeval Timestamp in
* @param pathname The pathname to rename from.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rnfr(String pathname) throws IOException
{
return sendCommand(FTPCommand.RNFR, pathname);
}
/***
* A convenience method to send the FTP RNTO command to the server,
* receive the reply, and return the reply code.
*
* @param pathname The pathname to rename to
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rnto(String pathname) throws IOException
{
return sendCommand(FTPCommand.RNTO, pathname);
}
/***
* A convenience method to send the FTP DELE command to the server,
* receive the reply, and return the reply code.
*
* @param pathname The pathname to delete.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int dele(String pathname) throws IOException
{
return sendCommand(FTPCommand.DELE, pathname);
}
/***
* A convenience method to send the FTP RMD command to the server,
* receive the reply, and return the reply code.
*
* @param pathname The pathname of the directory to remove.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int rmd(String pathname) throws IOException
{
return sendCommand(FTPCommand.RMD, pathname);
}
/***
* A convenience method to send the FTP MKD command to the server,
* receive the reply, and return the reply code.
*
* @param pathname The pathname of the new directory to create.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int mkd(String pathname) throws IOException
{
return sendCommand(FTPCommand.MKD, pathname);
}
/***
* A convenience method to send the FTP PWD command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int pwd() throws IOException
{
return sendCommand(FTPCommand.PWD);
}
/***
* A convenience method to send the FTP LIST command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int list() throws IOException
{
return sendCommand(FTPCommand.LIST);
}
/***
* A convenience method to send the FTP LIST command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @param pathname The pathname to list.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int list(String pathname) throws IOException
{
return sendCommand(FTPCommand.LIST, pathname);
}
/***
* A convenience method to send the FTP NLST command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int nlst() throws IOException
{
return sendCommand(FTPCommand.NLST);
}
/***
* A convenience method to send the FTP NLST command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
*
* @param pathname The pathname to list.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int nlst(String pathname) throws IOException
{
return sendCommand(FTPCommand.NLST, pathname);
}
/***
* A convenience method to send the FTP SITE command to the server,
* receive the reply, and return the reply code.
*
* @param parameters The site parameters to send.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int site(String parameters) throws IOException
{
return sendCommand(FTPCommand.SITE, parameters);
}
/***
* A convenience method to send the FTP SYST command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int syst() throws IOException
{
return sendCommand(FTPCommand.SYST);
}
/***
* A convenience method to send the FTP STAT command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat() throws IOException
{
return sendCommand(FTPCommand.STAT);
}
/***
* A convenience method to send the FTP STAT command to the server,
* receive the reply, and return the reply code.
*
* @param pathname A pathname to list.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stat(String pathname) throws IOException
{
return sendCommand(FTPCommand.STAT, pathname);
}
/***
* A convenience method to send the FTP HELP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help() throws IOException
{
return sendCommand(FTPCommand.HELP);
}
/***
* A convenience method to send the FTP HELP command to the server,
* receive the reply, and return the reply code.
*
* @param command The command name on which to request help.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int help(String command) throws IOException
{
return sendCommand(FTPCommand.HELP, command);
}
/***
* A convenience method to send the FTP NOOP command to the server,
* receive the reply, and return the reply code.
*
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int noop() throws IOException
{
return sendCommand(FTPCommand.NOOP);
}
/**
* Return whether strict multiline parsing is enabled, as per RFC 959, section 4.2.
* @return True if strict, false if lenient
* @since 2.0
*/
public boolean isStrictMultilineParsing() {
return strictMultilineParsing;
}
/**
* Set strict multiline parsing.
* @param strictMultilineParsing
* @since 2.0
*/
public void setStrictMultilineParsing(boolean strictMultilineParsing) {
this.strictMultilineParsing = strictMultilineParsing;
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPSClient.java 0000644 0001750 0001750 00000047510 11446141442 026036 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
/**
* FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all can be used to
* see wire-level SSL details.
*
* @version $Id: FTPSClient.java 999437 2010-09-21 14:37:22Z sebb $
* @since 2.0
*/
public class FTPSClient extends FTPClient {
/** @deprecated - not used - will be removed in next major release */
@Deprecated
public static String KEYSTORE_ALGORITHM;
/** @deprecated - not used - will be removed in next major release */
@Deprecated
public static String TRUSTSTORE_ALGORITHM;
/** @deprecated - not used - will be removed in next major release */
@Deprecated
public static String PROVIDER;
/** @deprecated - not used - will be removed in next major release */
@Deprecated
public static String STORE_TYPE;
/** The value that I can set in PROT command (C = Clear, P = Protected) */
private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"};
/** Default PROT Command */
private static final String DEFAULT_PROT = "C";
/** Default secure socket protocol name, i.e. TLS */
private static final String DEFAULT_PROTOCOL = "TLS";
/** The security mode. (True - Implicit Mode / False - Explicit Mode) */
private final boolean isImplicit;
/** The secure socket protocol to be used, e.g. SSL/TLS. */
private final String protocol;
/** The AUTH Command value */
private String auth = DEFAULT_PROTOCOL;
/** The context object. */
private SSLContext context;
/** The socket object. */
private Socket plainSocket;
/** The established socket flag. */
private boolean isCreation = true;
/** The use client mode flag. */
private boolean isClientMode = true;
/** The need client auth flag. */
private boolean isNeedClientAuth = false;
/** The want client auth flag. */
private boolean isWantClientAuth = false;
/** The cipher suites */
private String[] suites = null;
/** The protocol versions */
private String[] protocols = null;
/** The FTPS {@link TrustManager} implementation. */
private TrustManager trustManager = new FTPSTrustManager();
/** The {@link KeyManager} */
private KeyManager keyManager;
/**
* Constructor for FTPSClient.
* Sets security mode to explicit (isImplicit = false)
* @throws NoSuchAlgorithmException A requested cryptographic algorithm
* is not available in the environment.
*/
public FTPSClient() throws NoSuchAlgorithmException {
this.protocol = DEFAULT_PROTOCOL;
this.isImplicit = false;
}
/**
* Constructor for FTPSClient.
* @param isImplicit The security mode (Implicit/Explicit).
* @throws NoSuchAlgorithmException A requested cryptographic algorithm
* is not available in the environment.
*/
public FTPSClient(boolean isImplicit) throws NoSuchAlgorithmException {
this.protocol = DEFAULT_PROTOCOL;
this.isImplicit = isImplicit;
}
/**
* Constructor for FTPSClient.
* @param protocol the protocol
* @throws NoSuchAlgorithmException A requested cryptographic algorithm
* is not available in the environment.
*/
public FTPSClient(String protocol) throws NoSuchAlgorithmException {
this.protocol = protocol;
this.isImplicit = false;
}
/**
* Constructor for FTPSClient.
* @param protocol the protocol
* @param isImplicit The security mode(Implicit/Explicit).
* @throws NoSuchAlgorithmException A requested cryptographic algorithm
* is not available in the environment.
*/
public FTPSClient(String protocol, boolean isImplicit)
throws NoSuchAlgorithmException {
this.protocol = protocol;
this.isImplicit = isImplicit;
}
/**
* Constructor for FTPSClient.
* @param isImplicit The security mode(Implicit/Explicit).
* @param context A pre-configured SSL Context
*/
public FTPSClient(boolean isImplicit, SSLContext context) {
this.isImplicit = isImplicit;
this.context = context;
this.protocol = DEFAULT_PROTOCOL;
}
/**
* Constructor for FTPSClient.
* @param context A pre-configured SSL Context
*/
public FTPSClient(SSLContext context) {
this(false, context);
}
/**
* Set AUTH command use value.
* This processing is done before connected processing.
* @param auth AUTH command use value.
*/
public void setAuthValue(String auth) {
this.auth = auth;
}
/**
* Return AUTH command use value.
* @return AUTH command use value.
*/
public String getAuthValue() {
return this.auth;
}
/**
* Because there are so many connect() methods,
* the _connectAction_() method is provided as a means of performing
* some action immediately after establishing a connection,
* rather than reimplementing all of the connect() methods.
* @throws IOException If it throw by _connectAction_.
* @see org.apache.commons.net.SocketClient#_connectAction_()
*/
@Override
protected void _connectAction_() throws IOException {
// Implicit mode.
if (isImplicit) sslNegotiation();
super._connectAction_();
// Explicit mode.
if (!isImplicit) {
execAUTH();
sslNegotiation();
}
}
/**
* AUTH command.
* @throws SSLException If it server reply code not equal "234" and "334".
* @throws IOException If an I/O error occurs while either sending
* the command.
*/
private void execAUTH() throws SSLException, IOException {
int replyCode = sendCommand(
FTPSCommand._commands[FTPSCommand.AUTH], auth);
if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
// replyCode = 334
// I carry out an ADAT command.
} else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
throw new SSLException(getReplyString());
}
}
/**
* Performs a lazy init of the SSL context
* @throws IOException
*/
private void initSslContext() throws IOException {
if(context == null) {
try {
context = SSLContext.getInstance(protocol);
context.init(new KeyManager[] { getKeyManager() } , new TrustManager[] { getTrustManager() } , null);
} catch (KeyManagementException e) {
IOException ioe = new IOException("Could not initialize SSL context");
ioe.initCause(e);
throw ioe;
} catch (NoSuchAlgorithmException e) {
IOException ioe = new IOException("Could not initialize SSL context");
ioe.initCause(e);
throw ioe;
}
}
}
/**
* SSL/TLS negotiation. Acquires an SSL socket of a control
* connection and carries out handshake processing.
* @throws IOException If server negotiation fails
*/
private void sslNegotiation() throws IOException {
plainSocket = _socket_;
initSslContext();
SSLSocketFactory ssf = context.getSocketFactory();
String ip = _socket_.getInetAddress().getHostAddress();
int port = _socket_.getPort();
SSLSocket socket =
(SSLSocket) ssf.createSocket(_socket_, ip, port, true);
socket.setEnableSessionCreation(isCreation);
socket.setUseClientMode(isClientMode);
// server mode
if (!isClientMode) {
socket.setNeedClientAuth(isNeedClientAuth);
socket.setWantClientAuth(isWantClientAuth);
}
if (protocols != null) socket.setEnabledProtocols(protocols);
if (suites != null) socket.setEnabledCipherSuites(suites);
socket.startHandshake();
_socket_ = socket;
_controlInput_ = new BufferedReader(new InputStreamReader(
socket .getInputStream(), getControlEncoding()));
_controlOutput_ = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream(), getControlEncoding()));
}
/**
* Get the {@link KeyManager} instance.
* @return The {@link KeyManager} instance
*/
private KeyManager getKeyManager() {
return keyManager;
}
/**
* Set a {@link KeyManager} to use
*
* @param keyManager The KeyManager implementation to set.
*/
public void setKeyManager(KeyManager keyManager) {
this.keyManager = keyManager;
}
/**
* Controls whether new a SSL session may be established by this socket.
* @param isCreation The established socket flag.
*/
public void setEnabledSessionCreation(boolean isCreation) {
this.isCreation = isCreation;
}
/**
* Returns true if new SSL sessions may be established by this socket.
* When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
* instance of {@link SSLSocket} with {@link SSLSocket}{@link #getEnableSessionCreation()}) enabled,
* this returns False.
* @return true - Indicates that sessions may be created;
* this is the default.
* false - indicates that an existing session must be resumed.
*/
public boolean getEnableSessionCreation() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getEnableSessionCreation();
return false;
}
/**
* Configures the socket to require client authentication.
* @param isNeedClientAuth The need client auth flag.
*/
public void setNeedClientAuth(boolean isNeedClientAuth) {
this.isNeedClientAuth = isNeedClientAuth;
}
/**
* Returns true if the socket will require client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
public boolean getNeedClientAuth() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getNeedClientAuth();
return false;
}
/**
* Configures the socket to request client authentication,
* but only if such a request is appropriate to the cipher
* suite negotiated.
* @param isWantClientAuth The want client auth flag.
*/
public void setWantClientAuth(boolean isWantClientAuth) {
this.isWantClientAuth = isWantClientAuth;
}
/**
* Returns true if the socket will request client authentication.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
* @return true - If the server mode socket should request
* that the client authenticate itself.
*/
public boolean getWantClientAuth() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getWantClientAuth();
return false;
}
/**
* Configures the socket to use client (or server) mode in its first
* handshake.
* @param isClientMode The use client mode flag.
*/
public void setUseClientMode(boolean isClientMode) {
this.isClientMode = isClientMode;
}
/**
* Returns true if the socket is set to use client mode
* in its first handshake.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
* @return true - If the socket should start its first handshake
* in "client" mode.
*/
public boolean getUseClientMode() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getUseClientMode();
return false;
}
/**
* Controls which particular cipher suites are enabled for use on this
* connection. Called before server negotiation.
* @param cipherSuites The cipher suites.
*/
public void setEnabledCipherSuites(String[] cipherSuites) {
suites = new String[cipherSuites.length];
System.arraycopy(cipherSuites, 0, suites, 0, cipherSuites.length);
}
/**
* Returns the names of the cipher suites which could be enabled
* for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
* @return An array of cipher suite names, or
* @param command The command code.
* @return The FTPS command string corresponding to a specified
* command code.
*/
public static final String getCommand(int command) {
return _commands[command];
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPHTTPClient.java 0000644 0001750 0001750 00000011567 11466231525 026422 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.util.Base64;
/**
* Experimental attempt at FTP client that tunnels over an HTTP proxy connection.
*
* @author rory
* @since 2.2
*/
public class FTPHTTPClient extends FTPClient {
private final String proxyHost;
private final int proxyPort;
private final String proxyUsername;
private final String proxyPassword;
private String host;
private int port;
private final byte[] CRLF;
private final Base64 base64 = new Base64();
public FTPHTTPClient(String proxyHost, int proxyPort, String proxyUser, String proxyPass) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
this.proxyUsername = proxyUser;
this.proxyPassword = proxyPass;
try {
CRLF = "\r\n".getBytes(getControlEncoding());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public FTPHTTPClient(String proxyHost, int proxyPort) {
this(proxyHost, proxyPort, null, null);
}
@Override
protected Socket _openDataConnection_(int command, String arg)
throws IOException {
Socket socket = new Socket(host, port);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
tunnelHandshake(host, port, is, os);
return socket;
}
@Override
public void connect(String host, int port) throws SocketException,
IOException {
this.host = host;
this.port = port;
_socket_ = new Socket(proxyHost, proxyPort);
_input_ = _socket_.getInputStream();
_output_ = _socket_.getOutputStream();
try {
tunnelHandshake(host, port, _input_, _output_);
}
catch (Exception e) {
IOException ioe = new IOException("Could not connect to " + host);
ioe.initCause(e);
throw ioe;
}
}
private void tunnelHandshake(String host, int port, InputStream input, OutputStream output) throws IOException,
UnsupportedEncodingException {
final String connectString = "CONNECT " + host + ":" + port + " HTTP/1.1";
_output_.write(connectString.getBytes(getControlEncoding()));
_output_.write(CRLF);
if (proxyUsername != null && proxyPassword != null) {
final String header = "Proxy-Authorization: Basic "
+ base64.encode(proxyUsername + ":" + proxyPassword) + "\r\n";
_output_.write(header.getBytes("UTF-8"));
_output_.write(CRLF);
List
* Set up the {@link FTPClientConfig#setDefaultDateFormatStr(java.lang.String) defaultDateFormat}
* and optionally the {@link FTPClientConfig#setRecentDateFormatStr(String) recentDateFormat}
* to values supplied in the config based on month names configured as follows:
*
* Finally if a {@link org.apache.commons.net.ftp.FTPClientConfig#setServerTimeZoneId(String) serverTimeZoneId}
* has been supplied via the config, set that into all date formats that have
* been configured.
*
*
* @author Winston Ojeda
* @author Stephane ESTE-GRACIAS
* @version $Id: VMSVersioningFTPEntryParser.java 999923 2010-09-22 13:03:51Z sebb $
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
*/
public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
{
private final Pattern _preparse_pattern_;
private static final String PRE_PARSE_REGEX =
"(.*);([0-9]+)\\s*.*";
/**
* Constructor for a VMSFTPEntryParser object.
*
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
*
* For now end users may specify this format only via
*
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry) {
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
boolean isDevice = false;
if (matches(entry))
{
String typeStr = group(1);
String hardLinkCount = group(15);
String usr = group(16);
String grp = group(17);
String filesize = group(18);
String datestr = group(19) + " " + group(20);
String name = group(21);
String endtoken = group(22);
try
{
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
// intentionally do nothing
}
// bcdlfmpSs-
switch (typeStr.charAt(0))
{
case 'd':
type = FTPFile.DIRECTORY_TYPE;
break;
case 'e':
type = FTPFile.SYMBOLIC_LINK_TYPE;
break;
case 'l':
type = FTPFile.SYMBOLIC_LINK_TYPE;
break;
case 'b':
case 'c':
isDevice = true;
// break; - fall through
//$FALL-THROUGH$ TODO change this if DEVICE_TYPE implemented
case 'f':
case '-':
type = FTPFile.FILE_TYPE;
break;
default:
type = FTPFile.UNKNOWN_TYPE;
}
file.setType(type);
int g = 4;
for (int access = 0; access < 3; access++, g += 4)
{
// Use != '-' to avoid having to check for suid and sticky bits
file.setPermission(access, FTPFile.READ_PERMISSION,
(!group(g).equals("-")));
file.setPermission(access, FTPFile.WRITE_PERMISSION,
(!group(g + 1).equals("-")));
String execPerm = group(g + 2);
if (!execPerm.equals("-") && !Character.isUpperCase(execPerm.charAt(0)))
{
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, true);
}
else
{
file.setPermission(access, FTPFile.EXECUTE_PERMISSION, false);
}
}
if (!isDevice)
{
try
{
file.setHardLinkCount(Integer.parseInt(hardLinkCount));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}
}
file.setUser(usr);
file.setGroup(grp);
try
{
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}
if (null == endtoken)
{
file.setName(name);
}
else
{
// oddball cases like symbolic links, file names
// with spaces in them.
name += endtoken;
if (type == FTPFile.SYMBOLIC_LINK_TYPE)
{
int end = name.indexOf(" -> ");
// Give up if no link indicator is present
if (end == -1)
{
file.setName(name);
}
else
{
file.setName(name.substring(0, end));
file.setLink(name.substring(end + 4));
}
}
else
{
file.setName(name);
}
}
return file;
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_UNIX,
DEFAULT_DATE_FORMAT,
DEFAULT_RECENT_DATE_FORMAT,
null, null, null);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java 0000644 0001750 0001750 00000011441 11014672436 030570 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
/**
* Implementation of FTPFileEntryParser and FTPFileListParser for OS2 Systems.
*
* @author Winston Ojeda
* @author Steve Cohen
* @version $Id: OS2FTPEntryParser.java 658518 2008-05-21 01:04:30Z sebb $
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
*/
public class OS2FTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
= "MM-dd-yy HH:mm"; //11-09-01 12:30
/**
* this is the regular expression used by this parser.
*/
private static final String REGEX =
"\\s*([0-9]+)\\s*"
+ "(\\s+|[A-Z]+)\\s*"
+ "(DIR|\\s+)\\s*"
+ "(\\S+)\\s+(\\S+)\\s+" /* date stuff */
+ "(\\S.*)";
/**
* The default constructor for a OS2FTPEntryParser object.
*
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
*
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry)
{
FTPFile f = new FTPFile();
if (matches(entry))
{
String size = group(1);
String attrib = group(2);
String dirString = group(3);
String datestr = group(4)+" "+group(5);
String name = group(6);
try
{
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
// intentionally do nothing
}
//is it a DIR or a file
if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR"))
{
f.setType(FTPFile.DIRECTORY_TYPE);
}
else
{
f.setType(FTPFile.FILE_TYPE);
}
//set the name
f.setName(name.trim());
//set the size
f.setSize(Long.parseLong(size.trim()));
return (f);
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_OS2,
DEFAULT_DATE_FORMAT,
null, null, null, null);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java 0000644 0001750 0001750 00000003655 11014672436 031116 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.util.Calendar;
/**
* This interface specifies the concept of parsing an FTP server's
* timestamp.
* @since 1.4
*/
public interface FTPTimestampParser {
/**
* the default default date format.
*/
public static final String DEFAULT_SDF = UnixFTPEntryParser.DEFAULT_DATE_FORMAT;
/**
* the default recent date format.
*/
public static final String DEFAULT_RECENT_SDF = UnixFTPEntryParser.DEFAULT_RECENT_DATE_FORMAT;
/**
* Parses the supplied datestamp parameter. This parameter typically would
* have been pulled from a longer FTP listing via the regular expression
* mechanism
* @param timestampStr - the timestamp portion of the FTP directory listing
* to be parsed
* @return a
* Note: EnterpriseUnixFTPEntryParser can only be instantiated through the
* DefaultFTPParserFactory by classname. It will not be chosen
* by the autodetection scheme.
*
* @version $Id: EnterpriseUnixFTPEntryParser.java 658518 2008-05-21 01:04:30Z sebb $
* @author Winston Ojeda
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
*/
public class EnterpriseUnixFTPEntryParser extends RegexFTPFileEntryParserImpl
{
/**
* months abbreviations looked for by this parser. Also used
* to determine which month has been matched by the parser.
*/
private static final String MONTHS =
"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
/**
* this is the regular expression used by this parser.
*/
private static final String REGEX =
"(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])"
+ "([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))"
+ "(\\S*)\\s*"
+ "(\\S+)\\s*"
+ "(\\S*)\\s*"
+ "(\\d*)\\s*"
+ "(\\d*)\\s*"
+ MONTHS
+ "\\s*"
+ "((?:[012]\\d*)|(?:3[01]))\\s*"
+ "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
+ "(\\S*)(\\s*.*)";
/**
* The sole constructor for a EnterpriseUnixFTPEntryParser object.
*
*/
public EnterpriseUnixFTPEntryParser()
{
super(REGEX);
}
/**
* Parses a line of a unix FTP server file listing and converts it into a
* usable format in the form of an
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry)
{
FTPFile f = new FTPFile();
f.setRawListing(entry);
if (matches(entry))
{
String datestr = group(1)+" "+group(2);
String dirString = group(3);
String size = group(4);
String name = group(5);
try
{
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
// parsing fails, try the other date format
try
{
f.setTimestamp(timestampParser.parseTimestamp(datestr));
}
catch (ParseException e2)
{
// intentionally do nothing
}
}
if (null == name || name.equals(".") || name.equals(".."))
{
return (null);
}
f.setName(name);
if ("
*
* Netware file permissions are in the following format: RWCEAFMS, and are explained as follows:
*
* This abstract class implements the common timestamp parsing
* algorithm for all the concrete parsers. Classes derived from
* this one will parse file listings via a supplied regular expression
* that pulls out the date portion as a separate string which is
* passed to the underlying {@link FTPTimestampParser delegate} to
* handle parsing of the file timestamp.
*
* This class also implements the {@link Configurable Configurable}
* interface to allow the parser to be configured from the outside.
*
* @param timestampStr the timestamp string pulled from the
* file listing by the regular expression parser, to be submitted
* to the
* Note: VMSFTPEntryParser can only be instantiated through the
* DefaultFTPParserFactory by classname. It will not be chosen
* by the autodetection scheme.
*
*
*
* @author Winston Ojeda
* @author Steve Cohen
* @author Stephane ESTE-GRACIAS
* @version $Id: VMSFTPEntryParser.java 1032938 2010-11-09 11:41:09Z sebb $
*
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
*/
public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
= "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24
/**
* this is the regular expression used by this parser.
*/
private static final String REGEX =
"(.*;[0-9]+)\\s*" //1 file and version
+ "(\\d+)/\\d+\\s*" //2 size/allocated
+"(\\S+)\\s+(\\S+)\\s+" //3+4 date and time
+ "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*" //5(6,7,8) owner
+ "\\([a-zA-Z]*,([a-zA-Z]*),([a-zA-Z]*),([a-zA-Z]*)\\)"; //9,10,11 Permissions (O,G,W)
// TODO - perhaps restrict permissions to [RWED]* ?
/**
* Constructor for a VMSFTPEntryParser object.
*
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
*
* @param listStream The InputStream from which the file list should be
* read.
* @return The list of file information contained in the given path. null
* if the list could not be obtained or if there are no files in
* the directory.
* @exception IOException If an I/O error occurs reading the listStream.
* @deprecated (2.2) No other FTPFileEntryParser implementations have this method.
* Not currently used by NET code. To be removed in 3.0
***/
@Deprecated
public FTPFile[] parseFileList(InputStream listStream) throws IOException {
FTPListParseEngine engine = new FTPListParseEngine(this);
engine.readServerList(listStream, null);
return engine.getFiles();
}
/**
* Parses a line of a VMS FTP server file listing and converts it into a
* usable format in the form of an
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry)
{
//one block in VMS equals 512 bytes
long longBlock = 512;
if (matches(entry))
{
FTPFile f = new FTPFile();
f.setRawListing(entry);
String name = group(1);
String size = group(2);
String datestr = group(3)+" "+group(4);
String owner = group(5);
String permissions[] = new String[3];
permissions[0]= group(9);
permissions[1]= group(10);
permissions[2]= group(11);
try
{
f.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
// intentionally do nothing
}
String grp;
String user;
StringTokenizer t = new StringTokenizer(owner, ",");
switch (t.countTokens()) {
case 1:
grp = null;
user = t.nextToken();
break;
case 2:
grp = t.nextToken();
user = t.nextToken();
break;
default:
grp = null;
user = null;
}
if (name.lastIndexOf(".DIR") != -1)
{
f.setType(FTPFile.DIRECTORY_TYPE);
}
else
{
f.setType(FTPFile.FILE_TYPE);
}
//set FTPFile name
//Check also for versions to be returned or not
if (isVersioning())
{
f.setName(name);
}
else
{
name = name.substring(0, name.lastIndexOf(";"));
f.setName(name);
}
//size is retreived in blocks and needs to be put in bytes
//for us humans and added to the FTPFile array
long sizeInBytes = Long.parseLong(size) * longBlock;
f.setSize(sizeInBytes);
f.setGroup(grp);
f.setUser(user);
//set group and owner
//Set file permission.
//VMS has (SYSTEM,OWNER,GROUP,WORLD) users that can contain
//R (read) W (write) E (execute) D (delete)
//iterate for OWNER GROUP WORLD permissions
for (int access = 0; access < 3; access++)
{
String permission = permissions[access];
f.setPermission(access, FTPFile.READ_PERMISSION, permission.indexOf('R')>=0);
f.setPermission(access, FTPFile.WRITE_PERMISSION, permission.indexOf('W')>=0);
f.setPermission(access, FTPFile.EXECUTE_PERMISSION, permission.indexOf('E')>=0);
}
return f;
}
return null;
}
/**
* Reads the next entry using the supplied BufferedReader object up to
* whatever delemits one entry from the next. This parser cannot use
* the default implementation of simply calling BufferedReader.readLine(),
* because one entry may span multiple lines.
*
* @param reader The BufferedReader object from which entries are to be
* read.
*
* @return A string representing the next ftp entry or null if none found.
* @exception IOException thrown on any IO Error reading from the reader.
*/
@Override
public String readNextEntry(BufferedReader reader) throws IOException
{
String line = reader.readLine();
StringBuilder entry = new StringBuilder();
while (line != null)
{
if (line.startsWith("Directory") || line.startsWith("Total")) {
line = reader.readLine();
continue;
}
entry.append(line);
if (line.trim().endsWith(")"))
{
break;
}
line = reader.readLine();
}
return (entry.length() == 0 ? null : entry.toString());
}
protected boolean isVersioning() {
return false;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_VMS,
DEFAULT_DATE_FORMAT,
null, null, null, null);
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java 0000644 0001750 0001750 00000005244 11014672436 032400 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFileEntryParser;
/**
* The interface describes a factory for creating FTPFileEntryParsers.
* @since 1.2
*/
public interface FTPFileEntryParserFactory
{
/**
* Implementation should be a method that decodes the
* supplied key and creates an object implementing the
* interface FTPFileEntryParser.
*
* @param key A string that somehow identifies an
* FTPFileEntryParser to be created.
*
* @return the FTPFileEntryParser created.
* @exception ParserInitializationException
* Thrown on any exception in instantiation
*/
public FTPFileEntryParser createFileEntryParser(String key)
throws ParserInitializationException;
/**
*
* Implementation should be a method that extracts
* a key from the supplied {@link FTPClientConfig FTPClientConfig}
* parameter and creates an object implementing the
* interface FTPFileEntryParser and uses the supplied configuration
* to configure it.
*
* Note that this method will generally not be called in scenarios
* that call for autodetection of parser type but rather, for situations
* where the user knows that the server uses a non-default configuration
* and knows what that configuration is.
* Implementation extracts a key from the supplied
* {@link FTPClientConfig FTPClientConfig}
* parameter and creates an object implementing the
* interface FTPFileEntryParser and uses the supplied configuration
* to configure it.
*
* Note that this method will generally not be called in scenarios
* that call for autodetection of parser type but rather, for situations
* where the user knows that the server uses a non-default configuration
* and knows what that configuration is.
*
*
* @author Daniel F. Savarese
* @see DaytimeTCPClient
***/
public final class DaytimeUDPClient extends DatagramSocketClient
{
/*** The default daytime port. It is set to 13 according to RFC 867. ***/
public static final int DEFAULT_PORT = 13;
private final byte[] __dummyData = new byte[1];
// Received dates should be less than 256 bytes
private final byte[] __timeData = new byte[256];
/***
* Retrieves the time string from the specified server and port and
* returns it.
*
* @param host The address of the server.
* @param port The port of the service.
* @return The time string.
* @exception IOException If an error occurs while retrieving the time.
***/
public String getTime(InetAddress host, int port) throws IOException
{
DatagramPacket sendPacket, receivePacket;
sendPacket =
new DatagramPacket(__dummyData, __dummyData.length, host, port);
receivePacket = new DatagramPacket(__timeData, __timeData.length);
_socket_.send(sendPacket);
_socket_.receive(receivePacket);
return new String(receivePacket.getData(), 0, receivePacket.getLength());
}
/*** Same as
*
* @author Daniel F. Savarese
* @see DaytimeUDPClient
***/
public final class DaytimeTCPClient extends SocketClient
{
/*** The default daytime port. It is set to 13 according to RFC 867. ***/
public static final int DEFAULT_PORT = 13;
// Received dates will likely be less than 64 characters.
// This is a temporary buffer used while receiving data.
private final char[] __buffer = new char[64];
/***
* The default DaytimeTCPClient constructor. It merely sets the default
* port to
* @return The time string retrieved from the server.
* @exception IOException If an error occurs while fetching the time string.
***/
public String getTime() throws IOException
{
int read;
StringBuilder result = new StringBuilder(__buffer.length);
BufferedReader reader;
reader = new BufferedReader(new InputStreamReader(_input_));
while (true)
{
read = reader.read(__buffer, 0, __buffer.length);
if (read <= 0)
break;
result.append(__buffer, 0, read);
}
return result.toString();
}
}
commons-net-2.2/src/site/ 0000755 0001750 0001750 00000000000 11617452470 015314 5 ustar twerner twerner commons-net-2.2/src/site/resources/ 0000755 0001750 0001750 00000000000 11617452467 017334 5 ustar twerner twerner commons-net-2.2/src/site/resources/images/ 0000755 0001750 0001750 00000000000 11617452470 020573 5 ustar twerner twerner commons-net-2.2/src/site/resources/images/net-logo-white.xcf 0000644 0001750 0001750 00000045361 10034336445 024143 0 ustar twerner twerner gimp xcf file æ Q B B K /
gimp-comment Created with The GIMP ¦ ¤ Ã ë I 4 net ÿ
¤ &java.text.SimpleDateFormat
for code descriptions.
*/
public final static String NTP_DATE_FORMAT = "EEE, MMM dd yyyy HH:mm:ss.SSS";
/*
* Caches for the DateFormatters used by various toString methods.
*/
private static SoftReferencelong
value
* represented by this TimeStamp
object. That is, the hashcode
* is the value of the expression:
*
*
* @return a hash code value for this object.
*/
@Override
public int hashCode()
{
return (int) (ntpTime ^ (ntpTime >>> 32));
}
/***
* Compares this object against the specified object.
* The result is
* (int)(this.ntpValue()^(this.ntpValue() >>> 32))
*
true
if and only if the argument is
* not null
and is a Long
object that
* contains the same long
value as this object.
*
* @param obj the object to compare with.
* @return true
if the objects are the same;
* false
otherwise.
*/
@Override
public boolean equals(Object obj)
{
if (obj instanceof TimeStamp) {
return ntpTime == ((TimeStamp) obj).ntpValue();
}
return false;
}
/***
* Converts this TimeStamp
object to a String
.
* The NTP timestamp 64-bit long value is represented as hex string with
* seconds separated by fractional seconds by a decimal point;
* e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
*
* @return NTP timestamp 64-bit long value as hex string with seconds
* separated by fractional seconds.
*/
@Override
public String toString()
{
return toString(ntpTime);
}
/***
* Left-pad 8-character hex string with 0's
*
* @param buf - StringBuilder which is appended with leading 0's.
* @param l - a long.
*/
private static void appendHexString(StringBuilder buf, long l)
{
String s = Long.toHexString(l);
for (int i = s.length(); i < 8; i++)
buf.append('0');
buf.append(s);
}
/***
* Converts 64-bit NTP timestamp value to a String
.
* The NTP timestamp value is represented as hex string with
* seconds separated by fractional seconds by a decimal point;
* e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
*
* @return NTP timestamp 64-bit long value as hex string with seconds
* separated by fractional seconds.
*/
public static String toString(long ntpTime)
{
StringBuilder buf = new StringBuilder();
// high-order second bits (32..63) as hexstring
appendHexString(buf, (ntpTime >>> 32) & 0xffffffffL);
// low-order fractional seconds bits (0..31) as hexstring
buf.append('.');
appendHexString(buf, ntpTime & 0xffffffffL);
return buf.toString();
}
/***
* Converts this TimeStamp
object to a String
* of the form:
*
* See java.text.SimpleDataFormat for code descriptions.
*
* @return a string representation of this date.
*/
public String toDateString()
{
DateFormat formatter = null;
if (simpleFormatter != null) {
formatter = simpleFormatter.get();
}
if (formatter == null) {
// No cache yet, or cached formatter GC'd
formatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US);
formatter.setTimeZone(TimeZone.getDefault());
simpleFormatter = new SoftReference
* EEE, MMM dd yyyy HH:mm:ss.SSS
TimeStamp
object to a String
* of the form:
*
* See java.text.SimpleDataFormat for code descriptions.
*
* @return a string representation of this date in UTC.
*/
public String toUTCString()
{
DateFormat formatter = null;
if (utcFormatter != null)
formatter = utcFormatter.get();
if (formatter == null) {
// No cache yet, or cached formatter GC'd
formatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'",
Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
utcFormatter = new SoftReference
* EEE, MMM dd yyyy HH:mm:ss.SSS UTC
TimeStamp
to be compared.
* @return the value 0
if the argument TimeStamp is equal to
* this TimeStamp; a value less than 0
if this TimeStamp
* is numerically less than the TimeStamp argument; and a
* value greater than 0
if this TimeStamp is
* numerically greater than the TimeStamp argument
* (signed comparison).
*/
public int compareTo(TimeStamp anotherTimeStamp)
{
long thisVal = this.ntpTime;
long anotherVal = anotherTimeStamp.ntpTime;
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java 0000644 0001750 0001750 00000014507 10542533103 026230 0 ustar twerner twerner package org.apache.commons.net.ntp;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.DatagramPacket;
/**
* Interface for a NtpV3Packet with get/set methods corresponding to the fields
* in the NTP Data Message Header described in RFC 1305.
*
* @author Naz Irizarry, MITRE Corp
* @author Jason Mathews, MITRE Corp
* @version $Revision: 489397 $ $Date: 2006-12-21 17:28:51 +0100 (Do, 21. Dez 2006) $
*/
public interface NtpV3Packet
{
/**
* Standard NTP UDP port
*/
public static final int NTP_PORT = 123;
public static final int LI_NO_WARNING = 0;
public static final int LI_LAST_MINUTE_HAS_61_SECONDS = 1;
public static final int LI_LAST_MINUTE_HAS_59_SECONDS = 2;
public static final int LI_ALARM_CONDITION = 3;
/* mode options */
public static final int MODE_RESERVED = 0;
public static final int MODE_SYMMETRIC_ACTIVE = 1;
public static final int MODE_SYMMETRIC_PASSIVE = 2;
public static final int MODE_CLIENT = 3;
public static final int MODE_SERVER = 4;
public static final int MODE_BROADCAST = 5;
public static final int MODE_CONTROL_MESSAGE = 6;
public static final int MODE_PRIVATE = 7;
public static final int NTP_MINPOLL = 4; // 16 seconds
public static final int NTP_MAXPOLL = 14; // 16284 seconds
public static final int NTP_MINCLOCK = 1;
public static final int NTP_MAXCLOCK = 10;
public static final int VERSION_3 = 3;
public static final int VERSION_4 = 4;
/* possible getType values such that other time-related protocols can
* have its information represented as NTP packets
*/
public static final String TYPE_NTP = "NTP"; // RFC-1305/2030
public static final String TYPE_ICMP = "ICMP"; // RFC-792
public static final String TYPE_TIME = "TIME"; // RFC-868
public static final String TYPE_DAYTIME = "DAYTIME"; // RFC-867
/**
* @return a datagram packet with the NTP parts already filled in
*/
public DatagramPacket getDatagramPacket();
/**
* Set the contents of this object from the datagram packet
*/
public void setDatagramPacket(DatagramPacket dp);
/**
* @return leap indicator as defined in RFC-1305
*/
public int getLeapIndicator();
/**
* Set leap indicator.
* @param li - leap indicator code
*/
public void setLeapIndicator(int li);
/**
* @return mode as defined in RFC-1305
*/
public int getMode();
/**
* @return mode as human readable string; e.g. 3=Client
*/
public String getModeName();
/**
* Set mode as defined in RFC-1305
*/
public void setMode(int mode);
/**
* @return poll interval as defined in RFC-1305.
* Field range between NTP_MINPOLL and NTP_MAXPOLL.
*/
public int getPoll();
/**
* Set poll interval as defined in RFC-1305.
* Field range between NTP_MINPOLL and NTP_MAXPOLL.
*/
public void setPoll(int poll);
/**
* @return precision as defined in RFC-1305
*/
public int getPrecision();
/**
* @return root delay as defined in RFC-1305
*/
public int getRootDelay();
/**
* @return root delay in milliseconds
*/
public double getRootDelayInMillisDouble();
/**
* @return root dispersion as defined in RFC-1305
*/
public int getRootDispersion();
/**
* @return root dispersion in milliseconds
*/
public long getRootDispersionInMillis();
/**
* @return root dispersion in milliseconds
*/
public double getRootDispersionInMillisDouble();
/**
* @return version as defined in RFC-1305
*/
public int getVersion();
/**
* Set version as defined in RFC-1305
*/
public void setVersion(int mode);
/**
* @return stratum as defined in RFC-1305
*/
public int getStratum();
/**
* Set stratum as defined in RFC-1305
*/
public void setStratum(int stratum);
/**
* @return the reference id string
*/
public String getReferenceIdString();
/**
* @return the reference id (32-bit code) as defined in RFC-1305
*/
public int getReferenceId();
/**
* Set reference clock identifier field.
* @param refId
*/
public void setReferenceId(int refId);
/**
* @return the transmit timestamp as defined in RFC-1305
*/
public TimeStamp getTransmitTimeStamp();
/**
* @return the reference time as defined in RFC-1305
*/
public TimeStamp getReferenceTimeStamp();
/**
* @return the originate time as defined in RFC-1305
*/
public TimeStamp getOriginateTimeStamp();
/**
* @return the receive time as defined in RFC-1305
*/
public TimeStamp getReceiveTimeStamp();
/**
* Set the transmit timestamp given NTP TimeStamp object.
* @param ts - timestamp
*/
public void setTransmitTime(TimeStamp ts);
/**
* Set the reference timestamp given NTP TimeStamp object.
* @param ts - timestamp
*/
public void setReferenceTime(TimeStamp ts);
/**
* Set originate timestamp given NTP TimeStamp object.
* @param ts - timestamp
*/
public void setOriginateTimeStamp(TimeStamp ts);
/**
* Set receive timestamp given NTP TimeStamp object.
* @param ts - timestamp
*/
public void setReceiveTimeStamp(TimeStamp ts);
/**
* Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...)
* correspond to the protocol used to obtain the timing information.
*
* @return packet type string identifier
*/
public String getType();
}
commons-net-2.2/src/main/java/org/apache/commons/net/ntp/NTPUDPClient.java 0000644 0001750 0001750 00000012516 10542533103 026275 0 ustar twerner twerner package org.apache.commons.net.ntp;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import org.apache.commons.net.DatagramSocketClient;
/***
* The NTPUDPClient class is a UDP implementation of a client for the
* Network Time Protocol (NTP) described in RFC 1305 as well as the
* Simple Network Time Protocol (SNTP) in RFC-2030. To use the class,
* merely open a local datagram socket with open
* and call getTime to retrieve the time. Then call
* close
* to close the connection properly.
* Successive calls to getTime are permitted
* without re-establishing a connection. That is because UDP is a
* connectionless protocol and the Network Time Protocol is stateless.
*
* @author Jason Mathews, MITRE Corp
* @version $Revision: 489397 $ $Date: 2006-12-21 17:28:51 +0100 (Do, 21. Dez 2006) $
***/
public final class NTPUDPClient extends DatagramSocketClient
{
/*** The default NTP port. It is set to 123 according to RFC 1305. ***/
public static final int DEFAULT_PORT = 123;
private int _version = NtpV3Packet.VERSION_3;
/***
* Retrieves the time information from the specified server and port and
* returns it. The time is the number of miliiseconds since
* 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
* This method reads the raw NTP packet and constructs a TimeInfo
* object that allows access to all the fields of the NTP message header.
* ts
is null then zero time is used.
*
* @param ts NTP timestamp
*/
public void setTransmitTime(TimeStamp ts)
{
setTimestamp(TRANSMIT_TIMESTAMP_INDEX, ts);
}
/***
* Set originate timestamp given NTP TimeStamp object.
* If ts
is null then zero time is used.
*
* @param ts NTP timestamp
*/
public void setOriginateTimeStamp(TimeStamp ts)
{
setTimestamp(ORIGINATE_TIMESTAMP_INDEX, ts);
}
/***
* Returns the originate time as defined in RFC-1305.
*
* @return the originate time.
* Never returns null.
*/
public TimeStamp getOriginateTimeStamp()
{
return getTimestamp(ORIGINATE_TIMESTAMP_INDEX);
}
/***
* Returns the reference time as defined in RFC-1305.
*
* @return the reference time as TimeStamp
object.
* Never returns null.
*/
public TimeStamp getReferenceTimeStamp()
{
return getTimestamp(REFERENCE_TIMESTAMP_INDEX);
}
/***
* Set Reference time with NTP timestamp. If ts
is null
* then zero time is used.
*
* @param ts NTP timestamp
*/
public void setReferenceTime(TimeStamp ts)
{
setTimestamp(REFERENCE_TIMESTAMP_INDEX, ts);
}
/***
* Returns receive timestamp as defined in RFC-1305.
*
* @return the receive time.
* Never returns null.
*/
public TimeStamp getReceiveTimeStamp()
{
return getTimestamp(RECEIVE_TIMESTAMP_INDEX);
}
/***
* Set receive timestamp given NTP TimeStamp object.
* If ts
is null then zero time is used.
*
* @param ts timestamp
*/
public void setReceiveTimeStamp(TimeStamp ts)
{
setTimestamp(RECEIVE_TIMESTAMP_INDEX, ts);
}
/***
* Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...)
* correspond to the protocol used to obtain the timing information.
*
* @return packet type string identifier which in this case is "NTP".
*/
public String getType()
{
return "NTP";
}
/***
* @return 4 bytes as 32-bit int
*/
private int getInt(int index)
{
int i = ui(buf[index]) << 24 |
ui(buf[index + 1]) << 16 |
ui(buf[index + 2]) << 8 |
ui(buf[index + 3]);
return i;
}
/***
* Get NTP Timestamp at specified starting index.
*
* @param index index into data array
* @return TimeStamp object for 64 bits starting at index
*/
private TimeStamp getTimestamp(int index)
{
return new TimeStamp(getLong(index));
}
/***
* Get Long value represented by bits starting at specified index.
*
* @return 8 bytes as 64-bit long
*/
private long getLong(int index)
{
long i = ul(buf[index]) << 56 |
ul(buf[index + 1]) << 48 |
ul(buf[index + 2]) << 40 |
ul(buf[index + 3]) << 32 |
ul(buf[index + 4]) << 24 |
ul(buf[index + 5]) << 16 |
ul(buf[index + 6]) << 8 |
ul(buf[index + 7]);
return i;
}
/***
* Sets the NTP timestamp at the given array index.
*
* @param index index into the byte array.
* @param t TimeStamp.
*/
private void setTimestamp(int index, TimeStamp t)
{
long ntpTime = (t == null) ? 0 : t.ntpValue();
// copy 64-bits from Long value into 8 x 8-bit bytes of array
// one byte at a time shifting 8-bits for each position.
for (int i = 7; i >= 0; i--) {
buf[index + i] = (byte) (ntpTime & 0xFF);
ntpTime >>>= 8; // shift to next byte
}
// buf[index] |= 0x80; // only set if 1900 baseline....
}
/***
* Returns the datagram packet with the NTP details already filled in.
*
* @return a datagram packet.
*/
public synchronized DatagramPacket getDatagramPacket()
{
if (dp == null) {
dp = new DatagramPacket(buf, buf.length);
dp.setPort(NTP_PORT);
}
return dp;
}
/***
* Set the contents of this object from source datagram packet.
*
* @param srcDp source DatagramPacket to copy contents from.
*/
public void setDatagramPacket(DatagramPacket srcDp)
{
byte[] incomingBuf = srcDp.getData();
int len = srcDp.getLength();
if (len > buf.length)
len = buf.length;
System.arraycopy(incomingBuf, 0, buf, 0, len);
}
/***
* Convert byte to unsigned integer.
* Java only has signed types so we have to do
* more work to get unsigned ops.
*
* @param b
* @return unsigned int value of byte
*/
protected final static int ui(byte b)
{
int i = b & 0xFF;
return i;
}
/***
* Convert byte to unsigned long.
* Java only has signed types so we have to do
* more work to get unsigned ops
*
* @param b
* @return unsigned long value of byte
*/
protected final static long ul(byte b)
{
long i = b & 0xFF;
return i;
}
/***
* Returns details of NTP packet as a string.
*
* @return details of NTP packet as a string.
*/
@Override
public String toString()
{
return "[" +
"version:" + getVersion() +
", mode:" + getMode() +
", poll:" + getPoll() +
", precision:" + getPrecision() +
", delay:" + getRootDelay() +
", dispersion(ms):" + getRootDispersionInMillisDouble() +
", id:" + getReferenceIdString() +
", xmitTime:" + getTransmitTimeStamp().toDateString() +
" ]";
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/util/ 0000755 0001750 0001750 00000000000 11617452467 023451 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/util/ListenerList.java 0000644 0001750 0001750 00000003463 11014673543 026732 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.util;
import java.io.Serializable;
import java.util.EventListener;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Daniel F. Savarese
*/
public class ListenerList implements Serializable, Iterabletrue
if the return value of {@link SubnetInfo#getAddressCount()}
* includes the network address and broadcast addresses.
* @since 2.2
*/
public boolean isInclusiveHostCount() {
return inclusiveHostCount;
}
/**
* Set to true
if you want the return value of {@link SubnetInfo#getAddressCount()}
* to include the network and broadcast addresses.
* @param inclusiveHostCount
* @since 2.2
*/
public void setInclusiveHostCount(boolean inclusiveHostCount) {
this.inclusiveHostCount = inclusiveHostCount;
}
/**
* Convenience container for subnet summary information.
*
*/
public final class SubnetInfo {
private SubnetInfo() {}
private int netmask() { return netmask; }
private int network() { return network; }
private int address() { return address; }
private int broadcast() { return broadcast; }
private int low() { return network() + (isInclusiveHostCount() ? 0 : 1); }
private int high() { return broadcast() - (isInclusiveHostCount() ? 0 : 1); }
/**
* Returns true if the parameter address
is in the
* range of usable endpoint addresses for this subnet. This excludes the
* network and broadcast adresses.
* @param address A dot-delimited IPv4 address, e.g. "192.168.0.1"
* @return True if in range, false otherwise
*/
public boolean isInRange(String address) { return isInRange(toInteger(address)); }
private boolean isInRange(int address) {
int diff = address-low();
return (diff >= 0 && (diff <= (high()-low())));
}
public String getBroadcastAddress() { return format(toArray(broadcast())); }
public String getNetworkAddress() { return format(toArray(network())); }
public String getNetmask() { return format(toArray(netmask())); }
public String getAddress() { return format(toArray(address())); }
public String getLowAddress() { return format(toArray(low())); }
public String getHighAddress() { return format(toArray(high())); }
public int getAddressCount() { return (broadcast() - low() + (isInclusiveHostCount() ? 1 : 0)); }
public int asInteger(String address) { return toInteger(address); }
public String getCidrSignature() {
return toCidrNotation(
format(toArray(address())),
format(toArray(netmask()))
);
}
public String[] getAllAddresses() {
String[] addresses = new String[getAddressCount()];
for (int add = low(), j=0; add <= high(); ++add, ++j) {
addresses[j] = format(toArray(add));
}
return addresses;
}
/**
* {@inheritDoc}
* @since 2.2
*/
@Override
public String toString() {
final StringBuilder buf = new StringBuilder();
buf.append("CIDR Signature:\t[").append(getCidrSignature()).append("]")
.append(" Netmask: [").append(getNetmask()).append("]\n")
.append("Network:\t[").append(getNetworkAddress()).append("]\n")
.append("Broadcast:\t[").append(getBroadcastAddress()).append("]\n")
.append("First Address:\t[").append(getLowAddress()).append("]\n")
.append("Last Address:\t[").append(getHighAddress()).append("]\n")
.append("# Addresses:\t[").append(getAddressCount()).append("]\n");
return buf.toString();
}
}
/**
* Return a {@link SubnetInfo} instance that contains subnet-specific statistics
* @return new instance
*/
public final SubnetInfo getInfo() { return new SubnetInfo(); }
/*
* Initialize the internal fields from the supplied CIDR mask
*/
private void calculate(String mask) {
Matcher matcher = cidrPattern.matcher(mask);
if (matcher.matches()) {
address = matchAddress(matcher);
/* Create a binary netmask from the number of bits specification /x */
int cidrPart = rangeCheck(Integer.parseInt(matcher.group(5)), -1, NBITS);
for (int j = 0; j < cidrPart; ++j) {
netmask |= (1 << 31-j);
}
rangeCheck(pop(netmask),0, NBITS);
/* Calculate base network address */
network = (address & netmask);
/* Calculate broadcast address */
broadcast = network | ~(netmask);
}
else
throw new IllegalArgumentException("Could not parse [" + mask + "]");
}
/*
* Convert a dotted decimal format address to a packed integer format
*/
private int toInteger(String address) {
Matcher matcher = addressPattern.matcher(address);
if (matcher.matches()) {
return matchAddress(matcher);
}
else
throw new IllegalArgumentException("Could not parse [" + address + "]");
}
/*
* Convenience method to extract the components of a dotted decimal address and
* pack into an integer using a regex match
*/
private int matchAddress(Matcher matcher) {
int addr = 0;
for (int i = 1; i <= 4; ++i) {
int n = (rangeCheck(Integer.parseInt(matcher.group(i)), -1, 255));
addr |= ((n & 0xff) << 8*(4-i));
}
return addr;
}
/*
* Convert a packed integer address into a 4-element array
*/
private int[] toArray(int val) {
int ret[] = new int[4];
for (int j = 3; j >= 0; --j)
ret[j] |= ((val >>> 8*(3-j)) & (0xff));
return ret;
}
/*
* Convert a 4-element array into dotted decimal format
*/
private String format(int[] octets) {
StringBuilder str = new StringBuilder();
for (int i =0; i < octets.length; ++i){
str.append(octets[i]);
if (i != octets.length - 1) {
str.append(".");
}
}
return str.toString();
}
/*
* Convenience function to check integer boundaries.
* Checks if a value x is in the range (begin,end].
* Returns x if it is in range, throws an exception otherwise.
*/
private int rangeCheck(int value, int begin, int end) {
if (value > begin && value <= end) // (begin,end]
return value;
throw new IllegalArgumentException("Value [" + value + "] not in range ("+begin+","+end+"]");
}
/*
* Count the number of 1-bits in a 32-bit integer using a divide-and-conquer strategy
* see Hacker's Delight section 5.1
*/
int pop(int x) {
x = x - ((x >>> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
x = (x + (x >>> 4)) & 0x0F0F0F0F;
x = x + (x >>> 8);
x = x + (x >>> 16);
return x & 0x0000003F;
}
/* Convert two dotted decimal addresses to a single xxx.xxx.xxx.xxx/yy format
* by counting the 1-bit population in the mask address. (It may be better to count
* NBITS-#trailing zeroes for this case)
*/
private String toCidrNotation(String addr, String mask) {
return addr + "/" + pop(toInteger(mask));
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/util/Base64.java 0000644 0001750 0001750 00000116025 11466231525 025335 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.util;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
/**
* Provides Base64 encoding and decoding as defined by RFC 2045.
*
*
*
* decodeSize = 3 + lineSeparator.length;
*/
private final int decodeSize;
/**
* Convenience variable to help us determine when our buffer is going to run out of room and needs resizing.
* encodeSize = 4 + lineSeparator.length;
*/
private final int encodeSize;
/**
* Buffer for streaming.
*/
private byte[] buffer;
/**
* Position where next character should be written in the buffer.
*/
private int pos;
/**
* Position where next character should be read from the buffer.
*/
private int readPos;
/**
* Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
* make sure each encoded line never goes beyond lineLength (if lineLength > 0).
*/
private int currentLinePos;
/**
* Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when decoding. This variable
* helps track that.
*/
private int modulus;
/**
* Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64 object becomes useless,
* and must be thrown away.
*/
private boolean eof;
/**
* Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store and extract the
* base64 encoding or decoding from this variable.
*/
private int x;
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* true
, URL-safe encoding is used. In most cases this should be set to
* false
.
* @since 1.4
*/
public Base64(boolean urlSafe) {
this(CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode.
* octet
is in the base 64 alphabet.
*
* @param octet
* The value to test
* @return true
if the value is defined in the the base 64 alphabet, false
otherwise.
* @since 1.4
*/
public static boolean isBase64(byte octet) {
return octet == PAD || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1);
}
/**
* Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
* method treats whitespace as valid.
*
* @param arrayOctet
* byte array to test
* @return true
if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
* false, otherwise
*/
public static boolean isArrayByteBase64(byte[] arrayOctet) {
for (int i = 0; i < arrayOctet.length; i++) {
if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) {
return false;
}
}
return true;
}
/**
* Tests a given byte array to see if it contains only valid characters within the Base64 alphabet.
*
* @param arrayOctet
* byte array to test
* @return true
if any byte is a valid character in the Base64 alphabet; false herwise
*/
private static boolean containsBase64Byte(byte[] arrayOctet) {
for (int i = 0; i < arrayOctet.length; i++) {
if (isBase64(arrayOctet[i])) {
return true;
}
}
return false;
}
/**
* Encodes binary data using the base64 algorithm but does not chunk the output.
*
* @param binaryData
* binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
*/
public static byte[] encodeBase64(byte[] binaryData) {
return encodeBase64(binaryData, false);
}
/**
* Encodes binary data using the base64 algorithm into 76 character blocks separated by CRLF.
*
* @param binaryData
* binary data to encode
* @return String containing Base64 characters.
* @since 1.4
*/
public static String encodeBase64String(byte[] binaryData) {
return newStringUtf8(encodeBase64(binaryData, true));
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
* url-safe variation emits - and _ instead of + and / characters.
*
* @param binaryData
* binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
* @since 1.4
*/
public static byte[] encodeBase64URLSafe(byte[] binaryData) {
return encodeBase64(binaryData, false, true);
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The
* url-safe variation emits - and _ instead of + and / characters.
*
* @param binaryData
* binary data to encode
* @return String containing Base64 characters
* @since 1.4
*/
public static String encodeBase64URLSafeString(byte[] binaryData) {
return newStringUtf8(encodeBase64(binaryData, false, true));
}
/**
* Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks
*
* @param binaryData
* binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(byte[] binaryData) {
return encodeBase64(binaryData, true);
}
/**
* Decodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the
* Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String.
*
* @param pObject
* Object to decode
* @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied.
* @throws RuntimeException
* if the parameter supplied is not of type byte[]
*/
public Object decode(Object pObject) {
if (pObject instanceof byte[]) {
return decode((byte[]) pObject);
} else if (pObject instanceof String) {
return decode((String) pObject);
} else {
throw new RuntimeException("Parameter supplied to Base64 decode is not a byte[] or a String");
}
}
/**
* Decodes a String containing containing characters in the Base64 alphabet.
*
* @param pArray
* A String containing Base64 character data
* @return a byte array containing binary data
* @since 1.4
*/
public byte[] decode(String pArray) {
return decode(getBytesUtf8(pArray));
}
private byte[] getBytesUtf8(String pArray) {
try {
return pArray.getBytes("UTF8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* Decodes a byte[] containing containing characters in the Base64 alphabet.
*
* @param pArray
* A byte array containing Base64 character data
* @return a byte array containing binary data
*/
public byte[] decode(byte[] pArray) {
reset();
if (pArray == null || pArray.length == 0) {
return pArray;
}
long len = (pArray.length * 3) / 4;
byte[] buf = new byte[(int) len];
setInitialBuffer(buf, 0, buf.length);
decode(pArray, 0, pArray.length);
decode(pArray, 0, -1); // Notify decoder of EOF.
// Would be nice to just return buf (like we sometimes do in the encode
// logic), but we have no idea what the line-length was (could even be
// variable). So we cannot determine ahead of time exactly how big an
// array is necessary. Hence the need to construct a 2nd byte array to
// hold the final result:
byte[] result = new byte[pos];
readResults(result, 0, result.length);
return result;
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if true
this encoder will chunk the base64 output into 76 character blocks
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
return encodeBase64(binaryData, isChunked, false);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if true
this encoder will chunk the base64 output into 76 character blocks
* @param urlSafe
* if true
this encoder will emit - and _ instead of the usual + and / characters.
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE}
* @since 1.4
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe) {
return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks.
*
* @param binaryData
* Array containing binary data to encode.
* @param isChunked
* if true
this encoder will chunk the base64 output into 76 character blocks
* @param urlSafe
* if true
this encoder will emit - and _ instead of the usual + and / characters.
* @param maxResultSize
* The maximum result size to accept.
* @return Base64-encoded data.
* @throws IllegalArgumentException
* Thrown when the input array needs an output array bigger than maxResultSize
* @since 1.4
*/
public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) {
if (binaryData == null || binaryData.length == 0) {
return binaryData;
}
long len = getEncodeLength(binaryData, CHUNK_SIZE, CHUNK_SEPARATOR);
if (len > maxResultSize) {
throw new IllegalArgumentException("Input array too big, the output array would be bigger (" +
len +
") than the specified maxium size of " +
maxResultSize);
}
Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
return b64.encode(binaryData);
}
/**
* Decodes a Base64 String into octets
*
* @param base64String
* String containing Base64 data
* @return Array containing decoded data.
* @since 1.4
*/
public static byte[] decodeBase64(String base64String) {
return new Base64().decode(base64String);
}
/**
* Decodes Base64 data into octets
*
* @param base64Data
* Byte array containing Base64 data
* @return Array containing decoded data.
*/
public static byte[] decodeBase64(byte[] base64Data) {
return new Base64().decode(base64Data);
}
/**
* Checks if a byte value is whitespace or not.
*
* @param byteToCheck
* the byte to check
* @return true if byte is whitespace, false otherwise
*/
private static boolean isWhiteSpace(byte byteToCheck) {
switch (byteToCheck) {
case ' ' :
case '\n' :
case '\r' :
case '\t' :
return true;
default :
return false;
}
}
// Implementation of the Encoder Interface
/**
* Encodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the
* Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[].
*
* @param pObject
* Object to encode
* @return An object (of type byte[]) containing the base64 encoded data which corresponds to the byte[] supplied.
* @throws RuntimeException
* if the parameter supplied is not of type byte[]
*/
public Object encode(Object pObject) {
if (!(pObject instanceof byte[])) {
throw new RuntimeException("Parameter supplied to Base64 encode is not a byte[]");
}
return encode((byte[]) pObject);
}
/**
* Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet.
*
* @param pArray
* a byte array containing binary data
* @return A String containing only Base64 character data
* @since 1.4
*/
public String encodeToString(byte[] pArray) {
return newStringUtf8(encode(pArray));
}
private static String newStringUtf8(byte[] encode) {
String str = null;
try {
str = new String(encode, "UTF8");
} catch (UnsupportedEncodingException ue) {
throw new RuntimeException(ue);
}
return str;
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet.
*
* @param pArray
* a byte array containing binary data
* @return A byte array containing only Base64 character data
*/
public byte[] encode(byte[] pArray) {
reset();
if (pArray == null || pArray.length == 0) {
return pArray;
}
long len = getEncodeLength(pArray, lineLength, lineSeparator);
byte[] buf = new byte[(int) len];
setInitialBuffer(buf, 0, buf.length);
encode(pArray, 0, pArray.length);
encode(pArray, 0, -1); // Notify encoder of EOF.
// Encoder might have resized, even though it was unnecessary.
if (buffer != buf) {
readResults(buf, 0, buf.length);
}
// In URL-SAFE mode we skip the padding characters, so sometimes our
// final length is a bit smaller.
if (isUrlSafe() && pos < buf.length) {
byte[] smallerBuf = new byte[pos];
System.arraycopy(buf, 0, smallerBuf, 0, pos);
buf = smallerBuf;
}
return buf;
}
/**
* Pre-calculates the amount of space needed to base64-encode the supplied array.
*
* @param pArray byte[] array which will later be encoded
* @param chunkSize line-length of the output (<= 0 means no chunking) between each
* chunkSeparator (e.g. CRLF).
* @param chunkSeparator the sequence of bytes used to separate chunks of output (e.g. CRLF).
*
* @return amount of space needed to encoded the supplied array. Returns
* a long since a max-len array will require Integer.MAX_VALUE + 33%.
*/
private static long getEncodeLength(byte[] pArray, int chunkSize, byte[] chunkSeparator) {
// base64 always encodes to multiples of 4.
chunkSize = (chunkSize / 4) * 4;
long len = (pArray.length * 4) / 3;
long mod = len % 4;
if (mod != 0) {
len += 4 - mod;
}
if (chunkSize > 0) {
boolean lenChunksPerfectly = len % chunkSize == 0;
len += (len / chunkSize) * chunkSeparator.length;
if (!lenChunksPerfectly) {
len += chunkSeparator.length;
}
}
return len;
}
// Implementation of integer encoding used for crypto
/**
* Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
*
* @param pArray
* a byte array containing base64 character data
* @return A BigInteger
* @since 1.4
*/
public static BigInteger decodeInteger(byte[] pArray) {
return new BigInteger(1, decodeBase64(pArray));
}
/**
* Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature
*
* @param bigInt
* a BigInteger
* @return A byte array containing base64 character data
* @throws NullPointerException
* if null is passed in
* @since 1.4
*/
public static byte[] encodeInteger(BigInteger bigInt) {
if (bigInt == null) {
throw new NullPointerException("encodeInteger called with null parameter");
}
return encodeBase64(toIntegerBytes(bigInt), false);
}
/**
* Returns a byte-array representation of a BigInteger
without sign bit.
*
* @param bigInt
* BigInteger
to be converted
* @return a byte array representation of the BigInteger parameter
*/
static byte[] toIntegerBytes(BigInteger bigInt) {
int bitlen = bigInt.bitLength();
// round bitlen
bitlen = ((bitlen + 7) >> 3) << 3;
byte[] bigBytes = bigInt.toByteArray();
if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) {
return bigBytes;
}
// set up params for copying everything but sign bit
int startSrc = 0;
int len = bigBytes.length;
// if bigInt is exactly byte-aligned, just skip signbit in copy
if ((bigInt.bitLength() % 8) == 0) {
startSrc = 1;
len--;
}
int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec
byte[] resizedBytes = new byte[bitlen / 8];
System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
return resizedBytes;
}
/**
* Resets this Base64 object to its initial newly constructed state.
*/
private void reset() {
buffer = null;
pos = 0;
readPos = 0;
currentLinePos = 0;
modulus = 0;
eof = false;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/discard/ 0000755 0001750 0001750 00000000000 11617452467 024105 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/discard/DiscardTCPClient.java 0000644 0001750 0001750 00000004542 10761044665 030030 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.discard;
import java.io.OutputStream;
import org.apache.commons.net.SocketClient;
/***
* The DiscardTCPClient class is a TCP implementation of a client for the
* Discard protocol described in RFC 863. To use the class, merely
* establish a connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* and call {@link #getOutputStream getOutputStream() } to
* retrieve the discard output stream. Don't close the output stream
* when you're done writing to it. Rather, call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
* DEFAULT_PORT
.
***/
public DiscardTCPClient ()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Returns an OutputStream through which you may write data to the server.
* You should NOT close the OutputStream when you're finished
* reading from it. Rather, you should call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
* send(data, length, host. DiscardUDPClient.DEFAULT_PORT)
.
***/
public void send(byte[] data, int length, InetAddress host)
throws IOException
{
send(data, length, host, DEFAULT_PORT);
}
/***
* Same as
* send(data, data.length, host. DiscardUDPClient.DEFAULT_PORT)
.
***/
public void send(byte[] data, InetAddress host) throws IOException
{
send(data, data.length, host, DEFAULT_PORT);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java 0000644 0001750 0001750 00000005015 10542533103 031045 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/***
* DefaultDatagramSocketFactory implements the DatagramSocketFactory
* interface by simply wrapping the java.net.DatagramSocket
* constructors. It is the default DatagramSocketFactory used by
* {@link org.apache.commons.net.DatagramSocketClient}
* implementations.
* send(data, data.length, host)
***/
@Override
public void send(byte[] data, InetAddress host) throws IOException
{
send(data, data.length, host, DEFAULT_PORT);
}
/***
* Receives echoed data and returns its length. The data may be divided
* up among multiple datagrams, requiring multiple calls to receive.
* Also, the UDP packets will not necessarily arrive in the same order
* they were sent.
* receive(data, data.length)
***/
public int receive(byte[] data) throws IOException
{
return receive(data, data.length);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/echo/EchoTCPClient.java 0000644 0001750 0001750 00000004744 10766022773 026647 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.echo;
import java.io.InputStream;
import org.apache.commons.net.discard.DiscardTCPClient;
/***
* The EchoTCPClient class is a TCP implementation of a client for the
* Echo protocol described in RFC 862. To use the class, merely
* establish a connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* and call {@link DiscardTCPClient#getOutputStream getOutputStream() } to
* retrieve the echo output stream and
* {@link #getInputStream getInputStream() }
* to get the echo input stream.
* Don't close either stream when you're done using them. Rather, call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
* DEFAULT_PORT
.
***/
public EchoTCPClient ()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Returns an InputStream from which you may read echoed data from
* the server. You should NOT close the InputStream when you're finished
* reading from it. Rather, you should call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
* separateErrorStream
* parameter of {@link #rcommand rcommand() } to true
.
* The standard input of the remote process can be written to through
* the output stream returned by
* {@link org.apache.commons.net.bsd.RExecClient#getOutputStream getOutputStream() }
* .
* DEFAULT_PORT
.
***/
public RCommandClient()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Opens a Socket connected to a remote host at the specified port and
* originating from the specified local address using a port in a range
* acceptable to the BSD rshell daemon.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* MIN_CLIENT_PORT
and
* MAX_CLIENT_PORT
or an IllegalArgumentException will
* be thrown.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* MIN_CLIENT_PORT
and
* MAX_CLIENT_PORT
or an IllegalArgumentException will
* be thrown.
* Before returning, {@link org.apache.commons.net.SocketClient#_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* rcommand(localUsername, remoteUsername, command, false);
***/
public void rcommand(String localUsername, String remoteUsername,
String command)
throws IOException
{
rcommand(localUsername, remoteUsername, command, false);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/bsd/RExecClient.java 0000644 0001750 0001750 00000024564 11354512541 026253 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.bsd;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.commons.net.SocketClient;
import org.apache.commons.net.io.SocketInputStream;
/***
* RExecClient implements the rexec() facility that first appeared in
* 4.2BSD Unix. This class will probably only be of use for connecting
* to Unix systems and only when the rexecd daemon is configured to run,
* which is a rarity these days because of the security risks involved.
* However, rexec() can be very useful for performing administrative tasks
* on a network behind a firewall.
* separateErrorStream
* parameter of {@link #rexec rexec() } to true
.
* The standard input of the remote process can be written to through
* the output stream returned by
* {@link #getOutputStream getOutputSream() }.
* _errorStream_
* will point to an InputStream from which the standard error of the
* remote process can be read (after a call to rexec()). Otherwise,
* _errorStream_
will be null.
***/
protected InputStream _errorStream_;
// This can be overridden in local package to implement port range
// limitations of rcmd and rlogin
InputStream _createErrorStream() throws IOException
{
ServerSocket server;
Socket socket;
server = _serverSocketFactory_.createServerSocket(0, 1, getLocalAddress());
_output_.write(Integer.toString(server.getLocalPort()).getBytes());
_output_.write('\0');
_output_.flush();
socket = server.accept();
server.close();
if (__remoteVerificationEnabled && !verifyRemote(socket))
{
socket.close();
throw new IOException(
"Security violation: unexpected connection attempt by " +
socket.getInetAddress().getHostAddress());
}
return (new SocketInputStream(socket, socket.getInputStream()));
}
/***
* The default RExecClient constructor. Initializes the
* default port to DEFAULT_PORT
.
***/
public RExecClient()
{
_errorStream_ = null;
setDefaultPort(DEFAULT_PORT);
}
/***
* Returns the InputStream from which the standard outputof the remote
* process can be read. The input stream will only be set after a
* successful rexec() invocation.
* rexec(username, password, command, false);
***/
public void rexec(String username, String password,
String command)
throws IOException
{
rexec(username, password, command, false);
}
/***
* Disconnects from the server, closing all associated open sockets and
* streams.
* DEFAULT_PORT
.
***/
public RLoginClient()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Logins into a remote machine through the rlogind daemon on the server
* to which the RLoginClient is connected. After calling this method,
* you may interact with the remote login shell through its standard input
* and output streams. Standard error is sent over the same stream as
* standard output. You will typically be able to detect
* the termination of the remote login shell after reaching end of file
* on its standard output (accessible through
* {@link #getInputStream getInputStream() }. Disconnecting
* from the server or closing the process streams before reaching
* end of file will terminate the remote login shell in most cases.
*
* query = new NewsGroupsOrNewsQuery(new GregorianCalendar(97, 11, 15), false);
* query.addDistribution("comp");
* NewsgroupInfo[] newsgroups = client.listNewgroups(query);
*
* This will retrieve the list of newsgroups starting with the comp.
* distribution prefix created since midnight 11/15/97.
* *
wildcard, as in
* comp.lang.*
or comp.lang.java.*
. Adding
* at least one newsgroup is mandatory for the NEWNEWS command.
* *
wildcard, as in
* comp.lang.*
or comp.lang.java.*
.
*
* query.addNewsgroup("comp.lang.java.*");
* query.omitNewsgroup("comp.lang.java.advocacy");
*
* NNTPConectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
* , you must disconnect the connection with
* {@link org.apache.commons.net.nntp.NNTP#disconnect disconnect() }
* to properly clean up the
* system resources used by NNTP. Before disconnecting, you may check the
* last reply code and text with
* {@link org.apache.commons.net.nntp.NNTP#getReplyCode getReplyCode } and
* {@link org.apache.commons.net.nntp.NNTP#getReplyString getReplyString }.
* articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticle(articleId, null)
***/
public Reader retrieveArticle(String articleId) throws IOException
{
return retrieveArticle(articleId, null);
}
/*** Same as retrieveArticle(null)
***/
public Reader retrieveArticle() throws IOException
{
return retrieveArticle(null);
}
/***
* Retrieves an article from the currently selected newsgroup. The
* article is referenced by its article number.
* The article number and identifier contained in the server reply
* are returned through an ArticlePointer. The articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticle(articleNumber, null)
***/
public Reader retrieveArticle(int articleNumber) throws IOException
{
return retrieveArticle(articleNumber, null);
}
/***
* Retrieves an article header from the NNTP server. The article is
* referenced
* by its unique article identifier (including the enclosing < and >).
* The article number and identifier contained in the server reply
* are returned through an ArticlePointer. The articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticleHeader(articleId, null)
***/
public Reader retrieveArticleHeader(String articleId) throws IOException
{
return retrieveArticleHeader(articleId, null);
}
/*** Same as retrieveArticleHeader(null)
***/
public Reader retrieveArticleHeader() throws IOException
{
return retrieveArticleHeader(null);
}
/***
* Retrieves an article header from the currently selected newsgroup. The
* article is referenced by its article number.
* The article number and identifier contained in the server reply
* are returned through an ArticlePointer. The articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticleHeader(articleNumber, null)
***/
public Reader retrieveArticleHeader(int articleNumber) throws IOException
{
return retrieveArticleHeader(articleNumber, null);
}
/***
* Retrieves an article body from the NNTP server. The article is
* referenced
* by its unique article identifier (including the enclosing < and >).
* The article number and identifier contained in the server reply
* are returned through an ArticlePointer. The articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticleBody(articleId, null)
***/
public Reader retrieveArticleBody(String articleId) throws IOException
{
return retrieveArticleBody(articleId, null);
}
/*** Same as retrieveArticleBody(null)
***/
public Reader retrieveArticleBody() throws IOException
{
return retrieveArticleBody(null);
}
/***
* Retrieves an article body from the currently selected newsgroup. The
* article is referenced by its article number.
* The article number and identifier contained in the server reply
* are returned through an ArticlePointer. The articleId
* field of the ArticlePointer cannot always be trusted because some
* NNTP servers do not correctly follow the RFC 977 reply format.
* retrieveArticleBody(articleNumber, null)
***/
public Reader retrieveArticleBody(int articleNumber) throws IOException
{
return retrieveArticleBody(articleNumber, null);
}
/***
* Select the specified newsgroup to be the target of for future article
* retrieval and posting operations. Also return the newsgroup
* information contained in the server reply through the info parameter.
* selectNewsgroup(newsgroup, null)
***/
public boolean selectNewsgroup(String newsgroup) throws IOException
{
return selectNewsgroup(newsgroup, null);
}
/***
* List the command help from the server.
* selectArticle(articleId, null)
***/
public boolean selectArticle(String articleId) throws IOException
{
return selectArticle(articleId, null);
}
/****
* Same as selectArticle(null, articleId)
. Useful
* for retrieving the current article number.
***/
public boolean selectArticle(ArticlePointer pointer) throws IOException
{
return selectArticle(null, pointer);
}
/***
* Select an article in the currently selected newsgroup by its number.
* and return its article number and id through the
* pointer parameter. This is achieved through the STAT command.
* According to RFC 977, this WILL set the current article pointer
* on the server. Use this command to select an article before retrieving
* it, or to obtain an article's unique identifier given its number.
* selectArticle(articleNumber, null)
***/
public boolean selectArticle(int articleNumber) throws IOException
{
return selectArticle(articleNumber, null);
}
/***
* Select the article preceeding the currently selected article in the
* currently selected newsgroup and return its number and unique id
* through the pointer parameter. Because of deviating server
* implementations, the articleId information cannot be trusted. To
* obtain the article identifier, issue a
* selectArticle(pointer.articleNumber, pointer)
immediately
* afterward.
* selectPreviousArticle(null)
***/
public boolean selectPreviousArticle() throws IOException
{
return selectPreviousArticle(null);
}
/***
* Select the article following the currently selected article in the
* currently selected newsgroup and return its number and unique id
* through the pointer parameter. Because of deviating server
* implementations, the articleId information cannot be trusted. To
* obtain the article identifier, issue a
* selectArticle(pointer.articleNumber, pointer)
immediately
* afterward.
* selectNextArticle(null)
***/
public boolean selectNextArticle() throws IOException
{
return selectNextArticle(null);
}
/***
* List all newsgroups served by the NNTP server. If no newsgroups
* are served, a zero length array will be returned. If the command
* fails, null will be returned.
*
* writer = client.postArticle();
* if(writer == null) // failure
* return false;
* header = new SimpleNNTPHeader("foobar@foo.com", "Just testing");
* header.addNewsgroup("alt.test");
* writer.write(header.toString());
* writer.write("This is just a test");
* writer.close();
* if(!client.completePendingCommand()) // failure
* return false;
*
* NNTPConectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
* , you must disconnect the connection with
* {@link #disconnect disconnect() } to properly clean up the
* system resources used by NNTP. Before disconnecting, you may check the
* last reply code and text with
* {@link #getReplyCode getReplyCode } and
* {@link #getReplyString getReplyString }.
* DEFAULT_PORT
and initializes internal data structures
* for saving NNTP reply information.
***/
public NNTP()
{
setDefaultPort(DEFAULT_PORT);
__commandBuffer = new StringBuffer();
_replyString = null;
_reader_ = null;
_writer_ = null;
_isAllowedToPost = false;
_commandSupport_ = new ProtocolCommandSupport(this);
}
private void __getReply() throws IOException
{
_replyString = _reader_.readLine();
if (_replyString == null)
throw new NNTPConnectionClosedException(
"Connection closed without indication.");
// In case we run into an anomaly we don't want fatal index exceptions
// to be thrown.
if (_replyString.length() < 3)
throw new MalformedServerReplyException(
"Truncated server reply: " + _replyString);
try
{
_replyCode = Integer.parseInt(_replyString.substring(0, 3));
}
catch (NumberFormatException e)
{
throw new MalformedServerReplyException(
"Could not parse response code.\nServer Reply: " + _replyString);
}
if (_commandSupport_.getListenerCount() > 0)
_commandSupport_.fireReplyReceived(_replyCode, _replyString +
SocketClient.NETASCII_EOL);
if (_replyCode == NNTPReply.SERVICE_DISCONTINUED)
throw new NNTPConnectionClosedException(
"NNTP response 400 received. Server closed connection.");
}
/***
* Initiates control connections and gets initial reply, determining
* if the client is allowed to post to the server. Initializes
* {@link #_reader_} and {@link #_writer_} to wrap
* {@link SocketClient#_input_} and {@link SocketClient#_output_}.
***/
@Override
protected void _connectAction_() throws IOException
{
super._connectAction_();
_reader_ =
new BufferedReader(new InputStreamReader(_input_,
__DEFAULT_ENCODING));
_writer_ =
new BufferedWriter(new OutputStreamWriter(_output_,
__DEFAULT_ENCODING));
__getReply();
_isAllowedToPost = (_replyCode == NNTPReply.SERVER_READY_POSTING_ALLOWED);
}
/***
* Adds a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
* connect
is of type void.
*
* writer = client.postArticle();
* if(writer == null) // failure
* return false;
* header = new SimpleNNTPHeader("foobar@foo.com", "Just testing");
* header.addNewsgroup("alt.test");
* header.addHeaderField("Organization", "Foobar, Inc.");
* writer.write(header.toString());
* writer.write("This is just a test");
* writer.close();
* if(!client.completePendingCommand()) // failure
* return false;
*
* From:
header field. This
* should be the article poster's email address.
* @param subject The value of the Subject:
header field.
* This should be the subject of the article.
***/
public SimpleNNTPHeader(String from, String subject)
{
__from = from;
__subject = subject;
__newsgroups = new StringBuilder();
__headerFields = new StringBuilder();
__newsgroupCount = 0;
}
/***
* Adds a newsgroup to the article Newsgroups:
field.
*
* header.addHeaderField("Organization", "Foobar, Inc.");
*
* From:
header field.
* Subject:
header field.
* Newsgroups:
header field.
* POSTING_PERMISSION
constants.
*
* WhoisClient whois;
*
* whois = new WhoisClient();
*
* try {
* whois.connect(WhoisClient.DEFAULT_HOST);
* System.out.println(whois.query("foobar"));
* whois.disconnect();
* } catch(IOException e) {
* System.err.println("Error I/O exception: " + e.getMessage());
* return;
* }
*
*
* DEFAULT_PORT
.
***/
public WhoisClient()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Queries the connected whois server for information regarding
* the given handle. It is up to the programmer to be familiar with the
* handle syntax of the whois server. You must first connect to a whois
* server before calling this method, and you should disconnect afterward.
* copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE);
***/
public static final long copyStream(InputStream source, OutputStream dest)
throws CopyStreamException
{
return copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE);
}
/***
* Copies the contents of a Reader to a Writer using a
* copy buffer of a given size and notifies the provided
* CopyStreamListener of the progress of the copy operation by calling
* its bytesTransferred(long, int) method after each write to the
* destination. If you wish to notify more than one listener you should
* use a CopyStreamAdapter as the listener and register the additional
* listeners with the CopyStreamAdapter.
* copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE);
***/
public static final long copyReader(Reader source, Writer dest)
throws CopyStreamException
{
return copyReader(source, dest, DEFAULT_COPY_BUFFER_SIZE);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java 0000644 0001750 0001750 00000011340 11354710167 027324 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.util.EventListener;
import org.apache.commons.net.util.ListenerList;
/**
* The CopyStreamAdapter will relay CopyStreamEvents to a list of listeners
* when either of its bytesTransferred() methods are called. Its purpose
* is to facilitate the notification of the progress of a copy operation
* performed by one of the static copyStream() methods in
* org.apache.commons.io.Util to multiple listeners. The static
* copyStream() methods invoke the
* bytesTransfered(long, int) of a CopyStreamListener for performance
* reasons and also because multiple listeners cannot be registered given
* that the methods are static.
* UNKNOWN_STREAM_SIZE
if the
* size is unknown.
*/
public CopyStreamEvent(Object source, long totalBytesTransferred,
int bytesTransferred, long streamSize)
{
super(source);
this.bytesTransferred = bytesTransferred;
this.totalBytesTransferred = totalBytesTransferred;
this.streamSize = streamSize;
}
/**
* Returns the number of bytes transferred by the write that triggered
* the event.
* @return The number of bytes transferred by the write that triggered
* the vent.
*/
public int getBytesTransferred()
{
return bytesTransferred;
}
/**
* Returns the total number of bytes transferred so far by the copy
* operation.
* @return The total number of bytes transferred so far by the copy
* operation.
*/
public long getTotalBytesTransferred()
{
return totalBytesTransferred;
}
/**
* Returns the size of the stream being copied.
* This may be set to UNKNOWN_STREAM_SIZE
if the
* size is unknown.
* @return The size of the stream being copied.
*/
public long getStreamSize()
{
return streamSize;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java 0000644 0001750 0001750 00000015051 11330134214 031170 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.io;
import java.io.IOException;
import java.io.Writer;
/***
* DotTerminatedMessageWriter is a class used to write messages to a
* server that are terminated by a single dot followed by a
* <CR><LF>
* sequence and with double dots appearing at the begining of lines which
* do not signal end of message yet start with a dot. Various Internet
* protocols such as NNTP and POP3 produce messages of this type.
* flush()
will
* not flush the last byte written if that byte was a carriage
* return. A call to {@link #close close() }, however, will
* flush the carriage return.
*
* FingerClient finger;
*
* finger = new FingerClient();
*
* try {
* finger.connect("foo.bar.com");
* System.out.println(finger.query("foobar", false));
* finger.disconnect();
* } catch(IOException e) {
* System.err.println("Error I/O exception: " + e.getMessage());
* return;
* }
*
* DEFAULT_PORT
.
***/
public FingerClient()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Fingers a user at the connected host and returns the output
* as a String. You must first connect to a finger server before
* calling this method, and you should disconnect afterward.
* query(longOutput, "")
.
* DEFAULT_PORT
.
***/
public CharGenTCPClient ()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Returns an InputStream from which the server generated data can be
* read. You should NOT close the InputStream when you're finished
* reading from it. Rather, you should call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to clean up properly.
* send(host, CharGenUDPClient.DEFAULT_PORT);
***/
public void send(InetAddress host) throws IOException
{
send(host, DEFAULT_PORT);
}
/***
* Receive the reply data from the server. This will always be 512 bytes
* or less. Chargen and quote of the day only return one packet. Netstat
* and systat require multiple calls to receive() with timeout detection.
*
* try {
* int reply;
* client.connect("mail.foobar.com");
* System.out.print(client.getReplyString());
*
* // After connection attempt, you should check the reply code to verify
* // success.
* reply = client.getReplyCode();
*
* if(!SMTPReply.isPositiveCompletion(reply)) {
* client.disconnect();
* System.err.println("SMTP server refused connection.");
* System.exit(1);
* }
*
* // Do useful stuff here.
* ...
* } catch(IOException e) {
* if(client.isConnected()) {
* try {
* client.disconnect();
* } catch(IOException f) {
* // do nothing
* }
* }
* System.err.println("Could not connect to server.");
* e.printStackTrace();
* System.exit(1);
* }
*
* SMTPConectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
* , you must disconnect the connection with
* {@link #disconnect disconnect() } to properly clean up the
* system resources used by SMTPClient. Before disconnecting, you may check
* the last reply code and text with
* {@link org.apache.commons.net.smtp.SMTP#getReplyCode getReplyCode },
* {@link org.apache.commons.net.smtp.SMTP#getReplyString getReplyString },
* and
* {@link org.apache.commons.net.smtp.SMTP#getReplyStrings getReplyStrings}.
*
* writer = client.sendMessage();
* if(writer == null) // failure
* return false;
* header =
* new SimpleSMTPHeader("foobar@foo.com", "foo@foobar.com", "Re: Foo");
* writer.write(header.toString());
* writer.write("This is just a test");
* writer.close();
* if(!client.completePendingCommand()) // failure
* return false;
*
* < @bar.com,@foo.com:foobar@foo.com >
*
* path = new RelayPath("foobar@foo.com");
* path.addRelay("bar.com");
* path.addRelay("foo.com");
*
*
* writer = client.sendMessageData();
* if(writer == null) // failure
* return false;
* header =
* new SimpleSMTPHeader("foobar@foo.com", "foo@bar.com" "Just testing");
* header.addCC("bar@foo.com");
* header.addHeaderField("Organization", "Foobar, Inc.");
* writer.write(header.toString());
* writer.write("This is just a test");
* writer.close();
* if(!client.completePendingCommand()) // failure
* return false;
*
* From:
header field. This
* should be the sender's email address.
* @param to The value of the To:
header field. This
* should be the recipient's email address.
* @param subject The value of the Subject:
header field.
* This should be the subject of the message.
***/
public SimpleSMTPHeader(String from, String to, String subject)
{
__to = to;
__from = from;
__subject = subject;
__headerFields = new StringBuffer();
__cc = null;
}
/***
* Adds an arbitrary header field with the given value to the article
* header. These headers will be written before the From, To, Subject, and
* Cc fields when the SimpleSMTPHeader is convertered to a string.
* An example use would be:
*
* header.addHeaderField("Organization", "Foobar, Inc.");
*
* SMTPConectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
* , you must disconnect the connection with
* {@link org.apache.commons.net.SocketClient#disconnect disconnect() }
* to properly clean up the system resources used by SMTP. Before
* disconnecting, you may check the
* last reply code and text with
* {@link #getReplyCode getReplyCode },
* {@link #getReplyString getReplyString },
* and {@link #getReplyStrings getReplyStrings}.
* DEFAULT_PORT
and initializes internal data structures
* for saving SMTP reply information.
***/
public SMTP()
{
setDefaultPort(DEFAULT_PORT);
__commandBuffer = new StringBuffer();
_replyLines = new ArrayList connect
is of type void.
* number
* contains the number of messages in the mailbox, size
* contains the size of the mailbox in bytes, and identifier
* is null.
* number
* contains the message number, size
contains the
* size of the message in bytes, and identifier
is null.
* number
contains
* the message number, size
is undefined, and
* identifier
contains the message's unique identifier.
* number
and
* size
set to 0, and identifier
set to
* null.
***/
public POP3MessageInfo()
{
number = size = 0;
identifier = null;
}
/***
* Creates a POP3MessageInfo instance with number
set
* to num
, size
set to octets
,
* and identifier
set to null.
***/
public POP3MessageInfo(int num, int octets)
{
number = num;
size = octets;
identifier = null;
}
/***
* Creates a POP3MessageInfo instance with number
set
* to num
, size
undefined,
* and identifier
set to uid
.
***/
public POP3MessageInfo(int num, String uid)
{
number = num;
size = -1;
identifier = uid;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/pop3/POP3Client.java 0000644 0001750 0001750 00000051650 11354512541 026073 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.pop3;
import java.io.IOException;
import java.io.Reader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.StringTokenizer;
import org.apache.commons.net.io.DotTerminatedMessageReader;
/***
* The POP3Client class implements the client side of the Internet POP3
* Protocol defined in RFC 1939. All commands are supported, including
* the APOP command which requires MD5 encryption. See RFC 1939 for
* more details on the POP3 protocol.
* DISCONNECTED_STATE
.
***/
public POP3()
{
setDefaultPort(DEFAULT_PORT);
__commandBuffer = new StringBuffer();
__popState = DISCONNECTED_STATE;
_reader = null;
__writer = null;
_replyLines = new Vector AUTHORIZATION_STATE
.
***/
@Override
protected void _connectAction_() throws IOException
{
super._connectAction_();
_reader =
new BufferedReader(new InputStreamReader(_input_,
__DEFAULT_ENCODING));
__writer =
new BufferedWriter(new OutputStreamWriter(_output_,
__DEFAULT_ENCODING));
__getReply();
setState(AUTHORIZATION_STATE);
}
/***
* Adds a ProtocolCommandListener. Delegates this task to
* {@link #_commandSupport_ _commandSupport_ }.
* _STATE
constants.
* DISCONNECTED_STATE
. The reply text information
* from the last issued command is voided to allow garbage collection
* of the memory used to store that information.
* getReplyStrings
* again. You only have to worry about this if you are implementing
* your own client using the {@link #sendCommand sendCommand } methods.
* getReplyString
* again. You only have to worry about this if you are implementing
* your own client using the {@link #sendCommand sendCommand } methods.
* super._connectAction_()
first to ensure the
* initialization of the aforementioned protected variables.
*/
protected void _connectAction_() throws IOException
{
_socket_.setSoTimeout(_timeout_);
_input_ = _socket_.getInputStream();
_output_ = _socket_.getOutputStream();
}
/**
* Opens a Socket connected to a remote host at the specified port and
* originating from the current host at a system assigned port.
* Before returning, {@link #_connectAction_ _connectAction_() }
* is called to perform connection initialization actions.
* getTime(host, DEFAULT_PORT);
***/
public long getTime(InetAddress host) throws IOException
{
return getTime(host, DEFAULT_PORT);
}
/***
* Retrieves the time from the server and returns a Java Date
* containing the time converted to the local timezone.
* getTime(host, DEFAULT_PORT);
***/
public Date getDate(InetAddress host) throws IOException
{
return new Date((getTime(host, DEFAULT_PORT) -
SECONDS_1900_TO_1970)*1000L);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/time/TimeTCPClient.java 0000644 0001750 0001750 00000010023 10766054003 026661 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.time;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Date;
import org.apache.commons.net.SocketClient;
/***
* The TimeTCPClient class is a TCP implementation of a client for the
* Time protocol described in RFC 868. To use the class, merely
* establish a connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* and call either {@link #getTime getTime() } or
* {@link #getDate getDate() } to retrieve the time, then
* call {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to close the connection properly.
* DEFAULT_PORT
.
***/
public TimeTCPClient ()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Retrieves the time from the server and returns it. The time
* is the number of seconds since 00:00 (midnight) 1 January 1900 GMT,
* as specified by RFC 868. This method reads the raw 32-bit big-endian
* unsigned integer from the server, converts it to a Java long, and
* returns the value.
* getTime()
again.
* getDate()
again.
* config
are somehow inadequate to configure the
* Configurable object.
*/
public void configure(FTPClientConfig config);
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPFile.java 0000644 0001750 0001750 00000023601 11352735312 025350 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.Serializable;
import java.util.Calendar;
/***
* The FTPFile class is used to represent information about files stored
* on an FTP server.
* DIRECTORY_TYPE
, false if
* not.
***/
public boolean isDirectory()
{
return (_type == DIRECTORY_TYPE);
}
/***
* Determine if the file is a regular file.
* FILE_TYPE
, false if
* not.
***/
public boolean isFile()
{
return (_type == FILE_TYPE);
}
/***
* Determine if the file is a symbolic link.
* UNKNOWN_TYPE
, false if
* not.
***/
public boolean isSymbolicLink()
{
return (_type == SYMBOLIC_LINK_TYPE);
}
/***
* Determine if the type of the file is unknown.
* UNKNOWN_TYPE
, false if
* not.
***/
public boolean isUnknown()
{
return (_type == UNKNOWN_TYPE);
}
/***
* Set the type of the file (DIRECTORY_TYPE
,
* FILE_TYPE
, etc.).
* _TYPE
constants),
* e.g., if it is a directory, a regular file, or a symbolic link.
* _ACCESS
* constants) has the given access permission (one of the
* _PERMISSION
constants) to the file.
* _ACCESS
* constants)
* @param permission The access permission (one of the
* _PERMISSION
constants)
* @param value True if permission is allowed, false if not.
***/
public void setPermission(int access, int permission, boolean value)
{
_permissions[access][permission] = value;
}
/***
* Determines if the given access group (one of the _ACCESS
* constants) has the given access permission (one of the
* _PERMISSION
constants) to the file.
* _ACCESS
* constants)
* @param permission The access permission (one of the
* _PERMISSION
constants)
***/
public boolean hasPermission(int access, int permission)
{
return _permissions[access][permission];
}
/***
* Returns a string representation of the FTPFile information. This
* will be the raw FTP server listing that was used to initialize the
* FTPFile instance.
* Examples of use of FTPClientConfig
* Use cases:
* You are trying to access a server that
*
*
* MM dd yyyy
MMM d yyyy
date formatting
*
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setServerLanguageCode("fr");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
*
*
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setServerLanguageCode("da");
* conf.setDefaultDateFormat("d MMM yyyy");
* conf.setRecentDateFormat("d MMM HH:mm");
* conf.setTimeZoneId("Europe/Copenhagen");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine =
* f.initiateListParsing("com.whatever.YourOwnParser", directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
* MMM d yyyy
date formatting
*
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_VMS);
* conf.setShortMonthNames(
* "jan|feb|mar|apr|ma\u00ED|j\u00FAn|j\u00FAl|\u00e1g\u00FA|sep|okt|n\u00F3v|des");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
*
*
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
* conf.setTimeZoneId("America/Denver");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
*
*
* FTPClient f=FTPClient();
* FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
* conf.setTimeZoneId("America/Denver");
* f.configure(conf);
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
*
* FTPClientConfig.SYST_*
codes
* or else the fully qualified class name of a parser implementing both
* the FTPFileEntryParser
and Configurable
* interfaces.
* @return Returns the serverSystemKey property.
*/
public String getServerSystemKey() {
return serverSystemKey;
}
/**
* getter for the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr}
* property.
* @return Returns the defaultDateFormatStr property.
*/
public String getDefaultDateFormatStr() {
return defaultDateFormatStr;
}
/**
* getter for the {@link #setRecentDateFormatStr(String) recentDateFormatStr} property.
* @return Returns the recentDateFormatStr property.
*/
public String getRecentDateFormatStr() {
return recentDateFormatStr;
}
/**
* getter for the {@link #setServerTimeZoneId(String) serverTimeZoneId} property.
* @return Returns the serverTimeZoneId property.
*/
public String getServerTimeZoneId() {
return serverTimeZoneId;
}
/**
* en_US
locales.
* java.text.SimpleDateFormat
.
* property.
* java.text.SimpleDateFormat
.
* java.util.TimeZone
to refer to time zones, for example,
* America/Chicago
or Asia/Rangoon
.
* "jan|feb|mar|apr|maí|jún|júl|ágú|sep|okt|nóv|des"
.
* en_US
* month names will be used. We are supporting here those language
* codes which, when a java.util.Locale
is constucted
* using it, and a java.text.SimpleDateFormat
is
* constructed using that Locale, the array returned by the
* SimpleDateFormat's getShortMonths()
method consists
* solely of three 8-bit ASCII character strings. Additionally,
* languages which do not meet this requirement are included if a
* common alternative set of short month names is known to be used.
* This means that users who can tell us of additional such encodings
* may get them added to the list of supported languages by contacting
* the Apache Commons Net team.
* en_US
date format
* orderings of MMM d yyyy
and MMM d HH:mm
* and attempting to deduce this automatically here would cause more
* problems than it would solve. The date format must be changed
* via the {@link #setDefaultDateFormatStr(String) defaultDateFormatStr} and/or
* {@link #setRecentDateFormatStr(String) recentDateFormatStr} parameters.
* Locale.US
* @param languageCode See {@link #setServerLanguageCode(String) serverLanguageCode}
* @return a DateFormatSymbols object configured with short month names
* corresponding to the supplied code, or with month names for
* Locale.US
if there is no corresponding entry in the internal
* table.
*/
public static DateFormatSymbols lookupDateFormatSymbols(String languageCode)
{
Object lang = LANGUAGE_CODE_MAP.get(languageCode);
if (lang != null) {
if (lang instanceof Locale) {
return new DateFormatSymbols((Locale) lang);
} else if (lang instanceof String){
return getDateFormatSymbols((String) lang);
}
}
return new DateFormatSymbols(Locale.US);
}
/**
* Returns a DateFormatSymbols object configured with short month names
* as in the supplied string
* @param shortmonths This should be as described in
* {@link #setShortMonthNames(String) shortMonthNames}
* @return a DateFormatSymbols object configured with short month names
* as in the supplied string
*/
public static DateFormatSymbols getDateFormatSymbols(String shortmonths)
{
String[] months = splitShortMonthString(shortmonths);
DateFormatSymbols dfs = new DateFormatSymbols(Locale.US);
dfs.setShortMonths(months);
return dfs;
}
private static String[] splitShortMonthString(String shortmonths) {
StringTokenizer st = new StringTokenizer(shortmonths, "|");
int monthcnt = st.countTokens();
if (12 != monthcnt) {
throw new IllegalArgumentException(
"expecting a pipe-delimited string containing 12 tokens");
}
String[] months = new String[13];
int pos = 0;
while(st.hasMoreTokens()) {
months[pos++] = st.nextToken();
}
months[pos]="";
return months;
}
/**
* Returns a Collection of all the language codes currently supported
* by this class. See {@link #setServerLanguageCode(String) serverLanguageCode}
* for a functional descrption of language codes within this system.
*
* @return a Collection of all the language codes currently supported
* by this class
*/
public static CollectionFTPFile
objects are not created until needed. This
* is suitable for paged displays. It requires that a parser object be created
* beforehand: parser
is an object (in the package
* org.apache.commons.net.ftp.parser
)
* implementing this inteface.
*
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFileList list = f.createFileList(directory, parser);
* FTPFileIterator iter = list.iterator();
*
* while (iter.hasNext()) {
* FTPFile[] files = iter.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
*
* The second example uses the revised FTPClient.listFiles()
* API to pull the whole list from the subfolder subfolder
in
* one call, attempting to automatically detect the parser type. This
* method, without a parserKey parameter, indicates that autodection should
* be used.
*
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles("subfolder");
*
*
* The third example uses the revised FTPClient.listFiles()
>
* API to pull the whole list from the current working directory in one call,
* but specifying by classname the parser to be used. For this particular
* parser class, this approach is necessary since there is no way to
* autodetect this server type.
*
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles(
* "org.apache.commons.net.ftp.parser.EnterpriseUnixFTPFileEntryParser",
* ".");
*
*
* The fourth example uses the revised FTPClient.listFiles()
* API to pull a single file listing in an arbitrary directory in one call,
* specifying by KEY the parser to be used, in this case, VMS.
*
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = f.listFiles("VMS", "subfolder/foo.java");
*
*
* @author Steve Cohen
* @version $Id: FTPFileEntryParser.java 748376 2009-02-27 01:57:19Z sebb $
* @see org.apache.commons.net.ftp.FTPFile
* @see org.apache.commons.net.ftp.FTPClient#listFiles()
*/
public interface FTPFileEntryParser
{
/**
* Parses a line of an FTP server file listing and converts it into a usable
* format in the form of an FTPFile
instance. If the
* file listing line doesn't describe a file, null
should be
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
* readNextEntry()
- which handles the issue of
* what delimits one entry from another, usually but not always a line
* feed and preParse()
- which handles removal of
* extraneous matter such as the preliminary lines of a listing, removal
* of duplicates on versioning systems, etc.
* getNext()
and
* getPrevious()
methods to provide "paged" output of less
* than the whole list at one time, or by calling the
* getFiles()
method to return the entire list.
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine = f.initiateListParsing(directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
* entries
list.
* After this method has completed, entries
will contain a
* collection of entries (as defined by
* FTPFileEntryParser.readNextEntry()
), but this may contain
* various non-entry preliminary lines from the server output, duplicates,
* and other data that will not be part of the final listing.
*
* @param stream The socket stream on which the input will be read.
* @param encoding The encoding to use.
*
* @exception IOException
* thrown on any failure to read the stream
*/
private void readStream(InputStream stream, String encoding) throws IOException
{
BufferedReader reader;
if (encoding == null)
{
reader = new BufferedReader(new InputStreamReader(stream));
}
else
{
reader = new BufferedReader(new InputStreamReader(stream, encoding));
}
String line = this.parser.readNextEntry(reader);
while (line != null)
{
this.entries.add(line);
line = this.parser.readNextEntry(reader);
}
reader.close();
}
/**
* Returns an array of at most quantityRequested
FTPFile
* objects starting at this object's internal iterator's current position.
* If fewer than quantityRequested
such
* elements are available, the returned array will have a length equal
* to the number of entries at and after after the current position.
* If no such entries are found, this array will have a length of 0.
*
* After this method is called this object's internal iterator is advanced
* by a number of positions equal to the size of the array returned.
*
* @param quantityRequested
* the maximum number of entries we want to get.
*
* @return an array of at most quantityRequested
FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
* and after its current position.
* quantityRequested
FTPFile
* objects starting at this object's internal iterator's current position,
* and working back toward the beginning.
*
* If fewer than quantityRequested
such
* elements are available, the returned array will have a length equal
* to the number of entries at and after after the current position.
* If no such entries are found, this array will have a length of 0.
*
* After this method is called this object's internal iterator is moved
* back by a number of positions equal to the size of the array returned.
*
* @param quantityRequested
* the maximum number of entries we want to get.
*
* @return an array of at most quantityRequested
FTPFile
* objects starting at the current position of this iterator within its
* list and at least the number of elements which exist in the list at
* and after its current position. This array will be in the same order
* as the underlying list (not reversed).
* null
.
*
* @return an array of FTPFile objects containing the whole list of
* files returned by the server as read by this object's parser.
* original
unmodified.
*/
public List
* boolean error = false;
* try {
* int reply;
* ftp.connect("ftp.foobar.com");
* System.out.println("Connected to " + server + ".");
* System.out.print(ftp.getReplyString());
*
* // After connection attempt, you should check the reply code to verify
* // success.
* reply = ftp.getReplyCode();
*
* if(!FTPReply.isPositiveCompletion(reply)) {
* ftp.disconnect();
* System.err.println("FTP server refused connection.");
* System.exit(1);
* }
* ... // transfer files
* ftp.logout();
* } catch(IOException e) {
* error = true;
* e.printStackTrace();
* } finally {
* if(ftp.isConnected()) {
* try {
* ftp.disconnect();
* } catch(IOException ioe) {
* // do nothing
* }
* }
* System.exit(error ? 1 : 0);
* }
*
* FTP.ASCII_FILE_TYPE
,
* FTP.NON_PRINT_TEXT_FORMAT
,
* FTP.STREAM_TRANSFER_MODE
, and
* FTP.FILE_STRUCTURE
. The only file types directly supported
* are FTP.ASCII_FILE_TYPE
and
* FTP.BINARY_FILE_TYPE
. Because there are at least 4
* different EBCDIC encodings, we have opted not to provide direct support
* for EBCDIC. To transfer EBCDIC and other unsupported file types you
* must create your own filter InputStreams and OutputStreams and wrap
* them around the streams returned or required by the FTPClient methods.
* FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}
* filter streams to provide transparent handling of ASCII files. We will
* consider incorporating EBCDIC support if there is enough demand.
* FTP.NON_PRINT_TEXT_FORMAT
,
* FTP.STREAM_TRANSFER_MODE
, and
* FTP.FILE_STRUCTURE
are the only supported formats,
* transfer modes, and file structures.
* FTPConnectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
* , you must disconnect the connection with
* {@link #disconnect disconnect() } to properly clean up the
* system resources used by FTPClient. Before disconnecting, you may check the
* last reply code and text with
* {@link org.apache.commons.net.ftp.FTP#getReplyCode getReplyCode },
* {@link org.apache.commons.net.ftp.FTP#getReplyString getReplyString },
* and
* {@link org.apache.commons.net.ftp.FTP#getReplyStrings getReplyStrings}.
* You may avoid server disconnections while the client is idle by
* periodically sending NOOP commands to the server.
*
* FTPClient f = new FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPFile[] files = listFiles(directory);
*
*
* FTPClient f = new FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine =
* f.initiateListParsing("com.whatever.YourOwnParser", directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
*
* FTPClient f = new FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine = f.initiateListParsing(directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
*
*
see {@link FTPClientConfig FTPClientConfig}.
* MM d yyyy
ACTIVE_LOCAL_DATA_CONNECTION_MODE
, the file type
* set to FTP.ASCII_FILE_TYPE
, the
* file format set to FTP.NON_PRINT_TEXT_FORMAT
,
* the file structure set to FTP.FILE_STRUCTURE
, and
* the transfer mode set to FTP.STREAM_TRANSFER_MODE
.
***/
public FTPClient()
{
__initDefaults();
__dataTimeout = -1;
__remoteVerificationEnabled = true;
__parserFactory = new DefaultFTPFileEntryParserFactory();
__configuration = null;
__listHiddenFiles = false;
__useEPSVwithIPv4 = false;
__random = new Random();
}
private void __initDefaults()
{
__dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
__passiveHost = null;
__passivePort = -1;
__activeExternalHost = null;
__activeMinPort = 0;
__activeMaxPort = 0;
__fileType = FTP.ASCII_FILE_TYPE;
__fileStructure = FTP.FILE_STRUCTURE;
__fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
__fileTransferMode = FTP.STREAM_TRANSFER_MODE;
__restartOffset = 0;
__systemName = null;
__entryParser = null;
__entryParserKey = "";
__bufferSize = Util.DEFAULT_COPY_BUFFER_SIZE;
}
private String __parsePathname(String reply)
{
int begin, end;
begin = reply.indexOf('"') + 1;
end = reply.indexOf('"', begin);
return reply.substring(begin, end);
}
private void __parsePassiveModeReply(String reply)
throws MalformedServerReplyException
{
java.util.regex.Matcher m = __parms_pat.matcher(reply);
if (!m.find()) {
throw new MalformedServerReplyException(
"Could not parse passive host information.\nServer Reply: " + reply);
}
reply = m.group();
String parts[] = m.group().split(",");
__passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' + parts[3];
try
{
int oct1 = Integer.parseInt(parts[4]);
int oct2 = Integer.parseInt(parts[5]);
__passivePort = (oct1 << 8) | oct2;
}
catch (NumberFormatException e)
{
throw new MalformedServerReplyException(
"Could not parse passive host information.\nServer Reply: " + reply);
}
}
private void __parseExtendedPassiveModeReply(String reply)
throws MalformedServerReplyException
{
int port;
reply = reply.substring(reply.indexOf('(') + 1,
reply.indexOf(')')).trim();
char delim1, delim2, delim3, delim4;
delim1 = reply.charAt(0);
delim2 = reply.charAt(1);
delim3 = reply.charAt(2);
delim4 = reply.charAt(reply.length()-1);
if (!(delim1 == delim2) || !(delim2 == delim3)
|| !(delim3 == delim4))
throw new MalformedServerReplyException(
"Could not parse extended passive host information.\nServer Reply: " + reply);
try
{
port = Integer.parseInt(reply.substring(3, reply.length()-1));
}
catch (NumberFormatException e)
{
throw new MalformedServerReplyException(
"Could not parse extended passive host information.\nServer Reply: " + reply);
}
// in EPSV mode, the passive host address is implicit
__passiveHost = getRemoteAddress().getHostAddress();
__passivePort = port;
}
private boolean __storeFile(int command, String remote, InputStream local)
throws IOException
{
OutputStream output;
Socket socket;
if ((socket = _openDataConnection_(command, remote)) == null)
return false;
output = new BufferedOutputStream(socket.getOutputStream(),
getBufferSize()
);
if (__fileType == ASCII_FILE_TYPE)
output = new ToNetASCIIOutputStream(output);
// Treat everything else as binary for now
try
{
Util.copyStream(local, output, getBufferSize(),
CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
false);
}
catch (IOException e)
{
try
{
socket.close();
}
catch (IOException f)
{}
throw e;
}
output.close();
socket.close();
return completePendingCommand();
}
private OutputStream __storeFileStream(int command, String remote)
throws IOException
{
OutputStream output;
Socket socket;
if ((socket = _openDataConnection_(command, remote)) == null)
return null;
output = socket.getOutputStream();
if (__fileType == ASCII_FILE_TYPE) {
// We buffer ascii transfers because the buffering has to
// be interposed between ToNetASCIIOutputSream and the underlying
// socket output stream. We don't buffer binary transfers
// because we don't want to impose a buffering policy on the
// programmer if possible. Programmers can decide on their
// own if they want to wrap the SocketOutputStream we return
// for file types other than ASCII.
output = new BufferedOutputStream(output,
getBufferSize());
output = new ToNetASCIIOutputStream(output);
}
return new org.apache.commons.net.io.SocketOutputStream(socket, output);
}
/**
* Establishes a data connection with the FTP server, returning
* a Socket for the connection if successful. If a restart
* offset has been set with {@link #setRestartOffset(long)},
* a REST command is issued to the server with the offset as
* an argument before establishing the data connection. Active
* mode connections also cause a local PORT command to be issued.
* ACTIVE_LOCAL_DATA_CONNECTION_MODE
. No communication
* with the FTP server is conducted, but this causes all future data
* transfers to require the FTP server to connect to the client's
* data port. Additionally, to accommodate differences between socket
* implementations on different platforms, this method causes the
* client to issue a PORT command before every data transfer.
***/
public void enterLocalActiveMode()
{
__dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
__passiveHost = null;
__passivePort = -1;
}
/***
* Set the current data connection mode to
* PASSIVE_LOCAL_DATA_CONNECTION_MODE
. Use this
* method only for data transfers between the client and server.
* This method causes a PASV (or EPSV) command to be issued to the server
* before the opening of every data connection, telling the server to
* open a data port to which the client will connect to conduct
* data transfers. The FTPClient will stay in
* PASSIVE_LOCAL_DATA_CONNECTION_MODE
until the
* mode is changed by calling some other method such as
* {@link #enterLocalActiveMode enterLocalActiveMode() }
* ACTIVE_REMOTE_DATA_CONNECTION
. Use this method only
* for server to server data transfers. This method issues a PORT
* command to the server, indicating the other server and port to which
* it should connect for data transfers. You must call this method
* before EVERY server to server transfer attempt. The FTPClient will
* NOT automatically continue to issue PORT commands. You also
* must remember to call
* {@link #enterLocalActiveMode enterLocalActiveMode() } if you
* wish to return to the normal data connection mode.
* PASSIVE_REMOTE_DATA_CONNECTION_MODE
. Use this
* method only for server to server data transfers.
* This method issues a PASV command to the server, telling it to
* open a data port to which the active server will connect to conduct
* data transfers. You must call this method
* before EVERY server to server transfer attempt. The FTPClient will
* NOT automatically continue to issue PASV commands. You also
* must remember to call
* {@link #enterLocalActiveMode enterLocalActiveMode() } if you
* wish to return to the normal data connection mode.
* _DATA_CONNECTION_MODE
constants.
* _DATA_CONNECTION_MODE
constants.
***/
public int getDataConnectionMode()
{
return __dataConnectionMode;
}
/**
* Get the client port for active mode.
* FTP.ASCII_FILE_TYPE
, FTP.BINARY_FILE_TYPE
,
* etc. The file type only needs to be set when you want to change the
* type. After changing it, the new type stays in effect until you change
* it again. The default file type is FTP.ASCII_FILE_TYPE
* if this method is never called.
* _FILE_TYPE
constant indcating the
* type of file.
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setFileType(int fileType) throws IOException
{
if (FTPReply.isPositiveCompletion(type(fileType)))
{
__fileType = fileType;
__fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
return true;
}
return false;
}
/***
* Sets the file type to be transferred and the format. The type should be
* one of FTP.ASCII_FILE_TYPE
,
* FTP.BINARY_FILE_TYPE
, etc. The file type only needs to
* be set when you want to change the type. After changing it, the new
* type stays in effect until you change it again. The default file type
* is FTP.ASCII_FILE_TYPE
if this method is never called.
* The format should be one of the FTP class TEXT_FORMAT
* constants, or if the type is FTP.LOCAL_FILE_TYPE
, the
* format should be the byte size for that type. The default format
* is FTP.NON_PRINT_TEXT_FORMAT
if this method is never
* called.
* _FILE_TYPE
constant indcating the
* type of file.
* @param formatOrByteSize The format of the file (one of the
* _FORMAT
constants. In the case of
* LOCAL_FILE_TYPE
, the byte size.
* FTP.FILE_STRUCTURE
if this method is never called.
* _STRUCTURE
constants).
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setFileStructure(int structure) throws IOException
{
if (FTPReply.isPositiveCompletion(stru(structure)))
{
__fileStructure = structure;
return true;
}
return false;
}
/***
* Sets the transfer mode. The default transfer mode
* FTP.STREAM_TRANSFER_MODE
if this method is never called.
* _TRANSFER_MODE
constants).
* @return True if successfully completed, false if not.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
***/
public boolean setFileTransferMode(int mode) throws IOException
{
if (FTPReply.isPositiveCompletion(mode(mode)))
{
__fileTransferMode = mode;
return true;
}
return false;
}
/***
* Initiate a server to server file transfer. This method tells the
* server to which the client is connected to retrieve a given file from
* the other server.
* remoteRetrieve
issued to it by another
* FTPClient.
* remoteRetrieve
issued
* to it by another FTPClient.
* remoteRetrieve
issued
* to it by another FTPClient. Many FTP servers require that a base
* filename be given from which the unique filename can be derived. For
* those servers use the other version of remoteStoreUnique
* remoteRetrieve
issued to it by another FTPClient.
*
* InputStream input;
* OutputStream output;
* input = new FileInputStream("foobaz.txt");
* output = ftp.storeFileStream("foobar.txt")
* if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
* input.close();
* output.close();
* ftp.logout();
* ftp.disconnect();
* System.err.println("File transfer failed.");
* System.exit(1);
* }
* Util.copyStream(input, output);
* input.close();
* output.close();
* // Must call completePendingCommand() to finish command.
* if(!ftp.completePendingCommand()) {
* ftp.logout();
* ftp.disconnect();
* System.err.println("File transfer failed.");
* System.exit(1);
* }
*
*
C> feat
S> 211-Extensions supported:
S> MLST size*;create;modify*;perm;media-type
S> SIZE
S> COMPRESSION
S> MDTM
S> 211 END
*
* @see http://www.faqs.org/rfcs/rfc2389.html
* @return True if successfully completed, false if not.
* @throws IOException
* @since 2.2
*/
public boolean features() throws IOException {
return FTPReply.isPositiveCompletion(feat());
}
/**
* Reserve space on the server for the next file transfer.
* STREAM_TRANSFER_MODE
file transfer starting
* from the given offset. This will only work on FTP servers supporting
* the REST comand for the stream transfer mode. However, most FTP
* servers support this. Any subsequent file transfer will start
* reading or writing the remote file from the indicated offset.
* FTPFileEntryParser
* used.
* FTPFileEntryParser
* used.
* listFiles("site", FTPFileFilters.DIRECTORY);
* @param pathname the initial path, may be null
* @param filter the filter, non-null
* @return the list of FTPFile entries.
* @throws IOException
* @since 2.2
*/
public FTPFile[] listFiles(String pathname, FTPFileFilter filter)
throws IOException
{
FTPListParseEngine engine = initiateListParsing((String) null, pathname);
return engine.getFiles(filter);
}
/**
* Using the default autodetect mechanism, initialize an FTPListParseEngine
* object containing a raw file information for the current working
* directory on the server
* This information is obtained through the LIST command. This object
* is then capable of being iterated to return a sequence of FTPFile
* objects with information filled in by the
* FTPFileEntryParser
used.
* parser
parameter. Null will be
* returned if a data connection cannot be opened. If the current working
* directory contains no files, an empty array will be the return.
*
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @exception ParserInitializationException
* Thrown if the autodetect mechanism cannot
* resolve the type of system we are connected with.
* @see FTPListParseEngine
*/
public FTPListParseEngine initiateListParsing()
throws IOException
{
return initiateListParsing((String) null);
}
/**
* Using the default autodetect mechanism, initialize an FTPListParseEngine
* object containing a raw file information for the supplied directory.
* This information is obtained through the LIST command. This object
* is then capable of being iterated to return a sequence of FTPFile
* objects with information filled in by the
* FTPFileEntryParser
used.
*
* FTPClient f=FTPClient();
* f.connect(server);
* f.login(username, password);
* FTPListParseEngine engine = f.initiateListParsing(directory);
*
* while (engine.hasNext()) {
* FTPFile[] files = engine.getNext(25); // "page size" you want
* //do whatever you want with these files, display them, etc.
* //expensive FTPFile objects not created until needed.
* }
*
*
* @return A FTPListParseEngine object that holds the raw information and
* is capable of providing parsed FTPFile objects, one for each file
* containing information contained in the given path in the format
* determined by the parser
parameter. Null will be
* returned if a data connection cannot be opened. If the current working
* directory contains no files, an empty array will be the return.
*
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @exception ParserInitializationException
* Thrown if the autodetect mechanism cannot
* resolve the type of system we are connected with.
* @see FTPListParseEngine
*/
public FTPListParseEngine initiateListParsing(
String pathname)
throws IOException
{
String key = null;
return initiateListParsing(key, pathname);
}
/**
* Using the supplied parser key, initialize an FTPListParseEngine
* object containing a raw file information for the supplied directory.
* This information is obtained through the LIST command. This object
* is then capable of being iterated to return a sequence of FTPFile
* objects with information filled in by the
* FTPFileEntryParser
used.
* FTPFileEntryParser
that should be
* used to parse each server file listing.
*
* @return A FTPListParseEngine object that holds the raw information and
* is capable of providing parsed FTPFile objects, one for each file
* containing information contained in the given path in the format
* determined by the parser
parameter. Null will be
* returned if a data connection cannot be opened. If the current working
* directory contains no files, an empty array will be the return.
*
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @exception ParserInitializationException
* Thrown if the parserKey parameter cannot be
* resolved by the selected parser factory.
* In the DefaultFTPEntryParserFactory, this will
* happen when parserKey is neither
* the fully qualified class name of a class
* implementing the interface
* org.apache.commons.net.ftp.FTPFileEntryParser
* nor a string containing one of the recognized keys
* mapping to such a parser or if class loader
* security issues prevent its being loaded.
* @see FTPListParseEngine
*/
public FTPListParseEngine initiateListParsing(
String parserKey, String pathname)
throws IOException
{
// We cache the value to avoid creation of a new object every
// time a file listing is generated.
if(__entryParser == null || ! __entryParserKey.equals(parserKey)) {
if (null != parserKey) {
// if a parser key was supplied in the parameters,
// use that to create the parser
__entryParser =
__parserFactory.createFileEntryParser(parserKey);
__entryParserKey = parserKey;
} else {
// if no parserKey was supplied, check for a configuration
// in the params, and if non-null, use that.
if (null != __configuration) {
__entryParser =
__parserFactory.createFileEntryParser(__configuration);
__entryParserKey = __configuration.getServerSystemKey();
} else {
// if a parserKey hasn't been supplied, and a configuration
// hasn't been supplied, then autodetect by calling
// the SYST command and use that to choose the parser.
final String systemType = getSystemType(); // cannot be null
__entryParser =
__parserFactory.createFileEntryParser(systemType);
__entryParserKey = systemType;
}
}
}
return initiateListParsing(__entryParser, pathname);
}
/**
* private method through which all listFiles() and
* initiateListParsing methods pass once a parser is determined.
*
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException
* If an I/O error occurs while either sending a
* command to the server or receiving a reply from the server.
* @see FTPListParseEngine
*/
private FTPListParseEngine initiateListParsing(
FTPFileEntryParser parser, String pathname)
throws IOException
{
Socket socket;
FTPListParseEngine engine = new FTPListParseEngine(parser);
if ((socket = _openDataConnection_(FTPCommand.LIST, getListArguments(pathname))) == null)
{
return engine;
}
try {
engine.readServerList(socket.getInputStream(), getControlEncoding());
}
finally {
socket.close();
}
completePendingCommand();
return engine;
}
/**
* @since 2.0
*/
protected String getListArguments(String pathname) {
if (getListHiddenFiles())
{
if (pathname != null)
{
StringBuilder sb = new StringBuilder(pathname.length() + 3);
sb.append("-a ");
sb.append(pathname);
return sb.toString();
}
else
{
return "-a";
}
}
return pathname;
}
/***
* Issue the FTP STAT command to the server.
* YYYYMMDDhhmmss
format.
* @throws IOException if an I/O error occurs.
* @since 2.0
*/
public String getModificationTime(String pathname) throws IOException {
if (FTPReply.isPositiveCompletion(mdtm(pathname)))
return getReplyString();
return null;
}
/**
* Issue the FTP MFMT command (not supported by all servers) which sets the last
* modified time of a file.
*
* The timestamp should be in the form YYYYMMDDhhmmss
. It should also
* be in GMT, but not all servers honour this.
*
* An FTP server would indicate its support of this feature by including "MFMT"
* in its response to the FEAT command, which may be retrieved by FTPClient.features()
*
* @param pathname The file path for which last modified time is to be changed.
* @param timeval The timestamp to set to, in YYYYMMDDhhmmss
format.
* @return true if successfully set, false if not
* @throws IOException if an I/O error occurs.
* @since 2.2
* @see http://tools.ietf.org/html/draft-somers-ftp-mfxx-04
*/
public boolean setModificationTime(String pathname, String timeval) throws IOException {
return (FTPReply.isPositiveCompletion(mfmt(pathname, timeval)));
}
/**
* Set the internal buffer size.
*
* @param bufSize The size of the buffer
*/
public void setBufferSize(int bufSize) {
__bufferSize = bufSize;
}
/**
* Retrieve the current internal buffer size.
* @return The current buffer size.
*/
public int getBufferSize() {
return __bufferSize;
}
/**
* Implementation of the {@link Configurable Configurable} interface.
* In the case of this class, configuring merely makes the config object available for the
* factory methods that construct parsers.
* @param config {@link FTPClientConfig FTPClientConfig} object used to
* provide non-standard configurations to the parser.
* @since 1.4
*/
public void configure(FTPClientConfig config) {
this.__configuration = config;
}
/**
* You can set this to true if you would like to get hidden files when {@link #listFiles} too.
* A LIST -a
will be issued to the ftp server.
* It depends on your ftp server if you need to call this method, also dont expect to get rid
* of hidden files if you call this method with "false".
*
* @param listHiddenFiles true if hidden files should be listed
* @since 2.0
*/
public void setListHiddenFiles(boolean listHiddenFiles) {
this.__listHiddenFiles = listHiddenFiles;
}
/**
* @see #setListHiddenFiles(boolean)
* @return the current state
* @since 2.0
*/
public boolean getListHiddenFiles() {
return this.__listHiddenFiles;
}
/**
* Whether should attempt to use EPSV with IPv4.
* Default (if not set) is false
* @return true if should attempt EPS
* @since 2.2
*/
public boolean isUseEPSVwithIPv4() {
return __useEPSVwithIPv4;
}
/**
* Set whether to use EPSV with IPv4.
* Might be worth enabling in some circumstances.
*
* For example, when using IPv4 with NAT it
* may work with some rare configurations.
* E.g. if FTP server has a static PASV address (external network)
* and the client is coming from another internal network.
* In that case the data connection after PASV command would fail,
* while EPSV would make the client succeed by taking just the port.
*
* @param selected value to set.
* @since 2.2
*/
public void setUseEPSVwithIPv4(boolean selected) {
this.__useEPSVwithIPv4 = selected;
}
}
/* Emacs configuration
* Local variables: **
* mode: java **
* c-basic-offset: 4 **
* indent-tabs-mode: nil **
* End: **
*/
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTP.java 0000644 0001750 0001750 00000204071 11466235516 024561 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ProtocolCommandSupport;
import org.apache.commons.net.SocketClient;
/***
* FTP provides the basic the functionality necessary to implement your
* own FTP client. It extends org.apache.commons.net.SocketClient since
* extending TelnetClient was causing unwanted behavior (like connections
* that did not time out properly).
* FTPConectionClosedException
* is a subclass of IOException
and therefore need not be
* caught separately, but if you are going to catch it separately, its
* catch block must appear before the more general IOException
* catch block. When you encounter an
* {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
* , you must disconnect the connection with
* {@link #disconnect disconnect() } to properly clean up the
* system resources used by FTP. Before disconnecting, you may check the
* last reply code and text with
* {@link #getReplyCode getReplyCode },
* {@link #getReplyString getReplyString },
* and {@link #getReplyStrings getReplyStrings}.
* You may avoid server disconnections while the client is idle by
* periodicaly sending NOOP commands to the server.
* FILE_TYPE
are used to indicate file types.
***/
public static final int ASCII_FILE_TYPE = 0;
/***
* A constant used to indicate the file(s) being transfered should
* be treated as EBCDIC. Note however that there are several different
* EBCDIC formats. All constants ending in FILE_TYPE
* are used to indicate file types.
***/
public static final int EBCDIC_FILE_TYPE = 1;
/***
* A constant used to indicate the file(s) being transfered should
* be treated as a binary image, i.e., no translations should be
* performed. All constants ending in FILE_TYPE
are used to
* indicate file types.
***/
public static final int BINARY_FILE_TYPE = 2;
/***
* A constant used to indicate the file(s) being transfered should
* be treated as a local type. All constants ending in
* FILE_TYPE
are used to indicate file types.
***/
public static final int LOCAL_FILE_TYPE = 3;
/***
* A constant used for text files to indicate a non-print text format.
* This is the default format.
* All constants ending in TEXT_FORMAT
are used to indicate
* text formatting for text transfers (both ASCII and EBCDIC).
***/
public static final int NON_PRINT_TEXT_FORMAT = 4;
/***
* A constant used to indicate a text file contains format vertical format
* control characters.
* All constants ending in TEXT_FORMAT
are used to indicate
* text formatting for text transfers (both ASCII and EBCDIC).
***/
public static final int TELNET_TEXT_FORMAT = 5;
/***
* A constant used to indicate a text file contains ASA vertical format
* control characters.
* All constants ending in TEXT_FORMAT
are used to indicate
* text formatting for text transfers (both ASCII and EBCDIC).
***/
public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6;
/***
* A constant used to indicate a file is to be treated as a continuous
* sequence of bytes. This is the default structure. All constants ending
* in _STRUCTURE
are used to indicate file structure for
* file transfers.
***/
public static final int FILE_STRUCTURE = 7;
/***
* A constant used to indicate a file is to be treated as a sequence
* of records. All constants ending in _STRUCTURE
* are used to indicate file structure for file transfers.
***/
public static final int RECORD_STRUCTURE = 8;
/***
* A constant used to indicate a file is to be treated as a set of
* independent indexed pages. All constants ending in
* _STRUCTURE
are used to indicate file structure for file
* transfers.
***/
public static final int PAGE_STRUCTURE = 9;
/***
* A constant used to indicate a file is to be transfered as a stream
* of bytes. This is the default transfer mode. All constants ending
* in TRANSFER_MODE
are used to indicate file transfer
* modes.
***/
public static final int STREAM_TRANSFER_MODE = 10;
/***
* A constant used to indicate a file is to be transfered as a series
* of blocks. All constants ending in TRANSFER_MODE
are used
* to indicate file transfer modes.
***/
public static final int BLOCK_TRANSFER_MODE = 11;
/***
* A constant used to indicate a file is to be transfered as FTP
* compressed data. All constants ending in TRANSFER_MODE
* are used to indicate file transfer modes.
***/
public static final int COMPRESSED_TRANSFER_MODE = 12;
// We have to ensure that the protocol communication is in ASCII
// but we use ISO-8859-1 just in case 8-bit characters cross
// the wire.
/**
* The default character encoding used for communicating over an
* FTP control connection. The default encoding is an
* ASCII-compatible encoding. Some FTP servers expect other
* encodings. You can change the encoding used by an FTP instance
* with {@link #setControlEncoding setControlEncoding}.
*/
public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";
private static final String __modes = "AEILNTCFRPSBC";
private final StringBuilder __commandBuffer = new StringBuilder();
protected int _replyCode;
protected ArrayListDEFAULT_PORT
and initializes internal data structures
* for saving FTP reply information.
***/
public FTP()
{
super();
setDefaultPort(DEFAULT_PORT);
_replyLines = new ArrayList connect
is of type void.
*
*
*
*
* FILE_TYPE
* constants).
* @param formatOrByteSize The format of the file (one of the
* _FORMAT
constants. In the case of
* LOCAL_FILE_TYPE
, the byte size.
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int type(int fileType, int formatOrByteSize) throws IOException
{
StringBuilder arg = new StringBuilder();
arg.append(__modes.charAt(fileType));
arg.append(' ');
if (fileType == LOCAL_FILE_TYPE)
arg.append(formatOrByteSize);
else
arg.append(__modes.charAt(formatOrByteSize));
return sendCommand(FTPCommand.TYPE, arg.toString());
}
/**
* A convenience method to send the FTP TYPE command to the server,
* receive the reply, and return the reply code.
* FILE_TYPE
* constants).
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
*/
public int type(int fileType) throws IOException
{
return sendCommand(FTPCommand.TYPE,
__modes.substring(fileType, fileType + 1));
}
/***
* A convenience method to send the FTP STRU command to the server,
* receive the reply, and return the reply code.
* _STRUCTURE
constants).
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int stru(int structure) throws IOException
{
return sendCommand(FTPCommand.STRU,
__modes.substring(structure, structure + 1));
}
/***
* A convenience method to send the FTP MODE command to the server,
* receive the reply, and return the reply code.
* TRANSFER_MODE
constants).
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
***/
public int mode(int mode) throws IOException
{
return sendCommand(FTPCommand.MODE,
__modes.substring(mode, mode + 1));
}
/***
* A convenience method to send the FTP RETR command to the server,
* receive the reply, and return the reply code. Remember, it is up
* to you to manage the data connection. If you don't need this low
* level of access, use {@link org.apache.commons.net.ftp.FTPClient}
* , which will handle all low level details for you.
* YYYYMMDDhhmmss
format
* @return The reply code received from the server.
* @exception FTPConnectionClosedException
* If the FTP server prematurely closes the connection as a result
* of the client being idle or some other reason causing the server
* to send FTP reply code 421. This exception may be caught either
* as an IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending the
* command or receiving the server reply.
* @since 2.2
* @see http://tools.ietf.org/html/draft-somers-ftp-mfxx-04
**/
public int mfmt(String pathname, String timeval) throws IOException
{
return sendCommand(FTPCommand.MFMT, timeval + " " + pathname);
}
/***
* A convenience method to send the FTP RNFR command to the server,
* receive the reply, and return the reply code.
* null
*/
public String[] getEnabledCipherSuites() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getEnabledCipherSuites();
return null;
}
/**
* Controls which particular protocol versions are enabled for use on this
* connection. I perform setting before a server negotiation.
* @param protocolVersions The protocol versions.
*/
public void setEnabledProtocols(String[] protocolVersions) {
protocols = new String[protocolVersions.length];
System.arraycopy(protocolVersions, 0, protocols, 0, protocolVersions.length);
}
/**
* Returns the names of the protocol versions which are currently
* enabled for use on this connection.
* When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns null.
* @return An array of protocols, or null
*/
public String[] getEnabledProtocols() {
if (_socket_ instanceof SSLSocket)
return ((SSLSocket)_socket_).getEnabledProtocols();
return null;
}
/**
* PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
* @param pbsz Protection Buffer Size.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
* the command.
*/
public void execPBSZ(long pbsz) throws SSLException, IOException {
if (pbsz < 0 || 4294967295L < pbsz)
throw new IllegalArgumentException();
if (FTPReply.COMMAND_OK != sendCommand(
FTPSCommand._commands[FTPSCommand.PBSZ],String.valueOf(pbsz)))
throw new SSLException(getReplyString());
}
/**
* PROT command.
* C - Clear
* S - Safe(SSL protocol only)
* E - Confidential(SSL protocol only)
* P - Private
* @param prot Data Channel Protection Level.
* @throws SSLException If the server reply code does not equal "200".
* @throws IOException If an I/O error occurs while sending
* the command.
*/
public void execPROT(String prot) throws SSLException, IOException {
if (prot == null) prot = DEFAULT_PROT;
if (!checkPROTValue(prot)) throw new IllegalArgumentException();
if (FTPReply.COMMAND_OK != sendCommand(
FTPSCommand._commands[FTPSCommand.PROT], prot))
throw new SSLException(getReplyString());
if (DEFAULT_PROT.equals(prot)) {
setSocketFactory(null);
setServerSocketFactory(null);
} else {
setSocketFactory(new FTPSSocketFactory(context));
setServerSocketFactory(new FTPSServerSocketFactory(context));
initSslContext();
}
}
/**
* Check the value that can be set in PROT Command value.
* @param prot Data Channel Protection Level.
* @return True - A set point is right / False - A set point is not right
*/
private boolean checkPROTValue(String prot) {
for (int p = 0; p < PROT_COMMAND_VALUE.length; p++) {
if (PROT_COMMAND_VALUE[p].equals(prot)) return true;
}
return false;
}
/**
* Send an FTP command.
* The CCC (Clear Command Channel) command causes the underlying {@link SSLSocket} instance to be assigned
* to a plain {@link Socket} instances
* @param command The FTP command.
* @return server reply.
* @throws IOException If an I/O error occurs while sending
* the command.
* @see org.apache.commons.net.ftp.FTP#sendCommand(java.lang.String)
*/
@Override
public int sendCommand(String command, String args) throws IOException {
int repCode = super.sendCommand(command, args);
/* If CCC is issued, restore socket i/o streams to unsecured versions */
if (FTPSCommand._commands[FTPSCommand.CCC].equals(command)) {
if (FTPReply.COMMAND_OK == repCode) {
_socket_ = plainSocket;
_controlInput_ = new BufferedReader(
new InputStreamReader(
_socket_ .getInputStream(), getControlEncoding()));
_controlOutput_ = new BufferedWriter(
new OutputStreamWriter(
_socket_.getOutputStream(), getControlEncoding()));
setSocketFactory(null);
} else {
throw new SSLException(getReplyString());
}
}
return repCode;
}
/**
* Returns a socket of the data connection.
* Wrapped as an {@link SSLSocket}, which carries out handshake processing.
* @param command The textual representation of the FTP command to send.
* @param arg The arguments to the FTP command.
* If this parameter is set to null, then the command is sent with
* no arguments.
* @return corresponding to the established data connection.
* Null is returned if an FTP protocol error is reported at any point
* during the establishment and initialization of the connection.
* @throws IOException If there is any problem with the connection.
* @see FTPClient#_openDataConnection_(int, String)
*/
@Override
protected Socket _openDataConnection_(int command, String arg)
throws IOException {
Socket socket = super._openDataConnection_(command, arg);
if (socket != null && socket instanceof SSLSocket) {
SSLSocket sslSocket = (SSLSocket)socket;
sslSocket.setUseClientMode(isClientMode);
sslSocket.setEnableSessionCreation(isCreation);
// server mode
if (!isClientMode) {
sslSocket.setNeedClientAuth(isNeedClientAuth);
sslSocket.setWantClientAuth(isWantClientAuth);
}
if (suites != null)
sslSocket.setEnabledCipherSuites(suites);
if (protocols != null)
sslSocket.setEnabledProtocols(protocols);
sslSocket.startHandshake();
}
return socket;
}
/**
* Get the currently configured {@link TrustManager}.
*
* @return A TrustManager instance.
*/
public TrustManager getTrustManager() {
return trustManager;
}
/**
* Override the default {@link TrustManager} to use.
*
* @param trustManager The TrustManager implementation to set.
*/
public void setTrustManager(TrustManager trustManager) {
this.trustManager = trustManager;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java 0000644 0001750 0001750 00000003475 11143265407 026202 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp;
/**
* FTPS-specific command
* @since 2.0
*/
public final class FTPSCommand {
public static final int AUTH = 0;
public static final int ADAT = 1;
public static final int PBSZ = 2;
public static final int PROT = 3;
public static final int CCC = 4;
public static final int AUTHENTICATION_SECURITY_MECHANISM = AUTH;
public static final int AUTHENTICATION_SECURITY_DATA = ADAT;
public static final int PROTECTION_BUFFER_SIZE = PBSZ;
public static final int DATA_CHANNEL_PROTECTION_LEVEL = PROT;
public static final int CLEAR_COMMAND_CHANNEL = CCC;
static final String[] _commands = {"AUTH","ADAT","PBSZ","PROT","CCC"};
/**
* Retrieve the FTPS command string corresponding to a specified
* command code.
* FTPTimestampParser
according
* to the following logic:
*
*
config
, use that to parse parse timestamps.config
, use the month names represented
* by that {@link FTPClientConfig#lookupDateFormatSymbols(String) language}
* to parse timestamps.REGEX
is not a valid regular expression.
*/
public VMSVersioningFTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of a VMSVersioningFTPEntryParser
* object with something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public VMSVersioningFTPEntryParser(FTPClientConfig config)
{
super();
configure(config);
try
{
//_preparse_matcher_ = new Perl5Matcher();
_preparse_pattern_ = Pattern.compile(PRE_PARSE_REGEX);
}
catch (PatternSyntaxException pse)
{
throw new IllegalArgumentException (
"Unparseable regex supplied: " + PRE_PARSE_REGEX);
}
}
/**
* Implement hook provided for those implementers (such as
* VMSVersioningFTPEntryParser, and possibly others) which return
* multiple files with the same name to remove the duplicates ..
*
* @param original Original list
*
* @return Original list purged of duplicates
*/
@Override
public List"yyyy-MM-dd HH:mm
.
* This is a very welcome development, and hopefully it will soon become
* the standard. However, since it is so new, for now, and possibly
* forever, we merely accomodate it, but do not make it the default.
* UnixFTPEntryParser(FTPClientConfig)
.
* Steve Cohen - 2005-04-17
*/
public static final FTPClientConfig NUMERIC_DATE_CONFIG =
new FTPClientConfig(
FTPClientConfig.SYST_UNIX,
NUMERIC_DATE_FORMAT,
null, null, null, null);
/**
* this is the regular expression used by this parser.
*
* Permissions:
* r the file is readable
* w the file is writable
* x the file is executable
* - the indicated permission is not granted
* L mandatory locking occurs during access (the set-group-ID bit is
* on and the group execution bit is off)
* s the set-user-ID or set-group-ID bit is on, and the corresponding
* user or group execution bit is also on
* S undefined bit-state (the set-user-ID bit is on and the user
* execution bit is off)
* t the 1000 (octal) bit, or sticky bit, is on [see chmod(1)], and
* execution is on
* T the 1000 bit is turned on, and execution is off (undefined bit-
* state)
* e z/OS external link bit
*/
private static final String REGEX =
"([bcdelfmpSs-])"
+"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s*"
+ "(\\d+)\\s+" // link count
+ "(?:(\\S+(?:\\s\\S+)*?)\\s+)?" // owner name (optional spaces)
+ "(?:(\\S+(?:\\s\\S+)*)\\s+)?" // group name (optional spaces)
+ "(\\d+(?:,\\s*\\d+)?)\\s+" // size or n,m
/*
* numeric or standard format date:
* yyyy-mm-dd (expecting hh:mm to follow)
* MMMM [d]d
* [d]d MMM
*/
+ "((?:\\d+[-/]\\d+[-/]\\d+)|(?:[a-zA-Z]{3}\\s+\\d{1,2})|(?:\\d{1,2}\\s+[a-zA-Z]{3}))\\s+"
/*
year (for non-recent standard format) - yyyy
or time (for numeric or recent standard format) [h]h:mm
*/
+ "(\\d+(?::\\d+)?)\\s+"
+ "(\\S*)(\\s*.*)"; // the rest
/**
* The default constructor for a UnixFTPEntryParser object.
*
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
*/
public UnixFTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of a UnixFTPEntryParser object with
* something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public UnixFTPEntryParser(FTPClientConfig config)
{
super(REGEX);
configure(config);
}
/**
* Parses a line of a unix (standard) FTP server file listing and converts
* it into a usable format in the form of an FTPFile
* instance. If the file listing line doesn't describe a file,
* null
is returned, otherwise a FTPFile
* instance representing the files in the directory is returned.
* REGEX
is not a valid regular expression.
*/
public OS2FTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of an OS2FTPEntryParser object
* with something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public OS2FTPEntryParser(FTPClientConfig config)
{
super(REGEX);
configure(config);
}
/**
* Parses a line of an OS2 FTP server file listing and converts it into a
* usable format in the form of an FTPFile
instance. If the
* file listing line doesn't describe a file, null
is
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
* java.util.Calendar
object initialized to the date
* parsed by the parser
* @throws ParseException if none of the parser mechanisms belonging to
* the implementor can parse the input.
*/
public Calendar parseTimestamp(String timestampStr) throws ParseException;
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java 0000644 0001750 0001750 00000013240 11014672436 033150 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.util.Calendar;
import org.apache.commons.net.ftp.FTPFile;
/**
* Parser for the Connect Enterprise Unix FTP Server From Sterling Commerce.
* Here is a sample of the sort of output line this parser processes:
* "-C--E-----FTP B QUA1I1 18128 41 Aug 12 13:56 QUADTEST"
* FTPFile
instance. If
* the file listing line doesn't describe a file, null
is
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
*
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry)
{
FTPFile file = new FTPFile();
file.setRawListing(entry);
if (matches(entry))
{
String usr = group(14);
String grp = group(15);
String filesize = group(16);
String mo = group(17);
String da = group(18);
String yr = group(20);
String hr = group(21);
String min = group(22);
String name = group(23);
file.setType(FTPFile.FILE_TYPE);
file.setUser(usr);
file.setGroup(grp);
try
{
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND,
0);
cal.set(Calendar.MINUTE,
0);
cal.set(Calendar.HOUR_OF_DAY,
0);
try
{
int pos = MONTHS.indexOf(mo);
int month = pos / 4;
if (yr != null)
{
// it's a year
cal.set(Calendar.YEAR,
Integer.parseInt(yr));
}
else
{
// it must be hour/minute or we wouldn't have matched
int year = cal.get(Calendar.YEAR);
// if the month we're reading is greater than now, it must
// be last year
if (cal.get(Calendar.MONTH) < month)
{
year--;
}
cal.set(Calendar.YEAR,
year);
cal.set(Calendar.HOUR_OF_DAY,
Integer.parseInt(hr));
cal.set(Calendar.MINUTE,
Integer.parseInt(min));
}
cal.set(Calendar.MONTH,
month);
cal.set(Calendar.DATE,
Integer.parseInt(da));
file.setTimestamp(cal);
}
catch (NumberFormatException e)
{
// do nothing, date will be uninitialized
}
file.setName(name);
return file;
}
return null;
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java 0000644 0001750 0001750 00000013455 11456020116 030505 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import org.apache.commons.net.ftp.Configurable;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
/**
* Implementation of FTPFileEntryParser and FTPFileListParser for NT Systems.
*
* @author Winston Ojeda
* @author Steve Cohen
* @version $Id: NTFTPEntryParser.java 1022867 2010-10-15 09:35:10Z sebb $
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
*/
public class NTFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
{
private static final String DEFAULT_DATE_FORMAT
= "MM-dd-yy hh:mma"; //11-09-01 12:30PM
private static final String DEFAULT_DATE_FORMAT2
= "MM-dd-yy kk:mm"; //11-09-01 18:30
private FTPTimestampParser timestampParser;
/**
* this is the regular expression used by this parser.
*/
private static final String REGEX =
"(\\S+)\\s+(\\S+)\\s+" // MM-dd-yy whitespace hh:mma|kk:mm; swallow trailing spaces
+ "(?:(REGEX
is not a valid regular expression.
*/
public NTFTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of an NTFTPEntryParser object
* with something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public NTFTPEntryParser(FTPClientConfig config)
{
super(REGEX);
configure(config);
FTPClientConfig config2 = new FTPClientConfig(
FTPClientConfig.SYST_NT,
DEFAULT_DATE_FORMAT2,
null, null, null, null);
config2.setDefaultDateFormatStr(DEFAULT_DATE_FORMAT2);
this.timestampParser = new FTPTimestampParserImpl();
((Configurable)this.timestampParser).configure(config2);
}
/**
* Parses a line of an NT FTP server file listing and converts it into a
* usable format in the form of an FTPFile
instance. If the
* file listing line doesn't describe a file, null
is
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
* matchnum'th
group of the internal
* match or null if this method is called without a match having
* been made.
*/
public String group(int matchnum) {
if (this.result == null) {
return null;
}
return this.result.group(matchnum);
}
/**
* For debugging purposes - returns a string shows each match group by
* number.
*
* @return a string shows each match group by number.
*/
public String getGroupsAsString() {
StringBuilder b = new StringBuilder();
for (int i = 1; i <= this.result.groupCount(); i++) {
b.append(i).append(") ").append(this.result.group(i)).append(
System.getProperty("line.separator"));
}
return b.toString();
}
/**
* Alter the current regular expression being utilised for entry parsing
* and create a new {@link Pattern} instance.
* @param regex The new regular expression
* @return true if the compiled pattern is not null
* @since 2.0
*/
public boolean setRegex(String regex) {
try {
pattern = Pattern.compile(regex);
} catch (PatternSyntaxException pse) {
throw new IllegalArgumentException("Unparseable regex supplied: "
+ regex);
}
return (pattern != null);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java 0000644 0001750 0001750 00000045433 11014673543 030642 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.util.List;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
/**
* Implementation of FTPFileEntryParser and FTPFileListParser for IBM zOS/MVS
* Systems.
*
* @author Henrik Sorensen
* @author Jeff Nadler
* @author William Noto
*
* @version $Id: MVSFTPEntryParser.java 658520 2008-05-21 01:14:11Z sebb $
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for
* usage instructions)
*/
public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
static final int UNKNOWN_LIST_TYPE = -1;
static final int FILE_LIST_TYPE = 0;
static final int MEMBER_LIST_TYPE = 1;
static final int UNIX_LIST_TYPE = 2;
static final int JES_LEVEL_1_LIST_TYPE = 3;
static final int JES_LEVEL_2_LIST_TYPE = 4;
private int isType = UNKNOWN_LIST_TYPE;
/**
* Fallback parser for Unix-style listings
*/
private UnixFTPEntryParser unixFTPEntryParser;
/**
* Dates are ignored for file lists, but are used for member lists where
* possible
*/
static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd HH:mm"; // 2001/09/18
// 13:52
/**
* Matches these entries: Volume Unit Referred Ext Used Recfm Lrecl BlkSz
* Dsorg Dsname B10142 3390 2006/03/20 2 31 F 80 80 PS MDI.OKL.WORK
*
*/
static final String FILE_LIST_REGEX = "\\S+\\s+" + // volume
// ignored
"\\S+\\s+" + // unit - ignored
"\\S+\\s+" + // access date - ignored
"\\S+\\s+" + // extents -ignored
"\\S+\\s+" + // used - ignored
"[FV]\\S*\\s+" + // recfm - must start with F or V
"\\S+\\s+" + // logical record length -ignored
"\\S+\\s+" + // block size - ignored
"(PS|PO|PO-E)\\s+" + // Dataset organisation. Many exist
// but only support: PS, PO, PO-E
"(\\S+)\\s*"; // Dataset Name (file name)
/**
* Matches these entries: Name VV.MM Created Changed Size Init Mod Id
* TBSHELF 01.03 2002/09/12 2002/10/11 09:37 11 11 0 KIL001
*/
static final String MEMBER_LIST_REGEX = "(\\S+)\\s+" + // name
"\\S+\\s+" + // version, modification (ignored)
"\\S+\\s+" + // create date (ignored)
"(\\S+)\\s+" + // modification date
"(\\S+)\\s+" + // modification time
"\\S+\\s+" + // size in lines (ignored)
"\\S+\\s+" + // size in lines at creation(ignored)
"\\S+\\s+" + // lines modified (ignored)
"\\S+\\s*"; // id of user who modified (ignored)
/**
* Matches these entries, note: no header: IBMUSER1 JOB01906 OUTPUT 3 Spool
* Files 012345678901234567890123456789012345678901234 1 2 3 4
*/
static final String JES_LEVEL_1_LIST_REGEX = "(\\S+)\\s+" + // job
// name
// ignored
"(\\S+)\\s+" + // job number
"(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE)
"(\\S+)\\s+" + // number of spool files
"(\\S+)\\s+" + // Text "Spool" ignored
"(\\S+)\\s*" // Text "Files" ignored
;
/**
* JES INTERFACE LEVEL 2 parser Matches these entries: JOBNAME JOBID OWNER
* STATUS CLASS IBMUSER1 JOB01906 IBMUSER OUTPUT A RC=0000 3 spool files
* IBMUSER TSU01830 IBMUSER OUTPUT TSU ABEND=522 3 spool files
* 012345678901234567890123456789012345678901234 1 2 3 4
* 012345678901234567890123456789012345678901234567890
*/
static final String JES_LEVEL_2_LIST_REGEX = "(\\S+)\\s+" + // job
// name
// ignored
"(\\S+)\\s+" + // job number
"(\\S+)\\s+" + // owner ignored
"(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE) ignored
"(\\S+)\\s+" + // job class ignored
"(\\S+).*" // rest ignored
;
/*
* ---------------------------------------------------------------------
* Very brief and incomplete description of the zOS/MVS-filesystem. (Note:
* "zOS" is the operating system on the mainframe, and is the new name for
* MVS)
*
* The filesystem on the mainframe does not have hierarchal structure as for
* example the unix filesystem. For a more comprehensive description, please
* refer to the IBM manuals
*
* @LINK:
* http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/dgt2d440/CONTENTS
*
*
* Dataset names =============
*
* A dataset name consist of a number of qualifiers separated by '.', each
* qualifier can be at most 8 characters, and the total length of a dataset
* can be max 44 characters including the dots.
*
*
* Dataset organisation ====================
*
* A dataset represents a piece of storage allocated on one or more disks.
* The structure of the storage is described with the field dataset
* organinsation (DSORG). There are a number of dataset organisations, but
* only two are usable for FTP transfer.
*
* DSORG: PS: sequential, or flat file PO: partitioned dataset PO-E:
* extended partitioned dataset
*
* The PS file is just a flat file, as you would find it on the unix file
* system.
*
* The PO and PO-E files, can be compared to a single level directory
* structure. A PO file consist of a number of dataset members, or files if
* you will. It is possible to CD into the file, and to retrieve the
* individual members.
*
*
* Dataset record format =====================
*
* The physical layout of the dataset is described on the dataset itself.
* There are a number of record formats (RECFM), but just a few is relavant
* for the FTP transfer.
*
* Any one beginning with either F or V can safely used by FTP transfer. All
* others should only be used with great care, so this version will just
* ignore the other record formats. F means a fixed number of records per
* allocated storage, and V means a variable number of records.
*
*
* Other notes ===========
*
* The file system supports automatically backup and retrieval of datasets.
* If a file is backed up, the ftp LIST command will return: ARCIVE Not
* Direct Access Device KJ.IOP998.ERROR.PL.UNITTEST
*
*
* Implementation notes ====================
*
* Only datasets that have dsorg PS, PO or PO-E and have recfm beginning
* with F or V, is fully parsed.
*
* The following fields in FTPFile is used: FTPFile.Rawlisting: Always set.
* FTPFile.Type: DIRECTORY_TYPE or FILE_TYPE or UNKNOWN FTPFile.Name: name
* FTPFile.Timestamp: change time or null
*
*
*
* Additional information ======================
*
* The MVS ftp server supports a number of features via the FTP interface.
* The features are controlled with the FTP command quote site filetype=
FTPFile
instance.
* If the file listing line doesn't describe a file, then
* null
is returned. Otherwise a FTPFile
* instance representing the file is returned.
*
* @param entry
* A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry) {
boolean isParsed = false;
FTPFile f = new FTPFile();
if (isType == FILE_LIST_TYPE)
isParsed = parseFileList(f, entry);
else if (isType == MEMBER_LIST_TYPE) {
isParsed = parseMemberList(f, entry);
if (!isParsed)
isParsed = parseSimpleEntry(f, entry);
} else if (isType == UNIX_LIST_TYPE) {
isParsed = parseUnixList(f, entry);
} else if (isType == JES_LEVEL_1_LIST_TYPE) {
isParsed = parseJeslevel1List(f, entry);
} else if (isType == JES_LEVEL_2_LIST_TYPE) {
isParsed = parseJeslevel2List(f, entry);
}
if (!isParsed)
f = null;
return f;
}
/**
* Parse entries representing a dataset list. Only datasets with DSORG PS or
* PO or PO-E and with RECFM F* or V* will be parsed.
*
* Format of ZOS/MVS file list: 1 2 3 4 5 6 7 8 9 10 Volume Unit Referred
* Ext Used Recfm Lrecl BlkSz Dsorg Dsname B10142 3390 2006/03/20 2 31 F 80
* 80 PS MDI.OKL.WORK ARCIVE Not Direct Access Device
* KJ.IOP998.ERROR.PL.UNITTEST B1N231 3390 2006/03/20 1 15 VB 256 27998 PO
* PLU B1N231 3390 2006/03/20 1 15 VB 256 27998 PO-E PLB
*
* ----------------------------------- Group within Regex [1] Volume [2]
* Unit [3] Referred [4] Ext: number of extents [5] Used [6] Recfm: Record
* format [7] Lrecl: Logical record length [8] BlkSz: Block size [9] Dsorg:
* Dataset organisation. Many exists but only support: PS, PO, PO-E [10]
* Dsname: Dataset name
*
* Note: When volume is ARCIVE, it means the dataset is stored somewhere in
* a tape archive. These entries is currently not supported by this parser.
* A null value is returned.
*
* @param file
* will be updated with Name, Type, Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
private boolean parseFileList(FTPFile file, String entry) {
if (matches(entry)) {
file.setRawListing(entry);
String name = group(2);
String dsorg = group(1);
file.setName(name);
// DSORG
if ("PS".equals(dsorg)) {
file.setType(FTPFile.FILE_TYPE);
}
else if ("PO".equals(dsorg) || "PO-E".equals(dsorg)) {
// regex already ruled out anything other than PO or PO-E
file.setType(FTPFile.DIRECTORY_TYPE);
}
else {
return false;
}
return true;
}
return false;
}
/**
* Parse entries within a partitioned dataset.
*
* Format of a memberlist within a PDS: 1 2 3 4 5 6 7 8 9 Name VV.MM Created
* Changed Size Init Mod Id TBSHELF 01.03 2002/09/12 2002/10/11 09:37 11 11
* 0 KIL001 TBTOOL 01.12 2002/09/12 2004/11/26 19:54 51 28 0 KIL001
*
* ------------------------------------------- [1] Name [2] VV.MM: Version .
* modification [3] Created: yyyy / MM / dd [4,5] Changed: yyyy / MM / dd
* HH:mm [6] Size: number of lines [7] Init: number of lines when first
* created [8] Mod: number of modified lines a last save [9] Id: User id for
* last update
*
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
private boolean parseMemberList(FTPFile file, String entry) {
if (matches(entry)) {
file.setRawListing(entry);
String name = group(1);
String datestr = group(2) + " " + group(3);
file.setName(name);
file.setType(FTPFile.FILE_TYPE);
try {
file.setTimestamp(super.parseTimestamp(datestr));
} catch (ParseException e) {
e.printStackTrace();
// just ignore parsing errors.
// TODO check this is ok
return false; // this is a parsing failure too.
}
return true;
}
return false;
}
/**
* Assigns the name to the first word of the entry. Only to be used from a
* safe context, for example from a memberlist, where the regex for some
* reason fails. Then just assign the name field of FTPFile.
*
* @param file
* @param entry
* @return
*/
private boolean parseSimpleEntry(FTPFile file, String entry) {
if (entry != null && entry.length() > 0) {
file.setRawListing(entry);
String name = entry.split(" ")[0];
file.setName(name);
file.setType(FTPFile.FILE_TYPE);
return true;
}
return false;
}
/**
* Parse the entry as a standard unix file. Using the UnixFTPEntryParser.
*
* @param file
* @param entry
* @return true: entry is parsed, false: entry could not be parsed.
*/
private boolean parseUnixList(FTPFile file, String entry) {
file = unixFTPEntryParser.parseFTPEntry(entry);
if (file == null)
return false;
return true;
}
/**
* Matches these entries, note: no header: [1] [2] [3] [4] [5] IBMUSER1
* JOB01906 OUTPUT 3 Spool Files
* 012345678901234567890123456789012345678901234 1 2 3 4
* ------------------------------------------- Group in regex [1] Job name
* [2] Job number [3] Job status (INPUT,ACTIVE,OUTPUT) [4] Number of sysout
* files [5] The string "Spool Files"
*
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
private boolean parseJeslevel1List(FTPFile file, String entry) {
if (matches(entry)) {
if (group(3).equalsIgnoreCase("OUTPUT")) {
file.setRawListing(entry);
String name = group(2); /* Job Number, used by GET */
file.setName(name);
file.setType(FTPFile.FILE_TYPE);
return true;
}
}
return false;
}
/**
* Matches these entries, note: no header: [1] [2] [3] [4] [5] JOBNAME JOBID
* OWNER STATUS CLASS IBMUSER1 JOB01906 IBMUSER OUTPUT A RC=0000 3 spool
* files IBMUSER TSU01830 IBMUSER OUTPUT TSU ABEND=522 3 spool files
* 012345678901234567890123456789012345678901234 1 2 3 4
* ------------------------------------------- Group in regex [1] Job name
* [2] Job number [3] Owner [4] Job status (INPUT,ACTIVE,OUTPUT) [5] Job
* Class [6] The rest
*
*
* @param file
* will be updated with Name, Type and Timestamp if parsed.
* @param entry zosDirectoryEntry
* @return true: entry was parsed, false: entry was not parsed.
*/
private boolean parseJeslevel2List(FTPFile file, String entry) {
if (matches(entry)) {
if (group(4).equalsIgnoreCase("OUTPUT")) {
file.setRawListing(entry);
String name = group(2); /* Job Number, used by GET */
file.setName(name);
file.setType(FTPFile.FILE_TYPE);
return true;
}
}
return false;
}
/**
* preParse is called as part of the interface. Per definition is is called
* before the parsing takes place. Three kind of lists is recognize:
* z/OS-MVS File lists z/OS-MVS Member lists unix file lists
* @since 2.0
*/
@Override
public ListREGEX
is not a valid regular expression.
*/
public OS400FTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of an OS400FTPEntryParser object
* with something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public OS400FTPEntryParser(FTPClientConfig config)
{
super(REGEX);
configure(config);
}
public FTPFile parseFTPEntry(String entry)
{
FTPFile file = new FTPFile();
file.setRawListing(entry);
int type;
if (matches(entry))
{
String usr = group(1);
String filesize = group(2);
String datestr = group(3)+" "+group(4);
String typeStr = group(5);
String name = group(6);
try
{
file.setTimestamp(super.parseTimestamp(datestr));
}
catch (ParseException e)
{
// intentionally do nothing
}
if (typeStr.equalsIgnoreCase("*STMF"))
{
type = FTPFile.FILE_TYPE;
}
else if (typeStr.equalsIgnoreCase("*DIR"))
{
type = FTPFile.DIRECTORY_TYPE;
}
else
{
type = FTPFile.UNKNOWN_TYPE;
}
file.setType(type);
file.setUser(usr);
try
{
file.setSize(Long.parseLong(filesize));
}
catch (NumberFormatException e)
{
// intentionally do nothing
}
if (name.endsWith("/"))
{
name = name.substring(0, name.length() - 1);
}
int pos = name.lastIndexOf('/');
if (pos > -1)
{
name = name.substring(pos + 1);
}
file.setName(name);
return file;
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(
FTPClientConfig.SYST_OS400,
DEFAULT_DATE_FORMAT,
null, null, null, null);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java 0000644 0001750 0001750 00000015664 11014673543 031605 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
/**
* Implementation of FTPFileEntryParser and FTPFileListParser for Netware Systems. Note that some of the proprietary
* extensions for Novell-specific operations are not supported. See
* http://www.novell.com/documentation/nw65/index.html?page=/documentation/nw65/ftp_enu/data/fbhbgcfa.html
* for more details.
*
* @author Rory Winston
* @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
* @version $Id: NetwareFTPEntryParser.java 658520 2008-05-21 01:14:11Z sebb $
* @since 1.5
*/
public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
/**
* Default date format is e.g. Feb 22 2006
*/
private static final String DEFAULT_DATE_FORMAT = "MMM dd yyyy";
/**
* Default recent date format is e.g. Feb 22 17:32
*/
private static final String DEFAULT_RECENT_DATE_FORMAT = "MMM dd HH:mm";
/**
* this is the regular expression used by this parser.
* Example: d [-W---F--] SCION_VOL2 512 Apr 13 23:12 VOL2
*/
private static final String REGEX = "(d|-){1}\\s+" // Directory/file flag
+ "\\[(.*)\\]\\s+" // Attributes
+ "(\\S+)\\s+" + "(\\d+)\\s+" // Owner and size
+ "(\\S+\\s+\\S+\\s+((\\d+:\\d+)|(\\d{4})))" // Long/short date format
+ "\\s+(.*)"; // Filename (incl. spaces)
/**
* The default constructor for a NetwareFTPEntryParser object.
*
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
*/
public NetwareFTPEntryParser() {
this(null);
}
/**
* This constructor allows the creation of an NetwareFTPEntryParser object
* with something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public NetwareFTPEntryParser(FTPClientConfig config) {
super(REGEX);
configure(config);
}
/**
* Parses a line of an NetwareFTP server file listing and converts it into a
* usable format in the form of an FTPFile
instance. If the
* file listing line doesn't describe a file, null
is
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
*
*
*
* See here
* for more details
*
* @param entry A line of text from the file listing
* @return An FTPFile instance corresponding to the supplied entry
*/
public FTPFile parseFTPEntry(String entry) {
FTPFile f = new FTPFile();
if (matches(entry)) {
String dirString = group(1);
String attrib = group(2);
String user = group(3);
String size = group(4);
String datestr = group(5);
String name = group(9);
try {
f.setTimestamp(super.parseTimestamp(datestr));
} catch (ParseException e) {
// intentionally do nothing
}
//is it a DIR or a file
if (dirString.trim().equals("d")) {
f.setType(FTPFile.DIRECTORY_TYPE);
} else // Should be "-"
{
f.setType(FTPFile.FILE_TYPE);
}
f.setUser(user);
//set the name
f.setName(name.trim());
//set the size
f.setSize(Long.parseLong(size.trim()));
// Now set the permissions (or at least a subset thereof - full permissions would probably require
// subclassing FTPFile and adding extra metainformation there)
if (attrib.indexOf("R") != -1) {
f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION,
true);
}
if (attrib.indexOf("W") != -1) {
f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION,
true);
}
return (f);
}
return null;
}
/**
* Defines a default configuration to be used when this class is
* instantiated without a {@link FTPClientConfig FTPClientConfig}
* parameter being specified.
* @return the default configuration for this parser.
*/
@Override
protected FTPClientConfig getDefaultConfiguration() {
return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT, null, null,
null);
}
}
././@LongLink 0000000 0000000 0000000 00000000150 00000000000 011561 L ustar root root commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java commons-net-2.2/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.j0000644 0001750 0001750 00000010645 11330134135 033512 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.ftp.parser;
import java.text.ParseException;
import java.util.Calendar;
import org.apache.commons.net.ftp.Configurable;
import org.apache.commons.net.ftp.FTPClientConfig;
/**
* timestampParser
for extracting the timestamp.
* @return a java.util.Calendar
containing results of the
* timestamp parse.
*/
public Calendar parseTimestamp(String timestampStr) throws ParseException {
return this.timestampParser.parseTimestamp(timestampStr);
}
/**
* Implementation of the {@link Configurable Configurable}
* interface. Configures this parser by delegating to the
* underlying Configurable FTPTimestampParser implementation, '
* passing it the supplied {@link FTPClientConfig FTPClientConfig}
* if that is non-null or a default configuration defined by
* each concrete subclass.
* REGEX
is not a valid regular expression.
*/
public VMSFTPEntryParser()
{
this(null);
}
/**
* This constructor allows the creation of a VMSFTPEntryParser object with
* something other than the default configuration.
*
* @param config The {@link FTPClientConfig configuration} object used to
* configure this parser.
* @exception IllegalArgumentException
* Thrown if the regular expression is unparseable. Should not be seen
* under normal conditions. It it is seen, this is a sign that
* REGEX
is not a valid regular expression.
* @since 1.4
*/
public VMSFTPEntryParser(FTPClientConfig config)
{
super(REGEX);
configure(config);
}
/***
* Parses an FTP server file listing and converts it into a usable format
* in the form of an array of FTPFile
instances. If the
* file list contains no files, null
should be
* returned, otherwise an array of FTPFile
instances
* representing the files in the directory is returned.
* FTPFile
instance. If the
* file listing line doesn't describe a file, null
is
* returned, otherwise a FTPFile
instance representing the
* files in the directory is returned.
* key
is not recognized as a fully qualified
* classname known to the system, this method will then attempt
* to see whether it contains a string identifying one of
* the known parsers. This comparison is case-insensitive.
* The intent here is where possible, to select as keys strings
* which are returned by the SYST command on the systems which
* the corresponding parser successfully parses. This enables
* this factory to be used in the auto-detection system.
*
*
* @param key should be a fully qualified classname corresponding to
* a class implementing the FTPFileEntryParser interface
* OR
* a string containing (case-insensitively) one of the
* following keywords:
*
*
* @return the FTPFileEntryParser corresponding to the supplied key.
* @throws ParserInitializationException thrown if for any reason the factory cannot resolve
* the supplied key into an FTPFileEntryParser.
* @see FTPFileEntryParser
*/
public FTPFileEntryParser createFileEntryParser(String key)
{
if (key == null)
throw new ParserInitializationException("Parser key cannot be null");
Class> parserClass = null;
FTPFileEntryParser parser = null;
try
{
parserClass = Class.forName(key);
try {
parser = (FTPFileEntryParser) parserClass.newInstance();
} catch (ClassCastException e) {
throw new ParserInitializationException(parserClass.getName()
+ " does not implement the interface "
+ "org.apache.commons.net.ftp.FTPFileEntryParser.", e);
}
}
catch (ClassNotFoundException e)
{
try
{
String ukey = key.toUpperCase(java.util.Locale.ENGLISH);
if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0)
{
parser = createUnixFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
{
parser = createVMSVersioningFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
{
parser = createNTFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
{
parser = createOS2FTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0 ||
ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0)
{
parser = createOS400FTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
{
parser = createMVSEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0)
{
parser = createNetwareFTPEntryParser();
}
else if (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0)
{
// L8 normally means Unix, but move it to the end for some L8 systems that aren't.
// This check should be last!
parser = createUnixFTPEntryParser();
}
else
{
throw new ParserInitializationException("Unknown parser type: " + key);
}
}
// TODO can this happen?
catch (NoClassDefFoundError nf) {
throw new ParserInitializationException("Error initializing parser", nf);
}
}
catch (NoClassDefFoundError e)
{
throw new ParserInitializationException("Error initializing parser", e);
}
catch (ParserInitializationException e) // Don't rewrap exception
{
throw e;
}
catch (Throwable e)
{
throw new ParserInitializationException("Error initializing parser", e);
}
if (parser instanceof Configurable) {
((Configurable)parser).configure(this.config);
}
return parser;
}
/**
* null
.
* @return true
if the file is to be included, false
otherwise
*/
public boolean accept(FTPFile file);
}
commons-net-2.2/src/main/java/org/apache/commons/net/ftp/FTPFileFilters.java 0000644 0001750 0001750 00000003175 11466231525 026710 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.commons.net.ftp;
/**
* Implements some simple FTPFileFilter classes.
* @since 2.2
*/
public class FTPFileFilters {
/**
* Accepts all FTPFile entries, including null
*/
public static final FTPFileFilter ALL = new FTPFileFilter() {
public boolean accept(FTPFile file) {
return true;
}
};
/**
* Accepts all non-null FTPFile entries
*/
public static final FTPFileFilter NON_NULL = new FTPFileFilter() {
public boolean accept(FTPFile file) {
return file != null;
}
};
/**
* Accepts all (non-null) FTPFile directory entries
*/
public static final FTPFileFilter DIRECTORIES = new FTPFileFilter() {
public boolean accept(FTPFile file) {
return file != null && file.isDirectory();
}
};
}
commons-net-2.2/src/main/java/org/apache/commons/net/daytime/ 0000755 0001750 0001750 00000000000 11617452467 024130 5 ustar twerner twerner commons-net-2.2/src/main/java/org/apache/commons/net/daytime/DaytimeUDPClient.java 0000644 0001750 0001750 00000006053 11354710167 030073 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.daytime;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import org.apache.commons.net.DatagramSocketClient;
/***
* The DaytimeUDPClient class is a UDP implementation of a client for the
* Daytime protocol described in RFC 867. To use the class, merely
* open a local datagram socket with
* {@link org.apache.commons.net.DatagramSocketClient#open open }
* and call {@link #getTime getTime } to retrieve the daytime
* string, then
* call {@link org.apache.commons.net.DatagramSocketClient#close close }
* to close the connection properly. Unlike
* {@link org.apache.commons.net.daytime.DaytimeTCPClient},
* successive calls to {@link #getTime getTime } are permitted
* without re-establishing a connection. That is because UDP is a
* connectionless protocol and the Daytime protocol is stateless.
* getTime(host, DaytimeUDPClient.DEFAULT_PORT);
***/
public String getTime(InetAddress host) throws IOException
{
return getTime(host, DEFAULT_PORT);
}
}
commons-net-2.2/src/main/java/org/apache/commons/net/daytime/DaytimeTCPClient.java 0000644 0001750 0001750 00000006176 11354710167 030077 0 ustar twerner twerner /*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.daytime;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.commons.net.SocketClient;
/***
* The DaytimeTCPClient class is a TCP implementation of a client for the
* Daytime protocol described in RFC 867. To use the class, merely
* establish a connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* and call {@link #getTime getTime() } to retrieve the daytime
* string, then
* call {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* to close the connection properly.
* DEFAULT_PORT
.
***/
public DaytimeTCPClient ()
{
setDefaultPort(DEFAULT_PORT);
}
/***
* Retrieves the time string from the server and returns it. The
* server will have closed the connection at this point, so you should
* call
* {@link org.apache.commons.net.SocketClient#disconnect disconnect }
* after calling this method. To retrieve another time, you must
* initiate another connection with
* {@link org.apache.commons.net.SocketClient#connect connect }
* before calling getTime()
again.
*