1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Bug 475609 - Add support for telnet

Change-Id: I78696aae0d986c479a3fedfe314b4321640b1cc7
Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
Greg Watson 2015-08-21 17:07:39 -04:00
parent 8148e71c38
commit 880e5906e3
51 changed files with 3574 additions and 0 deletions

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.telnet-feature</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.pde.FeatureBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.FeatureNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,4 @@
bin.includes = feature.xml,\
feature.properties,\
epl-v10.html,\
eclipse_update_120.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,328 @@
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 9">
<meta name=Originator content="Microsoft Word 9">
<link rel=File-List
href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
<title>Eclipse Public License - Version 1.0</title>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Revision>2</o:Revision>
<o:TotalTime>3</o:TotalTime>
<o:Created>2004-03-05T23:03:00Z</o:Created>
<o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
<o:Pages>4</o:Pages>
<o:Words>1626</o:Words>
<o:Characters>9270</o:Characters>
<o:Lines>77</o:Lines>
<o:Paragraphs>18</o:Paragraphs>
<o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
<o:Version>9.4402</o:Version>
</o:DocumentProperties>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:TrackRevisions/>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
p
{margin-right:0in;
mso-margin-top-alt:auto;
mso-margin-bottom-alt:auto;
margin-left:0in;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
p.BalloonText, li.BalloonText, div.BalloonText
{mso-style-name:"Balloon Text";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:8.0pt;
font-family:Tahoma;
mso-fareast-font-family:"Times New Roman";}
@page Section1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>
</head>
<body lang=EN-US style='tab-interval:.5in'>
<div class=Section1>
<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
</p>
<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
OF THIS AGREEMENT.</span> </p>
<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
in the case of the initial Contributor, the initial code and documentation
distributed under this Agreement, and<br clear=left>
b) in the case of each subsequent Contributor:</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
changes to the Program, and</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
additions to the Program;</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
such changes and/or additions to the Program originate from and are distributed
by that particular Contributor. A Contribution 'originates' from a Contributor
if it was added to the Program by such Contributor itself or anyone acting on
such Contributor's behalf. Contributions do not include additions to the
Program which: (i) are separate modules of software distributed in conjunction
with the Program under their own license agreement, and (ii) are not derivative
works of the Program. </span></p>
<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
entity that distributes the Program.</span> </p>
<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
claims licensable by a Contributor which are necessarily infringed by the use
or sale of its Contribution alone or when combined with the Program. </span></p>
<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
distributed in accordance with this Agreement.</span> </p>
<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
receives the Program under this Agreement, including all Contributors.</span> </p>
<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
Subject to the terms of this Agreement, each Contributor hereby grants Recipient
a non-exclusive, worldwide, royalty-free copyright license to<span
style='color:red'> </span>reproduce, prepare derivative works of, publicly
display, publicly perform, distribute and sublicense the Contribution of such
Contributor, if any, and such derivative works, in source code and object code
form.</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
patent license under Licensed Patents to make, use, sell, offer to sell, import
and otherwise transfer the Contribution of such Contributor, if any, in source
code and object code form. This patent license shall apply to the combination
of the Contribution and the Program if, at the time the Contribution is added
by the Contributor, such addition of the Contribution causes such combination
to be covered by the Licensed Patents. The patent license shall not apply to
any other combinations which include the Contribution. No hardware per se is
licensed hereunder. </span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
Recipient understands that although each Contributor grants the licenses to its
Contributions set forth herein, no assurances are provided by any Contributor
that the Program does not infringe the patent or other intellectual property
rights of any other entity. Each Contributor disclaims any liability to Recipient
for claims brought by any other entity based on infringement of intellectual
property rights or otherwise. As a condition to exercising the rights and
licenses granted hereunder, each Recipient hereby assumes sole responsibility
to secure any other intellectual property rights needed, if any. For example,
if a third party patent license is required to allow Recipient to distribute
the Program, it is Recipient's responsibility to acquire that license before
distributing the Program.</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
Each Contributor represents that to its knowledge it has sufficient copyright
rights in its Contribution, if any, to grant the copyright license set forth in
this Agreement. </span></p>
<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
Program in object code form under its own license agreement, provided that:</span>
</p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
it complies with the terms and conditions of this Agreement; and</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
its license agreement:</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title
and non-infringement, and implied warranties or conditions of merchantability
and fitness for a particular purpose; </span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
effectively excludes on behalf of all Contributors all liability for damages,
including direct, indirect, special, incidental and consequential damages, such
as lost profits; </span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
states that any provisions which differ from this Agreement are offered by that
Contributor alone and not by any other party; and</span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
states that source code for the Program is available from such Contributor, and
informs licensees how to obtain it in a reasonable manner on or through a
medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
<p><span style='font-size:10.0pt'>When the Program is made available in source
code form:</span> </p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
it must be made available under this Agreement; and </span></p>
<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
copy of this Agreement must be included with each copy of the Program. </span></p>
<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
copyright notices contained within the Program. </span></p>
<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
originator of its Contribution, if any, in a manner that reasonably allows
subsequent Recipients to identify the originator of the Contribution. </span></p>
<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
<p><span style='font-size:10.0pt'>Commercial distributors of software may
accept certain responsibilities with respect to end users, business partners
and the like. While this license is intended to facilitate the commercial use
of the Program, the Contributor who includes the Program in a commercial
product offering should do so in a manner which does not create potential
liability for other Contributors. Therefore, if a Contributor includes the
Program in a commercial product offering, such Contributor (&quot;Commercial
Contributor&quot;) hereby agrees to defend and indemnify every other
Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
legal actions brought by a third party against the Indemnified Contributor to
the extent caused by the acts or omissions of such Commercial Contributor in
connection with its distribution of the Program in a commercial product
offering. The obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement. In order
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
Contributor in writing of such claim, and b) allow the Commercial Contributor
to control, and cooperate with the Commercial Contributor in, the defense and
any related settlement negotiations. The Indemnified Contributor may participate
in any such claim at its own expense.</span> </p>
<p><span style='font-size:10.0pt'>For example, a Contributor might include the
Program in a commercial product offering, Product X. That Contributor is then a
Commercial Contributor. If that Commercial Contributor then makes performance
claims, or offers warranties related to Product X, those performance claims and
warranties are such Commercial Contributor's responsibility alone. Under this
section, the Commercial Contributor would have to defend claims against the
other Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.</span> </p>
<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
responsible for determining the appropriateness of using and distributing the
Program and assumes all risks associated with its exercise of rights under this
Agreement , including but not limited to the risks and costs of program errors,
compliance with applicable laws, damage to or loss of data, programs or
equipment, and unavailability or interruption of operations. </span></p>
<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
or unenforceable under applicable law, it shall not affect the validity or
enforceability of the remainder of the terms of this Agreement, and without
further action by the parties hereto, such provision shall be reformed to the
minimum extent necessary to make such provision valid and enforceable.</span> </p>
<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
against any entity (including a cross-claim or counterclaim in a lawsuit)
alleging that the Program itself (excluding combinations of the Program with
other software or hardware) infringes such Recipient's patent(s), then such
Recipient's rights granted under Section 2(b) shall terminate as of the date
such litigation is filed. </span></p>
<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
shall terminate if it fails to comply with any of the material terms or
conditions of this Agreement and does not cure such failure in a reasonable
period of time after becoming aware of such noncompliance. If all Recipient's
rights under this Agreement terminate, Recipient agrees to cease use and
distribution of the Program as soon as reasonably practicable. However,
Recipient's obligations under this Agreement and any licenses granted by
Recipient relating to the Program shall continue and survive. </span></p>
<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
copies of this Agreement, but in order to avoid inconsistency the Agreement is
copyrighted and may only be modified in the following manner. The Agreement
Steward reserves the right to publish new versions (including revisions) of
this Agreement from time to time. No one other than the Agreement Steward has
the right to modify this Agreement. The Eclipse Foundation is the initial
Agreement Steward. The Eclipse Foundation may assign the responsibility to
serve as the Agreement Steward to a suitable separate entity. Each new version
of the Agreement will be given a distinguishing version number. The Program
(including Contributions) may always be distributed subject to the version of
the Agreement under which it was received. In addition, after a new version of
the Agreement is published, Contributor may elect to distribute the Program
(including its Contributions) under the new version. Except as expressly stated
in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
the intellectual property of any Contributor under this Agreement, whether
expressly, by implication, estoppel or otherwise. All rights in the Program not
expressly granted under this Agreement are reserved.</span> </p>
<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
State of New York and the intellectual property laws of the United States of
America. No party to this Agreement will bring a legal action under this
Agreement more than one year after the cause of action arose. Each party waives
its rights to a jury trial in any resulting litigation.</span> </p>
<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
</div>
</body>
</html>

View file

@ -0,0 +1,24 @@
#################################################################################
# Copyright (c) 2015 IBM Corporation.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#################################################################################
# "featureName" property - name of the feature
featureName=Tlnet Remote Services
# "providerName" property - name of the company that provides the feature
providerName=Eclipse PTP
# "description" property - description of the feature
description=Provides telnet services for the remote framework
# copyright
copyright=\
Copyright (c) 2015 IBM Corporation.\n\
All rights reserved. This program and the accompanying materials\n\
are made available under the terms of the Eclipse Public License v1.0\n\
which accompanies this distribution, and is available at\n\
http://www.eclipse.org/legal/epl-v10.html\n

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="org.eclipse.remote.telnet"
label="%featureName"
version="2.0.1.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
<description>
%description
</description>
<copyright>
%copyright
</copyright>
<license url="%licenseURL">
%license
</license>
<plugin
id="org.eclipse.remote.telnet.core"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="org.eclipse.remote.telnet.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<groupId>org.eclipse.remote.features</groupId>
<artifactId>org.eclipse.remote.telnet</artifactId>
<version>2.0.1-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-source-feature-plugin</artifactId>
<executions>
<execution>
<id>source-feature</id>
<phase>package</phase>
<goals>
<goal>source-feature</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>attached-p2-metadata</id>
<phase>package</phase>
<goals>
<goal>p2-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1 @@
/bin/

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.telnet.core</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7

View file

@ -0,0 +1,14 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.remote.telnet.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.remote.telnet.internal.core.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.remote.core;bundle-version="2.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.remote.telnet.core,
org.eclipse.remote.telnet.internal.core;x-internal:=true
Bundle-Localization: plugin

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>May 2, 2006</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org.</p>
</body>
</html>

View file

@ -0,0 +1,27 @@
# about.ini
# contains information about a feature
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# "%key" are externalized strings defined in about.properties
# This file does not need to be translated.
# Property "aboutText" contains blurb for "About" dialog (translated)
aboutText=%blurb
# Property "windowImage" contains path to window icon (16x16)
# needed for primary features only
# Property "featureImage" contains path to feature image (32x32)
featureImage=ptp_logo_icon32.png
# Property "aboutImage" contains path to product image (500x330 or 115x164)
# needed for primary features only
# Property "appName" contains name of the application (not translated)
# needed for primary features only
# Property "welcomePage" contains path to welcome page (special XML-based format)
# optional
# Property "welcomePerspective" contains the id of the perspective in which the
# welcome page is to be opened.
# optional

View file

@ -0,0 +1,6 @@
# about.mappings
# contains fill-ins for about.properties
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# This file does not need to be translated.
0=@build@

View file

@ -0,0 +1,22 @@
###############################################################################
# Copyright (c) 2015 QNX Software Systems and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# QNX Software Systems - initial API and implementation
###############################################################################
# NLS_MESSAGEFORMAT_NONE
# NLS_ENCODING=UTF-8
blurb=Telnet Remote Services\n\
\n\
Version: {featureVersion}\n\
Build id: {0}\n\
\n\
Copyright (c) 2015 IBM Corporation, and others. All rights reserved.\n\
Visit http://www.eclipse.org/ptp\n

View file

@ -0,0 +1,11 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
about.html,\
about.ini,\
about.mappings,\
about.properties,\
ptp_logo_icon32.png,\
plugin.properties

View file

@ -0,0 +1,2 @@
bundleName = Remote Serial Port Services
providerName = Eclipse PTP

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.remote.core.remoteServices">
<connectionType
id="org.eclipse.remote.telnet.core.connectionType"
name="Telnet">
</connectionType>
<connectionService
connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
service="org.eclipse.remote.core.IRemoteConnectionControlService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
service="org.eclipse.remote.core.IRemoteConnectionHostService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
service="org.eclipse.remote.core.IRemoteCommandShellService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
factory="org.eclipse.remote.telnet.core.TelnetConnection$Factory"
service="org.eclipse.remote.telnet.core.TelnetConnection">
</connectionService>
</extension>
</plugin>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.remote.telnet.core</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fran Litterio (Wind River) - initial API and implementation
* Helmut Haigermoser (Wind River) - repackaged
* Ted Williams (Wind River) - repackaged into org.eclipse namespace
* Michael Scharf (Wind River) - split into core, view and connector plugins
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Greg Watson (IBM) - Adapted for org.eclipse.remote
*******************************************************************************/
package org.eclipse.remote.telnet.core;
/**
* This interface defines symbolic constants for numeric TELNET protocol command and
* option codes. Any class that needs to use these constants must implement this
* interface. The meanings of these constants are defined in the various TELNET RFCs
* (RFC 854 to RFC 861, and others).
*/
interface TelnetCodes
{
/** Command code: Subnegotiation End. */
static final byte TELNET_SE = (byte)240;
/** Command code: No-op. */
static final byte TELNET_NOP = (byte)241;
/** Command code: Data Mark. */
static final byte TELNET_DM = (byte)242;
/** Command code: Break. */
static final byte TELNET_BREAK = (byte)243;
/** Command code: Interrupt Process. */
static final byte TELNET_IP = (byte)244;
/** Command code: Abort Output. */
static final byte TELNET_AO = (byte)245;
/** Command code: Are You There. */
static final byte TELNET_AYT = (byte)246;
/** Command code: Erase Character. */
static final byte TELNET_EC = (byte)247;
/** Command code: Erase Line. */
static final byte TELNET_EL = (byte)248;
/** Command code: Go Ahead. */
static final byte TELNET_GA = (byte)249;
/** Command code: Subnegotiation Begin. */
static final byte TELNET_SB = (byte)250;
/** Command code: Will. */
static final byte TELNET_WILL = (byte)251;
/** Command code: Won't. */
static final byte TELNET_WONT = (byte)252;
/** Command code: Do. */
static final byte TELNET_DO = (byte)253;
/** Command code: Don't. */
static final byte TELNET_DONT = (byte)254;
/** Command code: Interpret As Command. */
static final byte TELNET_IAC = (byte)255;
/** Command code: IS. */
static final byte TELNET_IS = 0;
/** Command code: SEND. */
static final byte TELNET_SEND = 1;
/** Option code: Transmit Binary option. */
static final byte TELNET_OPTION_TRANSMIT_BINARY = 0;
/** Option code: Echo option. */
static final byte TELNET_OPTION_ECHO = 1;
/** Option code: Suppress Go Ahead option. */
static final byte TELNET_OPTION_SUPPRESS_GA = 3;
/** Option code: Terminal Type */
static final byte TELNET_OPTION_TERMINAL_TYPE = 24;
/** Option code: Negotitate About Window Size (NAWS) */
static final byte TELNET_OPTION_NAWS = 31;
}

View file

@ -0,0 +1,189 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.telnet.internal.core.Logger;
import org.eclipse.remote.telnet.internal.core.messages.Messages;
public class TelnetCommandShell implements IRemoteProcess {
private final TelnetConnection telnetConnection;
private TelnetProtocol protocol;
public TelnetCommandShell(IRemoteConnection remoteConnection, TelnetConnection telnetConnection) {
this.telnetConnection = telnetConnection;
assert(remoteConnection.getService(IRemoteConnectionHostService.class) != null);
}
@Override
public void destroy() {
if (protocol != null) {
protocol.interrupt();
}
}
@Override
public int exitValue() {
return 0;
}
@Override
public InputStream getErrorStream() {
return null;
}
@Override
public InputStream getInputStream() {
if (protocol != null) {
PipedOutputStream pipedOutput = new PipedOutputStream();
protocol.setClientOutputStream(pipedOutput);
try {
return new PipedInputStream(pipedOutput);
} catch (IOException e) {
return null;
}
}
return null;
}
@Override
public OutputStream getOutputStream() {
if (protocol != null) {
return protocol.getOutputStream();
}
return null;
}
@Override
public int waitFor() throws InterruptedException {
if (protocol != null && protocol.isConnected()) {
wait();
}
return 0;
}
@Override
public boolean isCompleted() {
return protocol == null || !protocol.isAlive();
}
@Override
public IRemoteConnection getRemoteConnection() {
return telnetConnection.getRemoteConnection();
}
@Override
public <T extends Service> T getService(Class<T> service) {
return null;
}
@Override
public <T extends Service> boolean hasService(Class<T> service) {
return false;
}
@Override
public IRemoteProcessBuilder getProcessBuilder() {
return null;
}
public void connect() throws RemoteConnectionException {
IRemoteConnectionHostService hostSvc = telnetConnection.getRemoteConnection()
.getService(IRemoteConnectionHostService.class);
// Retry the connect after a little pause in case the
// remote telnet server isn't ready. ConnectExceptions might
// happen if the telnet server process did not initialized itself.
// This is seen especially if the telnet server is a process
// providing it's input and output via a built in telnet server.
int remaining = 10;
while (remaining >= 0) {
// Pause before we re-try if the remaining tries are less than the initial value
if (remaining < 10) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
/* ignored on purpose */ }
}
try {
int nTimeout = hostSvc.getTimeout() * 1000;
String strHost = hostSvc.getHostname();
int nPort = hostSvc.getPort();
InetSocketAddress address = new InetSocketAddress(strHost, nPort);
Socket socket = new Socket();
socket.connect(address, nTimeout);
// If we get to this point, the connect succeeded and we will
// force the remaining counter to be 0.
remaining = 0;
// This next call causes reads on the socket to see TCP urgent data
// inline with the rest of the non-urgent data. Without this call, TCP
// urgent data is silently dropped by Java. This is required for
// TELNET support, because when the TELNET server sends "IAC DM", the
// IAC byte is TCP urgent data. If urgent data is silently dropped, we
// only see the DM, which looks like an ISO Latin-1 '�' character.
socket.setOOBInline(true);
socket.setKeepAlive(true);
protocol = new TelnetProtocol(socket, this);
protocol.start();
} catch (UnknownHostException ex) {
// No re-try in case of UnknownHostException, there is no indication that
// the DNS will fix itself
throw new RemoteConnectionException(Messages.TelnetCommandShell_0 + ex.getMessage());
} catch (SocketTimeoutException socketTimeoutException) {
// Time out occurred. No re-try in this case either. Time out can
// be increased by the user. Multiplying the timeout with the remaining
// counter is not desired.
throw new RemoteConnectionException(socketTimeoutException.getMessage());
} catch (ConnectException connectException) {
// In case of a ConnectException, do a re-try. The server could have been
// simply not ready yet and the worker would give up to early. If the terminal
// control is already closed (disconnected), don't print "Connection refused" errors
if (remaining == 0) {
throw new RemoteConnectionException(connectException.getMessage());
}
} catch (Exception exception) {
// Any other exception on connect. No re-try in this case either
// Log the exception
Logger.logException(exception);
// And signal failed
throw new RemoteConnectionException(exception.getMessage());
} finally {
remaining--;
}
}
}
protected void terminated() {
telnetConnection.terminated(this);
}
}

View file

@ -0,0 +1,209 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.core;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.remote.core.IRemoteCommandShellService;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnection.Service;
import org.eclipse.remote.core.IRemoteConnectionChangeListener;
import org.eclipse.remote.core.IRemoteConnectionControlService;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.RemoteConnectionChangeEvent;
import org.eclipse.remote.core.exception.RemoteConnectionException;
public class TelnetConnection implements IRemoteConnectionControlService, IRemoteCommandShellService, IRemoteConnectionHostService,
IRemoteConnectionChangeListener {
public static int DEFAULT_PORT = 23;
public static int DEFAULT_TIMEOUT = 0; // Infinite
public static final String HOSTNAME_ATTR = "telnet.hostname.attr"; //$NON-NLS-1$
public static final String USERNAME_ATTR = "telnet.username.attr"; //$NON-NLS-1$
public static final String PASSWORD_ATTR = "telnet.password.attr"; //$NON-NLS-1$
public static final String PORT_ATTR = "telnet.port.attr"; //$NON-NLS-1$
public static final String TIMEOUT_ATTR = "telnet.timeout.attr"; //$NON-NLS-1$
private final IRemoteConnection remoteConnection;
private final List<TelnetCommandShell> shells = Collections.synchronizedList(new ArrayList<TelnetCommandShell>());
private boolean isOpen;
private TelnetConnection(IRemoteConnection remoteConnection) {
this.remoteConnection = remoteConnection;
remoteConnection.addConnectionChangeListener(this);
}
public static class Factory implements IRemoteConnection.Service.Factory {
@SuppressWarnings("unchecked")
@Override
public <T extends Service> T getService(IRemoteConnection remoteConnection, Class<T> service) {
if (TelnetConnection.class.equals(service)) {
return (T) new TelnetConnection(remoteConnection);
} else if (IRemoteConnectionControlService.class.equals(service) || IRemoteConnectionHostService.class.equals(service)
|| IRemoteCommandShellService.class.equals(service)) {
return (T) remoteConnection.getService(TelnetConnection.class);
}
return null;
}
}
@Override
public IRemoteConnection getRemoteConnection() {
return remoteConnection;
}
@Override
public IRemoteProcess getCommandShell(int flags) throws IOException {
if (isOpen) {
TelnetCommandShell shell = new TelnetCommandShell(remoteConnection, this);
try {
shell.connect();
} catch (RemoteConnectionException e) {
throw new IOException(e.getMessage());
}
shells.add(shell);
return shell;
}
return null;
}
@Override
public int getPort() {
try {
return Integer.parseInt(remoteConnection.getAttribute(PORT_ATTR));
} catch (NumberFormatException e) {
return -1;
}
}
@Override
public int getTimeout() {
try {
return Integer.parseInt(remoteConnection.getAttribute(TIMEOUT_ATTR));
} catch (NumberFormatException e) {
return -1;
}
}
@Override
public void close() {
synchronized (shells) {
for (TelnetCommandShell shell : shells) {
shell.destroy();
}
}
isOpen = false;
}
@Override
public String getHostname() {
return remoteConnection.getAttribute(HOSTNAME_ATTR);
}
@Override
public boolean useLoginShell() {
return true;
}
@Override
public String getUsername() {
return remoteConnection.getAttribute(USERNAME_ATTR);
}
@Override
public void setHostname(String hostname) {
if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
wc.setAttribute(HOSTNAME_ATTR, hostname);
}
}
@Override
public void setPassphrase(String passphrase) {
// Ignore
}
@Override
public void setPassword(String password) {
if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
wc.setSecureAttribute(PASSWORD_ATTR, password);
}
}
@Override
public void setPort(int port) {
if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
wc.setAttribute(PORT_ATTR, Integer.toString(port));
}
}
@Override
public void setTimeout(int timeout) {
if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
wc.setAttribute(TIMEOUT_ATTR, Integer.toString(timeout));
}
}
@Override
public void setUseLoginShell(boolean useLogingShell) {
// Ignore
}
@Override
public void setUsePassword(boolean usePassword) {
// Ignore
}
@Override
public void setUsername(String username) {
if (remoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) remoteConnection;
wc.setAttribute(USERNAME_ATTR, username);
}
}
@Override
public void open(IProgressMonitor monitor) throws RemoteConnectionException {
isOpen = true;
}
@Override
public boolean isOpen() {
return isOpen;
}
@Override
public void connectionChanged(RemoteConnectionChangeEvent event) {
switch (event.getType()) {
case RemoteConnectionChangeEvent.CONNECTION_OPENED:
isOpen = true;
break;
case RemoteConnectionChangeEvent.CONNECTION_ABORTED:
case RemoteConnectionChangeEvent.CONNECTION_CLOSED:
isOpen = false;
break;
}
}
protected void terminated(TelnetCommandShell shell) {
shells.remove(shell);
}
}

View file

@ -0,0 +1,724 @@
/*******************************************************************************
* Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following Wind River employees contributed to the Terminal component
* that contains this file: Chris Thew, Fran Litterio, Stephen Lamb,
* Helmut Haigermoser and Ted Williams.
*
* Contributors:
* Michael Scharf (Wind River) - split into core, view and connector plugins
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Martin Oberhuber (Wind River) - [267181] Fix telnet option negotiation loop
* Anton Leherbauer (Wind River) - [453393] Add support for copying wrapped lines without line break
* Greg Watson (IBM) - Adapted for org.eclipse.remote
*******************************************************************************/
package org.eclipse.remote.telnet.core;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import org.eclipse.remote.telnet.internal.core.Logger;
/**
* This class represents a single TELNET protocol option at one endpoint of a TELNET
* connection. This class encapsulates the endpoint associated with the option (local
* or remote), the current state of the option (enabled or disabled), the desired state
* of the option, the current state of the negotiation, an OutputStream that allows
* communication with the remote endpoint, and the number of negotiations that have
* started within this connection.
* <p>
*
* In addition to encapsulating the above state, this class performs option negotiation
* to attempt to achieve the desired option state. For some options, this class also
* performs option sub-negotiation.
* <p>
*
* IMPORTANT: Understanding this code requires understanding the TELNET protocol and
* TELNET option processing.
* <p>
*
* @author Fran Litterio (francis.litterio@windriver.com)
*/
class TelnetOption implements TelnetCodes {
/**
* This array of Strings maps an integer TELNET option code value to the symbolic
* name of the option. Array elements of the form "?" represent unassigned option
* values.
*/
protected static final String[] optionNames = { "BINARY", // 0 //$NON-NLS-1$
"ECHO", // 1 //$NON-NLS-1$
"RECONNECTION", // 2 //$NON-NLS-1$
"SUPPRESS GO AHEAD", // 3 //$NON-NLS-1$
"MSG SIZE NEGOTIATION", // 4 //$NON-NLS-1$
"STATUS", // 5 //$NON-NLS-1$
"TIMING MARK", // 6 //$NON-NLS-1$
"REMOTE CTRL TRANS+ECHO", // 7 //$NON-NLS-1$
"OUTPUT LINE WIDTH", // 8 //$NON-NLS-1$
"OUTPUT PAGE SIZE", // 9 //$NON-NLS-1$
"OUTPUT CR DISPOSITION", // 10 //$NON-NLS-1$
"OUTPUT HORIZ TABSTOPS", // 11 //$NON-NLS-1$
"OUTPUT HORIZ TAB DISPOSITION", // 12 //$NON-NLS-1$
"OUTPUT FORMFEED DISPOSITION", // 13 //$NON-NLS-1$
"OUTPUT VERTICAL TABSTOPS", // 14 //$NON-NLS-1$
"OUTPUT VT DISPOSITION", // 15 //$NON-NLS-1$
"OUTPUT LF DISPOSITION", // 16 //$NON-NLS-1$
"EXTENDED ASCII", // 17 //$NON-NLS-1$
"LOGOUT", // 18 //$NON-NLS-1$
"BYTE MACRO", // 19 //$NON-NLS-1$
"DATA ENTRY TERMINAL", // 20 //$NON-NLS-1$
"SUPDUP", // 21 //$NON-NLS-1$
"SUPDUP OUTPUT", // 22 //$NON-NLS-1$
"SEND LOCATION", // 23 //$NON-NLS-1$
"TERMINAL TYPE", // 24 //$NON-NLS-1$
"END OF RECORD", // 25 //$NON-NLS-1$
"TACACS USER IDENTIFICATION", // 26 //$NON-NLS-1$
"OUTPUT MARKING", // 27 //$NON-NLS-1$
"TERMINAL LOCATION NUMBER", // 28 //$NON-NLS-1$
"3270 REGIME", // 29 //$NON-NLS-1$
"X.3 PAD", // 30 //$NON-NLS-1$
"NEGOTIATE ABOUT WINDOW SIZE", // 31 //$NON-NLS-1$
"TERMINAL SPEED", // 32 //$NON-NLS-1$
"REMOTE FLOW CONTROL", // 33 //$NON-NLS-1$
"LINEMODE", // 34 //$NON-NLS-1$
"X DISPLAY LOCATION", // 35 //$NON-NLS-1$
"ENVIRONMENT OPTION", // 36 //$NON-NLS-1$
"AUTHENTICATION OPTION", // 37 //$NON-NLS-1$
"ENCRYPTION OPTION", // 38 //$NON-NLS-1$
"NEW ENVIRONMENT OPTION", // 39 //$NON-NLS-1$
"TN3270E", // 40 //$NON-NLS-1$
"XAUTH", // 41 //$NON-NLS-1$
"CHARSET", // 42 //$NON-NLS-1$
"REMOTE SERIAL PORT", // 43 //$NON-NLS-1$
"COM PORT CONTROL OPTION", // 44 //$NON-NLS-1$
"SUPPRESS LOCAL ECHO", // 45 //$NON-NLS-1$
"START TLS", // 46 //$NON-NLS-1$
"KERMIT", // 47 //$NON-NLS-1$
"SEND URL", // 48 //$NON-NLS-1$
"FORWARD X", // 49 //$NON-NLS-1$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 50 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
// ...
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", // ... //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
// 137
"TELOPT PRAGMA LOGON", // 138 //$NON-NLS-1$
"TELOPT SSPI LOGON", // 139 //$NON-NLS-1$
"TELOPT PRAGMA HEARTBEAT", // 140 //$NON-NLS-1$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", // 141 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
// ...
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
"?", "?", "?", "?", // ... 254 //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"EXTENDED OPTIONS LIST" // 255 //$NON-NLS-1$
};
/**
* Negotiation state: Negotiation not yet started for this option.
* <p>
*
* This constant and the others having similar names represent the states of a
* finite state automaton (FSA) that tracks the negotiation state of this option.
* The initial state is NEGOTIATION_NOT_STARTED. The state machine is as follows
* (with transitions labeled with letters in parentheses):
* <p>
*
* <pre>
* NEGOTIATION_NOT_STARTED -----> {@link #NEGOTIATION_IN_PROGRESS}
* | (A) | ^
* (C)| (B)| |(D)
* | V |
* +--------> {@link #NEGOTIATION_DONE}
* </pre>
* <p>
*
* Once the FSA leaves state NEGOTIATION_NOT_STARTED, it never returns to that
* state. Transition A happens when the local endpoint sends an option command
* before receiving a command for the same option from the remote endpoint.
* <p>
*
* Transition B happens when the local endpoint receives a reply to an option
* command sent earlier by the local endpoint. Receipt of that reply terminates
* the negotiation.
* <p>
*
* Transition D happens after negotiation is done and "something changes" (see the
* RFCs for the definition of "something changes"). Either endpoint can
* re-negotiate an option after a previous negotiation, but only if some external
* influence (such as the user or the OS) causes it to do so. Re-negotiation must
* start more than {@link #NEGOTIATION_IGNORE_DURATION} milliseconds after the FSA
* enters state NEGOTIATION_DONE or it will be ignored. This is how this client
* prevents negotiation loops.
* <p>
*
* Transition C happens when the local endpoint receives an option command from the
* remote endpoint before sending a command for the same option. In that case, the
* local endpoint replies immediately with an option command and the negotiation
* terminates.
* <p>
*
* Some TELNET servers (e.g., the Solaris server), after sending WILL and receiving
* DONT, will reply with a superfluous WONT. Any such superfluous option command
* received from the remote endpoint while the option's FSA is in state
* {@link #NEGOTIATION_DONE} will be ignored by the local endpoint.
*/
protected static final int NEGOTIATION_NOT_STARTED = 0;
/** Negotiation state: Negotiation is in progress for this option. */
protected static final int NEGOTIATION_IN_PROGRESS = 1;
/** Negotiation state: Negotiation has terminated for this option. */
protected static final int NEGOTIATION_DONE = 2;
/**
* The number of milliseconds following the end of negotiation of this option
* before which the remote endpoint can re-negotiate the option. Any option
* command received from the remote endpoint before this time passes is ignored.
* This is used to prevent option negotiation loops.
*
* @see #ignoreNegotiation()
* @see #negotiationCompletionTime
*/
protected static final int NEGOTIATION_IGNORE_DURATION = 30000;
/**
* This field holds the current negotiation state for this option.
*/
protected int negotiationState = NEGOTIATION_NOT_STARTED;
/**
* This field holds the time when negotiation of this option most recently
* terminated (i.e., entered state {@link #NEGOTIATION_DONE}). This is used to
* determine whether an option command received from the remote endpoint after
* negotiation has terminated for this option is to be ignored or interpreted as
* the start of a new negotiation.
*
* @see #NEGOTIATION_IGNORE_DURATION
*/
protected Date negotiationCompletionTime = new Date(0);
/**
* Holds the total number of negotiations that have completed for this option.
*/
protected int negotiationCount = 0;
/**
* Holds the integer code representing the option.
*/
protected byte option = 0;
/**
* Holds the OutputStream object that allows data to be sent to the remote endpoint
* of the TELNET connection.
*/
protected OutputStream outputStream;
/**
* True if this option is for the local endpoint, false for the remote endpoint.
*/
protected boolean local = true;
/**
* This field is true if the option is enabled, false if it is disabled. All
* options are initially disabled until they are negotiated to be enabled.
* <p>
*/
protected boolean enabled = false;
/**
* This field is true if the client desires the option to be enabled, false if the
* client desires the option to be disabled. This field does not represent the
* remote's endpoints desire (as expressed via WILL and WONT commands) -- it
* represnet the local endpoint's desire.
* <p>
*
* @see #setDesired(boolean)
*/
protected boolean desired = false;
/**
* Constructor.
* <p>
*
* @param option
* The integer code of this option.
* @param desired
* Whether we desire this option to be enabled.
* @param local
* Whether this option is for the local or remote endpoint.
* @param serverOutputStream
* A stream used to negotiate with the remote endpoint.
*/
TelnetOption(byte option, boolean desired, boolean local, OutputStream outputStream) {
this.option = option;
this.desired = desired;
this.local = local;
this.outputStream = outputStream;
}
/**
* @return Returns a String containing the name of the TELNET option specified in
* parameter <i>option</i>.
*/
public String optionName() {
return optionNames[option & 0xFF];
}
/**
* Returns true if this option is enabled, false if it is disabled.
* <p>
*
* @return Returns true if this option is enabled, false if it is disabled.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Enables this option if <i>newValue</i> is true, otherwise disables this
* option.
* <p>
*
* @param newValue
* True if this option is to be enabled, false otherwise.
*/
public void setEnabled(boolean newValue) {
Logger.log("Enabling " + (local ? "local" : "remote") + " option " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
optionName());
enabled = newValue;
}
/**
* Returns true if the local endpoint desires this option to be enabled, false if
* not. It is not an error for the value returned by this method to differ from
* the value returned by isEnabled(). The value returned by this method can change
* over time, reflecting the local endpoint's changing desire regarding the
* option.
* <p>
*
* NOTE: Even if this option represents a remote endpoint option, the return value
* of this method represents the local endpint's desire regarding the remote
* option.
* <p>
*
* @return Returns true if the local endpoint desires this option to be enabled,
* false if not.
*/
public boolean isDesired() {
return desired;
}
/**
* Sets our desired value for this option. Note that the option can be desired
* when <i>enabled</i> is false, and the option can be undesired when
* <i>enabled</i> is true, though the latter state should not persist, since either
* endpoint can disable any option at any time.
* <p>
*
* @param newValue
* True if we desire this option to be enabled, false if
* we desire this option to be disabled.
*/
public void setDesired(boolean newValue) {
if (newValue) {
Logger.log("Setting " + (local ? "local" : "remote") + " option " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
optionName() + " as desired."); //$NON-NLS-1$
}
desired = newValue;
}
/**
* Call this method to request that negotiation begin for this option. This method
* does nothing if negotiation for this option has already started or is already
* complete. If negotiation has not yet started for this option and the local
* endpoint desires this option to be enabled, then we send a WILL or DO command to
* the remote endpoint.
*/
public void negotiate() {
if (negotiationState == NEGOTIATION_NOT_STARTED && desired) {
if (local) {
Logger.log("Starting negotiation for local option " + optionName()); //$NON-NLS-1$
sendWill();
} else {
Logger.log("Starting negotiation for remote option " + optionName()); //$NON-NLS-1$
sendDo();
}
negotiationState = NEGOTIATION_IN_PROGRESS;
}
}
/**
* This method is called whenever we receive a WILL command from the remote
* endpoint.
*/
public void handleWill() {
if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
Logger.log("Ignoring superfluous WILL command from remote endpoint."); //$NON-NLS-1$
return;
}
if (negotiationState == NEGOTIATION_IN_PROGRESS) {
if (desired) {
// We sent DO and server replied with WILL. Enable the option, and end
// this negotiation.
enabled = true;
Logger.log("Enabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// This should never happen! We sent DONT and the server replied with
// WILL. Bad server. No soup for you. Disable the option, and end
// this negotiation.
Logger.log("Server answered DONT with WILL!"); //$NON-NLS-1$
enabled = false;
Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
} else {
if (desired) {
// Server sent WILL, so we reply with DO. Enable the option, and end
// this negotiation.
sendDo();
enabled = true;
Logger.log("Enabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// Server sent WILL, so we reply with DONT. Disable the option, and
// end this negotiation.
sendDont();
enabled = false;
Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
}
}
/**
* Handles a WONT command sent by the remote endpoint for this option. The value
* of <i>desired</i> doesn't matter in this method, because the remote endpoint is
* forcing the option to be disabled.
*/
public void handleWont() {
if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
Logger.log("Ignoring superfluous WONT command from remote endpoint."); //$NON-NLS-1$
return;
}
if (negotiationState == NEGOTIATION_IN_PROGRESS) {
// We sent DO or DONT and server replied with WONT. Disable the
// option, and end this negotiation.
enabled = false;
Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// Server sent WONT, so we reply with DONT. Disable the option, and
// end this negotiation.
sendDont();
enabled = false;
Logger.log("Disabling remote option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
}
/**
* Handles a DO command sent by the remote endpoint for this option.
*/
public void handleDo() {
if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
Logger.log("Ignoring superfluous DO command from remote endpoint."); //$NON-NLS-1$
return;
}
if (negotiationState == NEGOTIATION_IN_PROGRESS) {
if (desired) {
// We sent WILL and server replied with DO. Enable the option, and end
// this negotiation.
enabled = true;
Logger.log("Enabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// We sent WONT and server replied with DO. This should never happen!
// Bad server. No soup for you. Disable the option, and end this
// negotiation.
Logger.log("Server answered WONT with DO!"); //$NON-NLS-1$
enabled = false;
Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
} else {
if (desired) {
// Server sent DO, so we reply with WILL. Enable the option, and end
// this negotiation.
sendWill();
enabled = true;
Logger.log("Enabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// Server sent DO, so we reply with WONT. Disable the option, and end
// this negotiation.
sendWont();
enabled = false;
Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
}
}
/**
* Handles a DONT command sent by the remote endpoint for this option. The value
* of <i>desired</i> doesn't matter in this method, because the remote endpoint is
* forcing the option to be disabled.
*/
public void handleDont() {
if (negotiationState == NEGOTIATION_DONE && ignoreNegotiation()) {
Logger.log("Ignoring superfluous DONT command from remote endpoint."); //$NON-NLS-1$
return;
}
if (negotiationState == NEGOTIATION_IN_PROGRESS) {
// We sent WILL or WONT and server replied with DONT. Disable the
// option, and end this negotiation.
enabled = false;
Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
} else {
// Server sent DONT, so we reply with WONT. Disable the option, and end
// this negotiation.
sendWont();
enabled = false;
Logger.log("Disabling local option " + optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
endNegotiation();
}
}
/**
* This method handles a subnegotiation command received from the remote endpoint.
* Currently, the only subnegotiation we handle is when the remote endpoint
* commands us to send our terminal type (which is "xterm").
*
* @param subnegotiationData
* An array of bytes containing a TELNET
* subnegotiation command received from the
* remote endpoint.
* @param count
* The number of bytes in array
* subnegotiationData to examine.
*/
public void handleSubnegotiation(byte[] subnegotiationData, int count) {
switch (option) {
case TELNET_OPTION_TERMINAL_TYPE:
if (subnegotiationData[1] != TELNET_SEND) {
// This should never happen!
Logger.log("Invalid TERMINAL-TYPE subnegotiation command from remote endpoint: " + //$NON-NLS-1$
(subnegotiationData[1] & 0xff));
break;
}
// Tell the remote endpoint our terminal type is "ansi" using this sequence
// of TELNET protocol bytes:
//
// IAC SB TERMINAL-TYPE IS x t e r m IAC SE
byte[] terminalTypeData = { TELNET_IAC, TELNET_SB, TELNET_OPTION_TERMINAL_TYPE, TELNET_IS, (byte) 'x', (byte) 't',
(byte) 'e', (byte) 'r', (byte) 'm', TELNET_IAC, TELNET_SE };
try {
outputStream.write(terminalTypeData);
} catch (IOException ex) {
Logger.log("IOException sending TERMINAL-TYPE subnegotiation!"); //$NON-NLS-1$
Logger.logException(ex);
}
break;
default:
// This should never happen!
Logger.log("SHOULD NOT BE REACHED: Called for option " + optionName()); //$NON-NLS-1$
break;
}
}
/**
* This method sends a subnegotiation command to the remote endpoint.
*
* @param subnegotiationData
* An array of Objects holding data to be used
* when generating the outbound subnegotiation
* command.
*/
public void sendSubnegotiation(Object[] subnegotiationData) {
switch (option) {
case TELNET_OPTION_NAWS:
// Get the width and height of the view and send it to the remote
// endpoint using this sequence of TELNET protocol bytes:
//
// IAC SB NAWS <width-highbyte> <width-lowbyte> <height-highbyte>
// <height-lowbyte> IAC SE
byte[] NAWSData = { TELNET_IAC, TELNET_SB, TELNET_OPTION_NAWS, 0, 0, 0, 0, TELNET_IAC, TELNET_SE };
int width = ((Integer) subnegotiationData[0]).intValue();
int height = ((Integer) subnegotiationData[1]).intValue();
NAWSData[3] = (byte) ((width >>> 8) & 0xff); // High order byte of width.
NAWSData[4] = (byte) (width & 0xff); // Low order byte of width.
NAWSData[5] = (byte) ((height >>> 8) & 0xff); // High order byte of height.
NAWSData[6] = (byte) (height & 0xff); // Low order byte of height.
Logger.log("sending terminal size to remote endpoint: width = " + width + //$NON-NLS-1$
", height = " + height + "."); //$NON-NLS-1$ //$NON-NLS-2$
// This final local variable is a hack to get around the fact that inner
// classes cannot reference a non-final local variable in a lexically
// enclosing scope.
final byte[] NAWSDataFinal = NAWSData;
// Send the NAWS data in a new thread. The current thread is the display
// thread, and calls to write() can block, but blocking the display thread
// is _bad_ (it hangs the GUI).
Thread t = new Thread() {
@Override
public void run() {
try {
outputStream.write(NAWSDataFinal);
} catch (IOException ex) {
Logger.log("IOException sending NAWS subnegotiation!"); //$NON-NLS-1$
Logger.logException(ex);
}
}
};
t.setDaemon(true);
t.start();
break;
default:
// This should never happen!
Logger.log("SHOULD NOT BE REACHED: Called for option " + optionName()); //$NON-NLS-1$
break;
}
}
/**
* This method returns true if there has not yet been any negotiation of this
* option.
*
* @return Returns true if there has not yet been any negotiation of this option.
*/
protected boolean notYetNegotiated() {
return negotiationState == NEGOTIATION_NOT_STARTED;
}
/**
* This method terminates the current negotiation and records the time at which the
* negotiation terminated.
*/
protected void endNegotiation() {
Logger.log("Ending negotiation #" + negotiationCount + " for " + //$NON-NLS-1$ //$NON-NLS-2$
(local ? "local" : "remote") + " option " + optionName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
negotiationState = NEGOTIATION_DONE;
negotiationCompletionTime.setTime(System.currentTimeMillis());
++negotiationCount;
}
/**
* This method determines whether or not to ignore what appears to be a new
* negotiation initiated by the remote endpoint. This is needed because some
* TELNET servers send superfluous option commands that a naive client might
* interpret as the start of a new negotiation. If the superfluous command is not
* ignored, an option negotiation loop can result (which is bad). For details
* about the superfluous commands sent by some servers, see the documentation for
* {@link #NEGOTIATION_NOT_STARTED}.
* <p>
*
* The current implementation of this method returns true if the new negotiation
* starts within NEGOTIATION_IGNORE_DURATION seconds of the end of the previous
* negotiation of this option.
* <p>
*
* @return Returns true if the new negotiation should be ignored, false if not.
*/
protected boolean ignoreNegotiation() {
return (System.currentTimeMillis() - negotiationCompletionTime.getTime()) < NEGOTIATION_IGNORE_DURATION;
}
/**
* Sends a DO command to the remote endpoint for this option.
*/
protected void sendDo() {
Logger.log("Sending DO " + optionName()); //$NON-NLS-1$
sendCommand(TELNET_DO);
}
/**
* Sends a DONT command to the remote endpoint for this option.
*/
protected void sendDont() {
Logger.log("Sending DONT " + optionName()); //$NON-NLS-1$
sendCommand(TELNET_DONT);
}
/**
* Sends a WILL command to the remote endpoint for this option.
*/
protected void sendWill() {
Logger.log("Sending WILL " + optionName()); //$NON-NLS-1$
sendCommand(TELNET_WILL);
}
/**
* Sends a WONT command to the remote endpoint for this option.
*/
protected void sendWont() {
Logger.log("Sending WONT " + optionName()); //$NON-NLS-1$
sendCommand(TELNET_WONT);
}
/**
* This method sends a WILL/WONT/DO/DONT command to the remote endpoint for this
* option.
*/
protected void sendCommand(byte command) {
byte[] data = { TELNET_IAC, 0, 0 };
data[1] = command;
data[2] = option;
try {
outputStream.write(data);
} catch (IOException ex) {
Logger.log("IOException sending command " + command); //$NON-NLS-1$
Logger.logException(ex);
}
}
}

View file

@ -0,0 +1,722 @@
/*******************************************************************************
* Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fran Litterio (Wind River) - initial API and implementation
* Helmut Haigermoser (Wind River) - repackaged
* Ted Williams (Wind River) - repackaged into org.eclipse namespace
* Michael Scharf (Wind River) - split into core, view and connector plugins
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Michael Scharf (Wind River) - [209665] Add ability to log byte streams from terminal
* Alex Panchenko (Xored) - [277061] TelnetProtocol.isConnected() should check if socket was not closed
* Uwe Stieber (Wind River) - [281329] Telnet connection not handling "SocketException: Connection reset" correct
* Nils Hagge (Siemens AG) - [276023] close socket streams after connection is disconnected
* Greg Watson (IBM) - Adapted for org.eclipse.remote
*******************************************************************************/
package org.eclipse.remote.telnet.core;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ReadableByteChannel;
import org.eclipse.remote.telnet.internal.core.Logger;
import org.eclipse.remote.telnet.internal.core.messages.Messages;
/**
* This class encapsulates a TELNET connection to a remote server. It processes
* incoming TELNET protocol data and generates outbound TELNET protocol data. It
* also manages two sets of TelnetOption objects: one for the local endpoint and
* one for the remote endpoint.
* <p>
*
* IMPORTANT: Understanding this code requires understanding the TELNET protocol
* and TELNET option processing, as defined in the RFCs listed below.
* <p>
*
* @author Fran Litterio (francis.litterio@windriver.com)
*
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc854.txt">RFC 854</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc855.txt">RFC 855</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc856.txt">RFC 856</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc857.txt">RFC 857</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc858.txt">RFC 858</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc859.txt">RFC 859</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc860.txt">RFC 860</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc861.txt">RFC 861</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1091.txt">RFC 1091</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1096.txt">RFC 1096</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1073.txt">RFC 1073</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1079.txt">RFC 1079</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1143.txt">RFC 1143</a>
* @see <a href="ftp://ftp.rfc-editor.org/in-notes/rfc1572.txt">RFC 1572</a>
*/
public class TelnetProtocol extends Thread implements TelnetCodes {
/**
* TELNET connection state: Initial state.
*/
protected static final int STATE_INITIAL = 0;
/**
* TELNET connection state: Last byte processed was IAC code. code.
*/
protected static final int STATE_IAC_RECEIVED = 1;
/**
* TELNET connection state: Last byte processed was WILL code. code.
*/
protected static final int STATE_WILL_RECEIVED = 2;
/**
* TELNET connection state: Last byte processed was WONT code.
*/
protected static final int STATE_WONT_RECEIVED = 3;
/**
* TELNET connection state: Last byte processed was DO code.
*/
protected static final int STATE_DO_RECEIVED = 4;
/**
* TELNET connection state: Last byte processed was DONT code.
*/
protected static final int STATE_DONT_RECEIVED = 5;
/**
* TELNET connection state: Last byte processed was SB.
*/
protected static final int STATE_SUBNEGOTIATION_STARTED = 6;
/**
* TELNET connection state: Currently receiving sub-negotiation data.
*/
protected static final int STATE_RECEIVING_SUBNEGOTIATION = 7;
/**
* Size of buffer for processing data received from remote endpoint.
*/
protected static final int BUFFER_SIZE = 2048;
/**
* Holds raw bytes received from the remote endpoint, prior to any TELNET
* protocol processing.
*/
protected ByteBuffer rawBytes = ByteBuffer.allocateDirect(BUFFER_SIZE);
/**
* Holds incoming network data after the TELNET protocol bytes have been
* processed and removed.
*/
protected byte[] processedBytes = new byte[BUFFER_SIZE];
/**
* This field holds a StringBuffer containing text recently received from
* the remote endpoint (after all TELNET protocol bytes have been processed
* and removed).
*/
protected StringBuffer processedStringBuffer = new StringBuffer(BUFFER_SIZE);
/**
* Holds the current state of the TELNET protocol processor.
*/
protected int telnetState = STATE_INITIAL;
/**
* This field is true if the remote endpoint is a TELNET server, false if
* not. We set this to true if and only if the remote endpoint sends
* recognizable TELNET protocol data. We do not assume that the remote
* endpoint is a TELNET server just because it is listening on port 23. This
* allows us to successfully connect to a TELNET server listening on a port
* other than 23.
* <p>
*
* When this field first changes from false to true, we send all WILL or DO
* commands to the remote endpoint.
* <p>
*
* @see #telnetServerDetected()
*/
protected boolean remoteIsTelnetServer = false;
/**
* An array of TelnetOption objects representing the local endpoint's TELNET
* options. The array is indexed by the numeric TELNET option code.
*/
protected TelnetOption[] localOptions = new TelnetOption[256];
/**
* An array of TelnetOption objects representing the remote endpoint's
* TELNET options. The array is indexed by the numeric TELNET option code.
*/
protected TelnetOption[] remoteOptions = new TelnetOption[256];
/**
* An array of bytes that holds the TELNET subnegotiation command most
* recently received from the remote endpoint. This array does _not_ include
* the leading IAC SB bytes, nor does it include the trailing IAC SE bytes.
* The first byte of this array is always a TELNET option code.
*/
protected byte[] receivedSubnegotiation = new byte[128];
/**
* This field holds the index into array {@link #receivedSubnegotiation} of
* the next unused byte. This is used by method
* {@link #processTelnetProtocol(int)} when the state machine is in states
* {@link #STATE_SUBNEGOTIATION_STARTED} and {@link
* #STATE_RECEIVING_SUBNEGOTIATION}.
*/
protected int nextSubnegotiationByteIndex = 0;
/**
* This field is true if an error occurs while processing a subnegotiation
* command.
*
* @see #processTelnetProtocol(int)
*/
protected boolean ignoreSubnegotiation = false;
/**
* This field holds the width of the Terminal screen in columns.
*/
protected int width = 0;
/**
* This field holds the height of the Terminal screen in rows.
*/
protected int height = 0;
/**
* This field holds a reference to the {@link TelnetCommandShell}.
*/
protected TelnetCommandShell shell;
/**
* This method holds the Socket object for the TELNET connection.
*/
protected Socket socket;
/**
* This field holds a reference to an {@link ReadableByteChannel} object used to
* receive data from the remote endpoint.
*/
protected ReadableByteChannel inputChannel;
/**
* This field holds a reference to an {@link OutputStream} object used to
* send data to the remote endpoint.
*/
protected OutputStream serverOutputStream;
/**
* This field holds a reference to an {@link OutputStream} object used to
* send data to the client.
*/
protected OutputStream clientOutputStream;
/**
* UNDER CONSTRUCTION
*/
protected boolean localEcho = true;
/**
* This constructor just initializes some internal object state from its
* arguments.
*/
public TelnetProtocol(Socket socket, TelnetCommandShell shell) throws IOException {
super();
Logger.log("entered"); //$NON-NLS-1$
this.shell = shell;
this.socket = socket;
// serverInputStream = socket.getInputStream();
serverOutputStream = socket.getOutputStream();
inputChannel = Channels.newChannel(socket.getInputStream());
initializeOptions();
}
public OutputStream getOutputStream() {
return serverOutputStream;
}
public void setClientOutputStream(OutputStream stream) {
clientOutputStream = stream;
}
/**
* Returns true if the TCP connection represented by this object is
* connected, false otherwise.
*/
public boolean isConnected() {
return socket != null && socket.isConnected() && !socket.isClosed();
}
/**
* Returns true if the TCP connection represented by this object is
* connected and the remote endpoint is a TELNET server, false otherwise.
*/
public boolean isRemoteTelnetServer() {
return remoteIsTelnetServer;
}
/**
* This method sets the terminal width and height to the supplied values. If
* either new value differs from the corresponding old value, we initiate a
* NAWS subnegotiation to inform the remote endpoint of the new terminal
* size.
*/
public void setTerminalSize(int newWidth, int newHeight) {
Logger.log("Setting new size: width = " + newWidth + ", height = " + newHeight); //$NON-NLS-1$ //$NON-NLS-2$
if (!isConnected() || !isRemoteTelnetServer()) {
return;
}
boolean sizeChanged = false;
if (newWidth != width || newHeight != height) {
sizeChanged = true;
}
width = newWidth;
height = newHeight;
if (sizeChanged && remoteIsTelnetServer && localOptions[TELNET_OPTION_NAWS].isEnabled()) {
Integer[] sizeData = { Integer.valueOf(width), Integer.valueOf(height) };
localOptions[TELNET_OPTION_NAWS].sendSubnegotiation(sizeData);
}
}
/**
* Returns true if local echoing is enabled for this TCP connection, false
* otherwise.
*/
public boolean localEcho() {
return localEcho;
}
/**
* This method runs in its own thread. It reads raw bytes from the TELNET
* connection socket, processes any TELNET protocol bytes (and removes
* them), and passes the remaining bytes to a TerminalDisplay object for
* display.
*/
@Override
public void run() {
Logger.log("Entered"); //$NON-NLS-1$
try {
while (socket.isConnected()) {
rawBytes.clear();
int nRawBytes = inputChannel.read(rawBytes);
if (nRawBytes == -1) {
// End of input on serverInputStream.
Logger.log("End of input reading from socket!"); //$NON-NLS-1$
// Announce to the user that the remote endpoint has closed the
// connection.
if (clientOutputStream != null) {
clientOutputStream.write(Messages.TelnetProtocol_0.getBytes());
}
break;
}
// Process any TELNET protocol data that we receive. Don't
// send any TELNET protocol data until we are sure the remote
// endpoint is a TELNET server.
int nProcessedBytes = processTelnetProtocol(nRawBytes);
if (nProcessedBytes > 0 && clientOutputStream != null) {
clientOutputStream.write(processedBytes, 0, nProcessedBytes);
clientOutputStream.flush();
}
}
} catch (ClosedByInterruptException e) {
// Handled by finally clause
} catch (SocketException ex) {
String message = ex.getMessage();
// A "socket closed" exception is normal here. It's caused by the
// user clicking the disconnect button on the Terminal view toolbar.
if (message != null && !message.equalsIgnoreCase("Socket closed") && !message.equalsIgnoreCase("Connection reset")) { //$NON-NLS-1$ //$NON-NLS-2$
Logger.logException(ex);
}
} catch (Exception ex) {
Logger.logException(ex);
} finally {
// Tell the command shell that we have terminated
shell.terminated();
try {
inputChannel.close();
} catch (IOException ioe) {
/* ignore */
}
try {
serverOutputStream.close();
} catch (IOException ioe) {
/* ignore */
}
try {
clientOutputStream.close();
} catch (IOException ioe) {
/* ignore */
}
}
}
/**
* This method initializes the localOptions[] and remoteOptions[] arrays so
* that they contain references to TelnetOption objects representing our
* desired state for each option. The goal is to achieve server-side
* echoing, suppression of Go Aheads, and to send the local terminal type
* and size to the remote endpoint.
*/
protected void initializeOptions() {
// First, create all the TelnetOption objects in the "undesired" state.
for (int i = 0; i < localOptions.length; ++i) {
localOptions[i] = new TelnetOption((byte) i, false, true, serverOutputStream);
}
for (int i = 0; i < localOptions.length; ++i) {
remoteOptions[i] = new TelnetOption((byte) i, false, false, serverOutputStream);
}
// Next, set some of the options to the "desired" state. The options we
// desire to be enabled are as follows:
//
// TELNET Option Desired for Desired for
// Name and Code Local Endpoint Remote Endpoint
// --------------------- -------------- ---------------
// Echo (1) No Yes
// Suppress Go Ahead (3) Yes Yes
// Terminal Type (24) Yes Yes
// NAWS (31) Yes Yes
//
// All other options remain in the "undesired" state, and thus will be
// disabled (since either endpoint can force any option to be disabled by simply
// answering WILL with DONT and DO with WONT).
localOptions[TELNET_OPTION_ECHO].setDesired(false);
remoteOptions[TELNET_OPTION_ECHO].setDesired(true);
localOptions[TELNET_OPTION_SUPPRESS_GA].setDesired(true);
remoteOptions[TELNET_OPTION_SUPPRESS_GA].setDesired(true);
localOptions[TELNET_OPTION_TERMINAL_TYPE].setDesired(true);
remoteOptions[TELNET_OPTION_TERMINAL_TYPE].setDesired(true);
localOptions[TELNET_OPTION_NAWS].setDesired(true);
remoteOptions[TELNET_OPTION_NAWS].setDesired(true);
}
/**
* Process TELNET protocol data contained in the first <i>count</i> bytes
* of <i>rawBytes</i>. This function preserves its state between calls,
* because a multi-byte TELNET command might be split between two (or more)
* calls to this function. The state is preserved in field <i>telnetState</i>.
* This function implements an FSA that recognizes TELNET option codes.
* TELNET option sub-negotiation is delegated to instances of TelnetOption.
*
* @return The number of bytes remaining in the buffer after removing all
* TELNET protocol bytes.
*/
// TELNET option state is stored in instances of TelnetOption.
protected int processTelnetProtocol(int count) {
// This is too noisy to leave on all the time.
// Logger.log("Processing " + count + " bytes of data.");
int nextProcessedByte = 0;
for (int byteIndex = 0; byteIndex < count; ++byteIndex) {
// It is possible for control to flow through the below code such
// that nothing happens. This happens when array rawBytes[] contains no
// TELNET protocol data.
byte inputByte = rawBytes.get(byteIndex);
int ubyte = inputByte & 0xFF;
switch (telnetState) {
case STATE_INITIAL:
if (inputByte == TELNET_IAC) {
telnetState = STATE_IAC_RECEIVED;
} else {
// It's not an IAC code, so just append it to
// processedBytes.
processedBytes[nextProcessedByte++] = inputByte;
}
break;
case STATE_IAC_RECEIVED:
switch (inputByte) {
case TELNET_IAC:
// Two IAC bytes in a row are translated into one byte with
// the
// value 0xff.
processedBytes[nextProcessedByte++] = (byte) 0xff;
telnetState = STATE_INITIAL;
break;
case TELNET_WILL:
telnetState = STATE_WILL_RECEIVED;
break;
case TELNET_WONT:
telnetState = STATE_WONT_RECEIVED;
break;
case TELNET_DO:
telnetState = STATE_DO_RECEIVED;
break;
case TELNET_DONT:
telnetState = STATE_DONT_RECEIVED;
break;
case TELNET_SB:
telnetState = STATE_SUBNEGOTIATION_STARTED;
break;
// Commands to consume and ignore.
// Data Mark (DM). This is sent by a TELNET server following an
// IAC sent as TCP urgent data. It should cause the client to
// skip all not yet processed non-TELNET-protocol data preceding the
// DM byte. However, Java 1.4.x has no way to inform clients of
// class Socket that urgent data is available, so we simply ignore the
// "IAC DM" command. Since the IAC is sent as TCP urgent data,
// the Socket must be put into OOB-inline mode via a call to
// setOOBInline(true), otherwise the IAC is silently dropped by
// Java and only the DM arrives (leaving the user to see a
// spurious ISO Latin-1 character).
case TELNET_DM:
case TELNET_NOP: // No-op.
case TELNET_GA: // Go Ahead command. Meaningless on a full-duplex link.
case TELNET_IP: // Interupt Process command. Server should never send this.
case TELNET_AO: // Abort Output command. Server should never send this.
case TELNET_AYT: // Are You There command. Server should never send this.
case TELNET_EC: // Erase Character command. Server should never send this.
case TELNET_EL: // Erase Line command. Server should never send this.
telnetState = STATE_INITIAL;
break;
default:
// Unrecognized command! This should never happen.
Logger.log("processTelnetProtocol: UNRECOGNIZED TELNET PROTOCOL COMMAND: " + //$NON-NLS-1$
ubyte);
telnetState = STATE_INITIAL;
break;
}
break;
// For the next four cases, WILL and WONT commands affect the state
// of remote options, and DO and DONT commands affect the state of
// local options.
case STATE_WILL_RECEIVED:
Logger.log("Received WILL " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
remoteOptions[ubyte].handleWill();
telnetState = STATE_INITIAL;
telnetServerDetected();
break;
case STATE_WONT_RECEIVED:
Logger.log("Received WONT " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
remoteOptions[ubyte].handleWont();
telnetState = STATE_INITIAL;
telnetServerDetected();
break;
case STATE_DO_RECEIVED:
Logger.log("Received DO " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
localOptions[ubyte].handleDo();
telnetState = STATE_INITIAL;
telnetServerDetected();
break;
case STATE_DONT_RECEIVED:
Logger.log("Received DONT " + localOptions[ubyte].optionName() + "."); //$NON-NLS-1$ //$NON-NLS-2$
localOptions[ubyte].handleDont();
telnetState = STATE_INITIAL;
telnetServerDetected();
break;
case STATE_SUBNEGOTIATION_STARTED:
Logger.log("Starting subnegotiation for option " + //$NON-NLS-1$
localOptions[ubyte].optionName() + "."); //$NON-NLS-1$
// First, zero out the array of received subnegotiation butes.
for (int i = 0; i < receivedSubnegotiation.length; ++i) {
receivedSubnegotiation[i] = 0;
}
// Forget about any previous subnegotiation errors.
ignoreSubnegotiation = false;
// Then insert this input byte into the array and enter state
// STATE_RECEIVING_SUBNEGOTIATION, where we will gather the
// remaining subnegotiation bytes.
nextSubnegotiationByteIndex = 0;
receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
telnetState = STATE_RECEIVING_SUBNEGOTIATION;
break;
case STATE_RECEIVING_SUBNEGOTIATION:
if (inputByte == TELNET_IAC) {
// Handle double IAC bytes. From RFC 855: "if parameters
// in an option 'subnegotiation' include a byte with a value
// of 255, it is necessary to double this byte in accordance
// the general TELNET rules."
if (nextSubnegotiationByteIndex > 0 && receivedSubnegotiation[nextSubnegotiationByteIndex - 1] == TELNET_IAC) {
// The last input byte we received in this
// subnegotiation was IAC, so this is a double IAC. Leave the previous IAC
// in the receivedSubnegotiation[] array and drop the current
// one (thus translating a double IAC into a single IAC).
Logger.log("Double IAC in subnegotiation translated into single IAC."); //$NON-NLS-1$
break;
}
// Append the IAC byte to receivedSubnegotiation[]. If there
// is no room for the IAC byte, it overwrites the last byte,
// because we need to know when the subnegotiation ends, and that is
// marked by an "IAC SE" command.
if (nextSubnegotiationByteIndex < receivedSubnegotiation.length) {
receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
} else {
receivedSubnegotiation[receivedSubnegotiation.length - 1] = inputByte;
}
break;
}
// Handle an "IAC SE" command, which marks the end of the
// subnegotiation. An SE byte by itself might be a legitimate
// part of the subnegotiation data, so don't do anything unless the SE
// is immediately preceded by an IAC.
if (inputByte == TELNET_SE && receivedSubnegotiation[nextSubnegotiationByteIndex - 1] == TELNET_IAC) {
Logger.log("Found SE code marking end of subnegotiation."); //$NON-NLS-1$
// We are done receiving the subnegotiation command. Now
// process it. We always use the option object stored in array
// localOptions[] to process the received subnegotiation.
// This is an arbitrary decision, but it is sufficient for handling
// options TERMINAL-TYPE and NAWS, which are the only options that
// we subnegotiate (presently). If, in the future,subnegotiations
// need to be handled by option objects stored in both
// localOptions[] and remoteOptions[], then some mechanism
// to choose the correct option object must be implemented.
//
// Also, if ignoreSubnegotiation is true, there was an error
// while receiving the subnegotiation, so we must not process the
// command, and instead just return to the initial state.
if (!ignoreSubnegotiation) {
// Remove the trailing IAC byte from
// receivedSubnegotiation[].
receivedSubnegotiation[nextSubnegotiationByteIndex - 1] = 0;
int subnegotiatedOption = receivedSubnegotiation[0] & 0xFF;
localOptions[subnegotiatedOption].handleSubnegotiation(receivedSubnegotiation, nextSubnegotiationByteIndex);
} else {
Logger.log("NOT CALLING handleSubnegotiation() BECAUSE OF ERRORS!"); //$NON-NLS-1$
}
// Return to the initial state.
telnetState = STATE_INITIAL;
}
// Check whether the receivedSubnegotiation[] array is full.
if (nextSubnegotiationByteIndex >= receivedSubnegotiation.length) {
// This should not happen. Array receivedSubnegotiation can
// hold 128 bytes, and no TELNET option that we perform
// subnegotiation for requires that many bytes in a subnegotiation command.
// In the interest of robustness, we handle this case by ignoring all
// remaining subnegotiation bytes until we receive the IAC SE
// command that ends the subnegotiation. Also, we set
// ignoreSubnegotiation to true to prevent a call to
// handleSubnegotiation() when the IAC SE command arrives.
Logger.log("SUBNEGOTIATION BUFFER FULL!"); //$NON-NLS-1$
ignoreSubnegotiation = true;
} else {
Logger.log("Recording subnegotiation byte " + ubyte); //$NON-NLS-1$
receivedSubnegotiation[nextSubnegotiationByteIndex++] = inputByte;
}
break;
default:
// This should _never_ happen! If it does, it means there is a
// bug in this FSA. For robustness, we return to the initial state.
Logger.log("INVALID TELNET STATE: " + telnetState); //$NON-NLS-1$
telnetState = STATE_INITIAL;
break;
}
}
// Return the number of bytes of processed data (i.e., number of bytes
// of raw data minus TELNET control bytes). This value can be zero.
return nextProcessedByte;
}
/**
* This method is called whenever we receive a valid TELNET protocol command
* from the remote endpoint. When it is called for the first time for this
* connection, we negotiate all options that we desire to be enabled.
* <p>
*
* This method does not negotiate options that we do not desire to be
* enabled, because all options are initially disabled.
* <p>
*/
protected void telnetServerDetected() {
if (!remoteIsTelnetServer) {
// This block only executes once per TelnetProtocol instance.
localEcho = false;
Logger.log("Detected TELNET server."); //$NON-NLS-1$
remoteIsTelnetServer = true;
for (TelnetOption localOption : localOptions) {
if (localOption.isDesired()) {
localOption.negotiate();
}
}
for (TelnetOption remoteOption : remoteOptions) {
if (remoteOption.isDesired()) {
remoteOption.negotiate();
}
}
}
}
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.core;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
public class Activator extends Plugin {
public static final String PLUGIN_ID = "org.eclipse.remote.telnet.core"; //$NON-NLS-1$
private static Plugin plugin;
@Override
public void start(BundleContext bundleContext) throws Exception {
plugin = this;
Logger.configure(bundleContext);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
plugin = null;
}
public static Plugin getDefault() {
return plugin;
}
public static void log(IStatus status) {
plugin.getLog().log(status);
}
public static void log(Throwable e) {
if (e instanceof CoreException) {
log(((CoreException) e).getStatus());
} else {
log(new Status(IStatus.ERROR, plugin.getBundle().getSymbolicName(), IStatus.ERROR, e.getLocalizedMessage(), e));
}
}
}

View file

@ -0,0 +1,237 @@
/*******************************************************************************
* Copyright (c) 2005, 2015 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fran Litterio (Wind River) - initial API and implementation
* Ted Williams (Wind River) - refactored into org.eclipse namespace
* Michael Scharf (Wind River) - split into core, view and connector plugins
* Martin Oberhuber (Wind River) - fixed copyright headers and beautified
* Greg Watson (IBM) - Adapted for org.eclipse.remote
*******************************************************************************/
package org.eclipse.remote.telnet.internal.core;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Hashtable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.osgi.framework.BundleContext;
/**
* A simple logger class. Every method in this class is static, so they can be
* called from both class and instance methods. To use this class, write code
* like this:
* <p>
*
* <pre>
* Logger.log(&quot;something has happened&quot;);
* Logger.log(&quot;counter is &quot; + counter);
* </pre>
*
* @author Fran Litterio <francis.litterio@windriver.com>
*
*/
public final class Logger implements DebugOptionsListener {
public static final String TRACE_DEBUG_LOG = "org.eclipse.remote.telnet.core/debug/log"; //$NON-NLS-1$
public static final String TRACE_DEBUG_LOG_CHAR = "org.eclipse.remote.telnet.coredebug/log/char"; //$NON-NLS-1$
public static final String TRACE_DEBUG_LOG_VT100BACKEND = "org.eclipse.remote.telnet.core/debug/log/VT100Backend"; //$NON-NLS-1$
private static PrintStream logStream;
private static Logger logger;
private DebugOptions options;
public static void configure(BundleContext context) {
if (logger == null) {
logger = new Logger(context);
}
}
private Logger(BundleContext context) {
Hashtable<String, String> props = new Hashtable<String, String>(2);
props.put(DebugOptions.LISTENER_SYMBOLICNAME, Activator.PLUGIN_ID);
context.registerService(DebugOptionsListener.class.getName(), this, props);
}
/**
* Encodes a String such that non-printable control characters are
* converted into user-readable escape sequences for logging.
*
* @param message
* String to encode
* @return encoded String
*/
public static final String encode(String message) {
boolean encoded = false;
StringBuffer buf = new StringBuffer(message.length() + 32);
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
switch (c) {
case '\\':
case '\'':
buf.append('\\');
buf.append(c);
encoded = true;
break;
case '\r':
buf.append('\\');
buf.append('r');
encoded = true;
break;
case '\n':
buf.append('\\');
buf.append('n');
encoded = true;
break;
case '\t':
buf.append('\\');
buf.append('t');
encoded = true;
break;
case '\f':
buf.append('\\');
buf.append('f');
encoded = true;
break;
case '\b':
buf.append('\\');
buf.append('b');
encoded = true;
break;
default:
if (c <= '\u000f') {
buf.append('\\');
buf.append('x');
buf.append('0');
buf.append(Integer.toHexString(c));
encoded = true;
} else if (c >= ' ' && c < '\u007f') {
buf.append(c);
} else if (c <= '\u00ff') {
buf.append('\\');
buf.append('x');
buf.append(Integer.toHexString(c));
encoded = true;
} else {
buf.append('\\');
buf.append('u');
if (c <= '\u0fff') {
buf.append('0');
}
buf.append(Integer.toHexString(c));
encoded = true;
}
}
}
if (encoded) {
return buf.toString();
}
return message;
}
/**
* Checks if logging is enabled.
*
* @return true if logging is enabled.
*/
public static final boolean isLogEnabled() {
return (logStream != null);
}
/**
* Logs the specified message. Do not append a newline to parameter
* <i>message</i>. This method does that for you.
*
* @param message
* A String containing the message to log.
*/
public static final void log(String message) {
if (logStream != null) {
// Read my own stack to get the class name, method name, and line
// number of
// where this method was called.
StackTraceElement caller = new Throwable().getStackTrace()[1];
int lineNumber = caller.getLineNumber();
String className = caller.getClassName();
String methodName = caller.getMethodName();
className = className.substring(className.lastIndexOf('.') + 1);
logStream.println(className + "." + methodName + ":" + lineNumber + ": " + message); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
logStream.flush();
}
}
/**
* Writes a stack trace for an exception to both Standard Error and to the
* log file.
*/
public static final void logException(Exception ex) {
// log in eclipse error log
if (Activator.getDefault() != null) {
Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, ex.getMessage(), ex));
} else {
ex.printStackTrace();
}
// Additional Tracing for debug purposes:
// Read my own stack to get the class name, method name, and line number
// of where this method was called
if (logStream != null) {
StackTraceElement caller = new Throwable().getStackTrace()[1];
int lineNumber = caller.getLineNumber();
String className = caller.getClassName();
String methodName = caller.getMethodName();
className = className.substring(className.lastIndexOf('.') + 1);
PrintStream tmpStream = System.err;
if (logStream != null) {
tmpStream = logStream;
}
tmpStream.println(className + "." + methodName + ":" + lineNumber + ": " + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
"Caught exception: " + ex); //$NON-NLS-1$
ex.printStackTrace(tmpStream);
}
}
@Override
public void optionsChanged(DebugOptions options) {
this.options = options;
// Any of the three known debugging options turns on the creation of the log file
boolean createLogFile = isOptionEnabled(TRACE_DEBUG_LOG) || isOptionEnabled(TRACE_DEBUG_LOG_CHAR)
|| isOptionEnabled(TRACE_DEBUG_LOG_VT100BACKEND);
// Log only if tracing is enabled
if (createLogFile && Activator.getDefault() != null) {
IPath logFile = Platform.getStateLocation(Activator.getDefault().getBundle());
if (logFile != null && logFile.toFile().isDirectory()) {
logFile = logFile.append("tmterminal.log"); //$NON-NLS-1$
try {
logStream = new PrintStream(new FileOutputStream(logFile.toFile(), true));
} catch (Exception ex) {
logStream = System.err;
logStream.println("Exception when opening log file -- logging to stderr!"); //$NON-NLS-1$
ex.printStackTrace(logStream);
}
}
}
}
public boolean isOptionEnabled(String option) {
if (options == null) {
return false;
}
return options.getBooleanOption(Activator.PLUGIN_ID + option, false);
}
}

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.core.messages;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.remote.telnet.internal.core.messages.messages"; //$NON-NLS-1$
public static String TelnetCommandShell_0;
public static String TelnetProtocol_0;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,12 @@
################################################################################
# Copyright (c) 2015 IBM Corporation, and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# IBM Corporation - initial contribution
################################################################################
TelnetCommandShell_0=Unknown host:
TelnetProtocol_0=Connection closed by foreign host.

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1 @@
/bin/

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.telnet.ui</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,15 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.remote.telnet.ui;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.remote.telnet.internal.ui.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.remote.core;bundle-version="2.0.0",
org.eclipse.remote.ui;bundle-version="2.0.0",
org.eclipse.remote.telnet.core;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>May 2, 2006</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org.</p>
</body>
</html>

View file

@ -0,0 +1,27 @@
# about.ini
# contains information about a feature
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# "%key" are externalized strings defined in about.properties
# This file does not need to be translated.
# Property "aboutText" contains blurb for "About" dialog (translated)
aboutText=%blurb
# Property "windowImage" contains path to window icon (16x16)
# needed for primary features only
# Property "featureImage" contains path to feature image (32x32)
featureImage=ptp_logo_icon32.png
# Property "aboutImage" contains path to product image (500x330 or 115x164)
# needed for primary features only
# Property "appName" contains name of the application (not translated)
# needed for primary features only
# Property "welcomePage" contains path to welcome page (special XML-based format)
# optional
# Property "welcomePerspective" contains the id of the perspective in which the
# welcome page is to be opened.
# optional

View file

@ -0,0 +1,6 @@
# about.mappings
# contains fill-ins for about.properties
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# This file does not need to be translated.
0=@build@

View file

@ -0,0 +1,22 @@
###############################################################################
# Copyright (c) 2015 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# IBM Corporation - initial API and implementation
###############################################################################
# NLS_MESSAGEFORMAT_NONE
# NLS_ENCODING=UTF-8
blurb=Telnet Remote Services\n\
\n\
Version: {featureVersion}\n\
Build id: {0}\n\
\n\
Copyright (c) 2015 IBM Corporation, and others. All rights reserved.\n\
Visit http://www.eclipse.org/ptp\n

View file

@ -0,0 +1,12 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
about.html,\
about.ini,\
about.mappings,\
about.properties,\
ptp_logo_icon32.png,\
icons/,\
plugin.properties

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View file

@ -0,0 +1,2 @@
bundleName = Remote Serial Port Services UI
providerName = Eclipse PTP

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.remote.core.remoteServices">
<connectionTypeService
connectionTypeId="org.eclipse.remote.telnet.core.connectionType"
factory="org.eclipse.remote.telnet.internal.ui.TelnetConnectionsUI$Factory"
service="org.eclipse.remote.ui.IRemoteUIConnectionService">
</connectionTypeService>
</extension>
</plugin>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>1.1.1-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.remote.serial.ui</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.ui;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.remote.telnet.ui"; //$NON-NLS-1$
// Image keys
public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
getImageRegistry().put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "/icons/telnet.png")); //$NON-NLS-1$
}
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
public static void log(IStatus status) {
plugin.getLog().log(status);
}
public static void log(Exception e) {
if (e instanceof CoreException) {
log(((CoreException) e).getStatus());
} else {
log(new Status(IStatus.ERROR, PLUGIN_ID, e.getLocalizedMessage(), e));
}
}
public static <T> T getService(Class<T> service) {
BundleContext context = plugin.getBundle().getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.ui;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.remote.telnet.internal.ui.messages"; //$NON-NLS-1$
public static String NewSerialPortConnectionWizardPage_BaudRateLabel;
public static String NewSerialPortConnectionWizardPage_ByteSizeLabel;
public static String NewSerialPortConnectionWizardPage_Description;
public static String NewSerialPortConnectionWizardPage_NameLabel;
public static String NewSerialPortConnectionWizardPage_ParityLabel;
public static String NewSerialPortConnectionWizardPage_PortLabel;
public static String NewSerialPortConnectionWizardPage_StopBitsLabel;
public static String NewSerialPortConnectionWizardPage_Title;
public static String TelnetConnectionWizardPage_0;
public static String TelnetConnectionWizardPage_1;
public static String TelnetConnectionWizardPage_2;
public static String TelnetConnectionWizardPage_3;
public static String TelnetConnectionWizardPage_4;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.ui;
import java.util.Set;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
import org.eclipse.swt.widgets.Shell;
public class TelnetConnectionWizard extends Wizard implements IRemoteUIConnectionWizard {
private TelnetConnectionWizardPage page;
private IRemoteConnectionWorkingCopy workingCopy;
private final Shell shell;
private final IRemoteConnectionType connectionType;
public TelnetConnectionWizard(Shell shell, IRemoteConnectionType connectionType) {
this.shell = shell;
this.connectionType = connectionType;
}
@Override
public void addPages() {
page = new TelnetConnectionWizardPage();
if (workingCopy != null) {
IRemoteConnectionHostService hostSvc = workingCopy.getService(IRemoteConnectionHostService.class);
if (hostSvc != null) {
page.setHost(hostSvc.getHostname());
page.setPort(hostSvc.getPort());
page.setTimeout(hostSvc.getTimeout());
}
}
addPage(page);
}
@Override
public boolean performFinish() {
IRemoteConnection conn = getConnection();
if (conn != null) {
IRemoteConnectionHostService hostSvc = conn.getService(IRemoteConnectionHostService.class);
if (hostSvc != null) {
hostSvc.setHostname(page.getHost());
hostSvc.setPort(page.getPort());
hostSvc.setTimeout(page.getTimeout());
return true;
}
}
return false;
}
@Override
public IRemoteConnectionWorkingCopy open() {
WizardDialog dialog = new WizardDialog(shell, this);
dialog.setBlockOnOpen(true);
if (dialog.open() == WizardDialog.OK) {
return getConnection();
}
return null;
}
@Override
public IRemoteConnectionWorkingCopy getConnection() {
if (workingCopy == null) {
try {
workingCopy = connectionType.newConnection(page.getHost());
} catch (RemoteConnectionException e) {
Activator.log(e.getStatus());
}
}
return workingCopy;
}
@Override
public void setConnection(IRemoteConnectionWorkingCopy connection) {
workingCopy = connection;
}
@Override
public void setConnectionName(String name) {
// Ignored
}
@Override
public void setInvalidConnectionNames(Set<String> names) {
// Ignored
}
}

View file

@ -0,0 +1,142 @@
/*******************************************************************************
* Copyright (c) 2015 IBM Corporation, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial contribution
*******************************************************************************/
package org.eclipse.remote.telnet.internal.ui;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.remote.telnet.core.TelnetConnection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class TelnetConnectionWizardPage extends WizardPage {
private String host;
private int port = TelnetConnection.DEFAULT_PORT;
private int timeout = TelnetConnection.DEFAULT_TIMEOUT;
private Text hostText;
private Text portText;
private Text timeoutText;
protected TelnetConnectionWizardPage() {
super(TelnetConnectionWizardPage.class.getName());
setDescription(Messages.TelnetConnectionWizardPage_0);
setTitle(Messages.TelnetConnectionWizardPage_1);
}
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
Label nameLabel = new Label(comp, SWT.NONE);
nameLabel.setText(Messages.TelnetConnectionWizardPage_2);
hostText = new Text(comp, SWT.BORDER | SWT.SINGLE);
hostText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
hostText.setText(host != null ? host : ""); //$NON-NLS-1$
hostText.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
updateStatus();
}
@Override
public void keyPressed(KeyEvent e) {
// Ignore
}
});
Label portLabel = new Label(comp, SWT.NONE);
portLabel.setText(Messages.TelnetConnectionWizardPage_3);
portText = new Text(comp, SWT.BORDER | SWT.SINGLE);
portText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
portText.setText(port < 0 ? "" : Integer.toString(port)); //$NON-NLS-1$
portText.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
updateStatus();
}
@Override
public void keyPressed(KeyEvent e) {
// Ignore
}
});
Label timeoutLabel = new Label(comp, SWT.NONE);
timeoutLabel.setText(Messages.TelnetConnectionWizardPage_4);
timeoutText = new Text(comp, SWT.BORDER | SWT.SINGLE);
timeoutText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
timeoutText.setText(timeout < 0 ? "" : Integer.toString(timeout)); //$NON-NLS-1$
timeoutText.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
updateStatus();
}
@Override
public void keyPressed(KeyEvent e) {
// Ignore
}
});
setControl(comp);
updateStatus();
}
private void updateStatus() {
host = hostText.getText();
try {
port = Integer.parseInt(portText.getText());
} catch (NumberFormatException e) {
port = -1;
}
try {
timeout = Integer.parseInt(timeoutText.getText());
} catch (NumberFormatException e) {
timeout = -1;
}
setPageComplete(!host.isEmpty());
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public int getTimeout() {
return timeout;
}
public void setHost(String host) {
this.host = host;
}
public void setPort(int port) {
this.port = port;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
}

View file

@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - initial contribution
* Greg Watson (IBM) - Adapted for telnet service
*******************************************************************************/
package org.eclipse.remote.telnet.internal.ui;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteConnectionType.Service;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.ui.AbstractRemoteUIConnectionService;
import org.eclipse.remote.ui.IRemoteUIConnectionService;
import org.eclipse.remote.ui.IRemoteUIConnectionWizard;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
public class TelnetConnectionsUI extends AbstractRemoteUIConnectionService {
private final IRemoteConnectionType connectionType;
private TelnetConnectionsUI(IRemoteConnectionType connectionType) {
this.connectionType = connectionType;
}
public static class Factory implements IRemoteConnectionType.Service.Factory {
@SuppressWarnings("unchecked")
@Override
public <T extends Service> T getService(IRemoteConnectionType connectionType, Class<T> service) {
if (IRemoteUIConnectionService.class.equals(service)) {
return (T) new TelnetConnectionsUI(connectionType);
}
return null;
}
}
@Override
public IRemoteConnectionType getConnectionType() {
return connectionType;
}
@Override
public IRemoteUIConnectionWizard getConnectionWizard(Shell shell) {
return new TelnetConnectionWizard(shell, connectionType);
}
@Override
public void openConnectionWithProgress(Shell shell, IRunnableContext context, final IRemoteConnection connection) {
try {
IRunnableWithProgress op = new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
connection.open(monitor);
} catch (RemoteConnectionException e) {
throw new InvocationTargetException(e);
}
if (monitor.isCanceled()) {
throw new InterruptedException();
}
}
};
if (context != null) {
context.run(true, true, op);
} else {
new ProgressMonitorDialog(shell).run(true, true, op);
}
} catch (InvocationTargetException | InterruptedException e) {
Activator.log(e);
}
}
@Override
public ILabelProvider getLabelProvider() {
return new DefaultLabelProvider() {
@Override
public Image getImage(Object element) {
return Activator.getDefault().getImageRegistry().get(Activator.IMG_CONNECTION_TYPE);
}
};
}
}

View file

@ -0,0 +1,23 @@
################################################################################
# Copyright (c) 2015 IBM Corporation, and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# IBM Corporation - initial contribution
################################################################################
NewSerialPortConnectionWizardPage_BaudRateLabel=Baud rate:
NewSerialPortConnectionWizardPage_ByteSizeLabel=Data size:
NewSerialPortConnectionWizardPage_Description=New serial port connection settings
NewSerialPortConnectionWizardPage_NameLabel=Connection name:
NewSerialPortConnectionWizardPage_ParityLabel=Parity:
NewSerialPortConnectionWizardPage_PortLabel=Serial port:
NewSerialPortConnectionWizardPage_StopBitsLabel=Stop bits:
NewSerialPortConnectionWizardPage_Title=New Serial Port Connection
TelnetConnectionWizardPage_0=New telnet connection settings
TelnetConnectionWizardPage_1=New Telnet Connection
TelnetConnectionWizardPage_2=Host
TelnetConnectionWizardPage_3=Port:
TelnetConnectionWizardPage_4=Timeout: