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:
parent
8148e71c38
commit
880e5906e3
51 changed files with 3574 additions and 0 deletions
17
org.eclipse.remote.telnet-feature/.project
Normal file
17
org.eclipse.remote.telnet-feature/.project
Normal 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>
|
4
org.eclipse.remote.telnet-feature/build.properties
Normal file
4
org.eclipse.remote.telnet-feature/build.properties
Normal file
|
@ -0,0 +1,4 @@
|
|||
bin.includes = feature.xml,\
|
||||
feature.properties,\
|
||||
epl-v10.html,\
|
||||
eclipse_update_120.jpg
|
BIN
org.eclipse.remote.telnet-feature/eclipse_update_120.jpg
Normal file
BIN
org.eclipse.remote.telnet-feature/eclipse_update_120.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
328
org.eclipse.remote.telnet-feature/epl-v10.html
Normal file
328
org.eclipse.remote.telnet-feature/epl-v10.html
Normal 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 ("AGREEMENT"). 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'>"Contribution" 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'>"Contributor" means any person or
|
||||
entity that distributes the Program.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Licensed Patents " 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'>"Program" means the Contributions
|
||||
distributed in accordance with this Agreement.</span> </p>
|
||||
|
||||
<p><span style='font-size:10.0pt'>"Recipient" 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 ("Commercial
|
||||
Contributor") hereby agrees to defend and indemnify every other
|
||||
Contributor ("Indemnified Contributor") against any losses, damages and
|
||||
costs (collectively "Losses") 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 "AS IS" 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]> <![endif]><o:p></o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
24
org.eclipse.remote.telnet-feature/feature.properties
Normal file
24
org.eclipse.remote.telnet-feature/feature.properties
Normal 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
|
36
org.eclipse.remote.telnet-feature/feature.xml
Normal file
36
org.eclipse.remote.telnet-feature/feature.xml
Normal 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>
|
49
org.eclipse.remote.telnet-feature/pom.xml
Normal file
49
org.eclipse.remote.telnet-feature/pom.xml
Normal 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>
|
7
org.eclipse.remote.telnet.core/.classpath
Normal file
7
org.eclipse.remote.telnet.core/.classpath
Normal 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>
|
1
org.eclipse.remote.telnet.core/.gitignore
vendored
Normal file
1
org.eclipse.remote.telnet.core/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/bin/
|
28
org.eclipse.remote.telnet.core/.project
Normal file
28
org.eclipse.remote.telnet.core/.project
Normal 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>
|
|
@ -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
|
14
org.eclipse.remote.telnet.core/META-INF/MANIFEST.MF
Normal file
14
org.eclipse.remote.telnet.core/META-INF/MANIFEST.MF
Normal 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
|
22
org.eclipse.remote.telnet.core/about.html
Normal file
22
org.eclipse.remote.telnet.core/about.html
Normal 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 ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). 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, "Program" 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 ("Redistributor") 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>
|
27
org.eclipse.remote.telnet.core/about.ini
Normal file
27
org.eclipse.remote.telnet.core/about.ini
Normal 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
|
6
org.eclipse.remote.telnet.core/about.mappings
Normal file
6
org.eclipse.remote.telnet.core/about.mappings
Normal 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@
|
22
org.eclipse.remote.telnet.core/about.properties
Normal file
22
org.eclipse.remote.telnet.core/about.properties
Normal 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
|
||||
|
11
org.eclipse.remote.telnet.core/build.properties
Normal file
11
org.eclipse.remote.telnet.core/build.properties
Normal 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
|
2
org.eclipse.remote.telnet.core/plugin.properties
Normal file
2
org.eclipse.remote.telnet.core/plugin.properties
Normal file
|
@ -0,0 +1,2 @@
|
|||
bundleName = Remote Serial Port Services
|
||||
providerName = Eclipse PTP
|
32
org.eclipse.remote.telnet.core/plugin.xml
Normal file
32
org.eclipse.remote.telnet.core/plugin.xml
Normal 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>
|
16
org.eclipse.remote.telnet.core/pom.xml
Normal file
16
org.eclipse.remote.telnet.core/pom.xml
Normal 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>
|
BIN
org.eclipse.remote.telnet.core/ptp_logo_icon32.png
Normal file
BIN
org.eclipse.remote.telnet.core/ptp_logo_icon32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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("something has happened");
|
||||
* Logger.log("counter is " + 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);
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
}
|
|
@ -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.
|
7
org.eclipse.remote.telnet.ui/.classpath
Normal file
7
org.eclipse.remote.telnet.ui/.classpath
Normal 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>
|
1
org.eclipse.remote.telnet.ui/.gitignore
vendored
Normal file
1
org.eclipse.remote.telnet.ui/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/bin/
|
28
org.eclipse.remote.telnet.ui/.project
Normal file
28
org.eclipse.remote.telnet.ui/.project
Normal 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>
|
|
@ -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
|
15
org.eclipse.remote.telnet.ui/META-INF/MANIFEST.MF
Normal file
15
org.eclipse.remote.telnet.ui/META-INF/MANIFEST.MF
Normal 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
|
22
org.eclipse.remote.telnet.ui/about.html
Normal file
22
org.eclipse.remote.telnet.ui/about.html
Normal 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 ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). 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, "Program" 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 ("Redistributor") 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>
|
27
org.eclipse.remote.telnet.ui/about.ini
Normal file
27
org.eclipse.remote.telnet.ui/about.ini
Normal 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
|
6
org.eclipse.remote.telnet.ui/about.mappings
Normal file
6
org.eclipse.remote.telnet.ui/about.mappings
Normal 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@
|
22
org.eclipse.remote.telnet.ui/about.properties
Normal file
22
org.eclipse.remote.telnet.ui/about.properties
Normal 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
|
||||
|
12
org.eclipse.remote.telnet.ui/build.properties
Normal file
12
org.eclipse.remote.telnet.ui/build.properties
Normal 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
|
BIN
org.eclipse.remote.telnet.ui/icons/telnet.png
Normal file
BIN
org.eclipse.remote.telnet.ui/icons/telnet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
2
org.eclipse.remote.telnet.ui/plugin.properties
Normal file
2
org.eclipse.remote.telnet.ui/plugin.properties
Normal file
|
@ -0,0 +1,2 @@
|
|||
bundleName = Remote Serial Port Services UI
|
||||
providerName = Eclipse PTP
|
13
org.eclipse.remote.telnet.ui/plugin.xml
Normal file
13
org.eclipse.remote.telnet.ui/plugin.xml
Normal 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>
|
16
org.eclipse.remote.telnet.ui/pom.xml
Normal file
16
org.eclipse.remote.telnet.ui/pom.xml
Normal 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>
|
BIN
org.eclipse.remote.telnet.ui/ptp_logo_icon32.png
Normal file
BIN
org.eclipse.remote.telnet.ui/ptp_logo_icon32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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() {
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -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:
|
Loading…
Add table
Reference in a new issue