Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Administrator
Arthas
Commits
5d7c4150
Commit
5d7c4150
authored
Dec 21, 2023
by
shengnan hu
Browse files
init
parents
Pipeline
#6771
failed with stage
in 4 seconds
Changes
457
Pipelines
914
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
5090 additions
and
0 deletions
+5090
-0
client/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
.../org/apache/commons/net/DefaultDatagramSocketFactory.java
+79
-0
client/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
...ain/java/org/apache/commons/net/DefaultSocketFactory.java
+230
-0
client/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
...org/apache/commons/net/MalformedServerReplyException.java
+56
-0
client/src/main/java/org/apache/commons/net/PrintCommandListener.java
...ain/java/org/apache/commons/net/PrintCommandListener.java
+200
-0
client/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
...ain/java/org/apache/commons/net/ProtocolCommandEvent.java
+148
-0
client/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
.../java/org/apache/commons/net/ProtocolCommandListener.java
+58
-0
client/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
...n/java/org/apache/commons/net/ProtocolCommandSupport.java
+135
-0
client/src/main/java/org/apache/commons/net/SocketClient.java
...nt/src/main/java/org/apache/commons/net/SocketClient.java
+888
-0
client/src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java
...java/org/apache/commons/net/telnet/EchoOptionHandler.java
+52
-0
client/src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
...ache/commons/net/telnet/InvalidTelnetOptionException.java
+62
-0
client/src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
...va/org/apache/commons/net/telnet/SimpleOptionHandler.java
+59
-0
client/src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
...rg/apache/commons/net/telnet/SuppressGAOptionHandler.java
+52
-0
client/src/main/java/org/apache/commons/net/telnet/Telnet.java
...t/src/main/java/org/apache/commons/net/telnet/Telnet.java
+1265
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
...main/java/org/apache/commons/net/telnet/TelnetClient.java
+414
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetCommand.java
...ain/java/org/apache/commons/net/telnet/TelnetCommand.java
+131
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetInputListener.java
...va/org/apache/commons/net/telnet/TelnetInputListener.java
+37
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
...java/org/apache/commons/net/telnet/TelnetInputStream.java
+680
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
.../apache/commons/net/telnet/TelnetNotificationHandler.java
+68
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetOption.java
...main/java/org/apache/commons/net/telnet/TelnetOption.java
+193
-0
client/src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
...va/org/apache/commons/net/telnet/TelnetOptionHandler.java
+283
-0
No files found.
Too many changes to show.
To preserve performance only
457 of 457+
files are displayed.
Plain diff
Email patch
client/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
0 → 100644
View file @
5d7c4150
/*
* 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.
*
*
* @see DatagramSocketFactory
* @see DatagramSocketClient
* @see DatagramSocketClient#setDatagramSocketFactory
***/
public
class
DefaultDatagramSocketFactory
implements
DatagramSocketFactory
{
/***
* Creates a DatagramSocket on the local host at the first available port.
* @return a new DatagramSocket
* @exception SocketException If the socket could not be created.
***/
@Override
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.
* @return a new DatagramSocket
* @exception SocketException If the socket could not be created.
***/
@Override
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.
* @return a new DatagramSocket
* @exception SocketException If the socket could not be created.
***/
@Override
public
DatagramSocket
createDatagramSocket
(
int
port
,
InetAddress
laddr
)
throws
SocketException
{
return
new
DatagramSocket
(
port
,
laddr
);
}
}
client/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
0 → 100644
View file @
5d7c4150
/*
* 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.InetSocketAddress
;
import
java.net.Proxy
;
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.
*
*
* @see SocketFactory
* @see SocketClient
* @see SocketClient#setSocketFactory
***/
public
class
DefaultSocketFactory
extends
SocketFactory
{
/** The proxy to use when creating new sockets. */
private
final
Proxy
connProxy
;
/**
* The default constructor.
*/
public
DefaultSocketFactory
()
{
this
(
null
);
}
/**
* A constructor for sockets with proxy support.
*
* @param proxy The Proxy to use when creating new Sockets.
* @since 3.2
*/
public
DefaultSocketFactory
(
Proxy
proxy
)
{
connProxy
=
proxy
;
}
/**
* Creates an unconnected Socket.
*
* @return A new unconnected Socket.
* @exception IOException If an I/O error occurs while creating the Socket.
* @since 3.2
*/
@Override
public
Socket
createSocket
()
throws
IOException
{
if
(
connProxy
!=
null
)
{
return
new
Socket
(
connProxy
);
}
return
new
Socket
();
}
/***
* 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
{
if
(
connProxy
!=
null
)
{
Socket
s
=
new
Socket
(
connProxy
);
s
.
connect
(
new
InetSocketAddress
(
host
,
port
));
return
s
;
}
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
{
if
(
connProxy
!=
null
)
{
Socket
s
=
new
Socket
(
connProxy
);
s
.
connect
(
new
InetSocketAddress
(
address
,
port
));
return
s
;
}
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
{
if
(
connProxy
!=
null
)
{
Socket
s
=
new
Socket
(
connProxy
);
s
.
bind
(
new
InetSocketAddress
(
localAddr
,
localPort
));
s
.
connect
(
new
InetSocketAddress
(
host
,
port
));
return
s
;
}
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
{
if
(
connProxy
!=
null
)
{
Socket
s
=
new
Socket
(
connProxy
);
s
.
bind
(
new
InetSocketAddress
(
localAddr
,
localPort
));
s
.
connect
(
new
InetSocketAddress
(
address
,
port
));
return
s
;
}
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
);
}
}
client/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
0 → 100644
View file @
5d7c4150
/*
* 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
;
/***
* This exception is used to indicate that the reply from a server
* could not be interpreted. Most of the NetComponents classes attempt
* to be as lenient as possible when receiving server replies. Many
* server implementations deviate from IETF protocol specifications, making
* it necessary to be as flexible as possible. However, there will be
* certain situations where it is not possible to continue an operation
* because the server reply could not be interpreted in a meaningful manner.
* In these cases, a MalformedServerReplyException should be thrown.
*
*
***/
public
class
MalformedServerReplyException
extends
IOException
{
private
static
final
long
serialVersionUID
=
6006765264250543945L
;
/*** 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
);
}
}
client/src/main/java/org/apache/commons/net/PrintCommandListener.java
0 → 100644
View file @
5d7c4150
/*
* 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.PrintStream
;
import
java.io.PrintWriter
;
/***
* 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
;
private
final
boolean
__nologin
;
private
final
char
__eolMarker
;
private
final
boolean
__directionMarker
;
/**
* Create the default instance which prints everything.
*
* @param stream where to write the commands and responses
* e.g. System.out
* @since 3.0
*/
public
PrintCommandListener
(
PrintStream
stream
)
{
this
(
new
PrintWriter
(
stream
));
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintStream
stream
,
boolean
suppressLogin
)
{
this
(
new
PrintWriter
(
stream
),
suppressLogin
);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintStream
stream
,
boolean
suppressLogin
,
char
eolMarker
)
{
this
(
new
PrintWriter
(
stream
),
suppressLogin
,
eolMarker
);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param stream where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code "> "} or {@code "< "} as appropriate to the output
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintStream
stream
,
boolean
suppressLogin
,
char
eolMarker
,
boolean
showDirection
)
{
this
(
new
PrintWriter
(
stream
),
suppressLogin
,
eolMarker
,
showDirection
);
}
/**
* Create the default instance which prints everything.
*
* @param writer where to write the commands and responses
*/
public
PrintCommandListener
(
PrintWriter
writer
)
{
this
(
writer
,
false
);
}
/**
* Create an instance which optionally suppresses login command text.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintWriter
writer
,
boolean
suppressLogin
)
{
this
(
writer
,
suppressLogin
,
(
char
)
0
);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintWriter
writer
,
boolean
suppressLogin
,
char
eolMarker
)
{
this
(
writer
,
suppressLogin
,
eolMarker
,
false
);
}
/**
* Create an instance which optionally suppresses login command text
* and indicates where the EOL starts with the specified character.
*
* @param writer where to write the commands and responses
* @param suppressLogin if {@code true}, only print command name for login
* @param eolMarker if non-zero, add a marker just before the EOL.
* @param showDirection if {@code true}, add {@code ">} " or {@code "< "} as appropriate to the output
*
* @since 3.0
*/
public
PrintCommandListener
(
PrintWriter
writer
,
boolean
suppressLogin
,
char
eolMarker
,
boolean
showDirection
)
{
__writer
=
writer
;
__nologin
=
suppressLogin
;
__eolMarker
=
eolMarker
;
__directionMarker
=
showDirection
;
}
@Override
public
void
protocolCommandSent
(
ProtocolCommandEvent
event
)
{
if
(
__directionMarker
)
{
__writer
.
print
(
"> "
);
}
if
(
__nologin
)
{
String
cmd
=
event
.
getCommand
();
if
(
"PASS"
.
equalsIgnoreCase
(
cmd
)
||
"USER"
.
equalsIgnoreCase
(
cmd
))
{
__writer
.
print
(
cmd
);
__writer
.
println
(
" *******"
);
// Don't bother with EOL marker for this!
}
else
{
final
String
IMAP_LOGIN
=
"LOGIN"
;
if
(
IMAP_LOGIN
.
equalsIgnoreCase
(
cmd
))
{
// IMAP
String
msg
=
event
.
getMessage
();
msg
=
msg
.
substring
(
0
,
msg
.
indexOf
(
IMAP_LOGIN
)+
IMAP_LOGIN
.
length
());
__writer
.
print
(
msg
);
__writer
.
println
(
" *******"
);
// Don't bother with EOL marker for this!
}
else
{
__writer
.
print
(
getPrintableString
(
event
.
getMessage
()));
}
}
}
else
{
__writer
.
print
(
getPrintableString
(
event
.
getMessage
()));
}
__writer
.
flush
();
}
private
String
getPrintableString
(
String
msg
){
if
(
__eolMarker
==
0
)
{
return
msg
;
}
int
pos
=
msg
.
indexOf
(
SocketClient
.
NETASCII_EOL
);
if
(
pos
>
0
)
{
return
msg
.
substring
(
0
,
pos
)
+
__eolMarker
+
msg
.
substring
(
pos
);
}
return
msg
;
}
@Override
public
void
protocolReplyReceived
(
ProtocolCommandEvent
event
)
{
if
(
__directionMarker
)
{
__writer
.
print
(
"< "
);
}
__writer
.
print
(
event
.
getMessage
());
__writer
.
flush
();
}
}
client/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
0 → 100644
View file @
5d7c4150
/*
* 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
***/
public
class
ProtocolCommandEvent
extends
EventObject
{
private
static
final
long
serialVersionUID
=
403743538418947240L
;
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.
* Includes the line terminator.
*
* @return The entire message sent to or received from the server.
***/
public
String
getMessage
()
{
return
__message
;
}
}
client/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
0 → 100644
View file @
5d7c4150
/*
* 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.
* <p>
* 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
***/
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
);
}
client/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
0 → 100644
View file @
5d7c4150
/*
* 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
***/
public
class
ProtocolCommandSupport
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
8017692739988399978L
;
private
final
Object
__source
;
private
final
ListenerList
__listeners
;
/***
* Creates a ProtocolCommandSupport instance using the indicated source
* as the source of 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
();
}
}
client/src/main/java/org/apache/commons/net/SocketClient.java
0 → 100644
View file @
5d7c4150
/*
* 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.Proxy
;
import
java.net.Socket
;
import
java.net.SocketException
;
import
java.nio.charset.Charset
;
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 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.
* @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
();
/**
* A ProtocolCommandSupport object used to manage the registering of
* ProtocolCommandListeners and the firing of ProtocolCommandEvents.
*/
private
ProtocolCommandSupport
__commandSupport
;
/** The timeout to use after opening a socket. */
protected
int
_timeout_
;
/** The socket used for the connection. */
protected
Socket
_socket_
;
/** The hostname used for the connection (null = no hostname supplied). */
protected
String
_hostname_
;
/** 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 */
private
int
receiveBufferSize
=
-
1
;
/** Hint for SO_SNDBUF size */
private
int
sendBufferSize
=
-
1
;
/** The proxy to use when connecting. */
private
Proxy
connProxy
;
/**
* Charset to use for byte IO.
*/
private
Charset
charset
=
Charset
.
defaultCharset
();
/**
* Default constructor for SocketClient. Initializes
* _socket_ to null, _timeout_ to 0, _defaultPort to 0,
* _isConnected_ to false, charset to {@code Charset.defaultCharset()}
* and _socketFactory_ to a shared instance of
* {@link org.apache.commons.net.DefaultSocketFactory}.
*/
public
SocketClient
()
{
_socket_
=
null
;
_hostname_
=
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.
* <p>
* 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.
* <p>
* Subclasses overriding this method should start by calling
* <code> super._connectAction_() </code> first to ensure the
* initialization of the aforementioned protected variables.
* @throws IOException (SocketException) if a problem occurs with the socket
*/
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.
* <p>
* @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
{
_hostname_
=
null
;
_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.
* <p>
* @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 java.net.UnknownHostException If the hostname cannot be resolved.
*/
public
void
connect
(
String
hostname
,
int
port
)
throws
SocketException
,
IOException
{
connect
(
InetAddress
.
getByName
(
hostname
),
port
);
_hostname_
=
hostname
;
}
/**
* 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.
* <p>
* @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
{
_hostname_
=
null
;
_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.
* <p>
* @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 java.net.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
);
_hostname_
=
hostname
;
}
/**
* 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.
* <p>
* @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
{
_hostname_
=
null
;
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.
* <p>
* @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 java.net.UnknownHostException If the hostname cannot be resolved.
*/
public
void
connect
(
String
hostname
)
throws
SocketException
,
IOException
{
connect
(
hostname
,
_defaultPort_
);
_hostname_
=
hostname
;
}
/**
* 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.
* <p>
* @exception IOException If there is an error closing the socket.
*/
public
void
disconnect
()
throws
IOException
{
closeQuietly
(
_socket_
);
closeQuietly
(
_input_
);
closeQuietly
(
_output_
);
_socket_
=
null
;
_hostname_
=
null
;
_input_
=
null
;
_output_
=
null
;
}
private
void
closeQuietly
(
Socket
socket
)
{
if
(
socket
!=
null
){
try
{
socket
.
close
();
}
catch
(
IOException
e
)
{
// Ignored
}
}
}
private
void
closeQuietly
(
Closeable
close
){
if
(
close
!=
null
){
try
{
close
.
close
();
}
catch
(
IOException
e
)
{
// Ignored
}
}
}
/**
* Returns true if the client is currently connected to a server.
* <p>
* Delegates to {@link Socket#isConnected()}
* @return True if the client is currently connected to a server,
* false otherwise.
*/
public
boolean
isConnected
()
{
if
(
_socket_
==
null
)
{
return
false
;
}
return
_socket_
.
isConnected
();
}
/**
* Make various checks on the socket to test if it is available for use.
* Note that the only sure test is to use it, but these checks may help
* in some cases.
* @see <a href="https://issues.apache.org/jira/browse/NET-350">NET-350</a>
* @return {@code true} if the socket appears to be available for use
* @since 3.0
*/
public
boolean
isAvailable
(){
if
(
isConnected
())
{
try
{
if
(
_socket_
.
getInetAddress
()
==
null
)
{
return
false
;
}
if
(
_socket_
.
getPort
()
==
0
)
{
return
false
;
}
if
(
_socket_
.
getRemoteSocketAddress
()
==
null
)
{
return
false
;
}
if
(
_socket_
.
isClosed
())
{
return
false
;
}
/* these aren't exact checks (a Socket can be half-open),
but since we usually require two-way data transfer,
we check these here too: */
if
(
_socket_
.
isInputShutdown
())
{
return
false
;
}
if
(
_socket_
.
isOutputShutdown
())
{
return
false
;
}
/* ignore the result, catch exceptions: */
_socket_
.
getInputStream
();
_socket_
.
getOutputStream
();
}
catch
(
IOException
ioex
)
{
return
false
;
}
return
true
;
}
else
{
return
false
;
}
}
/**
* 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.
* <p>
* @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_ }).
* <p>
* @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.
* <p>
* @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.
* <p>
* @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()}.
* <p>
* To set the initial timeout, use {@link #setDefaultTimeout(int)} instead.
*
* @param timeout The timeout in milliseconds to use for the currently
* open socket connection.
* @exception SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public
void
setSoTimeout
(
int
timeout
)
throws
SocketException
{
_socket_
.
setSoTimeout
(
timeout
);
}
/**
* Set the underlying socket send buffer size.
* <p>
* @param size The size of the buffer in bytes.
* @throws SocketException never thrown, but subclasses might want to do so
* @since 2.0
*/
public
void
setSendBufferSize
(
int
size
)
throws
SocketException
{
sendBufferSize
=
size
;
}
/**
* Get the current sendBuffer size
* @return the size, or -1 if not initialised
* @since 3.0
*/
protected
int
getSendBufferSize
(){
return
sendBufferSize
;
}
/**
* Sets the underlying socket receive buffer size.
* <p>
* @param size The size of the buffer in bytes.
* @throws SocketException never (but subclasses may wish to do so)
* @since 2.0
*/
public
void
setReceiveBufferSize
(
int
size
)
throws
SocketException
{
receiveBufferSize
=
size
;
}
/**
* Get the current receivedBuffer size
* @return the size, or -1 if not initialised
* @since 3.0
*/
protected
int
getReceiveBufferSize
(){
return
receiveBufferSize
;
}
/**
* Returns the timeout in milliseconds of the currently opened socket.
* <p>
* @return The timeout in milliseconds of the currently opened socket.
* @exception SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public
int
getSoTimeout
()
throws
SocketException
{
return
_socket_
.
getSoTimeout
();
}
/**
* Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
* currently opened socket.
* <p>
* @param on True if Nagle's algorithm is to be enabled, false if not.
* @exception SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public
void
setTcpNoDelay
(
boolean
on
)
throws
SocketException
{
_socket_
.
setTcpNoDelay
(
on
);
}
/**
* Returns true if Nagle's algorithm is enabled on the currently opened
* socket.
* <p>
* @return True if Nagle's algorithm is enabled on the currently opened
* socket, false otherwise.
* @exception SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
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 if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
* @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.
* Delegates to {@link Socket#getKeepAlive()}
* @return True if SO_KEEPALIVE is enabled.
* @throws SocketException if there is a problem with the socket
* @throws NullPointerException if the socket is not currently open
* @since 2.2
*/
public
boolean
getKeepAlive
()
throws
SocketException
{
return
_socket_
.
getKeepAlive
();
}
/**
* Sets the SO_LINGER timeout on the currently opened socket.
* <p>
* @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.
* @throws NullPointerException if the socket is not currently open
*/
public
void
setSoLinger
(
boolean
on
,
int
val
)
throws
SocketException
{
_socket_
.
setSoLinger
(
on
,
val
);
}
/**
* Returns the current SO_LINGER timeout of the currently opened socket.
* <p>
* @return The current SO_LINGER timeout. If SO_LINGER is disabled returns
* -1.
* @exception SocketException If the operation fails.
* @throws NullPointerException if the socket is not currently open
*/
public
int
getSoLinger
()
throws
SocketException
{
return
_socket_
.
getSoLinger
();
}
/**
* Returns the port number of the open socket on the local host used
* for the connection.
* Delegates to {@link Socket#getLocalPort()}
* <p>
* @return The port number of the open socket on the local host used
* for the connection.
* @throws NullPointerException if the socket is not currently open
*/
public
int
getLocalPort
()
{
return
_socket_
.
getLocalPort
();
}
/**
* Returns the local address to which the client's socket is bound.
* Delegates to {@link Socket#getLocalAddress()}
* <p>
* @return The local address to which the client's socket is bound.
* @throws NullPointerException if the socket is not currently open
*/
public
InetAddress
getLocalAddress
()
{
return
_socket_
.
getLocalAddress
();
}
/**
* Returns the port number of the remote host to which the client is
* connected.
* Delegates to {@link Socket#getPort()}
* <p>
* @return The port number of the remote host to which the client is
* connected.
* @throws NullPointerException if the socket is not currently open
*/
public
int
getRemotePort
()
{
return
_socket_
.
getPort
();
}
/**
* @return The remote address to which the client is connected.
* Delegates to {@link Socket#getInetAddress()}
* @throws NullPointerException if the socket is not currently open
*/
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.
* <p>
* @param socket the item to check against
* @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).
* Any proxy setting is discarded.
* <p>
* @param factory The new SocketFactory the SocketClient should use.
*/
public
void
setSocketFactory
(
SocketFactory
factory
)
{
if
(
factory
==
null
)
{
_socketFactory_
=
__DEFAULT_SOCKET_FACTORY
;
}
else
{
_socketFactory_
=
factory
;
}
// re-setting the socket factory makes the proxy setting useless,
// so set the field to null so that getProxy() doesn't return a
// Proxy that we're actually not using.
connProxy
=
null
;
}
/**
* 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).
* <p>
* @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_
;
}
/**
* Adds a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to add.
* @since 3.0
*/
public
void
addProtocolCommandListener
(
ProtocolCommandListener
listener
)
{
getCommandSupport
().
addProtocolCommandListener
(
listener
);
}
/**
* Removes a ProtocolCommandListener.
*
* @param listener The ProtocolCommandListener to remove.
* @since 3.0
*/
public
void
removeProtocolCommandListener
(
ProtocolCommandListener
listener
)
{
getCommandSupport
().
removeProtocolCommandListener
(
listener
);
}
/**
* If there are any listeners, send them the reply details.
*
* @param replyCode the code extracted from the reply
* @param reply the full reply text
* @since 3.0
*/
protected
void
fireReplyReceived
(
int
replyCode
,
String
reply
)
{
if
(
getCommandSupport
().
getListenerCount
()
>
0
)
{
getCommandSupport
().
fireReplyReceived
(
replyCode
,
reply
);
}
}
/**
* If there are any listeners, send them the command details.
*
* @param command the command name
* @param message the complete message, including command name
* @since 3.0
*/
protected
void
fireCommandSent
(
String
command
,
String
message
)
{
if
(
getCommandSupport
().
getListenerCount
()
>
0
)
{
getCommandSupport
().
fireCommandSent
(
command
,
message
);
}
}
/**
* Create the CommandSupport instance if required
*/
protected
void
createCommandSupport
(){
__commandSupport
=
new
ProtocolCommandSupport
(
this
);
}
/**
* Subclasses can override this if they need to provide their own
* instance field for backwards compatibilty.
*
* @return the CommandSupport instance, may be {@code null}
* @since 3.0
*/
protected
ProtocolCommandSupport
getCommandSupport
()
{
return
__commandSupport
;
}
/**
* Sets the proxy for use with all the connections.
* The proxy is used for connections established after the
* call to this method.
*
* @param proxy the new proxy for connections.
* @since 3.2
*/
public
void
setProxy
(
Proxy
proxy
)
{
setSocketFactory
(
new
DefaultSocketFactory
(
proxy
));
connProxy
=
proxy
;
}
/**
* Gets the proxy for use with all the connections.
* @return the current proxy for connections.
*/
public
Proxy
getProxy
()
{
return
connProxy
;
}
/**
* Gets the charset name.
*
* @return the charset.
* @since 3.3
* @deprecated Since the code now requires Java 1.6 as a mininmum
*/
@Deprecated
public
String
getCharsetName
()
{
return
charset
.
name
();
}
/**
* Gets the charset.
*
* @return the charset.
* @since 3.3
*/
public
Charset
getCharset
()
{
return
charset
;
}
/**
* Sets the charset.
*
* @param charset the charset.
* @since 3.3
*/
public
void
setCharset
(
Charset
charset
)
{
this
.
charset
=
charset
;
}
/*
* N.B. Fields cannot be pulled up into a super-class without breaking binary compatibility,
* so the abstract method is needed to pass the instance to the methods which were moved here.
*/
}
client/src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java
0 → 100644
View file @
5d7c4150
/*
* 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.
***/
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.
* <p>
* @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
);
}
}
client/src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
0 → 100644
View file @
5d7c4150
/*
* 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.
***/
public
class
InvalidTelnetOptionException
extends
Exception
{
private
static
final
long
serialVersionUID
=
-
2516777155928793597L
;
/***
* Option code
***/
private
final
int
optionCode
;
/***
* Error message
***/
private
final
String
msg
;
/***
* Constructor for the exception.
* <p>
* @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.
* <p>
* @return the error message.
***/
@Override
public
String
getMessage
()
{
return
(
msg
+
": "
+
optionCode
);
}
}
client/src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
0 → 100644
View file @
5d7c4150
/*
* 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.
***/
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.
* <p>
* @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
* <p>
* @param optcode - option code.
***/
public
SimpleOptionHandler
(
int
optcode
)
{
super
(
optcode
,
false
,
false
,
false
,
false
);
}
}
client/src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
0 → 100644
View file @
5d7c4150
/*
* 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.
***/
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.
* <p>
* @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
);
}
}
client/src/main/java/org/apache/commons/net/telnet/Telnet.java
0 → 100644
View file @
5d7c4150
/*
* 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
java.util.Arrays
;
import
org.apache.commons.net.SocketClient
;
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
final
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
final
Object
aytMonitor
=
new
Object
();
/***
* flag for AYT
***/
private
volatile
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.
* @throws IOException
***/
void
_setWill
(
int
option
)
throws
IOException
{
_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
)
{
_sendSubnegotiation
(
subneg
);
}
}
}
/* open TelnetOptionHandler functionality (end)*/
}
/***
* Sets the state of the option.
*
* @param option - option code to be set.
* @throws IOException
***/
void
_setDo
(
int
option
)
throws
IOException
{
_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
)
{
_sendSubnegotiation
(
subneg
);
}
}
}
/* 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
(
getCharset
()));
_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
)
{
System
.
err
.
println
(
Arrays
.
toString
(
subn
));
}
}
if
(
subn
!=
null
)
{
_output_
.
write
(
_COMMAND_SB
);
// Note _output_ is buffered, so might as well simplify by writing single bytes
for
(
int
element
:
subn
)
{
byte
b
=
(
byte
)
element
;
if
(
b
==
(
byte
)
TelnetCommand
.
IAC
)
{
// cast is necessary because IAC is outside the signed byte range
_output_
.
write
(
b
);
// double any IAC bytes
}
_output_
.
write
(
b
);
}
_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)*/
/**
* Sends a command, automatically adds IAC prefix and flushes the output.
*
* @param cmd - command data to be sent
* @throws IOException - Exception in I/O.
* @since 3.0
*/
final
synchronized
void
_sendCommand
(
byte
cmd
)
throws
IOException
{
_output_
.
write
(
TelnetCommand
.
IAC
);
_output_
.
write
(
cmd
);
_output_
.
flush
();
}
/* Code Section added for supporting AYT (start)*/
/***
* Processes the response of an AYT
***/
final
synchronized
void
_processAYTResponse
()
{
if
(!
aytFlag
)
{
synchronized
(
aytMonitor
)
{
aytFlag
=
true
;
aytMonitor
.
notifyAll
();
}
}
}
/* 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
())
{
_requestWill
(
optionHandlers
[
ii
].
getOptionCode
());
}
if
(
optionHandlers
[
ii
].
getInitRemote
())
{
_requestDo
(
optionHandlers
[
ii
].
getOptionCode
());
}
}
}
/* 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
();
}
aytMonitor
.
wait
(
timeout
);
if
(!
aytFlag
)
{
retValue
=
false
;
aytFlag
=
true
;
}
else
{
retValue
=
true
;
}
}
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.
* @throws IOException on error
**/
void
addOptionHandler
(
TelnetOptionHandler
opthand
)
throws
InvalidTelnetOptionException
,
IOException
{
int
optcode
=
opthand
.
getOptionCode
();
if
(
TelnetOption
.
isValidOption
(
optcode
))
{
if
(
optionHandlers
[
optcode
]
==
null
)
{
optionHandlers
[
optcode
]
=
opthand
;
if
(
isConnected
())
{
if
(
opthand
.
getInitLocal
())
{
_requestWill
(
optcode
);
}
if
(
opthand
.
getInitRemote
())
{
_requestDo
(
optcode
);
}
}
}
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.
* @throws IOException on error
**/
void
deleteOptionHandler
(
int
optcode
)
throws
InvalidTelnetOptionException
,
IOException
{
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
())
{
_requestWont
(
optcode
);
}
if
(
opthand
.
getDo
())
{
_requestDont
(
optcode
);
}
}
}
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'
)
// never write '\r' on its own
{
if
(
ch
==
'\n'
)
{
spy
.
write
(
'\r'
);
// add '\r' before '\n'
}
spy
.
write
(
ch
);
// write original character
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
;
}
}
client/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
0 → 100644
View file @
5d7c4150
/*
* 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
;
/***
* 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.
* <p>
* 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.
***/
public
class
TelnetClient
extends
Telnet
{
private
InputStream
__input
;
private
OutputStream
__output
;
protected
boolean
readerThread
=
true
;
private
TelnetInputListener
inputListener
;
/***
* Default TelnetClient constructor, sets terminal-type {@code VT100}.
***/
public
TelnetClient
()
{
/* TERMINAL-TYPE option (start)*/
super
(
"VT100"
);
/* TERMINAL-TYPE option (end)*/
__input
=
null
;
__output
=
null
;
}
/**
* Construct an instance with the specified terminal type.
*
* @param termtype the terminal type to use, e.g. {@code VT100}
*/
/* 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_
();
TelnetInputStream
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
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 on error
* @throws IllegalArgumentException on error
* @throws IOException on error
***/
public
boolean
sendAYT
(
long
timeout
)
throws
IOException
,
IllegalArgumentException
,
InterruptedException
{
return
(
_sendAYT
(
timeout
));
}
/* Code Section added for supporting AYT (start)*/
/***
* Sends a protocol-specific subnegotiation message to the remote peer.
* {@link TelnetClient} will add the IAC SB & IAC SE framing bytes;
* the first byte in {@code message} should be the appropriate telnet
* option code.
*
* <p>
* This method does not wait for any response. Subnegotiation messages
* sent by the remote end can be handled by registering an approrpriate
* {@link TelnetOptionHandler}.
* </p>
*
* @param message option code followed by subnegotiation payload
* @throws IllegalArgumentException if {@code message} has length zero
* @throws IOException if an I/O error occurs while writing the message
* @since 3.0
***/
public
void
sendSubnegotiation
(
int
[]
message
)
throws
IOException
,
IllegalArgumentException
{
if
(
message
.
length
<
1
)
{
throw
new
IllegalArgumentException
(
"zero length message"
);
}
_sendSubnegotiation
(
message
);
}
/***
* Sends a command byte to the remote peer, adding the IAC prefix.
*
* <p>
* This method does not wait for any response. Messages
* sent by the remote end can be handled by registering an approrpriate
* {@link TelnetOptionHandler}.
* </p>
*
* @param command the code for the command
* @throws IOException if an I/O error occurs while writing the message
* @throws IllegalArgumentException on error
* @since 3.0
***/
public
void
sendCommand
(
byte
command
)
throws
IOException
,
IllegalArgumentException
{
_sendCommand
(
command
);
}
/* open TelnetOptionHandler functionality (start)*/
/***
* Registers a new TelnetOptionHandler for this telnet client to use.
*
* @param opthand - option handler to be registered.
*
* @throws InvalidTelnetOptionException on error
* @throws IOException on error
***/
@Override
public
void
addOptionHandler
(
TelnetOptionHandler
opthand
)
throws
InvalidTelnetOptionException
,
IOException
{
super
.
addOptionHandler
(
opthand
);
}
/* open TelnetOptionHandler functionality (end)*/
/***
* Unregisters a TelnetOptionHandler.
*
* @param optcode - Code of the option to be unregistered.
*
* @throws InvalidTelnetOptionException on error
* @throws IOException on error
***/
@Override
public
void
deleteOptionHandler
(
int
optcode
)
throws
InvalidTelnetOptionException
,
IOException
{
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.
*
* <p>
* When enabled, a seaparate internal reader thread is created for new
* connections to read incoming data as it arrives. This results in
* immediate handling of option negotiation, notifications, etc.
* (at least until the fixed-size internal buffer fills up).
* Otherwise, no thread is created an all negotiation and option
* handling is deferred until a read() is performed on the
* {@link #getInputStream input stream}.
* </p>
*
* <p>
* The reader thread must be enabled for {@link TelnetInputListener}
* support.
* </p>
*
* <p>
* When this method is invoked, the reader thread status will apply to all
* subsequent connections; the current connection (if any) is not affected.
* </p>
*
* @param flag true to enable the reader thread, false to disable
* @see #registerInputListener
***/
public
void
setReaderThread
(
boolean
flag
)
{
readerThread
=
flag
;
}
/***
* Gets the status of the reader thread.
*
* @return true if the reader thread is enabled, false otherwise
***/
public
boolean
getReaderThread
()
{
return
(
readerThread
);
}
/***
* Register a listener to be notified when new incoming data is
* available to be read on the {@link #getInputStream input stream}.
* Only one listener is supported at a time.
*
* <p>
* More precisely, notifications are issued whenever the number of
* bytes available for immediate reading (i.e., the value returned
* by {@link InputStream#available}) transitions from zero to non-zero.
* Note that (in general) multiple reads may be required to empty the
* buffer and reset this notification, because incoming bytes are being
* added to the internal buffer asynchronously.
* </p>
*
* <p>
* Notifications are only supported when a {@link #setReaderThread
* reader thread} is enabled for the connection.
* </p>
*
* @param listener listener to be registered; replaces any previous
* @since 3.0
***/
public
synchronized
void
registerInputListener
(
TelnetInputListener
listener
)
{
this
.
inputListener
=
listener
;
}
/***
* Unregisters the current {@link TelnetInputListener}, if any.
*
* @since 3.0
***/
public
synchronized
void
unregisterInputListener
()
{
this
.
inputListener
=
null
;
}
// Notify input listener
void
notifyInputListener
()
{
TelnetInputListener
listener
;
synchronized
(
this
)
{
listener
=
this
.
inputListener
;
}
if
(
listener
!=
null
)
{
listener
.
telnetInputAvailable
();
}
}
}
client/src/main/java/org/apache/commons/net/telnet/TelnetCommand.java
0 → 100644
View file @
5d7c4150
/*
* 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.
* @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.
* <p>
* @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.
* <p>
* @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
()
{
}
}
client/src/main/java/org/apache/commons/net/telnet/TelnetInputListener.java
0 → 100644
View file @
5d7c4150
/*
* 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
;
/***
* Listener interface used for notification that incoming data is
* available to be read.
*
* @see TelnetClient
* @since 3.0
***/
public
interface
TelnetInputListener
{
/***
* Callback method invoked when new incoming data is available on a
* {@link TelnetClient}'s {@link TelnetClient#getInputStream input stream}.
*
* @see TelnetClient#registerInputListener
***/
public
void
telnetInputAvailable
();
}
client/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
0 → 100644
View file @
5d7c4150
/*
* 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
;
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
;
// @GuardedBy("__queue")
private
volatile
boolean
__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
[
512
];
private
int
__suboption_count
=
0
;
/* TERMINAL-TYPE option (end)*/
private
volatile
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
;
// tell _processChar that we are running threaded
}
// 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
case
TelnetCommand
.
SE
:
// unexpected byte! ignore it (don't send it as a command)
__receiveState
=
_STATE_DATA
;
continue
;
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
if
(
__suboption_count
<
__suboption
.
length
)
{
__suboption
[
__suboption_count
++]
=
ch
;
}
break
;
}
__receiveState
=
_STATE_SB
;
continue
;
case
_STATE_IAC_SB:
// IAC received during SB phase
switch
(
ch
)
{
case
TelnetCommand
.
SE
:
synchronized
(
__client
)
{
__client
.
_processSuboption
(
__suboption
,
__suboption_count
);
__client
.
_flushOutputStream
();
}
__receiveState
=
_STATE_DATA
;
continue
;
case
TelnetCommand
.
IAC
:
// De-dup the duplicated IAC
if
(
__suboption_count
<
__suboption
.
length
)
{
__suboption
[
__suboption_count
++]
=
ch
;
}
break
;
default
:
// unexpected byte! ignore it
break
;
}
__receiveState
=
_STATE_SB
;
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. Returns true if buffer was previously empty.
private
boolean
__processChar
(
int
ch
)
throws
InterruptedException
{
// Critical section because we're altering __bytesAvailable,
// __queueTail, and the contents of _queue.
boolean
bufferWasEmpty
;
synchronized
(
__queue
)
{
bufferWasEmpty
=
(
__bytesAvailable
==
0
);
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
;
}
}
return
bufferWasEmpty
;
}
@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
)
{
// must be EOF
if
(
ch
!=
WOULD_BLOCK
)
{
return
(
ch
);
}
}
}
catch
(
InterruptedIOException
e
)
{
synchronized
(
__queue
)
{
__ioException
=
e
;
__queue
.
notifyAll
();
try
{
__queue
.
wait
(
100
);
}
catch
(
InterruptedException
interrupted
)
{
// Ignored
}
}
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.
* <p>
* @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.
* <p>
* @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
)
{
if
(
__threaded
)
{
// Must not call super.available when running threaded: NET-466
return
__bytesAvailable
;
}
else
{
return
__bytesAvailable
+
super
.
available
();
}
}
}
// 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
();
}
}
@Override
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
;
}
// Process new character
boolean
notify
=
false
;
try
{
notify
=
__processChar
(
ch
);
}
catch
(
InterruptedException
e
)
{
if
(
__isClosed
)
{
break
_outerLoop
;
}
}
// Notify input listener if buffer was previously empty
if
(
notify
)
{
__client
.
notifyInputListener
();
}
}
}
catch
(
IOException
ioe
)
{
synchronized
(
__queue
)
{
__ioException
=
ioe
;
}
__client
.
notifyInputListener
();
}
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: **
*/
client/src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
0 → 100644
View file @
5d7c4150
/*
* 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.
* <p>
* The user can implement this interface and register a
* TelnetNotificationHandler by using the registerNotificationHandler()
* of TelnetClient to be notified of option negotiation commands.
***/
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
);
}
client/src/main/java/org/apache/commons/net/telnet/TelnetOption.java
0 → 100644
View file @
5d7c4150
/*
* 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.
* <p>
* Details regarding Telnet option specification can be found in RFC 855.
*
*
* @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
()
{
}
}
client/src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
0 → 100644
View file @
5d7c4150
/*
* 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.
* <p>
* TelnetOptionHandler implements basic option handling
* functionality and defines abstract methods that must be
* implemented to define subnegotiation behaviour.
***/
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.
* <p>
* @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.
* <p>
* @return Option code.
***/
public
int
getOptionCode
()
{
return
(
optionCode
);
}
/***
* Returns a boolean indicating whether to accept a DO
* request coming from the other end.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* @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.
* <p>
* This implementation returns null, and
* must be overridden by the actual TelnetOptionHandler to specify
* which response must be sent for the subnegotiation request.
* <p>
* @param suboptionData - the sequence received, without IAC SB & IAC SE
* @param suboptionLength - the length of data in suboption_data
* <p>
* @return response to be sent to the subnegotiation sequence. TelnetClient
* will add IAC SB & IAC SE. null means no response
***/
public
int
[]
answerSubnegotiation
(
int
suboptionData
[],
int
suboptionLength
)
{
return
null
;
}
/***
* 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.
* <p>
* This implementation returns null, and must be overriden by
* the actual TelnetOptionHandler to specify
* which response must be sent for the subnegotiation request.
* @return subnegotiation sequence to be sent by TelnetClient. TelnetClient
* will add IAC SB & IAC SE. null means no subnegotiation.
***/
public
int
[]
startSubnegotiationLocal
()
{
return
null
;
}
/***
* 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.
* <p>
* This implementation returns null, and must be overriden by
* the actual TelnetOptionHandler to specify
* which response must be sent for the subnegotiation request.
* @return subnegotiation sequence to be sent by TelnetClient. TelnetClient
* will add IAC SB & IAC SE. null means no subnegotiation.
***/
public
int
[]
startSubnegotiationRemote
()
{
return
null
;
}
/***
* Returns a boolean indicating whether a WILL request sent to the other
* side has been acknowledged.
* <p>
* @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).
* <p>
* @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.
* <p>
* @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).
* <p>
* @param state - if true, a DO request has been acknowledged.
***/
void
setDo
(
boolean
state
)
{
doFlag
=
state
;
}
}
Prev
1
2
3
4
5
6
7
8
9
10
…
23
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment